Merge from Chromium at DEPS revision 257591

This commit was generated by merge_to_master.py.

Change-Id: I834f3ca85c1ef7ec2c1061847a3d92aa461da043
diff --git a/Source/core/DEPS b/Source/core/DEPS
index d8be74f..b73f038 100644
--- a/Source/core/DEPS
+++ b/Source/core/DEPS
@@ -9,10 +9,6 @@
 
 # core/ should not depend on modules/ at all, but there are a number of pieces
 # of code that do. Please don't add to this list of exceptions.
-    "!modules/encryptedmedia/MediaKeyNeededEvent.h",
-    "!modules/encryptedmedia/MediaKeys.h",
     "!modules/filesystem/DraggedIsolatedFileSystem.h",
     "!modules/webaudio/MediaElementAudioSourceNode.h",
-    "!modules/webdatabase/DatabaseManager.h",
-    "!modules/webdatabase/DatabaseTask.h",
 ]
diff --git a/Source/core/Init.cpp b/Source/core/Init.cpp
index b48d1f6..3fbe791 100644
--- a/Source/core/Init.cpp
+++ b/Source/core/Init.cpp
@@ -39,11 +39,12 @@
 #include "HTMLNames.h"
 #include "InputTypeNames.h"
 #include "MathMLNames.h"
+#include "MediaFeatureNames.h"
+#include "MediaTypeNames.h"
 #include "SVGNames.h"
 #include "XLinkNames.h"
 #include "XMLNSNames.h"
 #include "XMLNames.h"
-#include "core/css/MediaFeatureNames.h"
 #include "core/html/parser/HTMLParserThread.h"
 #include "heap/Heap.h"
 #include "platform/EventTracer.h"
@@ -76,6 +77,7 @@
     FontFamilyNames::init();
     InputTypeNames::init();
     MediaFeatureNames::init();
+    MediaTypeNames::init();
     WTF::StringStatics::init();
     QualifiedName::init();
     Partitions::init();
diff --git a/Source/core/OWNERS b/Source/core/OWNERS
index 28beb4c..529dfde 100644
--- a/Source/core/OWNERS
+++ b/Source/core/OWNERS
@@ -29,6 +29,7 @@
 jochen@chromium.org
 junov@chromium.org
 kbr@chromium.org
+keishi@chromium.org
 kenneth.r.christiansen@intel.com
 kinuko@chromium.org
 levin@chromium.org
diff --git a/Source/core/accessibility/AXARIAGrid.cpp b/Source/core/accessibility/AXARIAGrid.cpp
index beac9c9..aa59da0 100644
--- a/Source/core/accessibility/AXARIAGrid.cpp
+++ b/Source/core/accessibility/AXARIAGrid.cpp
@@ -74,7 +74,7 @@
     if (!row->accessibilityIsIgnored())
         m_children.append(row);
     else
-        m_children.append(row->children());
+        m_children.appendVector(row->children());
 
     appendedRows.add(row);
     return true;
diff --git a/Source/core/accessibility/AXImageMapLink.cpp b/Source/core/accessibility/AXImageMapLink.cpp
index e497704..02ce023 100644
--- a/Source/core/accessibility/AXImageMapLink.cpp
+++ b/Source/core/accessibility/AXImageMapLink.cpp
@@ -37,8 +37,8 @@
 using namespace HTMLNames;
 
 AXImageMapLink::AXImageMapLink()
-    : m_areaElement(0)
-    , m_mapElement(0)
+    : m_areaElement(nullptr)
+    , m_mapElement(nullptr)
 {
 }
 
@@ -49,8 +49,8 @@
 void AXImageMapLink::detachFromParent()
 {
     AXMockObject::detachFromParent();
-    m_areaElement = 0;
-    m_mapElement = 0;
+    m_areaElement = nullptr;
+    m_mapElement = nullptr;
 }
 
 PassRefPtr<AXImageMapLink> AXImageMapLink::create()
diff --git a/Source/core/accessibility/AXInlineTextBox.cpp b/Source/core/accessibility/AXInlineTextBox.cpp
index 9c5d703..7ba1129 100644
--- a/Source/core/accessibility/AXInlineTextBox.cpp
+++ b/Source/core/accessibility/AXInlineTextBox.cpp
@@ -64,7 +64,7 @@
 
 void AXInlineTextBox::detach()
 {
-    m_inlineTextBox = 0;
+    m_inlineTextBox = nullptr;
     m_axObjectCache = 0;
     AXObject::detach();
 }
diff --git a/Source/core/accessibility/AXList.cpp b/Source/core/accessibility/AXList.cpp
index c1cbe27..3015a1a 100644
--- a/Source/core/accessibility/AXList.cpp
+++ b/Source/core/accessibility/AXList.cpp
@@ -29,6 +29,7 @@
 #include "config.h"
 #include "core/accessibility/AXList.h"
 
+#include "core/html/HTMLUListElement.h"
 #include "core/rendering/RenderObject.h"
 
 using namespace std;
@@ -61,15 +62,13 @@
     if (!m_renderer)
         return false;
 
-    Node* node = m_renderer->node();
-
     // The ARIA spec says the "list" role is supposed to mimic a UL or OL tag.
     // Since it can't be both, it's probably OK to say that it's an un-ordered list.
     // On the Mac, there's no distinction to the client.
     if (ariaRoleAttribute() == ListRole)
         return true;
 
-    return node && node->hasTagName(ulTag);
+    return isHTMLUListElement(m_renderer->node());
 }
 
 bool AXList::isOrderedList() const
@@ -81,8 +80,7 @@
     if (ariaRoleAttribute() == DirectoryRole)
         return true;
 
-    Node* node = m_renderer->node();
-    return node && node->hasTagName(olTag);
+    return isHTMLOListElement(m_renderer->node());
 }
 
 bool AXList::isDescriptionList() const
@@ -90,8 +88,7 @@
     if (!m_renderer)
         return false;
 
-    Node* node = m_renderer->node();
-    return node && node->hasTagName(dlTag);
+    return isHTMLDListElement(m_renderer->node());
 }
 
 
diff --git a/Source/core/accessibility/AXListBox.cpp b/Source/core/accessibility/AXListBox.cpp
index 444c304..d306616 100644
--- a/Source/core/accessibility/AXListBox.cpp
+++ b/Source/core/accessibility/AXListBox.cpp
@@ -126,7 +126,7 @@
 AXObject* AXListBox::listBoxOptionAXObject(HTMLElement* element) const
 {
     // skip hr elements
-    if (!element || element->hasTagName(hrTag))
+    if (!element || isHTMLHRElement(*element))
         return 0;
 
     AXObject* listBoxObject = m_renderer->document().axObjectCache()->getOrCreate(ListBoxOptionRole);
diff --git a/Source/core/accessibility/AXListBoxOption.cpp b/Source/core/accessibility/AXListBoxOption.cpp
index 3708ccd..2aa6c2e 100644
--- a/Source/core/accessibility/AXListBoxOption.cpp
+++ b/Source/core/accessibility/AXListBoxOption.cpp
@@ -60,7 +60,7 @@
     if (!m_optionElement)
         return false;
 
-    if (m_optionElement->hasTagName(optgroupTag))
+    if (isHTMLOptGroupElement(*m_optionElement))
         return false;
 
     if (equalIgnoringCase(getAttribute(aria_disabledAttr), "true"))
@@ -74,10 +74,7 @@
 
 bool AXListBoxOption::isSelected() const
 {
-    if (!m_optionElement)
-        return false;
-
-    if (!m_optionElement->hasTagName(optionTag))
+    if (!isHTMLOptionElement(m_optionElement))
         return false;
 
     return toHTMLOptionElement(m_optionElement)->selected();
@@ -127,10 +124,7 @@
 
 bool AXListBoxOption::canSetSelectedAttribute() const
 {
-    if (!m_optionElement)
-        return false;
-
-    if (!m_optionElement->hasTagName(optionTag))
+    if (!isHTMLOptionElement(m_optionElement))
         return false;
 
     if (m_optionElement->isDisabledFormControl())
@@ -152,10 +146,10 @@
     if (!ariaLabel.isNull())
         return ariaLabel;
 
-    if (m_optionElement->hasTagName(optionTag))
+    if (isHTMLOptionElement(*m_optionElement))
         return toHTMLOptionElement(m_optionElement)->text();
 
-    if (m_optionElement->hasTagName(optgroupTag))
+    if (isHTMLOptGroupElement(*m_optionElement))
         return toHTMLOptGroupElement(m_optionElement)->groupLabelText();
 
     return String();
@@ -198,10 +192,10 @@
     if (!m_optionElement)
         return 0;
 
-    if (m_optionElement->hasTagName(optionTag))
+    if (isHTMLOptionElement(*m_optionElement))
         return toHTMLOptionElement(m_optionElement)->ownerSelectElement();
 
-    if (m_optionElement->hasTagName(optgroupTag))
+    if (isHTMLOptGroupElement(*m_optionElement))
         return toHTMLOptGroupElement(m_optionElement)->ownerSelectElement();
 
     return 0;
diff --git a/Source/core/accessibility/AXMediaControls.cpp b/Source/core/accessibility/AXMediaControls.cpp
index 52eebbe..ca7113e 100644
--- a/Source/core/accessibility/AXMediaControls.cpp
+++ b/Source/core/accessibility/AXMediaControls.cpp
@@ -30,6 +30,7 @@
 #include "config.h"
 #include "core/accessibility/AXMediaControls.h"
 
+#include "core/html/HTMLMediaElement.h"
 #include "platform/text/PlatformLocale.h"
 
 namespace WebCore {
@@ -259,7 +260,7 @@
 String AccessibilityMediaTimeline::valueDescription() const
 {
     Node* node = m_renderer->node();
-    if (!node->hasTagName(inputTag))
+    if (!isHTMLInputElement(node))
         return String();
 
     return localizedMediaTimeDescription(toHTMLInputElement(node)->value().toFloat());
diff --git a/Source/core/accessibility/AXMenuListOption.cpp b/Source/core/accessibility/AXMenuListOption.cpp
index 7dc61b7..0c657b3 100644
--- a/Source/core/accessibility/AXMenuListOption.cpp
+++ b/Source/core/accessibility/AXMenuListOption.cpp
@@ -38,7 +38,7 @@
 
 void AXMenuListOption::setElement(HTMLElement* element)
 {
-    ASSERT_ARG(element, element->hasTagName(optionTag));
+    ASSERT_ARG(element, isHTMLOptionElement(element));
     m_element = element;
 }
 
diff --git a/Source/core/accessibility/AXMenuListPopup.cpp b/Source/core/accessibility/AXMenuListPopup.cpp
index 145792a..b5641a5 100644
--- a/Source/core/accessibility/AXMenuListPopup.cpp
+++ b/Source/core/accessibility/AXMenuListPopup.cpp
@@ -66,7 +66,8 @@
 
 AXMenuListOption* AXMenuListPopup::menuListOptionAXObject(HTMLElement* element) const
 {
-    if (!element->hasTagName(optionTag))
+    ASSERT(element);
+    if (!isHTMLOptionElement(*element))
         return 0;
 
     AXObject* object = document()->axObjectCache()->getOrCreate(MenuListOptionRole);
diff --git a/Source/core/accessibility/AXNodeObject.cpp b/Source/core/accessibility/AXNodeObject.cpp
index f57327e..fa59758 100644
--- a/Source/core/accessibility/AXNodeObject.cpp
+++ b/Source/core/accessibility/AXNodeObject.cpp
@@ -38,6 +38,7 @@
 #include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLLegendElement.h"
 #include "core/html/HTMLSelectElement.h"
+#include "core/html/HTMLTextAreaElement.h"
 #include "core/rendering/RenderObject.h"
 #include "platform/UserGestureIndicator.h"
 #include "wtf/text/StringBuilder.h"
@@ -76,8 +77,8 @@
     if (node->isTextNode())
         return toText(node)->data();
 
-    if (node->hasTagName(inputTag))
-        return toHTMLInputElement(node)->value();
+    if (isHTMLInputElement(*node))
+        return toHTMLInputElement(*node).value();
 
     if (node->isHTMLElement()) {
         const AtomicString& alt = toHTMLElement(node)->getAttribute(altAttr);
@@ -184,42 +185,42 @@
         return LinkRole;
     if (node()->isTextNode())
         return StaticTextRole;
-    if (node()->hasTagName(buttonTag))
+    if (isHTMLButtonElement(*node()))
         return buttonRoleType();
-    if (node()->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(node());
-        if (input->isCheckbox())
+    if (isHTMLInputElement(*node())) {
+        HTMLInputElement& input = toHTMLInputElement(*node());
+        if (input.isCheckbox())
             return CheckBoxRole;
-        if (input->isRadioButton())
+        if (input.isRadioButton())
             return RadioButtonRole;
-        if (input->isTextButton())
+        if (input.isTextButton())
             return buttonRoleType();
-        if (input->isRangeControl())
+        if (input.isRangeControl())
             return SliderRole;
 
-        const AtomicString& type = input->getAttribute(typeAttr);
+        const AtomicString& type = input.getAttribute(typeAttr);
         if (equalIgnoringCase(type, "color"))
             return ColorWellRole;
 
         return TextFieldRole;
     }
-    if (node()->hasTagName(selectTag)) {
-        HTMLSelectElement* selectElement = toHTMLSelectElement(node());
-        return selectElement->multiple() ? ListBoxRole : PopUpButtonRole;
+    if (isHTMLSelectElement(*node())) {
+        HTMLSelectElement& selectElement = toHTMLSelectElement(*node());
+        return selectElement.multiple() ? ListBoxRole : PopUpButtonRole;
     }
-    if (node()->hasTagName(textareaTag))
+    if (isHTMLTextAreaElement(*node()))
         return TextAreaRole;
     if (headingLevel())
         return HeadingRole;
-    if (node()->hasTagName(divTag))
+    if (isHTMLDivElement(*node()))
         return DivRole;
-    if (node()->hasTagName(pTag))
+    if (isHTMLParagraphElement(*node()))
         return ParagraphRole;
-    if (node()->hasTagName(labelTag))
+    if (isHTMLLabelElement(*node()))
         return LabelRole;
     if (node()->isElementNode() && toElement(node())->isFocusable())
         return GroupRole;
-    if (node()->hasTagName(aTag) && isClickable())
+    if (isHTMLAnchorElement(*node()) && isClickable())
         return LinkRole;
 
     return UnknownRole;
@@ -321,7 +322,7 @@
     // cases already, so we don't need to include them here.
     if (roleValue() == WebAreaRole)
         return false;
-    if (node() && node()->hasTagName(bodyTag))
+    if (isHTMLBodyElement(node()))
         return false;
 
     // An SVG root is focusable by default, but it's probably not interactive, so don't
@@ -344,7 +345,7 @@
     }
 
     for (Element* parent = element->parentElement(); parent; parent = parent->parentElement()) {
-        if (parent->hasTagName(labelTag))
+        if (isHTMLLabelElement(*parent))
             return toHTMLLabelElement(parent);
     }
 
@@ -370,12 +371,10 @@
     if (!parent)
         return 0;
 
-    for (Node* sibling = parent->firstChild(); sibling; sibling = sibling->nextSibling()) {
-        if (sibling->isElementNode()) {
-            const AtomicString& siblingAriaRole = toElement(sibling)->getAttribute(roleAttr);
-            if (equalIgnoringCase(siblingAriaRole, role))
-                return toElement(sibling);
-        }
+    for (Element* sibling = ElementTraversal::firstChild(*parent); sibling; sibling = ElementTraversal::nextSibling(*sibling)) {
+        const AtomicString& siblingAriaRole = sibling->getAttribute(roleAttr);
+        if (equalIgnoringCase(siblingAriaRole, role))
+            return sibling;
     }
 
     return 0;
@@ -472,11 +471,7 @@
 
 bool AXNodeObject::isFieldset() const
 {
-    Node* node = this->node();
-    if (!node)
-        return false;
-
-    return node->hasTagName(fieldsetTag);
+    return isHTMLFieldSetElement(node());
 }
 
 bool AXNodeObject::isHeading() const
@@ -506,11 +501,8 @@
 bool AXNodeObject::isInputImage() const
 {
     Node* node = this->node();
-    if (!node)
-        return false;
-
-    if (roleValue() == ButtonRole && node->hasTagName(inputTag))
-        return toHTMLInputElement(node)->isImageButton();
+    if (roleValue() == ButtonRole && isHTMLInputElement(node))
+        return toHTMLInputElement(*node).isImageButton();
 
     return false;
 }
@@ -538,13 +530,13 @@
     if (equalIgnoringCase(ariaMultiSelectable, "false"))
         return false;
 
-    return node() && node()->hasTagName(selectTag) && toHTMLSelectElement(node())->multiple();
+    return isHTMLSelectElement(node()) && toHTMLSelectElement(*node()).multiple();
 }
 
 bool AXNodeObject::isNativeCheckboxOrRadio() const
 {
     Node* node = this->node();
-    if (!node || !node->hasTagName(inputTag))
+    if (!isHTMLInputElement(node))
         return false;
 
     HTMLInputElement* input = toHTMLInputElement(node);
@@ -557,14 +549,14 @@
     if (!node)
         return false;
 
-    if (node->hasTagName(imgTag))
+    if (isHTMLImageElement(*node))
         return true;
 
-    if (node->hasTagName(appletTag) || node->hasTagName(embedTag) || node->hasTagName(objectTag))
+    if (isHTMLAppletElement(*node) || isHTMLEmbedElement(*node) || isHTMLObjectElement(*node))
         return true;
 
-    if (node->hasTagName(inputTag))
-        return toHTMLInputElement(node)->isImageButton();
+    if (isHTMLInputElement(*node))
+        return toHTMLInputElement(*node).isImageButton();
 
     return false;
 }
@@ -575,10 +567,10 @@
     if (!node)
         return false;
 
-    if (node->hasTagName(textareaTag))
+    if (isHTMLTextAreaElement(*node))
         return true;
 
-    if (node->hasTagName(inputTag)) {
+    if (isHTMLInputElement(*node)) {
         HTMLInputElement* input = toHTMLInputElement(node);
         return input->isText() || input->isNumberField();
     }
@@ -603,7 +595,7 @@
 bool AXNodeObject::isPasswordField() const
 {
     Node* node = this->node();
-    if (!node || !node->hasTagName(inputTag))
+    if (!isHTMLInputElement(node))
         return false;
 
     if (ariaRoleAttribute() != UnknownRole)
@@ -629,8 +621,8 @@
         return false;
 
     // First test for native checkedness semantics
-    if (node->hasTagName(inputTag))
-        return toHTMLInputElement(node)->shouldAppearChecked();
+    if (isHTMLInputElement(*node))
+        return toHTMLInputElement(*node).shouldAppearChecked();
 
     // Else, if this is an ARIA checkbox or radio, respect the aria-checked attribute
     AccessibilityRole ariaRole = ariaRoleAttribute();
@@ -673,7 +665,7 @@
 bool AXNodeObject::isIndeterminate() const
 {
     Node* node = this->node();
-    if (!node || !node->hasTagName(inputTag))
+    if (!isHTMLInputElement(node))
         return false;
 
     return toHTMLInputElement(node)->shouldAppearIndeterminate();
@@ -704,13 +696,13 @@
     if (!node)
         return true;
 
-    if (node->hasTagName(textareaTag))
-        return toHTMLFormControlElement(node)->isReadOnly();
+    if (isHTMLTextAreaElement(*node))
+        return toHTMLTextAreaElement(*node).isReadOnly();
 
-    if (node->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(node);
-        if (input->isTextField())
-            return input->isReadOnly();
+    if (isHTMLInputElement(*node)) {
+        HTMLInputElement& input = toHTMLInputElement(*node);
+        if (input.isTextField())
+            return input.isReadOnly();
     }
 
     return !node->rendererIsEditable();
@@ -768,18 +760,13 @@
 bool AXNodeObject::canvasHasFallbackContent() const
 {
     Node* node = this->node();
-    if (!node || !node->hasTagName(canvasTag))
+    if (!isHTMLCanvasElement(node))
         return false;
 
     // If it has any children that are elements, we'll assume it might be fallback
     // content. If it has no children or its only children are not elements
     // (e.g. just text nodes), it doesn't have fallback content.
-    for (Node* child = node->firstChild(); child; child = child->nextSibling()) {
-        if (child->isElementNode())
-            return true;
-    }
-
-    return false;
+    return ElementTraversal::firstChild(*node);
 }
 
 bool AXNodeObject::exposesTitleUIElement() const
@@ -881,8 +868,8 @@
     if (!node)
         return String();
 
-    if (isNativeTextControl() && (node->hasTagName(textareaTag) || node->hasTagName(inputTag)))
-        return toHTMLTextFormControlElement(node)->value();
+    if (isNativeTextControl() && (isHTMLTextAreaElement(*node) || isHTMLInputElement(*node)))
+        return toHTMLTextFormControlElement(*node).value();
 
     if (!node->isElementNode())
         return String();
@@ -922,7 +909,7 @@
     if (!isColorWell())
         return;
 
-    if (!node() || !node()->hasTagName(inputTag))
+    if (!isHTMLInputElement(node()))
         return;
 
     HTMLInputElement* input = toHTMLInputElement(node());
@@ -952,10 +939,10 @@
     if (hasAttribute(aria_valuenowAttr))
         return getAttribute(aria_valuenowAttr).toFloat();
 
-    if (node() && node()->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(node());
-        if (input->isRangeControl())
-            return input->valueAsNumber();
+    if (isHTMLInputElement(node())) {
+        HTMLInputElement& input = toHTMLInputElement(*node());
+        if (input.isRangeControl())
+            return input.valueAsNumber();
     }
 
     return 0.0;
@@ -966,10 +953,10 @@
     if (hasAttribute(aria_valuemaxAttr))
         return getAttribute(aria_valuemaxAttr).toFloat();
 
-    if (node() && node()->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(node());
-        if (input->isRangeControl())
-            return input->maximum();
+    if (isHTMLInputElement(node())) {
+        HTMLInputElement& input = toHTMLInputElement(*node());
+        if (input.isRangeControl())
+            return input.maximum();
     }
 
     return 0.0;
@@ -980,10 +967,10 @@
     if (hasAttribute(aria_valueminAttr))
         return getAttribute(aria_valueminAttr).toFloat();
 
-    if (node() && node()->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(node());
-        if (input->isRangeControl())
-            return input->minimum();
+    if (isHTMLInputElement(node())) {
+        HTMLInputElement& input = toHTMLInputElement(*node());
+        if (input.isRangeControl())
+            return input.minimum();
     }
 
     return 0.0;
@@ -1010,17 +997,17 @@
     if (node->isTextNode())
         return textUnderElement();
 
-    if (node->hasTagName(selectTag)) {
-        HTMLSelectElement* selectElement = toHTMLSelectElement(node);
-        int selectedIndex = selectElement->selectedIndex();
-        const Vector<HTMLElement*> listItems = selectElement->listItems();
+    if (isHTMLSelectElement(*node)) {
+        HTMLSelectElement& selectElement = toHTMLSelectElement(*node);
+        int selectedIndex = selectElement.selectedIndex();
+        const Vector<HTMLElement*> listItems = selectElement.listItems();
         if (selectedIndex >= 0 && static_cast<size_t>(selectedIndex) < listItems.size()) {
             const AtomicString& overriddenDescription = listItems[selectedIndex]->fastGetAttribute(aria_labelAttr);
             if (!overriddenDescription.isNull())
                 return overriddenDescription;
         }
-        if (!selectElement->multiple())
-            return selectElement->value();
+        if (!selectElement.multiple())
+            return selectElement.value();
         return String();
     }
 
@@ -1164,27 +1151,27 @@
     if (!node)
         return String();
 
-    bool isInputTag = node->hasTagName(inputTag);
-    if (isInputTag) {
-        HTMLInputElement* input = toHTMLInputElement(node);
-        if (input->isTextButton())
-            return input->valueWithDefault();
+    bool isInputElement = isHTMLInputElement(*node);
+    if (isInputElement) {
+        HTMLInputElement& input = toHTMLInputElement(*node);
+        if (input.isTextButton())
+            return input.valueWithDefault();
     }
 
-    if (isInputTag || AXObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
+    if (isInputElement || AXObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
         HTMLLabelElement* label = labelForElement(toElement(node));
         if (label && !exposesTitleUIElement())
             return label->innerText();
     }
 
     // If this node isn't rendered, there's no inner text we can extract from a select element.
-    if (!isAXRenderObject() && node->hasTagName(selectTag))
+    if (!isAXRenderObject() && isHTMLSelectElement(*node))
         return String();
 
     switch (roleValue()) {
     case PopUpButtonRole:
         // Native popup buttons should not use their button children's text as a title. That value is retrieved through stringValue().
-        if (node->hasTagName(selectTag))
+        if (isHTMLSelectElement(*node))
             return String();
     case ButtonRole:
     case ToggleButtonRole:
@@ -1331,7 +1318,7 @@
     m_haveChildren = true;
 
     // The only time we add children from the DOM tree to a node with a renderer is when it's a canvas.
-    if (renderer() && !m_node->hasTagName(canvasTag))
+    if (renderer() && !isHTMLCanvasElement(*m_node))
         return;
 
     for (Node* child = m_node->firstChild(); child; child = child->nextSibling())
@@ -1398,11 +1385,11 @@
     if (!node)
         return 0;
 
-    if (node->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(node);
-        if (!input->isDisabledFormControl() && (isCheckboxOrRadio() || input->isTextButton()))
-            return input;
-    } else if (node->hasTagName(buttonTag)) {
+    if (isHTMLInputElement(*node)) {
+        HTMLInputElement& input = toHTMLInputElement(*node);
+        if (!input.isDisabledFormControl() && (isCheckboxOrRadio() || input.isTextButton()))
+            return &input;
+    } else if (isHTMLButtonElement(*node)) {
         return toElement(node);
     }
 
@@ -1415,7 +1402,7 @@
     if (isImageButton())
         return toElement(node);
 
-    if (node->hasTagName(selectTag))
+    if (isHTMLSelectElement(*node))
         return toElement(node);
 
     switch (roleValue()) {
@@ -1447,7 +1434,7 @@
     // search up the DOM tree for an anchor element
     // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
     for ( ; node; node = node->parentNode()) {
-        if (node->hasTagName(aTag) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
+        if (isHTMLAnchorElement(*node) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
             return toElement(node);
     }
 
@@ -1495,7 +1482,7 @@
 
     // find if this has a parent that is a label
     for (Node* parentNode = node(); parentNode; parentNode = parentNode->parentNode()) {
-        if (parentNode->hasTagName(labelTag))
+        if (isHTMLLabelElement(*parentNode))
             return toHTMLLabelElement(parentNode);
     }
 
@@ -1509,7 +1496,7 @@
 
     Document* document = this->document();
     if (!on) {
-        document->setFocusedElement(0);
+        document->setFocusedElement(nullptr);
     } else {
         Node* node = this->node();
         if (node && node->isElementNode()) {
@@ -1517,11 +1504,11 @@
             // That is a problem when focus is removed from the webpage to chrome, and then returns.
             // In these cases, we need to do what keyboard and mouse focus do, which is reset focus first.
             if (document->focusedElement() == node)
-                document->setFocusedElement(0);
+                document->setFocusedElement(nullptr);
 
             toElement(node)->focus();
         } else {
-            document->setFocusedElement(0);
+            document->setFocusedElement(nullptr);
         }
     }
 }
@@ -1569,10 +1556,10 @@
 
 void AXNodeObject::selectionChanged()
 {
-    // When the selection changes, post the notification on the first ancestor that's an
-    // ARIA text box, or that's marked as contentEditable, otherwise post the notification
-    // on the web area.
-    if (isNonNativeTextControl() || isWebArea())
+    // Post the selected text changed event on the first ancestor that's
+    // focused (to handle form controls, ARIA text boxes and contentEditable),
+    // or the web area if the selection is just in the document somewhere.
+    if (isFocused() || isWebArea())
         axObjectCache()->postNotification(this, document(), AXObjectCache::AXSelectedTextChanged, true);
     else
         AXObject::selectionChanged(); // Calls selectionChanged on parent.
@@ -1633,7 +1620,7 @@
 
     Node* owner = document->ownerElement();
     if (owner) {
-        if (owner->hasTagName(frameTag) || owner->hasTagName(iframeTag)) {
+        if (isHTMLFrameElement(*owner) || isHTMLIFrameElement(*owner)) {
             const AtomicString& title = toElement(owner)->getAttribute(titleAttr);
             if (!title.isEmpty())
                 return title;
@@ -1743,8 +1730,7 @@
     if (!node)
         return;
 
-    bool isInputTag = node->hasTagName(inputTag);
-    if (isInputTag || AXObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
+    if (isHTMLInputElement(*node) || AXObject::isARIAInput(ariaRoleAttribute()) || isControl()) {
         HTMLLabelElement* label = labelForElement(toElement(node));
         if (label) {
             AXObject* labelObject = axObjectCache()->getOrCreate(label);
@@ -1764,17 +1750,16 @@
     if (!node)
         return;
 
-    bool isInputTag = node->hasTagName(inputTag);
-    if (isInputTag) {
-        HTMLInputElement* input = toHTMLInputElement(node);
-        if (input->isTextButton()) {
-            textOrder.append(AccessibilityText(input->valueWithDefault(), VisibleText));
+    if (isHTMLInputElement(*node)) {
+        HTMLInputElement& input = toHTMLInputElement(*node);
+        if (input.isTextButton()) {
+            textOrder.append(AccessibilityText(input.valueWithDefault(), VisibleText));
             return;
         }
     }
 
     // If this node isn't rendered, there's no inner text we can extract from a select element.
-    if (!isAXRenderObject() && node->hasTagName(selectTag))
+    if (!isAXRenderObject() && isHTMLSelectElement(*node))
         return;
 
     bool useTextUnderElement = false;
@@ -1782,7 +1767,7 @@
     switch (roleValue()) {
     case PopUpButtonRole:
         // Native popup buttons should not use their button children's text as a title. That value is retrieved through stringValue().
-        if (node->hasTagName(selectTag))
+        if (isHTMLSelectElement(*node))
             break;
     case ButtonRole:
     case ToggleButtonRole:
diff --git a/Source/core/accessibility/AXNodeObject.h b/Source/core/accessibility/AXNodeObject.h
index 9daabec..8b96571 100644
--- a/Source/core/accessibility/AXNodeObject.h
+++ b/Source/core/accessibility/AXNodeObject.h
@@ -37,7 +37,7 @@
 
 class AXObjectCache;
 class Element;
-class Frame;
+class LocalFrame;
 class FrameView;
 class HitTestResult;
 class HTMLAnchorElement;
diff --git a/Source/core/accessibility/AXObject.cpp b/Source/core/accessibility/AXObject.cpp
index 03cf996..4049f91 100644
--- a/Source/core/accessibility/AXObject.cpp
+++ b/Source/core/accessibility/AXObject.cpp
@@ -33,7 +33,7 @@
 #include "core/dom/NodeTraversal.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderListItem.h"
 #include "core/rendering/RenderTheme.h"
 #include "core/rendering/RenderView.h"
@@ -70,7 +70,7 @@
         { "contentinfo", ContentInfoRole },
         { "dialog", DialogRole },
         { "directory", DirectoryRole },
-        { "grid", TableRole },
+        { "grid", GridRole },
         { "gridcell", CellRole },
         { "columnheader", ColumnHeaderRole },
         { "combobox", ComboBoxRole },
diff --git a/Source/core/accessibility/AXObject.h b/Source/core/accessibility/AXObject.h
index b3fa7fd..cef5a0a 100644
--- a/Source/core/accessibility/AXObject.h
+++ b/Source/core/accessibility/AXObject.h
@@ -42,7 +42,7 @@
 class AXObject;
 class AXObjectCache;
 class Element;
-class Frame;
+class LocalFrame;
 class FrameView;
 class HTMLAnchorElement;
 class HTMLAreaElement;
@@ -426,6 +426,10 @@
     virtual AXObject* activeDescendant() const { return 0; }
     virtual String ariaDescribedByAttribute() const { return String(); }
     virtual void ariaFlowToElements(AccessibilityChildrenVector&) const { }
+    virtual void ariaControlsElements(AccessibilityChildrenVector&) const { }
+    virtual void ariaDescribedbyElements(AccessibilityChildrenVector& describedby) const { };
+    virtual void ariaLabelledbyElements(AccessibilityChildrenVector& labelledby) const { };
+    virtual void ariaOwnsElements(AccessibilityChildrenVector& owns) const { };
     virtual bool ariaHasPopup() const { return false; }
     bool ariaIsMultiline() const;
     virtual String ariaLabeledByAttribute() const { return String(); }
diff --git a/Source/core/accessibility/AXObjectCache.cpp b/Source/core/accessibility/AXObjectCache.cpp
index 0c74d9a..fe40706 100644
--- a/Source/core/accessibility/AXObjectCache.cpp
+++ b/Source/core/accessibility/AXObjectCache.cpp
@@ -56,7 +56,7 @@
 #include "core/accessibility/AXTableHeaderContainer.h"
 #include "core/accessibility/AXTableRow.h"
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAreaElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLInputElement.h"
@@ -107,10 +107,10 @@
 bool AXObjectCache::gAccessibilityEnabled = false;
 bool AXObjectCache::gInlineTextBoxAccessibility = false;
 
-AXObjectCache::AXObjectCache(const Document* doc)
-    : m_notificationPostTimer(this, &AXObjectCache::notificationPostTimerFired)
+AXObjectCache::AXObjectCache(Document& document)
+    : m_document(document)
+    , m_notificationPostTimer(this, &AXObjectCache::notificationPostTimerFired)
 {
-    m_document = const_cast<Document*>(doc);
     m_computedObjectAttributeCache = AXComputedObjectAttributeCache::create();
 }
 
@@ -167,7 +167,7 @@
     if (!focusedNode)
         focusedNode = focusedDocument;
 
-    if (focusedNode->hasTagName(areaTag))
+    if (isHTMLAreaElement(*focusedNode))
         return focusedImageMapUIElement(toHTMLAreaElement(focusedNode));
 
     AXObject* obj = focusedNode->document().axObjectCache()->getOrCreate(focusedNode);
@@ -271,7 +271,7 @@
     // If the node is aria role="list" or the aria role is empty and its a
     // ul/ol/dl type (it shouldn't be a list if aria says otherwise).
     if (node && ((nodeHasRole(node, "list") || nodeHasRole(node, "directory"))
-        || (nodeHasRole(node, nullAtom) && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(dlTag)))))
+        || (nodeHasRole(node, nullAtom) && (isHTMLUListElement(*node) || isHTMLOListElement(*node) || isHTMLDListElement(*node)))))
         return AXList::create(renderer);
 
     // aria tables
@@ -334,7 +334,7 @@
     if (AXObject* obj = get(widget))
         return obj;
 
-    RefPtr<AXObject> newObj = 0;
+    RefPtr<AXObject> newObj = nullptr;
     if (widget->isFrameView())
         newObj = AXScrollView::create(toScrollView(widget));
     else if (widget->isScrollbar())
@@ -447,12 +447,12 @@
     if (!gAccessibilityEnabled)
         return 0;
 
-    return getOrCreate(m_document->view());
+    return getOrCreate(m_document.view());
 }
 
 AXObject* AXObjectCache::getOrCreate(AccessibilityRole role)
 {
-    RefPtr<AXObject> obj = 0;
+    RefPtr<AXObject> obj = nullptr;
 
     // will be filled in...
     switch (role) {
@@ -484,7 +484,7 @@
         obj = AXSpinButtonPart::create();
         break;
     default:
-        obj = 0;
+        obj = nullptr;
     }
 
     if (obj)
@@ -767,7 +767,7 @@
     if (postType == PostAsynchronously) {
         m_notificationsToPost.append(std::make_pair(object, notification));
         if (!m_notificationPostTimer.isActive())
-            m_notificationPostTimer.startOneShot(0);
+            m_notificationPostTimer.startOneShot(0, FROM_HERE);
     } else {
         postPlatformNotification(object, notification);
     }
@@ -831,7 +831,7 @@
         handleAriaRoleChanged(element);
     else if (attrName == altAttr || attrName == titleAttr)
         textChanged(element);
-    else if (attrName == forAttr && element->hasTagName(labelTag))
+    else if (attrName == forAttr && isHTMLLabelElement(*element))
         labelChanged(element);
 
     if (!attrName.localName().string().startsWith("aria-"))
@@ -920,7 +920,7 @@
     if (!domNode)
         return;
 
-    if (domNode->hasTagName(inputTag) && toHTMLInputElement(domNode)->isPasswordField())
+    if (isHTMLInputElement(*domNode) && toHTMLInputElement(*domNode).isPasswordField())
         return;
 
     // find or create an accessibility object for this node
@@ -1030,4 +1030,14 @@
     postPlatformNotification(AXObject::firstAccessibleObjectFromNode(anchorNode), AXScrolledToAnchor);
 }
 
+void AXObjectCache::handleScrollPositionChanged(ScrollView* scrollView)
+{
+    postPlatformNotification(getOrCreate(scrollView), AXScrollPositionChanged);
+}
+
+void AXObjectCache::handleScrollPositionChanged(RenderObject* renderObject)
+{
+    postPlatformNotification(getOrCreate(renderObject), AXScrollPositionChanged);
+}
+
 } // namespace WebCore
diff --git a/Source/core/accessibility/AXObjectCache.h b/Source/core/accessibility/AXObjectCache.h
index 11df342..5024525 100644
--- a/Source/core/accessibility/AXObjectCache.h
+++ b/Source/core/accessibility/AXObjectCache.h
@@ -79,7 +79,7 @@
 class AXObjectCache {
     WTF_MAKE_NONCOPYABLE(AXObjectCache); WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit AXObjectCache(const Document*);
+    explicit AXObjectCache(Document&);
     ~AXObjectCache();
 
     static AXObject* focusedUIElementForPage(const Page*);
@@ -128,8 +128,14 @@
     void handleFocusedUIElementChanged(Node* oldFocusedNode, Node* newFocusedNode);
     void handleScrolledToAnchor(const Node* anchorNode);
     void handleAriaExpandedChange(Node*);
+
+    // Called when scroll bars are added / removed (as the view resizes).
     void handleScrollbarUpdate(ScrollView*);
 
+    // Called when the scroll offset changes.
+    void handleScrollPositionChanged(ScrollView*);
+    void handleScrollPositionChanged(RenderObject*);
+
     void handleAttributeChanged(const QualifiedName& attrName, Element*);
     void recomputeIsIgnored(RenderObject* renderer);
 
@@ -172,6 +178,7 @@
         AXRowCollapsed,
         AXRowCountChanged,
         AXRowExpanded,
+        AXScrollPositionChanged,
         AXScrolledToAnchor,
         AXSelectedChildrenChanged,
         AXSelectedTextChanged,
@@ -204,7 +211,7 @@
     bool isNodeInUse(Node* n) { return m_textMarkerNodes.contains(n); }
 
 private:
-    Document* m_document;
+    Document& m_document;
     HashMap<AXID, RefPtr<AXObject> > m_objects;
     HashMap<RenderObject*, AXID> m_renderObjectMapping;
     HashMap<Widget*, AXID> m_widgetObjectMapping;
diff --git a/Source/core/accessibility/AXRenderObject.cpp b/Source/core/accessibility/AXRenderObject.cpp
index 07eea95..a0ade62 100644
--- a/Source/core/accessibility/AXRenderObject.cpp
+++ b/Source/core/accessibility/AXRenderObject.cpp
@@ -43,7 +43,7 @@
 #include "core/editing/TextIterator.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLOptionElement.h"
@@ -231,7 +231,7 @@
 {
     if (!document())
         return 0;
-    return document()->topDocument();
+    return &document()->topDocument();
 }
 
 bool AXRenderObject::shouldNotifyActiveDescendant() const
@@ -283,14 +283,14 @@
         return ListItemRole;
     if (m_renderer->isListMarker())
         return ListMarkerRole;
-    if (node && node->hasTagName(buttonTag))
+    if (isHTMLButtonElement(node))
         return buttonRoleType();
-    if (node && node->hasTagName(legendTag))
+    if (isHTMLLegendElement(node))
         return LegendRole;
     if (m_renderer->isText())
         return StaticTextRole;
     if (cssBox && cssBox->isImage()) {
-        if (node && node->hasTagName(inputTag))
+        if (isHTMLInputElement(node))
             return ariaHasPopup() ? PopUpButtonRole : ButtonRole;
         if (isSVGImage())
             return SVGRootRole;
@@ -298,7 +298,7 @@
     }
 
     // Note: if JavaScript is disabled, the renderer won't be a RenderHTMLCanvas.
-    if (node && node->hasTagName(canvasTag) && m_renderer->isCanvas())
+    if (isHTMLCanvasElement(node) && m_renderer->isCanvas())
         return CanvasRole;
 
     if (cssBox && cssBox->isRenderView())
@@ -310,16 +310,16 @@
     if (cssBox && cssBox->isTextArea())
         return TextAreaRole;
 
-    if (node && node->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(node);
-        if (input->isCheckbox())
+    if (isHTMLInputElement(node)) {
+        HTMLInputElement& input = toHTMLInputElement(*node);
+        if (input.isCheckbox())
             return CheckBoxRole;
-        if (input->isRadioButton())
+        if (input.isRadioButton())
             return RadioButtonRole;
-        if (input->isTextButton())
+        if (input.isTextButton())
             return buttonRoleType();
 
-        const AtomicString& type = input->getAttribute(typeAttr);
+        const AtomicString& type = input.getAttribute(typeAttr);
         if (equalIgnoringCase(type, "color"))
             return ColorWellRole;
     }
@@ -354,16 +354,16 @@
     if (m_renderer->isHR())
         return HorizontalRuleRole;
 
-    if (node && node->hasTagName(pTag))
+    if (isHTMLParagraphElement(node))
         return ParagraphRole;
 
-    if (node && node->hasTagName(labelTag))
+    if (isHTMLLabelElement(node))
         return LabelRole;
 
-    if (node && node->hasTagName(divTag))
+    if (isHTMLDivElement(node))
         return DivRole;
 
-    if (node && node->hasTagName(formTag))
+    if (isHTMLFormElement(node))
         return FormRole;
 
     if (node && node->hasTagName(articleTag))
@@ -388,7 +388,7 @@
         return DialogRole;
 
     // The HTML element should not be exposed as an element. That's what the RenderView element does.
-    if (node && node->hasTagName(htmlTag))
+    if (isHTMLHtmlElement(node))
         return IgnoredRole;
 
     // There should only be one banner/contentInfo per page. If header/footer are being used within an article or section
@@ -398,7 +398,7 @@
     if (node && node->hasTagName(footerTag) && !isDescendantOfElementType(articleTag) && !isDescendantOfElementType(sectionTag))
         return FooterRole;
 
-    if (node && node->hasTagName(aTag) && isClickable())
+    if (isHTMLAnchorElement(node) && isClickable())
         return LinkRole;
 
     if (m_renderer->isRenderBlockFlow())
@@ -446,9 +446,9 @@
 
 bool AXRenderObject::isFileUploadButton() const
 {
-    if (m_renderer && m_renderer->node() && m_renderer->node()->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(m_renderer->node());
-        return input->isFileUpload();
+    if (m_renderer && isHTMLInputElement(m_renderer->node())) {
+        HTMLInputElement& input = toHTMLInputElement(*m_renderer->node());
+        return input.isFileUpload();
     }
 
     return false;
@@ -470,10 +470,10 @@
         return false;
 
     Element* anchor = anchorElement();
-    if (!anchor || !anchor->hasTagName(aTag))
+    if (!isHTMLAnchorElement(anchor))
         return false;
 
-    return !toHTMLAnchorElement(anchor)->href().isEmpty();
+    return !toHTMLAnchorElement(*anchor).href().isEmpty();
 }
 
 bool AXRenderObject::isLoaded() const
@@ -662,7 +662,7 @@
 
     // don't ignore labels, because they serve as TitleUIElements
     Node* node = m_renderer->node();
-    if (node && node->hasTagName(labelTag))
+    if (isHTMLLabelElement(node))
         return false;
 
     // Anything that is content editable should not be ignored.
@@ -688,7 +688,7 @@
     // objects are often containers with meaningful information, the inclusion of a span can have
     // the side effect of causing the immediate parent accessible to be ignored. This is especially
     // problematic for platforms which have distinct roles for textual block elements.
-    if (node && node->hasTagName(spanTag))
+    if (isHTMLSpanElement(node))
         return true;
 
     if (m_renderer->isRenderBlockFlow() && m_renderer->childrenInline() && !canSetFocusAttribute())
@@ -808,7 +808,7 @@
 
 KURL AXRenderObject::url() const
 {
-    if (isAnchor() && m_renderer->node()->hasTagName(aTag)) {
+    if (isAnchor() && isHTMLAnchorElement(m_renderer->node())) {
         if (HTMLAnchorElement* anchor = toHTMLAnchorElement(anchorElement()))
             return anchor->href();
     }
@@ -816,8 +816,8 @@
     if (isWebArea())
         return m_renderer->document().url();
 
-    if (isImage() && m_renderer->node() && m_renderer->node()->hasTagName(imgTag))
-        return toHTMLImageElement(m_renderer->node())->src();
+    if (isImage() && isHTMLImageElement(m_renderer->node()))
+        return toHTMLImageElement(*m_renderer->node()).src();
 
     if (isInputImage())
         return toHTMLInputElement(m_renderer->node())->src();
@@ -935,7 +935,10 @@
 
     if (m_renderer->node() && !m_renderer->node()->isElementNode())
         return 0;
+
     Element* element = toElement(m_renderer->node());
+    if (!element)
+        return 0;
 
     const AtomicString& activeDescendantAttrStr = element->getAttribute(aria_activedescendantAttr);
     if (activeDescendantAttrStr.isNull() || activeDescendantAttrStr.isEmpty())
@@ -954,21 +957,46 @@
     return 0;
 }
 
-void AXRenderObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) const
+void AXRenderObject::accessibilityChildrenFromAttribute(QualifiedName attr, AccessibilityChildrenVector& children) const
 {
     Vector<Element*> elements;
-    elementsFromAttribute(elements, aria_flowtoAttr);
+    elementsFromAttribute(elements, attr);
 
     AXObjectCache* cache = axObjectCache();
     unsigned count = elements.size();
     for (unsigned k = 0; k < count; ++k) {
         Element* element = elements[k];
-        AXObject* flowToElement = cache->getOrCreate(element);
-        if (flowToElement)
-            flowTo.append(flowToElement);
+        AXObject* child = cache->getOrCreate(element);
+        if (child)
+            children.append(child);
     }
 }
 
+void AXRenderObject::ariaFlowToElements(AccessibilityChildrenVector& flowTo) const
+{
+    accessibilityChildrenFromAttribute(aria_flowtoAttr, flowTo);
+}
+
+void AXRenderObject::ariaControlsElements(AccessibilityChildrenVector& controls) const
+{
+    accessibilityChildrenFromAttribute(aria_controlsAttr, controls);
+}
+
+void AXRenderObject::ariaDescribedbyElements(AccessibilityChildrenVector& describedby) const
+{
+    accessibilityChildrenFromAttribute(aria_describedbyAttr, describedby);
+}
+
+void AXRenderObject::ariaLabelledbyElements(AccessibilityChildrenVector& labelledby) const
+{
+    accessibilityChildrenFromAttribute(aria_labelledbyAttr, labelledby);
+}
+
+void AXRenderObject::ariaOwnsElements(AccessibilityChildrenVector& owns) const
+{
+    accessibilityChildrenFromAttribute(aria_ownsAttr, owns);
+}
+
 bool AXRenderObject::ariaHasPopup() const
 {
     return elementAttributeValue(aria_haspopupAttr);
@@ -1002,25 +1030,21 @@
 bool AXRenderObject::shouldFocusActiveDescendant() const
 {
     switch (ariaRoleAttribute()) {
+    case ComboBoxRole:
+    case GridRole:
     case GroupRole:
     case ListBoxRole:
     case MenuRole:
     case MenuBarRole:
-    case RadioGroupRole:
-    case RowRole:
+    case OutlineRole:
     case PopUpButtonRole:
     case ProgressIndicatorRole:
+    case RadioGroupRole:
+    case RowRole:
+    case TabListRole:
     case ToolbarRole:
-    case OutlineRole:
     case TreeRole:
-    case GridRole:
-    /* FIXME: replace these with actual roles when they are added to AccessibilityRole
-    composite
-    alert
-    alertdialog
-    status
-    timer
-    */
+    case TreeGridRole:
         return true;
     default:
         return false;
@@ -1264,11 +1288,11 @@
         return 0;
     Node* node = hitTestResult.innerNode()->deprecatedShadowAncestorNode();
 
-    if (node->hasTagName(areaTag))
+    if (isHTMLAreaElement(node))
         return accessibilityImageMapHitTest(toHTMLAreaElement(node), point);
 
-    if (node->hasTagName(optionTag))
-        node = toHTMLOptionElement(node)->ownerSelectElement();
+    if (isHTMLOptionElement(node))
+        node = toHTMLOptionElement(*node).ownerSelectElement();
 
     RenderObject* obj = node->renderer();
     if (!obj)
@@ -1496,7 +1520,7 @@
     if (!m_renderer)
         return 0;
 
-    // this is the RenderObject's Document's Frame's FrameView
+    // this is the RenderObject's Document's LocalFrame's FrameView
     return m_renderer->document().view();
 }
 
@@ -1525,7 +1549,7 @@
     // NOTE: this assumes that any non-image with an anchor is an HTMLAnchorElement
     Node* node = currRenderer->node();
     for ( ; node; node = node->parentNode()) {
-        if (node->hasTagName(aTag) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
+        if (isHTMLAnchorElement(*node) || (node->renderer() && cache->getOrCreate(node->renderer())->isAnchor()))
             return toElement(node);
     }
 
@@ -1580,7 +1604,7 @@
     }
 
     Document& document = m_renderer->document();
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     if (!frame)
         return;
     Node* node = m_renderer->node();
@@ -1596,11 +1620,10 @@
         return;
 
     RenderBoxModelObject* renderer = toRenderBoxModelObject(m_renderer);
-    if (renderer->isTextField() && node()->hasTagName(inputTag)) {
-        toHTMLInputElement(node())->setValue(string);
-    } else if (renderer->isTextArea() && node()->hasTagName(textareaTag)) {
-        toHTMLTextAreaElement(node())->setValue(string);
-    }
+    if (renderer->isTextField() && isHTMLInputElement(*node()))
+        toHTMLInputElement(*node()).setValue(string);
+    else if (renderer->isTextArea() && isHTMLTextAreaElement(*node()))
+        toHTMLTextAreaElement(*node()).setValue(string);
 }
 
 // FIXME: This function should use an IntSize to avoid the conversion below.
@@ -1836,8 +1859,8 @@
     if (!currentSelectionRange || !currentSelectionRange->intersectsNode(node, IGNORE_EXCEPTION))
         return PlainTextRange();
 
-    int start = indexForVisiblePosition(visibleSelection.start());
-    int end = indexForVisiblePosition(visibleSelection.end());
+    int start = indexForVisiblePosition(visibleSelection.visibleStart());
+    int end = indexForVisiblePosition(visibleSelection.visibleEnd());
 
     return PlainTextRange(start, end - start);
 }
@@ -1897,15 +1920,12 @@
 AXObject* AXRenderObject::internalLinkElement() const
 {
     Element* element = anchorElement();
-    if (!element)
-        return 0;
-
     // Right now, we do not support ARIA links as internal link elements
-    if (!element->hasTagName(aTag))
+    if (!isHTMLAnchorElement(element))
         return 0;
-    HTMLAnchorElement* anchor = toHTMLAnchorElement(element);
+    HTMLAnchorElement& anchor = toHTMLAnchorElement(*element);
 
-    KURL linkURL = anchor->href();
+    KURL linkURL = anchor.href();
     String fragmentIdentifier = linkURL.fragmentIdentifier();
     if (fragmentIdentifier.isEmpty())
         return 0;
@@ -2136,11 +2156,11 @@
 void AXRenderObject::addTextFieldChildren()
 {
     Node* node = this->node();
-    if (!node || !node->hasTagName(inputTag))
+    if (!isHTMLInputElement(node))
         return;
 
-    HTMLInputElement* input = toHTMLInputElement(node);
-    Element* spinButtonElement = input->userAgentShadowRoot()->getElementById(ShadowElementNames::spinButton());
+    HTMLInputElement& input = toHTMLInputElement(*node);
+    Element* spinButtonElement = input.userAgentShadowRoot()->getElementById(ShadowElementNames::spinButton());
     if (!spinButtonElement || !spinButtonElement->isSpinButtonElement())
         return;
 
@@ -2160,11 +2180,11 @@
     if (!map)
         return;
 
-    for (Element* current = ElementTraversal::firstWithin(*map); current; current = ElementTraversal::next(*current, map)) {
+    for (HTMLAreaElement* area = Traversal<HTMLAreaElement>::firstWithin(*map); area; area = Traversal<HTMLAreaElement>::next(*area, map)) {
         // add an <area> element for this child if it has a link
-        if (current->hasTagName(areaTag) && current->isLink()) {
+        if (area->isLink()) {
             AXImageMapLink* areaObject = toAXImageMapLink(axObjectCache()->getOrCreate(ImageMapLinkRole));
-            areaObject->setHTMLAreaElement(toHTMLAreaElement(current));
+            areaObject->setHTMLAreaElement(area);
             areaObject->setHTMLMapElement(map);
             areaObject->setParent(this);
             if (!areaObject->accessibilityIsIgnored())
@@ -2177,7 +2197,7 @@
 
 void AXRenderObject::addCanvasChildren()
 {
-    if (!node() || !node()->hasTagName(canvasTag))
+    if (!isHTMLCanvasElement(node()))
         return;
 
     // If it's a canvas, it won't have rendered children, but it might have accessible fallback content.
diff --git a/Source/core/accessibility/AXRenderObject.h b/Source/core/accessibility/AXRenderObject.h
index 550554b..867b076 100644
--- a/Source/core/accessibility/AXRenderObject.h
+++ b/Source/core/accessibility/AXRenderObject.h
@@ -38,7 +38,7 @@
 class AXSVGRoot;
 class AXObjectCache;
 class Element;
-class Frame;
+class LocalFrame;
 class FrameView;
 class HitTestResult;
 class HTMLAnchorElement;
@@ -126,6 +126,11 @@
     // ARIA attributes.
     virtual AXObject* activeDescendant() const OVERRIDE;
     virtual void ariaFlowToElements(AccessibilityChildrenVector&) const OVERRIDE;
+    virtual void ariaControlsElements(AccessibilityChildrenVector&) const OVERRIDE;
+    virtual void ariaDescribedbyElements(AccessibilityChildrenVector&) const OVERRIDE;
+    virtual void ariaLabelledbyElements(AccessibilityChildrenVector&) const OVERRIDE;
+    virtual void ariaOwnsElements(AccessibilityChildrenVector&) const OVERRIDE;
+
     virtual bool ariaHasPopup() const OVERRIDE;
     virtual bool ariaRoleHasPresentationalChildren() const OVERRIDE;
     virtual bool isPresentationalChildOfAriaRole() const OVERRIDE;
@@ -227,6 +232,7 @@
     LayoutRect computeElementRect() const;
     VisibleSelection selection() const;
     int indexForVisiblePosition(const VisiblePosition&) const;
+    void accessibilityChildrenFromAttribute(QualifiedName attr, AccessibilityChildrenVector&) const;
 };
 
 DEFINE_AX_OBJECT_TYPE_CASTS(AXRenderObject, isAXRenderObject());
diff --git a/Source/core/accessibility/AXScrollView.cpp b/Source/core/accessibility/AXScrollView.cpp
index 2626bb6..b254ea5 100644
--- a/Source/core/accessibility/AXScrollView.cpp
+++ b/Source/core/accessibility/AXScrollView.cpp
@@ -28,8 +28,8 @@
 
 #include "core/accessibility/AXObjectCache.h"
 #include "core/accessibility/AXScrollbar.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 
 namespace WebCore {
@@ -103,14 +103,14 @@
         m_horizontalScrollbar = addChildScrollbar(m_scrollView->horizontalScrollbar());
     } else if (!m_scrollView->horizontalScrollbar() && m_horizontalScrollbar) {
         removeChildScrollbar(m_horizontalScrollbar.get());
-        m_horizontalScrollbar = 0;
+        m_horizontalScrollbar = nullptr;
     }
 
     if (m_scrollView->verticalScrollbar() && !m_verticalScrollbar) {
         m_verticalScrollbar = addChildScrollbar(m_scrollView->verticalScrollbar());
     } else if (!m_scrollView->verticalScrollbar() && m_verticalScrollbar) {
         removeChildScrollbar(m_verticalScrollbar.get());
-        m_verticalScrollbar = 0;
+        m_verticalScrollbar = nullptr;
     }
 }
 
@@ -137,8 +137,8 @@
 void AXScrollView::clearChildren()
 {
     AXObject::clearChildren();
-    m_verticalScrollbar = 0;
-    m_horizontalScrollbar = 0;
+    m_verticalScrollbar = nullptr;
+    m_horizontalScrollbar = nullptr;
 }
 
 bool AXScrollView::computeAccessibilityIsIgnored() const
diff --git a/Source/core/accessibility/AXScrollbar.cpp b/Source/core/accessibility/AXScrollbar.cpp
index 0b47848..d8828dc 100644
--- a/Source/core/accessibility/AXScrollbar.cpp
+++ b/Source/core/accessibility/AXScrollbar.cpp
@@ -41,7 +41,7 @@
 
 void AXScrollbar::detachFromParent()
 {
-    m_scrollbar = 0;
+    m_scrollbar = nullptr;
     AXMockObject::detachFromParent();
 }
 
diff --git a/Source/core/accessibility/AXTable.cpp b/Source/core/accessibility/AXTable.cpp
index bccdc18..58ba002 100644
--- a/Source/core/accessibility/AXTable.cpp
+++ b/Source/core/accessibility/AXTable.cpp
@@ -35,6 +35,7 @@
 #include "core/accessibility/AXTableRow.h"
 #include "core/html/HTMLTableCaptionElement.h"
 #include "core/html/HTMLTableCellElement.h"
+#include "core/html/HTMLTableColElement.h"
 #include "core/html/HTMLTableElement.h"
 #include "core/rendering/RenderTableCell.h"
 
@@ -44,7 +45,7 @@
 
 AXTable::AXTable(RenderObject* renderer)
     : AXRenderObject(renderer)
-    , m_headerContainer(0)
+    , m_headerContainer(nullptr)
     , m_isAXTable(true)
 {
 }
@@ -106,7 +107,7 @@
 
     RenderTable* table = toRenderTable(m_renderer);
     Node* tableNode = table->node();
-    if (!tableNode || !tableNode->hasTagName(tableTag))
+    if (!isHTMLTableElement(tableNode))
         return false;
 
     // if there is a caption element, summary, THEAD, or TFOOT section, it's most certainly a data table
@@ -119,10 +120,8 @@
         return true;
 
     // if there's a colgroup or col element, it's probably a data table.
-    for (Node* child = tableElement->firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(colTag) || child->hasTagName(colgroupTag))
-            return true;
-    }
+    if (Traversal<HTMLTableColElement>::firstChild(*tableElement))
+        return true;
 
     // go through the cell's and check for tell-tale signs of "data" table status
     // cells have borders, or use attributes like headers, abbr, scope or axis
@@ -191,10 +190,10 @@
                 headersInFirstColumnCount++;
 
             // in this case, the developer explicitly assigned a "data" table attribute
-            if (cellNode->hasTagName(tdTag) || cellNode->hasTagName(thTag)) {
-                HTMLTableCellElement* cellElement = toHTMLTableCellElement(cellNode);
-                if (!cellElement->headers().isEmpty() || !cellElement->abbr().isEmpty()
-                    || !cellElement->axis().isEmpty() || !cellElement->scope().isEmpty())
+            if (isHTMLTableCellElement(*cellNode)) {
+                HTMLTableCellElement& cellElement = toHTMLTableCellElement(*cellNode);
+                if (!cellElement.headers().isEmpty() || !cellElement.abbr().isEmpty()
+                    || !cellElement.axis().isEmpty() || !cellElement.scope().isEmpty())
                     return true;
             }
 
@@ -314,7 +313,7 @@
 
     if (m_headerContainer) {
         m_headerContainer->detachFromParent();
-        m_headerContainer = 0;
+        m_headerContainer = nullptr;
     }
 }
 
@@ -439,7 +438,7 @@
     int numRows = m_rows.size();
     for (int row = 0; row < numRows; ++row) {
         AccessibilityChildrenVector rowChildren = m_rows[row]->children();
-        cells.append(rowChildren);
+        cells.appendVector(rowChildren);
     }
 }
 
@@ -535,7 +534,7 @@
 
     // see if there is a caption
     Node* tableElement = m_renderer->node();
-    if (tableElement && tableElement->hasTagName(tableTag)) {
+    if (isHTMLTableElement(tableElement)) {
         HTMLTableCaptionElement* caption = toHTMLTableElement(tableElement)->caption();
         if (caption)
             title = caption->innerText();
diff --git a/Source/core/animation/ActiveAnimations.cpp b/Source/core/animation/ActiveAnimations.cpp
index 317722a..c0c06e9 100644
--- a/Source/core/animation/ActiveAnimations.cpp
+++ b/Source/core/animation/ActiveAnimations.cpp
@@ -87,7 +87,7 @@
 
 void ActiveAnimations::cancelAnimationOnCompositor()
 {
-    for (PlayerSet::iterator it = m_players.begin(); it != players().end(); ++it)
+    for (AnimationPlayerSet::iterator it = m_players.begin(); it != players().end(); ++it)
         it->key->cancelAnimationOnCompositor();
 }
 
diff --git a/Source/core/animation/ActiveAnimations.h b/Source/core/animation/ActiveAnimations.h
index b12a9bf..0bbc264 100644
--- a/Source/core/animation/ActiveAnimations.h
+++ b/Source/core/animation/ActiveAnimations.h
@@ -63,10 +63,10 @@
     CSSAnimations& cssAnimations() { return m_cssAnimations; }
     const CSSAnimations& cssAnimations() const { return m_cssAnimations; }
 
-    typedef HashCountedSet<Player*> PlayerSet;
-    // Players which have animations targeting this element.
-    const PlayerSet& players() const { return m_players; }
-    PlayerSet& players() { return m_players; }
+    typedef HashCountedSet<AnimationPlayer*> AnimationPlayerSet;
+    // AnimationPlayers which have animations targeting this element.
+    const AnimationPlayerSet& players() const { return m_players; }
+    AnimationPlayerSet& players() { return m_players; }
 
     bool isEmpty() const { return m_defaultStack.isEmpty() && m_cssAnimations.isEmpty(); }
 
@@ -81,7 +81,7 @@
 
     AnimationStack m_defaultStack;
     CSSAnimations m_cssAnimations;
-    PlayerSet m_players;
+    AnimationPlayerSet m_players;
     bool m_animationStyleChange;
 
     // CSSAnimations checks if a style change is due to animation.
diff --git a/Source/core/animation/AnimatableColor.cpp b/Source/core/animation/AnimatableColor.cpp
index d501a81..011e77e 100644
--- a/Source/core/animation/AnimatableColor.cpp
+++ b/Source/core/animation/AnimatableColor.cpp
@@ -34,6 +34,15 @@
 #include "platform/animation/AnimationUtilities.h"
 #include "wtf/MathExtras.h"
 
+namespace {
+
+double square(double x)
+{
+    return x * x;
+}
+
+} // namespace
+
 namespace WebCore {
 
 AnimatableColorImpl::AnimatableColorImpl(float red, float green, float blue, float alpha)
@@ -83,6 +92,14 @@
         && m_alpha == other.m_alpha;
 }
 
+double AnimatableColorImpl::distanceTo(const AnimatableColorImpl& other) const
+{
+    return sqrt(square(m_red - other.m_red)
+        + square(m_green - other.m_green)
+        + square(m_blue - other.m_blue)
+        + square(m_alpha - other.m_alpha));
+}
+
 PassRefPtr<AnimatableColor> AnimatableColor::create(const AnimatableColorImpl& color, const AnimatableColorImpl& visitedLinkColor)
 {
     return adoptRef(new AnimatableColor(color, visitedLinkColor));
@@ -108,4 +125,10 @@
     return m_color == color->m_color && m_visitedLinkColor == color->m_visitedLinkColor;
 }
 
+double AnimatableColor::distanceTo(const AnimatableValue* value) const
+{
+    const AnimatableColor* color = toAnimatableColor(value);
+    return m_color.distanceTo(color->m_color);
+}
+
 } // namespace WebCore
diff --git a/Source/core/animation/AnimatableColor.h b/Source/core/animation/AnimatableColor.h
index e5fc028..b8c62f5 100644
--- a/Source/core/animation/AnimatableColor.h
+++ b/Source/core/animation/AnimatableColor.h
@@ -44,6 +44,7 @@
     AnimatableColorImpl interpolateTo(const AnimatableColorImpl&, double fraction) const;
     AnimatableColorImpl addWith(const AnimatableColorImpl&) const;
     bool operator==(const AnimatableColorImpl&) const;
+    double distanceTo(const AnimatableColorImpl&) const;
 
 private:
     float m_alpha;
@@ -74,6 +75,7 @@
     }
     virtual AnimatableType type() const OVERRIDE { return TypeColor; }
     virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
+    virtual double distanceTo(const AnimatableValue*) const OVERRIDE;
     const AnimatableColorImpl m_color;
     const AnimatableColorImpl m_visitedLinkColor;
 };
diff --git a/Source/core/animation/AnimatableColorTest.cpp b/Source/core/animation/AnimatableColorTest.cpp
index 12ecf85..ea66a8b 100644
--- a/Source/core/animation/AnimatableColorTest.cpp
+++ b/Source/core/animation/AnimatableColorTest.cpp
@@ -75,5 +75,16 @@
     EXPECT_EQ(AnimatableColorImpl(Color(0x10204080)).addWith(Color(0x104080C0)).toColor().rgb(), 0x203060A0u);
 }
 
+TEST(AnimationAnimatableColorTest, Distance)
+{
+    EXPECT_NEAR(1.0, AnimatableColorImpl(Color(0xFF000000)).distanceTo(Color(0xFFFF0000)), 0.00000001);
+    EXPECT_NEAR(13.0 / 255, AnimatableColorImpl(Color(0xFF53647C)).distanceTo(Color(0xFF506070)), 0.00000001);
+    EXPECT_NEAR(60.0 / 255, AnimatableColorImpl(Color(0x3C000000)).distanceTo(Color(0x00FFFFFF)), 0.00000001);
+    EXPECT_NEAR(60.0 / 255, AnimatableColorImpl(Color(0x3C000000)).distanceTo(Color(0x3C00FF00)), 0.00000001);
+
+    RefPtr<AnimatableColor> first = AnimatableColor::create(AnimatableColorImpl(Color(0xFF53647C)), AnimatableColorImpl(Color(0xFF000000)));
+    RefPtr<AnimatableColor> second = AnimatableColor::create(AnimatableColorImpl(Color(0xFF506070)), AnimatableColorImpl(Color(0xFF000000)));
+    EXPECT_NEAR(13.0 / 255, AnimatableValue::distance(first.get(), second.get()), 0.00000001);
 }
 
+}
diff --git a/Source/core/animation/AnimatableDouble.cpp b/Source/core/animation/AnimatableDouble.cpp
index e509bf9..77d80f7 100644
--- a/Source/core/animation/AnimatableDouble.cpp
+++ b/Source/core/animation/AnimatableDouble.cpp
@@ -34,10 +34,11 @@
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSValuePool.h"
 #include "platform/animation/AnimationUtilities.h"
+#include <math.h>
 
 namespace WebCore {
 
-PassRefPtr<CSSValue> AnimatableDouble::toCSSValue() const
+PassRefPtrWillBeRawPtr<CSSValue> AnimatableDouble::toCSSValue() const
 {
     return cssValuePool().createValue(m_number, CSSPrimitiveValue::CSS_NUMBER);
 }
@@ -74,4 +75,10 @@
     return m_number == toAnimatableDouble(value)->m_number;
 }
 
+double AnimatableDouble::distanceTo(const AnimatableValue* value) const
+{
+    const AnimatableDouble* other = toAnimatableDouble(value);
+    return fabs(m_number - other->m_number);
+}
+
 } // namespace WebCore
diff --git a/Source/core/animation/AnimatableDouble.h b/Source/core/animation/AnimatableDouble.h
index f05082e..172674c 100644
--- a/Source/core/animation/AnimatableDouble.h
+++ b/Source/core/animation/AnimatableDouble.h
@@ -50,7 +50,7 @@
         return adoptRef(new AnimatableDouble(number, constraint));
     }
 
-    PassRefPtr<CSSValue> toCSSValue() const;
+    PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const;
     double toDouble() const { return m_number; }
 
 protected:
@@ -66,6 +66,7 @@
     }
     virtual AnimatableType type() const OVERRIDE { return TypeDouble; }
     virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
+    virtual double distanceTo(const AnimatableValue*) const OVERRIDE;
 
     double m_number;
     Constraint m_constraint;
diff --git a/Source/core/animation/AnimatableDoubleTest.cpp b/Source/core/animation/AnimatableDoubleTest.cpp
index ce8510b..a5efd96 100644
--- a/Source/core/animation/AnimatableDoubleTest.cpp
+++ b/Source/core/animation/AnimatableDoubleTest.cpp
@@ -53,8 +53,8 @@
 
 TEST(AnimationAnimatableDoubleTest, ToCSSValue)
 {
-    RefPtr<CSSValue> cssValue5 = CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_NUMBER);
-    RefPtr<CSSValue> cssValue10 = CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_NUMBER);
+    RefPtrWillBeRawPtr<CSSValue> cssValue5 = CSSPrimitiveValue::create(5, CSSPrimitiveValue::CSS_NUMBER);
+    RefPtrWillBeRawPtr<CSSValue> cssValue10 = CSSPrimitiveValue::create(10, CSSPrimitiveValue::CSS_NUMBER);
     EXPECT_TRUE(AnimatableDouble::create(5)->toCSSValue()->equals(*cssValue5.get()));
     EXPECT_FALSE(AnimatableDouble::create(5)->toCSSValue()->equals(*cssValue10.get()));
 }
@@ -88,4 +88,15 @@
     EXPECT_EQ(30, toAnimatableDouble(AnimatableValue::add(AnimatableDouble::create(30).get(), AnimatableDouble::create(0).get()).get())->toDouble());
 }
 
+TEST(AnimationAnimatableDoubleTest, Distance)
+{
+    RefPtr<AnimatableDouble> first = AnimatableDouble::create(-1.5);
+    RefPtr<AnimatableDouble> second = AnimatableDouble::create(2.25);
+    RefPtr<AnimatableDouble> third = AnimatableDouble::create(3);
+
+    EXPECT_DOUBLE_EQ(3.75, AnimatableValue::distance(first.get(), second.get()));
+    EXPECT_DOUBLE_EQ(0.75, AnimatableValue::distance(second.get(), third.get()));
+    EXPECT_DOUBLE_EQ(4.5, AnimatableValue::distance(third.get(), first.get()));
+}
+
 }
diff --git a/Source/core/animation/AnimatableImage.cpp b/Source/core/animation/AnimatableImage.cpp
index 28f4cd3..49df97f 100644
--- a/Source/core/animation/AnimatableImage.cpp
+++ b/Source/core/animation/AnimatableImage.cpp
@@ -40,13 +40,13 @@
 // FIXME: Once cross-fade works on generated image types, remove this method.
 bool AnimatableImage::usesDefaultInterpolationWith(const AnimatableValue* value) const
 {
-    RefPtr<CSSValue> fromValue = toCSSValue();
+    RefPtrWillBeRawPtr<CSSValue> fromValue = toCSSValue();
     if (fromValue->isImageGeneratorValue())
         return true;
     if (!fromValue->isImageValue() && !m_image->isImageResource())
         return true;
     const AnimatableImage* image = toAnimatableImage(value);
-    RefPtr<CSSValue> toValue = image->toCSSValue();
+    RefPtrWillBeRawPtr<CSSValue> toValue = image->toCSSValue();
     if (toValue->isImageGeneratorValue())
         return true;
     if (!toValue->isImageValue() && !image->m_image->isImageResource())
@@ -58,7 +58,7 @@
 {
     if (fraction <= 0 || fraction >= 1)
         return defaultInterpolateTo(this, value, fraction);
-    RefPtr<CSSValue> fromValue = toCSSValue();
+    RefPtrWillBeRawPtr<CSSValue> fromValue = toCSSValue();
     // FIXME: Once cross-fade works on generated image types, remove this check.
     if (fromValue->isImageGeneratorValue())
         return defaultInterpolateTo(this, value, fraction);
@@ -69,7 +69,7 @@
         fromValue = CSSImageValue::create(resource->url(), m_image.get());
     }
     const AnimatableImage* image = toAnimatableImage(value);
-    RefPtr<CSSValue> toValue = image->toCSSValue();
+    RefPtrWillBeRawPtr<CSSValue> toValue = image->toCSSValue();
     // FIXME: Once cross-fade works on generated image types, remove this check.
     if (toValue->isImageGeneratorValue())
         return defaultInterpolateTo(this, value, fraction);
diff --git a/Source/core/animation/AnimatableImage.h b/Source/core/animation/AnimatableImage.h
index 1557d06..1c88d4c 100644
--- a/Source/core/animation/AnimatableImage.h
+++ b/Source/core/animation/AnimatableImage.h
@@ -44,7 +44,7 @@
     {
         return adoptRef(new AnimatableImage(image));
     }
-    PassRefPtr<CSSValue> toCSSValue() const { return m_image->cssValue(); }
+    PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const { return m_image->cssValue(); }
     StyleImage* toStyleImage() const { return m_image.get(); }
 
 protected:
diff --git a/Source/core/animation/AnimatableLength.cpp b/Source/core/animation/AnimatableLength.cpp
index 54724c1..13f66f1 100644
--- a/Source/core/animation/AnimatableLength.cpp
+++ b/Source/core/animation/AnimatableLength.cpp
@@ -56,7 +56,7 @@
         return create(toCSSCalcValue(value)->expressionNode());
 
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 bool AnimatableLength::canCreateFrom(const CSSValue* value)
@@ -74,7 +74,7 @@
     return value->isCalcValue();
 }
 
-PassRefPtr<CSSValue> AnimatableLength::toCSSValue(NumberRange range) const
+PassRefPtrWillBeRawPtr<CSSValue> AnimatableLength::toCSSValue(NumberRange range) const
 {
     return toCSSPrimitiveValue(range);
 }
diff --git a/Source/core/animation/AnimatableLength.h b/Source/core/animation/AnimatableLength.h
index 9462c3b..387467f 100644
--- a/Source/core/animation/AnimatableLength.h
+++ b/Source/core/animation/AnimatableLength.h
@@ -72,7 +72,7 @@
     {
         return adoptRef(new AnimatableLength(calcExpression, cssPrimitiveValue));
     }
-    PassRefPtr<CSSValue> toCSSValue(NumberRange = AllValues) const;
+    PassRefPtrWillBeRawPtr<CSSValue> toCSSValue(NumberRange = AllValues) const;
     Length toLength(const CSSToLengthConversionData&, NumberRange = AllValues) const;
 
 protected:
diff --git a/Source/core/animation/AnimatableLengthTest.cpp b/Source/core/animation/AnimatableLengthTest.cpp
index fb6fbac..38d0f10 100644
--- a/Source/core/animation/AnimatableLengthTest.cpp
+++ b/Source/core/animation/AnimatableLengthTest.cpp
@@ -75,7 +75,7 @@
         ));
     }
 
-    PassRefPtr<CSSValue> toCSSValue(CSSValue* cssValue)
+    PassRefPtrWillBeRawPtr<CSSValue> toCSSValue(CSSValue* cssValue)
     {
         return AnimatableLength::create(cssValue)->toCSSValue();
     }
diff --git a/Source/core/animation/AnimatableNeutral.h b/Source/core/animation/AnimatableNeutral.h
index 1001f58..9b4188f 100644
--- a/Source/core/animation/AnimatableNeutral.h
+++ b/Source/core/animation/AnimatableNeutral.h
@@ -44,7 +44,7 @@
     virtual PassRefPtr<AnimatableValue> interpolateTo(const AnimatableValue* value, double fraction) const OVERRIDE
     {
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 
 private:
diff --git a/Source/core/animation/AnimatableNeutralTest.cpp b/Source/core/animation/AnimatableNeutralTest.cpp
index dbf685a..2bdf4bc 100644
--- a/Source/core/animation/AnimatableNeutralTest.cpp
+++ b/Source/core/animation/AnimatableNeutralTest.cpp
@@ -47,7 +47,7 @@
 
 TEST(AnimationAnimatableNeutralTest, Add)
 {
-    RefPtr<CSSValue> cssValue = CSSArrayFunctionValue::create();
+    RefPtrWillBeRawPtr<CSSValue> cssValue = CSSArrayFunctionValue::create();
     RefPtr<AnimatableValue> animatableUnknown = AnimatableUnknown::create(cssValue);
 
     EXPECT_EQ(cssValue, toAnimatableUnknown(AnimatableValue::add(animatableUnknown.get(), AnimatableValue::neutralValue()).get())->toCSSValue());
diff --git a/Source/core/animation/AnimatableShapeValue.cpp b/Source/core/animation/AnimatableShapeValue.cpp
index 1742bac..e661e9e 100644
--- a/Source/core/animation/AnimatableShapeValue.cpp
+++ b/Source/core/animation/AnimatableShapeValue.cpp
@@ -37,7 +37,9 @@
 {
     const AnimatableShapeValue* shapeValue = toAnimatableShapeValue(value);
 
-    if (m_shape->type() != ShapeValue::Shape || shapeValue->m_shape->type() != ShapeValue::Shape)
+    if (m_shape->type() != ShapeValue::Shape
+        || shapeValue->m_shape->type() != ShapeValue::Shape
+        || m_shape->layoutBox() != shapeValue->m_shape->layoutBox())
         return true;
 
     const BasicShape* fromShape = this->m_shape->shape();
@@ -54,7 +56,7 @@
     const AnimatableShapeValue* shapeValue = toAnimatableShapeValue(value);
     const BasicShape* fromShape = this->m_shape->shape();
     const BasicShape* toShape = shapeValue->m_shape->shape();
-    return AnimatableShapeValue::create(ShapeValue::createShapeValue(toShape->blend(fromShape, fraction)).get());
+    return AnimatableShapeValue::create(ShapeValue::createShapeValue(toShape->blend(fromShape, fraction), shapeValue->m_shape->layoutBox()).get());
 }
 
 bool AnimatableShapeValue::equalTo(const AnimatableValue* value) const
diff --git a/Source/core/animation/AnimatableUnknown.h b/Source/core/animation/AnimatableUnknown.h
index 4080c4d..ec56925 100644
--- a/Source/core/animation/AnimatableUnknown.h
+++ b/Source/core/animation/AnimatableUnknown.h
@@ -41,7 +41,7 @@
 public:
     virtual ~AnimatableUnknown() { }
 
-    static PassRefPtr<AnimatableUnknown> create(PassRefPtr<CSSValue> value)
+    static PassRefPtr<AnimatableUnknown> create(PassRefPtrWillBeRawPtr<CSSValue> value)
     {
         return adoptRef(new AnimatableUnknown(value));
     }
@@ -50,7 +50,7 @@
         return adoptRef(new AnimatableUnknown(cssValuePool().createIdentifierValue(value)));
     }
 
-    PassRefPtr<CSSValue> toCSSValue() const { return m_value; }
+    PassRefPtrWillBeRawPtr<CSSValue> toCSSValue() const { return m_value; }
     CSSValueID toCSSValueID() const { return toCSSPrimitiveValue(m_value.get())->getValueID(); }
 
 protected:
@@ -62,7 +62,7 @@
     virtual bool usesDefaultInterpolationWith(const AnimatableValue*) const OVERRIDE { return true; }
 
 private:
-    explicit AnimatableUnknown(PassRefPtr<CSSValue> value)
+    explicit AnimatableUnknown(PassRefPtrWillBeRawPtr<CSSValue> value)
         : m_value(value)
     {
         ASSERT(m_value);
@@ -70,7 +70,7 @@
     virtual AnimatableType type() const OVERRIDE { return TypeUnknown; }
     virtual bool equalTo(const AnimatableValue*) const OVERRIDE;
 
-    const RefPtr<CSSValue> m_value;
+    const RefPtrWillBePersistent<CSSValue> m_value;
 };
 
 DEFINE_ANIMATABLE_VALUE_TYPE_CASTS(AnimatableUnknown, isUnknown());
diff --git a/Source/core/animation/AnimatableUnknownTest.cpp b/Source/core/animation/AnimatableUnknownTest.cpp
index 5ca1760..2785dfe 100644
--- a/Source/core/animation/AnimatableUnknownTest.cpp
+++ b/Source/core/animation/AnimatableUnknownTest.cpp
@@ -51,10 +51,10 @@
         otherAnimatableUnknown = AnimatableUnknown::create(otherCSSValue);
     }
 
-    RefPtr<CSSValue> cssValue;
+    RefPtrWillBePersistent<CSSValue> cssValue;
     RefPtr<AnimatableValue> animatableUnknown;
 
-    RefPtr<CSSValue> otherCSSValue;
+    RefPtrWillBePersistent<CSSValue> otherCSSValue;
     RefPtr<AnimatableValue> otherAnimatableUnknown;
 };
 
diff --git a/Source/core/animation/AnimatableValue.cpp b/Source/core/animation/AnimatableValue.cpp
index 1c9d175..a8b9557 100644
--- a/Source/core/animation/AnimatableValue.cpp
+++ b/Source/core/animation/AnimatableValue.cpp
@@ -34,6 +34,12 @@
 #include "wtf/StdLibExtras.h"
 #include <algorithm>
 
+namespace {
+
+const double defaultDistance = 1;
+
+} // namespace
+
 namespace WebCore {
 
 const AnimatableValue* AnimatableValue::neutralValue()
@@ -76,4 +82,20 @@
     return defaultAddWith(this, value);
 }
 
+double AnimatableValue::distance(const AnimatableValue* left, const AnimatableValue* right)
+{
+    ASSERT(left);
+    ASSERT(right);
+
+    if (left->isSameType(right))
+        return left->distanceTo(right);
+
+    return defaultDistance;
+}
+
+double AnimatableValue::distanceTo(const AnimatableValue*) const
+{
+    return defaultDistance;
+}
+
 } // namespace WebCore
diff --git a/Source/core/animation/AnimatableValue.h b/Source/core/animation/AnimatableValue.h
index 3771fb4..de043f5 100644
--- a/Source/core/animation/AnimatableValue.h
+++ b/Source/core/animation/AnimatableValue.h
@@ -46,6 +46,7 @@
     static PassRefPtr<AnimatableValue> interpolate(const AnimatableValue*, const AnimatableValue*, double fraction);
     // For noncommutative values read add(A, B) to mean the value A with B composed onto it.
     static PassRefPtr<AnimatableValue> add(const AnimatableValue*, const AnimatableValue*);
+    static double distance(const AnimatableValue* from, const AnimatableValue* to);
     static bool usesDefaultInterpolation(const AnimatableValue* from, const AnimatableValue* to)
     {
         return !from->isSameType(to) || from->usesDefaultInterpolationWith(to);
@@ -132,6 +133,8 @@
     // Implementations can assume that the object being compared has the same type as the object this is called on
     virtual bool equalTo(const AnimatableValue*) const = 0;
 
+    virtual double distanceTo(const AnimatableValue*) const;
+
     friend class KeyframeEffectModel;
 };
 
diff --git a/Source/core/animation/AnimatableValueTestHelper.cpp b/Source/core/animation/AnimatableValueTestHelper.cpp
index 1dbea42..d43a914 100644
--- a/Source/core/animation/AnimatableValueTestHelper.cpp
+++ b/Source/core/animation/AnimatableValueTestHelper.cpp
@@ -144,7 +144,7 @@
 {
     *os << "AnimatableStrokeDasharrayList(";
     RefPtr<SVGLengthList> list = animValue.toSVGLengthList();
-    size_t length = list->numberOfItems();
+    size_t length = list->length();
     for (size_t i = 0; i < length; ++i) {
         *os << list->at(i)->valueAsString().utf8().data();
         if (i != length-1)
diff --git a/Source/core/animation/AnimatableValueTestHelperTest.cpp b/Source/core/animation/AnimatableValueTestHelperTest.cpp
index 5836421..d7f98ca 100644
--- a/Source/core/animation/AnimatableValueTestHelperTest.cpp
+++ b/Source/core/animation/AnimatableValueTestHelperTest.cpp
@@ -132,7 +132,7 @@
         PrintToString(AnimatableSVGPaint::create(SVGPaint::SVG_PAINTTYPE_URI, Color(0xFFFF0000), "abc")));
 
     EXPECT_THAT(
-        PrintToString(AnimatableShapeValue::create(ShapeValue::createShapeValue(BasicShapeCircle::create().get()).get())),
+        PrintToString(AnimatableShapeValue::create(ShapeValue::createShapeValue(BasicShapeCircle::create().get(), ContentBox).get())),
         testing::StartsWith("AnimatableShapeValue@"));
 
     RefPtr<SVGLengthList> l2 = SVGLengthList::create();
diff --git a/Source/core/animation/Animation.cpp b/Source/core/animation/Animation.cpp
index d81f8ee..b5fde0c 100644
--- a/Source/core/animation/Animation.cpp
+++ b/Source/core/animation/Animation.cpp
@@ -34,290 +34,52 @@
 #include "bindings/v8/Dictionary.h"
 #include "core/animation/ActiveAnimations.h"
 #include "core/animation/AnimationHelpers.h"
+#include "core/animation/AnimationPlayer.h"
 #include "core/animation/CompositorAnimations.h"
 #include "core/animation/DocumentTimeline.h"
 #include "core/animation/KeyframeEffectModel.h"
-#include "core/animation/Player.h"
-#include "core/css/parser/BisonCSSParser.h"
-#include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Element.h"
 #include "core/rendering/RenderLayer.h"
-#include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
 
-PassRefPtr<Animation> Animation::create(PassRefPtr<Element> target, PassRefPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
+PassRefPtr<Animation> Animation::create(PassRefPtr<Element> target, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
 {
     return adoptRef(new Animation(target, effect, timing, priority, eventDelegate));
 }
 
-static bool checkDocumentAndRenderer(Element* element)
-{
-    if (!element->inActiveDocument())
-        return false;
-    element->document().updateStyleIfNeeded();
-    if (!element->renderer())
-        return false;
-    return true;
-}
-
-PassRefPtr<Animation> Animation::create(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
+PassRefPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Dictionary& timingInputDictionary)
 {
     ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
-
-    // FIXME: This test will not be neccessary once resolution of keyframe values occurs at
-    // animation application time.
-    if (!checkDocumentAndRenderer(element))
-        return 0;
-
-    return createUnsafe(element, keyframeDictionaryVector, timingInput);
+    return create(element, effect, TimingInput::convert(timingInputDictionary));
 }
-
-PassRefPtr<Animation> Animation::create(Element* element, Vector<Dictionary> keyframeDictionaryVector, double timingInput)
+PassRefPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, double duration)
 {
     ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
-
-    // FIXME: This test will not be neccessary once resolution of keyframe values occurs at
-    // animation application time.
-    if (!checkDocumentAndRenderer(element))
-        return 0;
-
-    return createUnsafe(element, keyframeDictionaryVector, timingInput);
+    return create(element, effect, TimingInput::convert(duration));
 }
-
-PassRefPtr<Animation> Animation::create(Element* element, Vector<Dictionary> keyframeDictionaryVector)
+PassRefPtr<Animation> Animation::create(Element* element, PassRefPtrWillBeRawPtr<AnimationEffect> effect)
 {
     ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
-
-    // FIXME: This test will not be neccessary once resolution of keyframe values occurs at
-    // animation application time.
-    if (!checkDocumentAndRenderer(element))
-        return 0;
-
-    return createUnsafe(element, keyframeDictionaryVector);
+    return create(element, effect, Timing());
 }
-
-void Animation::setStartDelay(Timing& timing, double startDelay)
+PassRefPtr<Animation> Animation::create(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, const Dictionary& timingInputDictionary)
 {
-    if (std::isfinite(startDelay))
-        timing.startDelay = startDelay;
-    else
-        timing.startDelay = 0;
+    ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+    return create(element, EffectInput::convert(element, keyframeDictionaryVector), TimingInput::convert(timingInputDictionary));
 }
-
-void Animation::setEndDelay(Timing& timing, double endDelay)
+PassRefPtr<Animation> Animation::create(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, double duration)
 {
-    if (std::isfinite(endDelay))
-        timing.endDelay = endDelay;
-    else
-        timing.endDelay = 0;
+    ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+    return create(element, EffectInput::convert(element, keyframeDictionaryVector), TimingInput::convert(duration));
 }
-
-void Animation::setFillMode(Timing& timing, String fillMode)
+PassRefPtr<Animation> Animation::create(Element* element, const Vector<Dictionary>& keyframeDictionaryVector)
 {
-    if (fillMode == "none") {
-        timing.fillMode = Timing::FillModeNone;
-    } else if (fillMode == "backwards") {
-        timing.fillMode = Timing::FillModeBackwards;
-    } else if (fillMode == "both") {
-        timing.fillMode = Timing::FillModeBoth;
-    } else if (fillMode == "forwards") {
-        timing.fillMode = Timing::FillModeForwards;
-    } else {
-        timing.fillMode = Timing::FillModeAuto;
-    }
+    ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+    return create(element, EffectInput::convert(element, keyframeDictionaryVector), Timing());
 }
 
-void Animation::setIterationStart(Timing& timing, double iterationStart)
-{
-    if (!std::isnan(iterationStart) && !std::isinf(iterationStart))
-        timing.iterationStart = std::max<double>(iterationStart, 0);
-    else
-        timing.iterationStart = 0;
-}
-
-void Animation::setIterationCount(Timing& timing, double iterationCount)
-{
-    if (!std::isnan(iterationCount))
-        timing.iterationCount = std::max<double>(iterationCount, 0);
-    else
-        timing.iterationCount = 1;
-}
-
-void Animation::setIterationDuration(Timing& timing, double iterationDuration)
-{
-    if (!std::isnan(iterationDuration) && iterationDuration >= 0)
-        timing.iterationDuration = iterationDuration;
-    else
-        timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-}
-
-void Animation::setPlaybackRate(Timing& timing, double playbackRate)
-{
-    if (!std::isnan(playbackRate) && !std::isinf(playbackRate))
-        timing.playbackRate = playbackRate;
-    else
-        timing.playbackRate = 1;
-}
-
-void Animation::setPlaybackDirection(Timing& timing, String direction)
-{
-    if (direction == "reverse") {
-        timing.direction = Timing::PlaybackDirectionReverse;
-    } else if (direction == "alternate") {
-        timing.direction = Timing::PlaybackDirectionAlternate;
-    } else if (direction == "alternate-reverse") {
-        timing.direction = Timing::PlaybackDirectionAlternateReverse;
-    } else {
-        timing.direction = Timing::PlaybackDirectionNormal;
-    }
-}
-
-void Animation::setTimingFunction(Timing& timing, String timingFunctionString)
-{
-    RefPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString);
-    if (timingFunctionValue) {
-        RefPtr<TimingFunction> timingFunction = CSSToStyleMap::animationTimingFunction(timingFunctionValue.get(), false);
-        if (timingFunction) {
-            timing.timingFunction = timingFunction;
-            return;
-        }
-    }
-    timing.timingFunction = LinearTimingFunction::create();
-}
-
-void Animation::populateTiming(Timing& timing, Dictionary timingInputDictionary)
-{
-    // FIXME: This method needs to be refactored to handle invalid
-    // null, NaN, Infinity values better.
-    // See: http://www.w3.org/TR/WebIDL/#es-double
-    double startDelay = 0;
-    timingInputDictionary.get("delay", startDelay);
-    setStartDelay(timing, startDelay);
-
-    double endDelay = 0;
-    timingInputDictionary.get("endDelay", endDelay);
-    setEndDelay(timing, endDelay);
-
-    String fillMode;
-    timingInputDictionary.get("fill", fillMode);
-    setFillMode(timing, fillMode);
-
-    double iterationStart = 0;
-    timingInputDictionary.get("iterationStart", iterationStart);
-    setIterationStart(timing, iterationStart);
-
-    double iterationCount = 1;
-    timingInputDictionary.get("iterations", iterationCount);
-    setIterationCount(timing, iterationCount);
-
-    v8::Local<v8::Value> iterationDurationValue;
-    if (timingInputDictionary.get("duration", iterationDurationValue)) {
-        double iterationDuration = iterationDurationValue->NumberValue();
-        setIterationDuration(timing, iterationDuration);
-    }
-
-    double playbackRate = 1;
-    timingInputDictionary.get("playbackRate", playbackRate);
-    setPlaybackRate(timing, playbackRate);
-
-    String direction;
-    timingInputDictionary.get("direction", direction);
-    setPlaybackDirection(timing, direction);
-
-    String timingFunctionString;
-    timingInputDictionary.get("easing", timingFunctionString);
-    setTimingFunction(timing, timingFunctionString);
-
-    timing.assertValid();
-}
-
-static PassRefPtr<KeyframeEffectModel> createKeyframeEffectModel(Element* element, Vector<Dictionary> keyframeDictionaryVector)
-{
-    KeyframeEffectModel::KeyframeVector keyframes;
-    Vector<RefPtr<MutableStylePropertySet> > propertySetVector;
-
-    for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) {
-        RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
-        propertySetVector.append(propertySet);
-
-        RefPtr<Keyframe> keyframe = Keyframe::create();
-        keyframes.append(keyframe);
-
-        double offset;
-        if (keyframeDictionaryVector[i].get("offset", offset)) {
-            keyframe->setOffset(offset);
-        }
-
-        String compositeString;
-        keyframeDictionaryVector[i].get("composite", compositeString);
-        if (compositeString == "add")
-            keyframe->setComposite(AnimationEffect::CompositeAdd);
-
-        String timingFunctionString;
-        if (keyframeDictionaryVector[i].get("easing", timingFunctionString)) {
-            RefPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString);
-            if (timingFunctionValue) {
-                keyframe->setEasing(CSSToStyleMap::animationTimingFunction(timingFunctionValue.get(), false));
-            }
-        }
-
-        Vector<String> keyframeProperties;
-        keyframeDictionaryVector[i].getOwnPropertyNames(keyframeProperties);
-
-        for (size_t j = 0; j < keyframeProperties.size(); ++j) {
-            String property = keyframeProperties[j];
-            CSSPropertyID id = camelCaseCSSPropertyNameToID(property);
-
-            // FIXME: There is no way to store invalid properties or invalid values
-            // in a Keyframe object, so for now I just skip over them. Eventually we
-            // will need to support getFrames(), which should return exactly the
-            // keyframes that were input through the API. We will add a layer to wrap
-            // KeyframeEffectModel, store input keyframes and implement getFrames.
-            if (id == CSSPropertyInvalid || !CSSAnimations::isAnimatableProperty(id))
-                continue;
-
-            String value;
-            keyframeDictionaryVector[i].get(property, value);
-            propertySet->setProperty(id, value);
-        }
-    }
-
-    // FIXME: Replace this with code that just parses, when that code is available.
-    RefPtr<KeyframeEffectModel> effect = StyleResolver::createKeyframeEffectModel(*element, propertySetVector, keyframes);
-    return effect;
-}
-
-PassRefPtr<Animation> Animation::createUnsafe(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
-{
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(element, keyframeDictionaryVector);
-
-    Timing timing;
-    populateTiming(timing, timingInput);
-
-    return create(element, effect, timing);
-}
-
-PassRefPtr<Animation> Animation::createUnsafe(Element* element, Vector<Dictionary> keyframeDictionaryVector, double timingInput)
-{
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(element, keyframeDictionaryVector);
-
-    Timing timing;
-    if (!std::isnan(timingInput))
-        timing.iterationDuration = std::max<double>(timingInput, 0);
-
-    return create(element, effect, timing);
-}
-
-PassRefPtr<Animation> Animation::createUnsafe(Element* element, Vector<Dictionary> keyframeDictionaryVector)
-{
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(element, keyframeDictionaryVector);
-    Timing timing;
-
-    return create(element, effect, timing);
-}
-
-Animation::Animation(PassRefPtr<Element> target, PassRefPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
+Animation::Animation(PassRefPtr<Element> target, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, Priority priority, PassOwnPtr<EventDelegate> eventDelegate)
     : TimedItem(timing, eventDelegate)
     , m_target(target)
     , m_effect(effect)
@@ -329,7 +91,7 @@
 void Animation::didAttach()
 {
     if (m_target)
-        m_target->ensureActiveAnimations()->players().add(player());
+        m_target->ensureActiveAnimations().players().add(player());
 }
 
 void Animation::willDetach()
@@ -342,14 +104,14 @@
 
 static AnimationStack& ensureAnimationStack(Element* element)
 {
-    return element->ensureActiveAnimations()->defaultStack();
+    return element->ensureActiveAnimations().defaultStack();
 }
 
-bool Animation::applyEffects(bool previouslyInEffect)
+void Animation::applyEffects(bool previouslyInEffect)
 {
     ASSERT(isInEffect());
     if (!m_target || !m_effect)
-        return false;
+        return;
 
     if (player() && !previouslyInEffect) {
         ensureAnimationStack(m_target.get()).add(this);
@@ -360,11 +122,8 @@
     ASSERT(iteration >= 0);
     // FIXME: Handle iteration values which overflow int.
     m_compositableValues = m_effect->sample(static_cast<int>(iteration), timeFraction());
-    if (player()) {
+    if (player())
         m_target->setNeedsAnimationStyleRecalc();
-        return true;
-    }
-    return false;
 }
 
 void Animation::clearEffects()
@@ -387,19 +146,14 @@
     invalidate();
 }
 
-bool Animation::updateChildrenAndEffects() const
+void Animation::updateChildrenAndEffects() const
 {
     if (!m_effect)
-        return false;
-
+        return;
     if (isInEffect())
-        return const_cast<Animation*>(this)->applyEffects(m_activeInAnimationStack);
-
-    if (m_activeInAnimationStack) {
+        const_cast<Animation*>(this)->applyEffects(m_activeInAnimationStack);
+    else if (m_activeInAnimationStack)
         const_cast<Animation*>(this)->clearEffects();
-        return true;
-    }
-    return false;
 }
 
 double Animation::calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const
diff --git a/Source/core/animation/Animation.h b/Source/core/animation/Animation.h
index 04d7f15..abc1be3 100644
--- a/Source/core/animation/Animation.h
+++ b/Source/core/animation/Animation.h
@@ -32,7 +32,10 @@
 #define Animation_h
 
 #include "core/animation/AnimationEffect.h"
+#include "core/animation/EffectInput.h"
 #include "core/animation/TimedItem.h"
+#include "core/animation/TimingInput.h"
+#include "heap/Handle.h"
 #include "wtf/RefPtr.h"
 
 namespace WebCore {
@@ -45,11 +48,14 @@
 public:
     enum Priority { DefaultPriority, TransitionPriority };
 
-    static PassRefPtr<Animation> create(PassRefPtr<Element>, PassRefPtr<AnimationEffect>, const Timing&, Priority = DefaultPriority, PassOwnPtr<EventDelegate> = nullptr);
+    static PassRefPtr<Animation> create(PassRefPtr<Element>, PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, Priority = DefaultPriority, PassOwnPtr<EventDelegate> = nullptr);
     // Web Animations API Bindings constructors.
-    static PassRefPtr<Animation> create(Element*, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput);
-    static PassRefPtr<Animation> create(Element*, Vector<Dictionary> keyframeDictionaryVector, double timingInput);
-    static PassRefPtr<Animation> create(Element*, Vector<Dictionary> keyframeDictionaryVector);
+    static PassRefPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, const Dictionary& timingInputDictionary);
+    static PassRefPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>, double duration);
+    static PassRefPtr<Animation> create(Element*, PassRefPtrWillBeRawPtr<AnimationEffect>);
+    static PassRefPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, const Dictionary& timingInputDictionary);
+    static PassRefPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector, double duration);
+    static PassRefPtr<Animation> create(Element*, const Vector<Dictionary>& keyframeDictionaryVector);
 
     // FIXME: Move all of these setter methods out of Animation,
     // possibly into a new class (TimingInput?).
@@ -85,25 +91,20 @@
     void pauseAnimationForTestingOnCompositor(double pauseTime);
 
 protected:
-    // Returns whether style recalc was triggered.
-    bool applyEffects(bool previouslyInEffect);
+    void applyEffects(bool previouslyInEffect);
     void clearEffects();
-    virtual bool updateChildrenAndEffects() const OVERRIDE;
+    virtual void updateChildrenAndEffects() const OVERRIDE;
     virtual void didAttach() OVERRIDE;
     virtual void willDetach() OVERRIDE;
     virtual double calculateTimeToEffectChange(bool forwards, double inheritedTime, double timeToNextIteration) const OVERRIDE;
 
 private:
     static void populateTiming(Timing&, Dictionary);
-    // createUnsafe should only be directly called from tests.
-    static PassRefPtr<Animation> createUnsafe(Element*, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput);
-    static PassRefPtr<Animation> createUnsafe(Element*, Vector<Dictionary> keyframeDictionaryVector, double timingInput);
-    static PassRefPtr<Animation> createUnsafe(Element*, Vector<Dictionary> keyframeDictionaryVector);
 
-    Animation(PassRefPtr<Element>, PassRefPtr<AnimationEffect>, const Timing&, Priority, PassOwnPtr<EventDelegate>);
+    Animation(PassRefPtr<Element>, PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, Priority, PassOwnPtr<EventDelegate>);
 
     RefPtr<Element> m_target;
-    RefPtr<AnimationEffect> m_effect;
+    RefPtrWillBePersistent<AnimationEffect> m_effect;
 
     bool m_activeInAnimationStack;
     OwnPtr<AnimationEffect::CompositableValueList> m_compositableValues;
@@ -113,7 +114,7 @@
     Vector<int> m_compositorAnimationIds;
 
     friend class CSSAnimations;
-    friend class AnimationAnimationTest;
+    friend class AnimationAnimationV8Test;
 };
 
 DEFINE_TYPE_CASTS(Animation, TimedItem, timedItem, timedItem->isAnimation(), timedItem.isAnimation());
diff --git a/Source/core/fetch/CachedMetadata.cpp b/Source/core/animation/AnimationClock.cpp
similarity index 76%
copy from Source/core/fetch/CachedMetadata.cpp
copy to Source/core/animation/AnimationClock.cpp
index 7edcac5..6492206 100644
--- a/Source/core/fetch/CachedMetadata.cpp
+++ b/Source/core/animation/AnimationClock.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (c) 2014, Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -29,8 +29,25 @@
  */
 
 #include "config.h"
-#include "core/fetch/CachedMetadata.h"
+#include "core/animation/AnimationClock.h"
 
 namespace WebCore {
 
-} // namespace WebCore
+void AnimationClock::updateTime(double time)
+{
+    if (time > m_time)
+        m_time = time;
+    m_frozen = true;
+}
+
+double AnimationClock::currentTime()
+{
+    if (!m_frozen) {
+        double newTime = m_monotonicallyIncreasingTime();
+        if (newTime >= m_time + minTimeBeforeUnsynchronizedAnimationClockTick)
+            m_time = newTime;
+    }
+    return m_time;
+}
+
+}
diff --git a/Source/core/animation/AnimationClock.h b/Source/core/animation/AnimationClock.h
index f6a2cdb..540dfbe 100644
--- a/Source/core/animation/AnimationClock.h
+++ b/Source/core/animation/AnimationClock.h
@@ -36,6 +36,13 @@
 
 namespace WebCore {
 
+// FIXME: This value is used to suppress updates when time is required outside of a frame.
+// The purpose of allowing the clock to update during such periods is to allow animations
+// to have an appropriate start time and for getComputedStyle to attempt to catch-up to a
+// compositor animation. However a more accurate system might be to attempt to phase-lock
+// with the frame clock.
+const double minTimeBeforeUnsynchronizedAnimationClockTick = 0.005;
+
 class AnimationClock {
 public:
     static PassOwnPtr<AnimationClock> create(WTF::TimeFunction monotonicallyIncreasingTime = WTF::monotonicallyIncreasingTime)
@@ -43,22 +50,9 @@
         return adoptPtr(new AnimationClock(monotonicallyIncreasingTime));
     }
 
-    void updateTime(double time)
-    {
-        if (time > m_time)
-            m_time = time;
-        m_frozen = true;
-    }
-
-    double currentTime()
-    {
-        if (!m_frozen)
-            updateTime(m_monotonicallyIncreasingTime());
-        return m_time;
-    }
-
+    void updateTime(double time);
+    double currentTime();
     void unfreeze() { m_frozen = false; }
-
     void resetTimeForTesting() { m_time = 0; m_frozen = true; }
 
 private:
diff --git a/Source/core/animation/AnimationClockTest.cpp b/Source/core/animation/AnimationClockTest.cpp
index 248da7b..7e54cde 100644
--- a/Source/core/animation/AnimationClockTest.cpp
+++ b/Source/core/animation/AnimationClockTest.cpp
@@ -48,7 +48,7 @@
 
     static double mockTimeFunction()
     {
-        return mockTime++;
+        return mockTime;
     }
 
     static double mockTime;
@@ -59,21 +59,29 @@
 
 TEST_F(AnimationAnimationClockTest, CurrentTime)
 {
+    // Current time should not advance until minTimeBeforeUnsynchronizedTick has elapsed
     EXPECT_EQ(200, animationClock->currentTime());
+    mockTime = 200 + minTimeBeforeUnsynchronizedAnimationClockTick / 2.0;
     EXPECT_EQ(200, animationClock->currentTime());
-    animationClock->unfreeze();
-    EXPECT_EQ(201, animationClock->currentTime());
-    EXPECT_EQ(201, animationClock->currentTime());
+
+    mockTime = 200 + minTimeBeforeUnsynchronizedAnimationClockTick;
+    EXPECT_EQ(mockTime, animationClock->currentTime());
 }
 
 TEST_F(AnimationAnimationClockTest, UpdateTime)
 {
     animationClock->updateTime(100);
     EXPECT_EQ(100, animationClock->currentTime());
+    mockTime = 200;
     EXPECT_EQ(100, animationClock->currentTime());
-    animationClock->updateTime(150);
-    EXPECT_EQ(150, animationClock->currentTime());
-    EXPECT_EQ(150, animationClock->currentTime());
+
+    animationClock->unfreeze();
+    EXPECT_EQ(200, animationClock->currentTime());
+
+    animationClock->updateTime(300);
+    EXPECT_EQ(300, animationClock->currentTime());
+    mockTime = 400;
+    EXPECT_EQ(300, animationClock->currentTime());
 }
 
 }
diff --git a/Source/core/animation/AnimationEffect.h b/Source/core/animation/AnimationEffect.h
index 7ea4d21..8438c2c 100644
--- a/Source/core/animation/AnimationEffect.h
+++ b/Source/core/animation/AnimationEffect.h
@@ -32,6 +32,7 @@
 #define AnimationEffect_h
 
 #include "CSSPropertyNames.h"
+#include "heap/Handle.h"
 #include "wtf/HashMap.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/RefCounted.h"
@@ -40,7 +41,7 @@
 
 class AnimatableValue;
 
-class AnimationEffect : public RefCounted<AnimationEffect> {
+class AnimationEffect : public RefCountedWillBeGarbageCollectedFinalized<AnimationEffect> {
 public:
     enum CompositeOperation {
         CompositeReplace,
@@ -63,6 +64,8 @@
 
     virtual bool affects(CSSPropertyID) { return false; };
     virtual bool isKeyframeEffectModel() const { return false; }
+
+    virtual void trace(Visitor*) = 0;
 };
 
 } // namespace WebCore
diff --git a/Source/core/animation/Player.cpp b/Source/core/animation/AnimationPlayer.cpp
similarity index 69%
rename from Source/core/animation/Player.cpp
rename to Source/core/animation/AnimationPlayer.cpp
index 2b91b40..7019e95 100644
--- a/Source/core/animation/Player.cpp
+++ b/Source/core/animation/AnimationPlayer.cpp
@@ -29,19 +29,29 @@
  */
 
 #include "config.h"
-#include "core/animation/Player.h"
+#include "core/animation/AnimationPlayer.h"
 
 #include "core/animation/Animation.h"
 #include "core/animation/DocumentTimeline.h"
 
 namespace WebCore {
 
-PassRefPtr<Player> Player::create(DocumentTimeline& timeline, TimedItem* content)
+namespace {
+
+static unsigned nextSequenceNumber()
 {
-    return adoptRef(new Player(timeline, content));
+    static unsigned next = 0;
+    return ++next;
 }
 
-Player::Player(DocumentTimeline& timeline, TimedItem* content)
+}
+
+PassRefPtr<AnimationPlayer> AnimationPlayer::create(DocumentTimeline& timeline, TimedItem* content)
+{
+    return adoptRef(new AnimationPlayer(timeline, content));
+}
+
+AnimationPlayer::AnimationPlayer(DocumentTimeline& timeline, TimedItem* content)
     : m_playbackRate(1)
     , m_startTime(nullValue())
     , m_holdTime(nullValue())
@@ -51,13 +61,17 @@
     , m_paused(false)
     , m_held(false)
     , m_isPausedForTesting(false)
-    , m_needsUpdate(false)
+    , m_outdated(false)
+    , m_sequenceNumber(nextSequenceNumber())
 {
-    if (m_content)
+    if (m_content) {
+        if (m_content->player())
+            m_content->player()->cancel();
         m_content->attach(this);
+    }
 }
 
-Player::~Player()
+AnimationPlayer::~AnimationPlayer()
 {
     if (m_content)
         m_content->detach();
@@ -65,17 +79,17 @@
         m_timeline->playerDestroyed(this);
 }
 
-double Player::sourceEnd() const
+double AnimationPlayer::sourceEnd() const
 {
     return m_content ? m_content->endTime() : 0;
 }
 
-bool Player::limited(double currentTime) const
+bool AnimationPlayer::limited(double currentTime) const
 {
     return (m_playbackRate < 0 && currentTime <= 0) || (m_playbackRate > 0 && currentTime >= sourceEnd());
 }
 
-double Player::currentTimeWithoutLag() const
+double AnimationPlayer::currentTimeWithoutLag() const
 {
     if (isNull(m_startTime) || !m_timeline)
         return 0;
@@ -85,39 +99,44 @@
     return (timelineTime - m_startTime) * m_playbackRate;
 }
 
-double Player::currentTimeWithLag() const
+double AnimationPlayer::currentTimeWithLag() const
 {
     ASSERT(!m_held);
     double time = currentTimeWithoutLag();
     return std::isinf(time) ? time : time - m_storedTimeLag;
 }
 
-void Player::updateTimingState(double newCurrentTime)
+void AnimationPlayer::updateTimingState(double newCurrentTime)
 {
     ASSERT(!isNull(newCurrentTime));
+    bool oldHeld = m_held;
     m_held = m_paused || !m_playbackRate || limited(newCurrentTime);
     if (m_held) {
+        if (!oldHeld || m_holdTime != newCurrentTime)
+            setOutdated();
         m_holdTime = newCurrentTime;
         m_storedTimeLag = nullValue();
     } else {
         m_holdTime = nullValue();
         m_storedTimeLag = currentTimeWithoutLag() - newCurrentTime;
+        setOutdated();
     }
-    setNeedsUpdate();
 }
 
-void Player::updateCurrentTimingState()
+void AnimationPlayer::updateCurrentTimingState()
 {
     if (m_held) {
         updateTimingState(m_holdTime);
-    } else {
-        updateTimingState(currentTimeWithLag());
-        if (m_held && limited(m_holdTime))
-            m_holdTime = m_playbackRate < 0 ? 0 : sourceEnd();
+        return;
     }
+    if (!limited(currentTimeWithLag()))
+        return;
+    m_held = true;
+    m_holdTime = m_playbackRate < 0 ? 0 : sourceEnd();
+    m_storedTimeLag = nullValue();
 }
 
-double Player::currentTime()
+double AnimationPlayer::currentTime()
 {
     updateCurrentTimingState();
     if (m_held)
@@ -125,41 +144,43 @@
     return currentTimeWithLag();
 }
 
-void Player::setCurrentTime(double newCurrentTime)
+void AnimationPlayer::setCurrentTime(double newCurrentTime)
 {
     if (!std::isfinite(newCurrentTime))
         return;
     updateTimingState(newCurrentTime);
 }
 
-void Player::setStartTime(double newStartTime)
+void AnimationPlayer::setStartTime(double newStartTime)
 {
     if (!std::isfinite(newStartTime))
         return;
     updateCurrentTimingState(); // Update the value of held
     m_startTime = newStartTime;
-    if (!m_held)
-        updateCurrentTimingState();
+    if (m_held)
+        return;
+    updateCurrentTimingState();
+    setOutdated();
 }
 
-void Player::setSource(TimedItem* newSource)
+void AnimationPlayer::setSource(TimedItem* newSource)
 {
     if (m_content == newSource)
         return;
     double storedCurrentTime = currentTime();
     if (m_content)
         m_content->detach();
+    m_content = newSource;
     if (newSource) {
         // FIXME: This logic needs to be updated once groups are implemented
         if (newSource->player())
-            newSource->detach();
+            newSource->player()->cancel();
         newSource->attach(this);
     }
-    m_content = newSource;
     updateTimingState(storedCurrentTime);
 }
 
-void Player::pause()
+void AnimationPlayer::pause()
 {
     if (m_paused)
         return;
@@ -169,7 +190,7 @@
     cancelAnimationOnCompositor();
 }
 
-void Player::unpause()
+void AnimationPlayer::unpause()
 {
     if (!m_paused)
         return;
@@ -177,7 +198,7 @@
     updateTimingState(currentTime());
 }
 
-void Player::play()
+void AnimationPlayer::play()
 {
     unpause();
     if (!m_content)
@@ -189,7 +210,7 @@
         setCurrentTime(sourceEnd());
 }
 
-void Player::reverse()
+void AnimationPlayer::reverse()
 {
     if (!m_playbackRate)
         return;
@@ -203,7 +224,7 @@
     unpause();
 }
 
-void Player::finish(ExceptionState& exceptionState)
+void AnimationPlayer::finish(ExceptionState& exceptionState)
 {
     if (!m_playbackRate)
         return;
@@ -211,7 +232,7 @@
         setCurrentTime(0);
     } else {
         if (sourceEnd() == std::numeric_limits<double>::infinity()) {
-            exceptionState.throwDOMException(InvalidStateError, "Player has source content whose end time is infinity.");
+            exceptionState.throwDOMException(InvalidStateError, "AnimationPlayer has source content whose end time is infinity.");
             return;
         }
         setCurrentTime(sourceEnd());
@@ -219,7 +240,7 @@
     ASSERT(finished());
 }
 
-void Player::setPlaybackRate(double playbackRate)
+void AnimationPlayer::setPlaybackRate(double playbackRate)
 {
     if (!std::isfinite(playbackRate))
         return;
@@ -228,14 +249,14 @@
     updateTimingState(storedCurrentTime);
 }
 
-void Player::setNeedsUpdate()
+void AnimationPlayer::setOutdated()
 {
-    m_needsUpdate = true;
+    m_outdated = true;
     if (m_timeline)
-        m_timeline->setHasPlayerNeedingUpdate();
+        m_timeline->setOutdatedAnimationPlayer(this);
 }
 
-bool Player::maybeStartAnimationOnCompositor()
+bool AnimationPlayer::maybeStartAnimationOnCompositor()
 {
     // FIXME: Support starting compositor animations that have a fixed
     // start time.
@@ -246,63 +267,65 @@
     return toAnimation(m_content.get())->maybeStartAnimationOnCompositor();
 }
 
-bool Player::hasActiveAnimationsOnCompositor()
+bool AnimationPlayer::hasActiveAnimationsOnCompositor()
 {
     if (!m_content || !m_content->isAnimation())
         return false;
     return toAnimation(m_content.get())->hasActiveAnimationsOnCompositor();
 }
 
-void Player::cancelAnimationOnCompositor()
+void AnimationPlayer::cancelAnimationOnCompositor()
 {
     if (hasActiveAnimationsOnCompositor())
         toAnimation(m_content.get())->cancelAnimationOnCompositor();
 }
 
-bool Player::update(bool* didTriggerStyleRecalc)
+bool AnimationPlayer::update()
 {
-    if (!m_timeline)
+    m_outdated = false;
+
+    if (!m_timeline || !m_content)
         return false;
 
     double inheritedTime = isNull(m_timeline->currentTime()) ? nullValue() : currentTime();
-    m_needsUpdate = false;
+    m_content->updateInheritedTime(inheritedTime);
 
-    if (!m_content) {
-        if (didTriggerStyleRecalc)
-            *didTriggerStyleRecalc = false;
-        return false;
-    }
-
-    bool didTriggerStyleRecalcLocal = m_content->updateInheritedTime(inheritedTime);
-
-    if (didTriggerStyleRecalc)
-        *didTriggerStyleRecalc = didTriggerStyleRecalcLocal;
-
-    ASSERT(!m_needsUpdate);
+    ASSERT(!m_outdated);
     return m_content->isCurrent() || m_content->isInEffect();
 }
 
-double Player::timeToEffectChange()
+double AnimationPlayer::timeToEffectChange()
 {
-    ASSERT(!m_needsUpdate);
+    ASSERT(!m_outdated);
     if (!m_content || !m_playbackRate)
         return std::numeric_limits<double>::infinity();
     if (m_playbackRate > 0)
         return m_content->timeToForwardsEffectChange() / m_playbackRate;
-    return m_content->timeToReverseEffectChange() / abs(m_playbackRate);
+    return m_content->timeToReverseEffectChange() / std::abs(m_playbackRate);
 }
 
-void Player::cancel()
+void AnimationPlayer::cancel()
 {
     if (!m_content)
         return;
 
     ASSERT(m_content->player() == this);
     m_content->detach();
-    m_content = 0;
+    m_content = nullptr;
 }
 
-void Player::pauseForTesting(double pauseTime)
+bool AnimationPlayer::hasLowerPriority(AnimationPlayer* player1, AnimationPlayer* player2)
+{
+    if (player1->m_startTime < player2->m_startTime)
+        return true;
+    if (player1->m_startTime > player2->m_startTime)
+        return false;
+    if (isNull(player1->m_startTime) != isNull(player2->m_startTime))
+        return isNull(player1->m_startTime);
+    return player1->m_sequenceNumber < player2->m_sequenceNumber;
+}
+
+void AnimationPlayer::pauseForTesting(double pauseTime)
 {
     RELEASE_ASSERT(!paused());
     updateTimingState(pauseTime);
diff --git a/Source/core/animation/Player.h b/Source/core/animation/AnimationPlayer.h
similarity index 86%
rename from Source/core/animation/Player.h
rename to Source/core/animation/AnimationPlayer.h
index 7015c98..371fc62 100644
--- a/Source/core/animation/Player.h
+++ b/Source/core/animation/AnimationPlayer.h
@@ -28,8 +28,8 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef Player_h
-#define Player_h
+#ifndef AnimationPlayer_h
+#define AnimationPlayer_h
 
 #include "core/animation/TimedItem.h"
 #include "wtf/RefPtr.h"
@@ -39,14 +39,14 @@
 class DocumentTimeline;
 class ExceptionState;
 
-class Player FINAL : public RefCounted<Player> {
+class AnimationPlayer FINAL : public RefCounted<AnimationPlayer> {
 
 public:
-    ~Player();
-    static PassRefPtr<Player> create(DocumentTimeline&, TimedItem*);
+    ~AnimationPlayer();
+    static PassRefPtr<AnimationPlayer> create(DocumentTimeline&, TimedItem*);
 
     // Returns whether this player is still current or in effect.
-    bool update(bool* didTriggerStyleRecalc = 0);
+    bool update();
 
     // timeToEffectChange returns:
     //  infinity  - if this player is no longer in effect
@@ -89,15 +89,17 @@
     // This should only be used for CSS
     void unpause();
 
-    void setNeedsUpdate();
-    bool needsUpdate() { return m_needsUpdate; }
+    void setOutdated();
+    bool outdated() { return m_outdated; }
 
     bool maybeStartAnimationOnCompositor();
     void cancelAnimationOnCompositor();
     bool hasActiveAnimationsOnCompositor();
 
+    static bool hasLowerPriority(AnimationPlayer*, AnimationPlayer*);
+
 private:
-    Player(DocumentTimeline&, TimedItem*);
+    AnimationPlayer(DocumentTimeline&, TimedItem*);
     double sourceEnd() const;
     bool limited(double currentTime) const;
     double currentTimeWithoutLag() const;
@@ -119,7 +121,11 @@
     bool m_held;
     bool m_isPausedForTesting;
 
-    bool m_needsUpdate;
+    // This indicates timing information relevant to the player has changed by
+    // means other than the ordinary progression of time
+    bool m_outdated;
+
+    unsigned m_sequenceNumber;
 };
 
 } // namespace
diff --git a/Source/core/animation/Player.idl b/Source/core/animation/AnimationPlayer.idl
similarity index 98%
rename from Source/core/animation/Player.idl
rename to Source/core/animation/AnimationPlayer.idl
index 1243c39..6a027d0 100644
--- a/Source/core/animation/Player.idl
+++ b/Source/core/animation/AnimationPlayer.idl
@@ -30,7 +30,7 @@
 
 [
     RuntimeEnabled=WebAnimationsAPI,
-] interface Player {
+] interface AnimationPlayer {
              attribute TimedItem? source;
              attribute double     startTime;
              attribute double     currentTime;
diff --git a/Source/core/animation/PlayerTest.cpp b/Source/core/animation/AnimationPlayerTest.cpp
similarity index 73%
rename from Source/core/animation/PlayerTest.cpp
rename to Source/core/animation/AnimationPlayerTest.cpp
index 837d347..412f5ee 100644
--- a/Source/core/animation/PlayerTest.cpp
+++ b/Source/core/animation/AnimationPlayerTest.cpp
@@ -29,7 +29,7 @@
  */
 
 #include "config.h"
-#include "core/animation/Player.h"
+#include "core/animation/AnimationPlayer.h"
 
 #include "core/animation/ActiveAnimations.h"
 #include "core/animation/Animation.h"
@@ -44,7 +44,7 @@
 
 namespace {
 
-class AnimationPlayerTest : public ::testing::Test {
+class AnimationAnimationPlayerTest : public ::testing::Test {
 protected:
     virtual void SetUp()
     {
@@ -57,7 +57,7 @@
         document = Document::create();
         document->animationClock().resetTimeForTesting();
         timeline = DocumentTimeline::create(document.get());
-        player = timeline->createPlayer(0);
+        player = timeline->createAnimationPlayer(0);
         player->setStartTime(0);
         player->setSource(makeAnimation().get());
     }
@@ -73,7 +73,7 @@
         Timing timing;
         timing.iterationDuration = duration;
         timing.playbackRate = playbackRate;
-        return Animation::create(0, 0, timing);
+        return Animation::create(nullptr, nullptr, timing);
     }
 
     bool updateTimeline(double time)
@@ -85,14 +85,14 @@
 
     RefPtr<Document> document;
     RefPtr<DocumentTimeline> timeline;
-    RefPtr<Player> player;
+    RefPtr<AnimationPlayer> player;
     TrackExceptionState exceptionState;
 };
 
-TEST_F(AnimationPlayerTest, InitialState)
+TEST_F(AnimationAnimationPlayerTest, InitialState)
 {
     setUpWithoutStartingTimeline();
-    player = timeline->createPlayer(0);
+    player = timeline->createAnimationPlayer(0);
     EXPECT_TRUE(isNull(timeline->currentTime()));
     EXPECT_EQ(0, player->currentTime());
     EXPECT_FALSE(player->paused());
@@ -113,7 +113,20 @@
 }
 
 
-TEST_F(AnimationPlayerTest, SetCurrentTime)
+TEST_F(AnimationAnimationPlayerTest, CurrentTimeDoesNotSetOutdated)
+{
+    EXPECT_FALSE(player->outdated());
+    EXPECT_EQ(0, player->currentTime());
+    EXPECT_FALSE(player->outdated());
+    // FIXME: We should split updateTimeline into a version that doesn't update
+    // the player and one that does, as most of the tests don't require update()
+    // to be called.
+    document->animationClock().updateTime(10);
+    EXPECT_EQ(10, player->currentTime());
+    EXPECT_FALSE(player->outdated());
+}
+
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTime)
 {
     player->setCurrentTime(10);
     EXPECT_EQ(10, player->currentTime());
@@ -121,7 +134,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetCurrentTimeNegative)
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeNegative)
 {
     player->setCurrentTime(-10);
     EXPECT_EQ(-10, player->currentTime());
@@ -135,7 +148,7 @@
     EXPECT_EQ(-10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetCurrentTimePastContentEnd)
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimePastContentEnd)
 {
     player->setCurrentTime(50);
     EXPECT_EQ(50, player->currentTime());
@@ -149,7 +162,7 @@
     EXPECT_EQ(10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetCurrentTimeBeforeTimelineStarted)
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeBeforeTimelineStarted)
 {
     setUpWithoutStartingTimeline();
     player->setCurrentTime(5);
@@ -159,7 +172,7 @@
     EXPECT_EQ(15, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetCurrentTimePastContentEndBeforeTimelineStarted)
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimePastContentEndBeforeTimelineStarted)
 {
     setUpWithoutStartingTimeline();
     player->setCurrentTime(250);
@@ -169,7 +182,7 @@
     EXPECT_EQ(250, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetCurrentTimeMax)
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeMax)
 {
     player->setCurrentTime(std::numeric_limits<double>::max());
     EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTime());
@@ -177,7 +190,7 @@
     EXPECT_EQ(std::numeric_limits<double>::max(), player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetCurrentTimeUnrestrictedDouble)
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeUnrestrictedDouble)
 {
     updateTimeline(10);
     player->setCurrentTime(nullValue());
@@ -188,9 +201,9 @@
     EXPECT_EQ(10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetCurrentTimeBeforeStartTimeSet)
+TEST_F(AnimationAnimationPlayerTest, SetCurrentTimeBeforeStartTimeSet)
 {
-    player = timeline->createPlayer(0);
+    player = timeline->createAnimationPlayer(0);
     player->setSource(makeAnimation().get());
     player->setCurrentTime(20);
     EXPECT_EQ(20, player->currentTime());
@@ -201,7 +214,7 @@
 }
 
 
-TEST_F(AnimationPlayerTest, TimeLag)
+TEST_F(AnimationAnimationPlayerTest, TimeLag)
 {
     player->setCurrentTime(10);
     EXPECT_EQ(-10, player->timeLag());
@@ -214,7 +227,7 @@
 }
 
 
-TEST_F(AnimationPlayerTest, SetStartTime)
+TEST_F(AnimationAnimationPlayerTest, SetStartTime)
 {
     updateTimeline(20);
     EXPECT_EQ(0, player->startTime());
@@ -227,7 +240,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetStartTimeLimitsPlayer)
+TEST_F(AnimationAnimationPlayerTest, SetStartTimeLimitsAnimationPlayer)
 {
     player->setStartTime(-50);
     EXPECT_EQ(30, player->currentTime());
@@ -237,7 +250,7 @@
     EXPECT_TRUE(player->finished());
 }
 
-TEST_F(AnimationPlayerTest, SetStartTimeOnLimitedPlayer)
+TEST_F(AnimationAnimationPlayerTest, SetStartTimeOnLimitedAnimationPlayer)
 {
     updateTimeline(30);
     player->setStartTime(-10);
@@ -248,7 +261,7 @@
     EXPECT_TRUE(player->finished());
 }
 
-TEST_F(AnimationPlayerTest, SetStartTimeWhilePaused)
+TEST_F(AnimationAnimationPlayerTest, SetStartTimeWhilePaused)
 {
     updateTimeline(10);
     player->pause();
@@ -260,7 +273,7 @@
 }
 
 
-TEST_F(AnimationPlayerTest, PausePlay)
+TEST_F(AnimationAnimationPlayerTest, PausePlay)
 {
     updateTimeline(10);
     player->pause();
@@ -274,7 +287,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, PauseBeforeTimelineStarted)
+TEST_F(AnimationAnimationPlayerTest, PauseBeforeTimelineStarted)
 {
     setUpWithoutStartingTimeline();
     player->pause();
@@ -289,9 +302,9 @@
     EXPECT_EQ(0, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, PauseBeforeStartTimeSet)
+TEST_F(AnimationAnimationPlayerTest, PauseBeforeStartTimeSet)
 {
-    player = timeline->createPlayer(0);
+    player = timeline->createAnimationPlayer(0);
     player->setSource(makeAnimation().get());
     updateTimeline(100);
     player->pause();
@@ -305,7 +318,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, PlayRewindsToStart)
+TEST_F(AnimationAnimationPlayerTest, PlayRewindsToStart)
 {
     player->setCurrentTime(30);
     player->play();
@@ -320,7 +333,7 @@
     EXPECT_EQ(0, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, PlayRewindsToEnd)
+TEST_F(AnimationAnimationPlayerTest, PlayRewindsToEnd)
 {
     player->setPlaybackRate(-1);
     player->play();
@@ -335,7 +348,7 @@
     EXPECT_EQ(30, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, PlayWithPlaybackRateZeroDoesNotSeek)
+TEST_F(AnimationAnimationPlayerTest, PlayWithPlaybackRateZeroDoesNotSeek)
 {
     player->setPlaybackRate(0);
     player->play();
@@ -351,7 +364,7 @@
 }
 
 
-TEST_F(AnimationPlayerTest, Reverse)
+TEST_F(AnimationAnimationPlayerTest, Reverse)
 {
     player->setCurrentTime(10);
     player->pause();
@@ -361,7 +374,7 @@
     EXPECT_EQ(10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, ReverseDoesNothingWithPlaybackRateZero)
+TEST_F(AnimationAnimationPlayerTest, ReverseDoesNothingWithPlaybackRateZero)
 {
     player->setCurrentTime(10);
     player->setPlaybackRate(0);
@@ -372,7 +385,7 @@
     EXPECT_EQ(10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, ReverseDoesNotSeekWithNoSource)
+TEST_F(AnimationAnimationPlayerTest, ReverseDoesNotSeekWithNoSource)
 {
     player->setSource(0);
     player->setCurrentTime(10);
@@ -380,7 +393,7 @@
     EXPECT_EQ(10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, ReverseSeeksToStart)
+TEST_F(AnimationAnimationPlayerTest, ReverseSeeksToStart)
 {
     player->setCurrentTime(-10);
     player->setPlaybackRate(-1);
@@ -388,14 +401,14 @@
     EXPECT_EQ(0, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, ReverseSeeksToEnd)
+TEST_F(AnimationAnimationPlayerTest, ReverseSeeksToEnd)
 {
     player->setCurrentTime(40);
     player->reverse();
     EXPECT_EQ(30, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, ReverseLimitsPlayer)
+TEST_F(AnimationAnimationPlayerTest, ReverseLimitsAnimationPlayer)
 {
     player->setCurrentTime(40);
     player->setPlaybackRate(-1);
@@ -410,7 +423,7 @@
 }
 
 
-TEST_F(AnimationPlayerTest, Finish)
+TEST_F(AnimationAnimationPlayerTest, Finish)
 {
     player->finish(exceptionState);
     EXPECT_EQ(30, player->currentTime());
@@ -424,14 +437,14 @@
     EXPECT_FALSE(exceptionState.hadException());
 }
 
-TEST_F(AnimationPlayerTest, FinishAfterSourceEnd)
+TEST_F(AnimationAnimationPlayerTest, FinishAfterSourceEnd)
 {
     player->setCurrentTime(40);
     player->finish(exceptionState);
     EXPECT_EQ(30, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, FinishBeforeStart)
+TEST_F(AnimationAnimationPlayerTest, FinishBeforeStart)
 {
     player->setCurrentTime(-10);
     player->setPlaybackRate(-1);
@@ -439,7 +452,7 @@
     EXPECT_EQ(0, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, FinishDoesNothingWithPlaybackRateZero)
+TEST_F(AnimationAnimationPlayerTest, FinishDoesNothingWithPlaybackRateZero)
 {
     player->setCurrentTime(10);
     player->setPlaybackRate(0);
@@ -447,12 +460,12 @@
     EXPECT_EQ(10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, FinishRaisesException)
+TEST_F(AnimationAnimationPlayerTest, FinishRaisesException)
 {
     Timing timing;
     timing.iterationDuration = 1;
     timing.iterationCount = std::numeric_limits<double>::infinity();
-    player->setSource(Animation::create(0, 0, timing).get());
+    player->setSource(Animation::create(nullptr, nullptr, timing).get());
     player->setCurrentTime(10);
 
     player->finish(exceptionState);
@@ -462,7 +475,7 @@
 }
 
 
-TEST_F(AnimationPlayerTest, LimitingAtSourceEnd)
+TEST_F(AnimationAnimationPlayerTest, LimitingAtSourceEnd)
 {
     updateTimeline(30);
     EXPECT_EQ(30, player->currentTime());
@@ -472,7 +485,7 @@
     EXPECT_FALSE(player->paused());
 }
 
-TEST_F(AnimationPlayerTest, LimitingAtStart)
+TEST_F(AnimationAnimationPlayerTest, LimitingAtStart)
 {
     updateTimeline(30);
     player->setPlaybackRate(-2);
@@ -484,7 +497,7 @@
     EXPECT_FALSE(player->paused());
 }
 
-TEST_F(AnimationPlayerTest, LimitingWithNoSource)
+TEST_F(AnimationAnimationPlayerTest, LimitingWithNoSource)
 {
     player->setSource(0);
     EXPECT_TRUE(player->finished());
@@ -493,7 +506,7 @@
 }
 
 
-TEST_F(AnimationPlayerTest, SetPlaybackRate)
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRate)
 {
     player->setPlaybackRate(2);
     EXPECT_EQ(2, player->playbackRate());
@@ -502,7 +515,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetPlaybackRateBeforeTimelineStarted)
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateBeforeTimelineStarted)
 {
     setUpWithoutStartingTimeline();
     player->setPlaybackRate(2);
@@ -513,7 +526,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetPlaybackRateWhilePaused)
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateWhilePaused)
 {
     updateTimeline(10);
     player->pause();
@@ -525,7 +538,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetPlaybackRateWhileLimited)
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateWhileLimited)
 {
     updateTimeline(40);
     EXPECT_EQ(30, player->currentTime());
@@ -538,7 +551,7 @@
     EXPECT_EQ(10, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetPlaybackRateZero)
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateZero)
 {
     updateTimeline(10);
     player->setPlaybackRate(0);
@@ -549,7 +562,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetPlaybackRateMax)
+TEST_F(AnimationAnimationPlayerTest, SetPlaybackRateMax)
 {
     player->setPlaybackRate(std::numeric_limits<double>::max());
     EXPECT_EQ(std::numeric_limits<double>::max(), player->playbackRate());
@@ -559,9 +572,9 @@
 }
 
 
-TEST_F(AnimationPlayerTest, SetSource)
+TEST_F(AnimationAnimationPlayerTest, SetSource)
 {
-    player = timeline->createPlayer(0);
+    player = timeline->createAnimationPlayer(0);
     player->setStartTime(0);
     RefPtr<TimedItem> source1 = makeAnimation();
     RefPtr<TimedItem> source2 = makeAnimation();
@@ -576,7 +589,7 @@
     EXPECT_EQ(source2, player->source());
 }
 
-TEST_F(AnimationPlayerTest, SetSourceLimitsPlayer)
+TEST_F(AnimationAnimationPlayerTest, SetSourceLimitsAnimationPlayer)
 {
     player->setCurrentTime(20);
     player->setSource(makeAnimation(10).get());
@@ -586,7 +599,7 @@
     EXPECT_EQ(20, player->currentTime());
 }
 
-TEST_F(AnimationPlayerTest, SetSourceUnlimitsPlayer)
+TEST_F(AnimationAnimationPlayerTest, SetSourceUnlimitsAnimationPlayer)
 {
     player->setCurrentTime(40);
     player->setSource(makeAnimation(60).get());
@@ -597,23 +610,32 @@
 }
 
 
-TEST_F(AnimationPlayerTest, EmptyPlayersDontUpdateEffects)
+TEST_F(AnimationAnimationPlayerTest, EmptyAnimationPlayersDontUpdateEffects)
 {
-    player = timeline->createPlayer(0);
+    player = timeline->createAnimationPlayer(0);
     EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
 
     updateTimeline(1234);
     EXPECT_EQ(std::numeric_limits<double>::infinity(), player->timeToEffectChange());
 }
 
-TEST_F(AnimationPlayerTest, PlayersReturnTimeToNextEffect)
+TEST_F(AnimationAnimationPlayerTest, AnimationPlayersDisassociateFromSource)
+{
+    TimedItem* timedItem = player->source();
+    AnimationPlayer* player2 = timeline->createAnimationPlayer(timedItem);
+    EXPECT_EQ(0, player->source());
+    player->setSource(timedItem);
+    EXPECT_EQ(0, player2->source());
+}
+
+TEST_F(AnimationAnimationPlayerTest, AnimationPlayersReturnTimeToNextEffect)
 {
     Timing timing;
     timing.startDelay = 1;
     timing.iterationDuration = 1;
     timing.endDelay = 1;
-    RefPtr<Animation> animation = Animation::create(0, 0, timing);
-    player = timeline->createPlayer(animation.get());
+    RefPtr<Animation> animation = Animation::create(nullptr, nullptr, timing);
+    player = timeline->createAnimationPlayer(animation.get());
     player->setStartTime(0);
 
     updateTimeline(0);
@@ -656,13 +678,13 @@
     EXPECT_EQ(0.5, player->timeToEffectChange());
 }
 
-TEST_F(AnimationPlayerTest, AttachedPlayers)
+TEST_F(AnimationAnimationPlayerTest, AttachedAnimationPlayers)
 {
     RefPtr<Element> element = document->createElement("foo", ASSERT_NO_EXCEPTION);
 
     Timing timing;
-    RefPtr<Animation> animation = Animation::create(element, 0, timing);
-    RefPtr<Player> player = timeline->createPlayer(animation.get());
+    RefPtr<Animation> animation = Animation::create(element, nullptr, timing);
+    RefPtr<AnimationPlayer> player = timeline->createAnimationPlayer(animation.get());
     timeline->serviceAnimations();
     EXPECT_EQ(1U, element->activeAnimations()->players().find(player.get())->value);
 
@@ -670,4 +692,30 @@
     EXPECT_TRUE(element->activeAnimations()->players().isEmpty());
 }
 
+TEST_F(AnimationAnimationPlayerTest, HasLowerPriority)
+{
+    // Note that start time defaults to null
+    RefPtr<AnimationPlayer> player1 = timeline->createAnimationPlayer(0);
+    RefPtr<AnimationPlayer> player2 = timeline->createAnimationPlayer(0);
+    player2->setStartTime(10);
+    RefPtr<AnimationPlayer> player3 = timeline->createAnimationPlayer(0);
+    RefPtr<AnimationPlayer> player4 = timeline->createAnimationPlayer(0);
+    player4->setStartTime(20);
+    RefPtr<AnimationPlayer> player5 = timeline->createAnimationPlayer(0);
+    player5->setStartTime(10);
+    RefPtr<AnimationPlayer> player6 = timeline->createAnimationPlayer(0);
+    player6->setStartTime(-10);
+    Vector<RefPtr<AnimationPlayer> > players;
+    players.append(player1);
+    players.append(player3);
+    players.append(player6);
+    players.append(player2);
+    players.append(player5);
+    players.append(player4);
+    for (size_t i = 0; i < players.size(); i++) {
+        for (size_t j = 0; j < players.size(); j++)
+            EXPECT_EQ(i < j, AnimationPlayer::hasLowerPriority(players[i].get(), players[j].get()));
+    }
+}
+
 }
diff --git a/Source/core/animation/AnimationStack.cpp b/Source/core/animation/AnimationStack.cpp
index 601e7e5..17f3852 100644
--- a/Source/core/animation/AnimationStack.cpp
+++ b/Source/core/animation/AnimationStack.cpp
@@ -65,7 +65,7 @@
     return false;
 }
 
-AnimationEffect::CompositableValueMap AnimationStack::compositableValues(const AnimationStack* animationStack, const Vector<InertAnimation*>* newAnimations, const HashSet<const Player*>* cancelledPlayers, Animation::Priority priority)
+AnimationEffect::CompositableValueMap AnimationStack::compositableValues(const AnimationStack* animationStack, const Vector<InertAnimation*>* newAnimations, const HashSet<const AnimationPlayer*>* cancelledAnimationPlayers, Animation::Priority priority)
 {
     AnimationEffect::CompositableValueMap result;
 
@@ -75,7 +75,7 @@
             Animation* animation = animations[i];
             if (animation->priority() != priority)
                 continue;
-            if (cancelledPlayers && cancelledPlayers->contains(animation->player()))
+            if (cancelledAnimationPlayers && cancelledAnimationPlayers->contains(animation->player()))
                 continue;
             copyToCompositableValueMap(animation->compositableValues(), result);
         }
diff --git a/Source/core/animation/AnimationStack.h b/Source/core/animation/AnimationStack.h
index e7ad32f..f8fc1de 100644
--- a/Source/core/animation/AnimationStack.h
+++ b/Source/core/animation/AnimationStack.h
@@ -53,7 +53,7 @@
     bool isEmpty() const { return m_activeAnimations.isEmpty(); }
     bool affects(CSSPropertyID) const;
     bool hasActiveAnimationsOnCompositor(CSSPropertyID) const;
-    static AnimationEffect::CompositableValueMap compositableValues(const AnimationStack*, const Vector<InertAnimation*>* newAnimations, const HashSet<const Player*>* cancelledPlayers, Animation::Priority);
+    static AnimationEffect::CompositableValueMap compositableValues(const AnimationStack*, const Vector<InertAnimation*>* newAnimations, const HashSet<const AnimationPlayer*>* cancelledAnimationPlayers, Animation::Priority);
 
 private:
     Vector<Animation*> m_activeAnimations;
diff --git a/Source/core/animation/AnimationTest.cpp b/Source/core/animation/AnimationTest.cpp
index 9ea0e3f..72f993b 100644
--- a/Source/core/animation/AnimationTest.cpp
+++ b/Source/core/animation/AnimationTest.cpp
@@ -9,100 +9,60 @@
 #include "core/animation/AnimatableLength.h"
 #include "core/animation/AnimationClock.h"
 #include "core/animation/AnimationHelpers.h"
+#include "core/animation/AnimationTestHelper.h"
 #include "core/animation/DocumentTimeline.h"
 #include "core/animation/KeyframeEffectModel.h"
 #include "core/animation/TimedItemTiming.h"
-#include "platform/animation/TimingFunctionTestHelper.h"
+#include "core/animation/Timing.h"
 
 #include <gtest/gtest.h>
 
 namespace WebCore {
 
-namespace {
-
-v8::Handle<v8::Value> stringToV8Value(String string)
-{
-    return v8::Handle<v8::Value>::Cast(v8String(v8::Isolate::GetCurrent(), string));
-}
-
-v8::Handle<v8::Value> doubleToV8Value(double number)
-{
-    return v8::Handle<v8::Value>::Cast(v8::Number::New(v8::Isolate::GetCurrent(), number));
-}
-
-void setV8ObjectPropertyAsString(v8::Handle<v8::Object> object, String name, String value)
-{
-    object->Set(stringToV8Value(name), stringToV8Value(value));
-}
-
-void setV8ObjectPropertyAsNumber(v8::Handle<v8::Object> object, String name, double value)
-{
-    object->Set(stringToV8Value(name), doubleToV8Value(value));
-}
-
-} // namespace
-
 class AnimationAnimationTest : public ::testing::Test {
 protected:
-    virtual void SetUp()
+    AnimationAnimationTest()
+        : document(Document::create())
+        , element(document->createElement("foo", ASSERT_NO_EXCEPTION))
     {
-        document = Document::create();
         document->animationClock().resetTimeForTesting();
-        element = document->createElement("foo", ASSERT_NO_EXCEPTION);
-        document->timeline()->setZeroTime(0);
-        ASSERT_EQ(0, document->timeline()->currentTime());
+        document->timeline().setZeroTime(0);
+        EXPECT_EQ(0, document->timeline().currentTime());
     }
 
     RefPtr<Document> document;
     RefPtr<Element> element;
-
-    PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
-    {
-        return Animation::createUnsafe(element, keyframeDictionaryVector, timingInput);
-    }
-
-    PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, double timingInput)
-    {
-        return Animation::createUnsafe(element, keyframeDictionaryVector, timingInput);
-    }
-
-    PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector)
-    {
-        return Animation::createUnsafe(element, keyframeDictionaryVector);
-    }
-
-    void populateTiming(Timing& timing, Dictionary timingInputDictionary)
-    {
-        Animation::populateTiming(timing, timingInputDictionary);
-    }
-
-    void applyTimingInputNumber(Timing& timing, v8::Isolate* isolate, String timingProperty, double timingPropertyValue)
-    {
-        v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
-        setV8ObjectPropertyAsNumber(timingInput, timingProperty, timingPropertyValue);
-        Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
-        populateTiming(timing, timingInputDictionary);
-    }
-
-    void applyTimingInputString(Timing& timing, v8::Isolate* isolate, String timingProperty, String timingPropertyValue)
-    {
-        v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
-        setV8ObjectPropertyAsString(timingInput, timingProperty, timingPropertyValue);
-        Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
-        populateTiming(timing, timingInputDictionary);
-    }
 };
 
-TEST_F(AnimationAnimationTest, CanCreateAnAnimation)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
+class AnimationAnimationV8Test : public AnimationAnimationTest {
+protected:
+    AnimationAnimationV8Test()
+        : m_isolate(v8::Isolate::GetCurrent())
+        , m_scope(V8ExecutionScope::create(m_isolate))
+    {
+    }
 
+    template<typename T>
+    static PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector, T timingInput)
+    {
+        return Animation::create(element, EffectInput::convert(element, keyframeDictionaryVector, true), timingInput);
+    }
+    static PassRefPtr<Animation> createAnimation(Element* element, Vector<Dictionary> keyframeDictionaryVector)
+    {
+        return Animation::create(element, EffectInput::convert(element, keyframeDictionaryVector, true));
+    }
+
+    v8::Isolate* m_isolate;
+
+private:
+    OwnPtr<V8ExecutionScope> m_scope;
+};
+
+TEST_F(AnimationAnimationV8Test, CanCreateAnAnimation)
+{
     Vector<Dictionary> jsKeyframes;
-    v8::Handle<v8::Object> keyframe1 = v8::Object::New(isolate);
-    v8::Handle<v8::Object> keyframe2 = v8::Object::New(isolate);
+    v8::Handle<v8::Object> keyframe1 = v8::Object::New(m_isolate);
+    v8::Handle<v8::Object> keyframe2 = v8::Object::New(m_isolate);
 
     setV8ObjectPropertyAsString(keyframe1, "width", "100px");
     setV8ObjectPropertyAsString(keyframe1, "offset", "0");
@@ -111,8 +71,8 @@
     setV8ObjectPropertyAsString(keyframe2, "offset", "1");
     setV8ObjectPropertyAsString(keyframe2, "easing", "cubic-bezier(1, 1, 0.3, 0.3)");
 
-    jsKeyframes.append(Dictionary(keyframe1, isolate));
-    jsKeyframes.append(Dictionary(keyframe2, isolate));
+    jsKeyframes.append(Dictionary(keyframe1, m_isolate));
+    jsKeyframes.append(Dictionary(keyframe2, m_isolate));
 
     String value1;
     ASSERT_TRUE(jsKeyframes[0].get("width", value1));
@@ -148,13 +108,8 @@
     EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), *keyframes[1]->easing());
 }
 
-TEST_F(AnimationAnimationTest, CanSetDuration)
+TEST_F(AnimationAnimationV8Test, CanSetDuration)
 {
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
     Vector<Dictionary, 0> jsKeyframes;
     double duration = 2;
 
@@ -163,44 +118,25 @@
     EXPECT_EQ(duration, animation->specifiedTiming().iterationDuration);
 }
 
-TEST_F(AnimationAnimationTest, CanOmitSpecifiedDuration)
+TEST_F(AnimationAnimationV8Test, CanOmitSpecifiedDuration)
 {
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
     Vector<Dictionary, 0> jsKeyframes;
-
     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes);
-
     EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration));
 }
 
-TEST_F(AnimationAnimationTest, ClipNegativeDurationToZero)
+TEST_F(AnimationAnimationV8Test, NegativeDurationIsAuto)
 {
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
     Vector<Dictionary, 0> jsKeyframes;
-
     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, -2);
-
-    EXPECT_EQ(0, animation->specifiedTiming().iterationDuration);
+    EXPECT_TRUE(std::isnan(animation->specifiedTiming().iterationDuration));
 }
 
-TEST_F(AnimationAnimationTest, SpecifiedGetters)
+TEST_F(AnimationAnimationV8Test, SpecifiedGetters)
 {
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
     Vector<Dictionary, 0> jsKeyframes;
 
-    v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
+    v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
     setV8ObjectPropertyAsNumber(timingInput, "delay", 2);
     setV8ObjectPropertyAsNumber(timingInput, "endDelay", 0.5);
     setV8ObjectPropertyAsString(timingInput, "fill", "backwards");
@@ -209,7 +145,7 @@
     setV8ObjectPropertyAsNumber(timingInput, "playbackRate", 2);
     setV8ObjectPropertyAsString(timingInput, "direction", "reverse");
     setV8ObjectPropertyAsString(timingInput, "easing", "step-start");
-    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
+    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
 
     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
 
@@ -224,18 +160,13 @@
     EXPECT_EQ("step-start", specified->easing());
 }
 
-TEST_F(AnimationAnimationTest, SpecifiedDurationGetter)
+TEST_F(AnimationAnimationV8Test, SpecifiedDurationGetter)
 {
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
     Vector<Dictionary, 0> jsKeyframes;
 
-    v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(isolate);
+    v8::Handle<v8::Object> timingInputWithDuration = v8::Object::New(m_isolate);
     setV8ObjectPropertyAsNumber(timingInputWithDuration, "duration", 2.5);
-    Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputWithDuration), isolate);
+    Dictionary timingInputDictionaryWithDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputWithDuration), m_isolate);
 
     RefPtr<Animation> animationWithDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryWithDuration);
 
@@ -251,8 +182,8 @@
     EXPECT_EQ("", stringDuration);
 
 
-    v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(isolate);
-    Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputNoDuration), isolate);
+    v8::Handle<v8::Object> timingInputNoDuration = v8::Object::New(m_isolate);
+    Dictionary timingInputDictionaryNoDuration = Dictionary(v8::Handle<v8::Value>::Cast(timingInputNoDuration), m_isolate);
 
     RefPtr<Animation> animationNoDuration = createAnimation(element.get(), jsKeyframes, timingInputDictionaryNoDuration);
 
@@ -268,16 +199,11 @@
     EXPECT_EQ("auto", stringDuration);
 }
 
-TEST_F(AnimationAnimationTest, SpecifiedSetters)
+TEST_F(AnimationAnimationV8Test, SpecifiedSetters)
 {
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
     Vector<Dictionary, 0> jsKeyframes;
-    v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
-    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
+    v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
 
     RefPtr<TimedItemTiming> specified = animation->specified();
@@ -315,16 +241,11 @@
     EXPECT_EQ("step-start", specified->easing());
 }
 
-TEST_F(AnimationAnimationTest, SetSpecifiedDuration)
+TEST_F(AnimationAnimationV8Test, SetSpecifiedDuration)
 {
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
     Vector<Dictionary, 0> jsKeyframes;
-    v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
-    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
+    v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
     RefPtr<Animation> animation = createAnimation(element.get(), jsKeyframes, timingInputDictionary);
 
     RefPtr<TimedItemTiming> specified = animation->specified();
@@ -351,392 +272,6 @@
     EXPECT_EQ("", stringDuration);
 }
 
-TEST_F(AnimationAnimationTest, TimingInputStartDelay)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    EXPECT_EQ(0, timing.startDelay);
-
-    applyTimingInputNumber(timing, isolate, "delay", 1.1);
-    EXPECT_EQ(1.1, timing.startDelay);
-    timing.startDelay = 0;
-
-    applyTimingInputNumber(timing, isolate, "delay", -1);
-    EXPECT_EQ(-1, timing.startDelay);
-    timing.startDelay = 0;
-
-    applyTimingInputString(timing, isolate, "delay", "1");
-    EXPECT_EQ(1, timing.startDelay);
-    timing.startDelay = 0;
-
-    applyTimingInputString(timing, isolate, "delay", "1s");
-    EXPECT_EQ(0, timing.startDelay);
-    timing.startDelay = 0;
-
-    applyTimingInputString(timing, isolate, "delay", "Infinity");
-    EXPECT_EQ(0, timing.startDelay);
-    timing.startDelay = 0;
-
-    applyTimingInputString(timing, isolate, "delay", "-Infinity");
-    EXPECT_EQ(0, timing.startDelay);
-    timing.startDelay = 0;
-
-    applyTimingInputString(timing, isolate, "delay", "NaN");
-    EXPECT_EQ(0, timing.startDelay);
-    timing.startDelay = 0;
-
-    applyTimingInputString(timing, isolate, "delay", "rubbish");
-    EXPECT_EQ(0, timing.startDelay);
-    timing.startDelay = 0;
-}
-
-TEST_F(AnimationAnimationTest, TimingInputEndDelay)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    applyTimingInputNumber(timing, isolate, "endDelay", 10);
-    EXPECT_EQ(10, timing.endDelay);
-    applyTimingInputNumber(timing, isolate, "endDelay", -2.5);
-    EXPECT_EQ(-2.5, timing.endDelay);
-}
-
-TEST_F(AnimationAnimationTest, TimingInputFillMode)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    Timing::FillMode defaultFillMode = Timing::FillModeAuto;
-    EXPECT_EQ(defaultFillMode, timing.fillMode);
-
-    applyTimingInputString(timing, isolate, "fill", "auto");
-    EXPECT_EQ(Timing::FillModeAuto, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-
-    applyTimingInputString(timing, isolate, "fill", "forwards");
-    EXPECT_EQ(Timing::FillModeForwards, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-
-    applyTimingInputString(timing, isolate, "fill", "none");
-    EXPECT_EQ(Timing::FillModeNone, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-
-    applyTimingInputString(timing, isolate, "fill", "backwards");
-    EXPECT_EQ(Timing::FillModeBackwards, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-
-    applyTimingInputString(timing, isolate, "fill", "both");
-    EXPECT_EQ(Timing::FillModeBoth, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-
-    applyTimingInputString(timing, isolate, "fill", "everything!");
-    EXPECT_EQ(defaultFillMode, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-
-    applyTimingInputString(timing, isolate, "fill", "backwardsandforwards");
-    EXPECT_EQ(defaultFillMode, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-
-    applyTimingInputNumber(timing, isolate, "fill", 2);
-    EXPECT_EQ(defaultFillMode, timing.fillMode);
-    timing.fillMode = defaultFillMode;
-}
-
-TEST_F(AnimationAnimationTest, TimingInputIterationStart)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    EXPECT_EQ(0, timing.iterationStart);
-
-    applyTimingInputNumber(timing, isolate, "iterationStart", 1.1);
-    EXPECT_EQ(1.1, timing.iterationStart);
-    timing.iterationStart = 0;
-
-    applyTimingInputNumber(timing, isolate, "iterationStart", -1);
-    EXPECT_EQ(0, timing.iterationStart);
-    timing.iterationStart = 0;
-
-    applyTimingInputString(timing, isolate, "iterationStart", "Infinity");
-    EXPECT_EQ(0, timing.iterationStart);
-    timing.iterationStart = 0;
-
-    applyTimingInputString(timing, isolate, "iterationStart", "-Infinity");
-    EXPECT_EQ(0, timing.iterationStart);
-    timing.iterationStart = 0;
-
-    applyTimingInputString(timing, isolate, "iterationStart", "NaN");
-    EXPECT_EQ(0, timing.iterationStart);
-    timing.iterationStart = 0;
-
-    applyTimingInputString(timing, isolate, "iterationStart", "rubbish");
-    EXPECT_EQ(0, timing.iterationStart);
-    timing.iterationStart = 0;
-}
-
-TEST_F(AnimationAnimationTest, TimingInputIterationCount)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    EXPECT_EQ(1, timing.iterationCount);
-
-    applyTimingInputNumber(timing, isolate, "iterations", 2.1);
-    EXPECT_EQ(2.1, timing.iterationCount);
-    timing.iterationCount = 1;
-
-    applyTimingInputNumber(timing, isolate, "iterations", -1);
-    EXPECT_EQ(0, timing.iterationCount);
-    timing.iterationCount = 1;
-
-    applyTimingInputString(timing, isolate, "iterations", "Infinity");
-    EXPECT_TRUE(std::isinf(timing.iterationCount) && (timing.iterationCount > 0));
-    timing.iterationCount = 1;
-
-    applyTimingInputString(timing, isolate, "iterations", "-Infinity");
-    EXPECT_EQ(0, timing.iterationCount);
-    timing.iterationCount = 1;
-
-    applyTimingInputString(timing, isolate, "iterations", "NaN");
-    EXPECT_EQ(1, timing.iterationCount);
-    timing.iterationCount = 1;
-
-    applyTimingInputString(timing, isolate, "iterations", "rubbish");
-    EXPECT_EQ(1, timing.iterationCount);
-    timing.iterationCount = 1;
-}
-
-TEST_F(AnimationAnimationTest, TimingInputIterationDuration)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    EXPECT_TRUE(std::isnan(timing.iterationDuration));
-
-    applyTimingInputNumber(timing, isolate, "duration", 1.1);
-    EXPECT_EQ(1.1, timing.iterationDuration);
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-
-    applyTimingInputNumber(timing, isolate, "duration", -1);
-    EXPECT_TRUE(std::isnan(timing.iterationDuration));
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-
-    applyTimingInputString(timing, isolate, "duration", "1");
-    EXPECT_EQ(1, timing.iterationDuration);
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-
-    applyTimingInputString(timing, isolate, "duration", "Infinity");
-    EXPECT_TRUE(std::isinf(timing.iterationDuration) && (timing.iterationDuration > 0));
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-
-    applyTimingInputString(timing, isolate, "duration", "-Infinity");
-    EXPECT_TRUE(std::isnan(timing.iterationDuration));
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-
-    applyTimingInputString(timing, isolate, "duration", "NaN");
-    EXPECT_TRUE(std::isnan(timing.iterationDuration));
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-
-    applyTimingInputString(timing, isolate, "duration", "auto");
-    EXPECT_TRUE(std::isnan(timing.iterationDuration));
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-
-    applyTimingInputString(timing, isolate, "duration", "rubbish");
-    EXPECT_TRUE(std::isnan(timing.iterationDuration));
-    timing.iterationDuration = std::numeric_limits<double>::quiet_NaN();
-}
-
-TEST_F(AnimationAnimationTest, TimingInputPlaybackRate)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    EXPECT_EQ(1, timing.playbackRate);
-
-    applyTimingInputNumber(timing, isolate, "playbackRate", 2.1);
-    EXPECT_EQ(2.1, timing.playbackRate);
-    timing.playbackRate = 1;
-
-    applyTimingInputNumber(timing, isolate, "playbackRate", -1);
-    EXPECT_EQ(-1, timing.playbackRate);
-    timing.playbackRate = 1;
-
-    applyTimingInputString(timing, isolate, "playbackRate", "Infinity");
-    EXPECT_EQ(1, timing.playbackRate);
-    timing.playbackRate = 1;
-
-    applyTimingInputString(timing, isolate, "playbackRate", "-Infinity");
-    EXPECT_EQ(1, timing.playbackRate);
-    timing.playbackRate = 1;
-
-    applyTimingInputString(timing, isolate, "playbackRate", "NaN");
-    EXPECT_EQ(1, timing.playbackRate);
-    timing.playbackRate = 1;
-
-    applyTimingInputString(timing, isolate, "playbackRate", "rubbish");
-    EXPECT_EQ(1, timing.playbackRate);
-    timing.playbackRate = 1;
-}
-
-TEST_F(AnimationAnimationTest, TimingInputDirection)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    Timing::PlaybackDirection defaultPlaybackDirection = Timing::PlaybackDirectionNormal;
-    EXPECT_EQ(defaultPlaybackDirection, timing.direction);
-
-    applyTimingInputString(timing, isolate, "direction", "normal");
-    EXPECT_EQ(Timing::PlaybackDirectionNormal, timing.direction);
-    timing.direction = defaultPlaybackDirection;
-
-    applyTimingInputString(timing, isolate, "direction", "reverse");
-    EXPECT_EQ(Timing::PlaybackDirectionReverse, timing.direction);
-    timing.direction = defaultPlaybackDirection;
-
-    applyTimingInputString(timing, isolate, "direction", "alternate");
-    EXPECT_EQ(Timing::PlaybackDirectionAlternate, timing.direction);
-    timing.direction = defaultPlaybackDirection;
-
-    applyTimingInputString(timing, isolate, "direction", "alternate-reverse");
-    EXPECT_EQ(Timing::PlaybackDirectionAlternateReverse, timing.direction);
-    timing.direction = defaultPlaybackDirection;
-
-    applyTimingInputString(timing, isolate, "direction", "rubbish");
-    EXPECT_EQ(defaultPlaybackDirection, timing.direction);
-    timing.direction = defaultPlaybackDirection;
-
-    applyTimingInputNumber(timing, isolate, "direction", 2);
-    EXPECT_EQ(defaultPlaybackDirection, timing.direction);
-    timing.direction = defaultPlaybackDirection;
-}
-
-TEST_F(AnimationAnimationTest, TimingInputTimingFunction)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing timing;
-    const RefPtr<TimingFunction> defaultTimingFunction = LinearTimingFunction::create();
-    EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
-
-    applyTimingInputString(timing, isolate, "easing", "ease");
-    EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease)), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "ease-in");
-    EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn)), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "ease-out");
-    EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut)), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "ease-in-out");
-    EXPECT_EQ(*(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut)), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "linear");
-    EXPECT_EQ(*(LinearTimingFunction::create()), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "initial");
-    EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "step-start");
-    EXPECT_EQ(*(StepsTimingFunction::preset(StepsTimingFunction::Start)), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "step-end");
-    EXPECT_EQ(*(StepsTimingFunction::preset(StepsTimingFunction::End)), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "cubic-bezier(1, 1, 0.3, 0.3)");
-    EXPECT_EQ(*(CubicBezierTimingFunction::create(1, 1, 0.3, 0.3).get()), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "steps(3, start)");
-    EXPECT_EQ(*(StepsTimingFunction::create(3, true).get()), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "steps(5, end)");
-    EXPECT_EQ(*(StepsTimingFunction::create(5, false).get()), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "steps(5.6, end)");
-    EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    // FIXME: Step-middle not yet implemented. Change this test when it is working.
-    applyTimingInputString(timing, isolate, "easing", "steps(5, middle)");
-    EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "cubic-bezier(2, 2, 0.3, 0.3)");
-    EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputString(timing, isolate, "easing", "rubbish");
-    EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-
-    applyTimingInputNumber(timing, isolate, "easing", 2);
-    EXPECT_EQ(*defaultTimingFunction.get(), *timing.timingFunction.get());
-    timing.timingFunction = defaultTimingFunction;
-}
-
-TEST_F(AnimationAnimationTest, TimingInputEmpty)
-{
-    v8::Isolate* isolate = v8::Isolate::GetCurrent();
-    v8::HandleScope scope(isolate);
-    v8::Local<v8::Context> context = v8::Context::New(isolate);
-    v8::Context::Scope contextScope(context);
-
-    Timing updatedTiming;
-    Timing controlTiming;
-
-    v8::Handle<v8::Object> timingInput = v8::Object::New(isolate);
-    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), isolate);
-    populateTiming(updatedTiming, timingInputDictionary);
-
-    EXPECT_EQ(controlTiming.startDelay, updatedTiming.startDelay);
-    EXPECT_EQ(controlTiming.fillMode, updatedTiming.fillMode);
-    EXPECT_EQ(controlTiming.iterationStart, updatedTiming.iterationStart);
-    EXPECT_EQ(controlTiming.iterationCount, updatedTiming.iterationCount);
-    EXPECT_TRUE(std::isnan(updatedTiming.iterationDuration));
-    EXPECT_EQ(controlTiming.playbackRate, updatedTiming.playbackRate);
-    EXPECT_EQ(controlTiming.direction, updatedTiming.direction);
-    EXPECT_EQ(*controlTiming.timingFunction.get(), *updatedTiming.timingFunction.get());
-}
-
 TEST_F(AnimationAnimationTest, TimeToEffectChange)
 {
     Timing timing;
@@ -744,8 +279,8 @@
     timing.startDelay = 100;
     timing.endDelay = 100;
     timing.fillMode = Timing::FillModeNone;
-    RefPtr<Animation> animation = Animation::create(0, 0, timing);
-    RefPtr<Player> player = document->timeline()->play(animation.get());
+    RefPtr<Animation> animation = Animation::create(nullptr, nullptr, timing);
+    RefPtr<AnimationPlayer> player = document->timeline().play(animation.get());
     double inf = std::numeric_limits<double>::infinity();
 
     EXPECT_EQ(100, animation->timeToForwardsEffectChange());
@@ -777,8 +312,8 @@
     timing.endDelay = 100;
     timing.playbackRate = 2;
     timing.fillMode = Timing::FillModeNone;
-    RefPtr<Animation> animation = Animation::create(0, 0, timing);
-    RefPtr<Player> player = document->timeline()->play(animation.get());
+    RefPtr<Animation> animation = Animation::create(nullptr, nullptr, timing);
+    RefPtr<AnimationPlayer> player = document->timeline().play(animation.get());
     double inf = std::numeric_limits<double>::infinity();
 
     EXPECT_EQ(100, animation->timeToForwardsEffectChange());
@@ -810,8 +345,8 @@
     timing.endDelay = 100;
     timing.playbackRate = -2;
     timing.fillMode = Timing::FillModeNone;
-    RefPtr<Animation> animation = Animation::create(0, 0, timing);
-    RefPtr<Player> player = document->timeline()->play(animation.get());
+    RefPtr<Animation> animation = Animation::create(nullptr, nullptr, timing);
+    RefPtr<AnimationPlayer> player = document->timeline().play(animation.get());
     double inf = std::numeric_limits<double>::infinity();
 
     EXPECT_EQ(100, animation->timeToForwardsEffectChange());
diff --git a/Source/core/animation/AnimationTestHelper.cpp b/Source/core/animation/AnimationTestHelper.cpp
new file mode 100644
index 0000000..12f4e37
--- /dev/null
+++ b/Source/core/animation/AnimationTestHelper.cpp
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/AnimationTestHelper.h"
+
+#include "bindings/v8/V8Binding.h"
+
+namespace WebCore {
+
+v8::Handle<v8::Value> stringToV8Value(String string)
+{
+    return v8::Handle<v8::Value>::Cast(v8String(v8::Isolate::GetCurrent(), string));
+}
+
+v8::Handle<v8::Value> doubleToV8Value(double number)
+{
+    return v8::Handle<v8::Value>::Cast(v8::Number::New(v8::Isolate::GetCurrent(), number));
+}
+
+void setV8ObjectPropertyAsString(v8::Handle<v8::Object> object, String name, String value)
+{
+    object->Set(stringToV8Value(name), stringToV8Value(value));
+}
+
+void setV8ObjectPropertyAsNumber(v8::Handle<v8::Object> object, String name, double value)
+{
+    object->Set(stringToV8Value(name), doubleToV8Value(value));
+}
+
+} // namespace WebCore
diff --git a/Source/core/animation/AnimationTestHelper.h b/Source/core/animation/AnimationTestHelper.h
new file mode 100644
index 0000000..5d20c7c
--- /dev/null
+++ b/Source/core/animation/AnimationTestHelper.h
@@ -0,0 +1,23 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef AnimationTestHelper_h
+#define AnimationTestHelper_h
+
+#include "wtf/text/WTFString.h"
+#include <v8.h>
+
+namespace WebCore {
+
+v8::Handle<v8::Value> stringToV8Value(String);
+
+v8::Handle<v8::Value> doubleToV8Value(double);
+
+void setV8ObjectPropertyAsString(v8::Handle<v8::Object>, String, String);
+
+void setV8ObjectPropertyAsNumber(v8::Handle<v8::Object>, String, double);
+
+} // namespace WebCore
+
+#endif // AnimationTestHelper_h
diff --git a/Source/core/animation/CompositorAnimations.cpp b/Source/core/animation/CompositorAnimations.cpp
index d578a6a..1807f38 100644
--- a/Source/core/animation/CompositorAnimations.cpp
+++ b/Source/core/animation/CompositorAnimations.cpp
@@ -37,10 +37,10 @@
 #include "core/animation/AnimatableValue.h"
 #include "core/animation/AnimationTranslationUtil.h"
 #include "core/animation/CompositorAnimationsImpl.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/RenderBoxModelObject.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderObject.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebAnimation.h"
 #include "public/platform/WebCompositorSupport.h"
@@ -105,18 +105,6 @@
     }
 }
 
-PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const ChainedTimingFunction* timefunc)
-{
-    RefPtr<ChainedTimingFunction> reversed = ChainedTimingFunction::create();
-    for (size_t i = 0; i < timefunc->m_segments.size(); i++) {
-        size_t index = timefunc->m_segments.size() - i - 1;
-
-        RefPtr<TimingFunction> rtf = reverse(timefunc->m_segments[index].m_timingFunction.get());
-        reversed->appendSegment(1 - timefunc->m_segments[index].m_min, rtf.get());
-    }
-    return reversed;
-}
-
 PassRefPtr<TimingFunction> CompositorAnimationsTimingFunctionReverser::reverse(const TimingFunction* timefunc)
 {
     switch (timefunc->type()) {
@@ -128,10 +116,6 @@
         const CubicBezierTimingFunction* cubic = toCubicBezierTimingFunction(timefunc);
         return reverse(cubic);
     }
-    case TimingFunction::ChainedFunction: {
-        const ChainedTimingFunction* chained = toChainedTimingFunction(timefunc);
-        return reverse(chained);
-    }
 
     // Steps function can not be reversed.
     case TimingFunction::StepsFunction:
@@ -208,42 +192,31 @@
     case TimingFunction::StepsFunction:
         return false;
 
-    case TimingFunction::ChainedFunction: {
-        // Currently we only support chained segments in the form the CSS code
-        // generates. These chained segments are only one level deep and have
-        // one timing function per frame.
-        const ChainedTimingFunction* chained = static_cast<const ChainedTimingFunction*>(timing.timingFunction.get());
-        if (!chained->m_segments.size())
-            return false;
-
-        if (frames.size() != chained->m_segments.size() + 1)
-            return false;
-
-        for (size_t timeIndex = 0; timeIndex < chained->m_segments.size(); timeIndex++) {
-            const ChainedTimingFunction::Segment& segment = chained->m_segments[timeIndex];
-
-            if (frames[timeIndex]->offset() != segment.m_min || frames[timeIndex + 1]->offset() != segment.m_max)
-                return false;
-
-            switch (segment.m_timingFunction->type()) {
-            case TimingFunction::LinearFunction:
-            case TimingFunction::CubicBezierFunction:
-                continue;
-
-            case TimingFunction::StepsFunction:
-            case TimingFunction::ChainedFunction:
-            default:
-                return false;
-            }
-        }
-
-        break;
-    }
     default:
         ASSERT_NOT_REACHED();
         return false;
     }
 
+    if (frames.size() < 2)
+        return false;
+
+    // Search for any segments with StepsFunction.
+    WillBeHeapVector<RefPtrWillBeMember<Keyframe> >::const_iterator end = keyframeEffect.getFrames().end() - 1; // Ignore timing function of last frame.
+    for (WillBeHeapVector<RefPtrWillBeMember<Keyframe> >::const_iterator iter = keyframeEffect.getFrames().begin(); iter != end; ++iter) {
+        RELEASE_ASSERT((*iter)->easing());
+        switch ((*iter)->easing()->type()) {
+        case TimingFunction::LinearFunction:
+        case TimingFunction::CubicBezierFunction:
+            continue;
+
+        case TimingFunction::StepsFunction:
+            return false;
+        default:
+            ASSERT_NOT_REACHED();
+            return false;
+        }
+    }
+
     return true;
 }
 
@@ -406,7 +379,6 @@
     }
 
     case TimingFunction::StepsFunction:
-    case TimingFunction::ChainedFunction:
     default:
         ASSERT_NOT_REACHED();
         return;
@@ -415,29 +387,17 @@
 
 } // namespace anoymous
 
-void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& curve, const KeyframeVector& keyframes, const TimingFunction& timingFunction)
+void CompositorAnimationsImpl::addKeyframesToCurve(blink::WebAnimationCurve& curve, const KeyframeVector& keyframes, bool reverse)
 {
     for (size_t i = 0; i < keyframes.size(); i++) {
+        RefPtr<TimingFunction> reversedTimingFunction;
         const TimingFunction* keyframeTimingFunction = 0;
-        if (i + 1 < keyframes.size()) { // Last keyframe has no timing function
-            switch (timingFunction.type()) {
-            case TimingFunction::LinearFunction:
-            case TimingFunction::CubicBezierFunction:
-                keyframeTimingFunction = &timingFunction;
-                break;
-
-            case TimingFunction::ChainedFunction: {
-                const ChainedTimingFunction& chained = toChainedTimingFunction(timingFunction);
-                // ChainedTimingFunction criteria was checked in isCandidate,
-                // assert it is valid.
-                ASSERT(keyframes.size() == chained.m_segments.size() + 1);
-
-                keyframeTimingFunction = chained.m_segments[i].m_timingFunction.get();
-                break;
-            }
-            case TimingFunction::StepsFunction:
-            default:
-                ASSERT_NOT_REACHED();
+        if (i < keyframes.size() - 1) { // Ignore timing function of last frame.
+            if (reverse) {
+                reversedTimingFunction = CompositorAnimationsTimingFunctionReverser::reverse(keyframes[i + 1]->easing());
+                keyframeTimingFunction = reversedTimingFunction.get();
+            } else {
+                keyframeTimingFunction = keyframes[i]->easing();
             }
         }
 
@@ -501,21 +461,21 @@
             targetProperty = blink::WebAnimation::TargetPropertyOpacity;
 
             blink::WebFloatAnimationCurve* floatCurve = blink::Platform::current()->compositorSupport()->createFloatAnimationCurve();
-            addKeyframesToCurve(*floatCurve, values, *timingFunction.get());
+            addKeyframesToCurve(*floatCurve, values, compositorTiming.reverse);
             curve = adoptPtr(floatCurve);
             break;
         }
         case CSSPropertyWebkitFilter: {
             targetProperty = blink::WebAnimation::TargetPropertyFilter;
             blink::WebFilterAnimationCurve* filterCurve = blink::Platform::current()->compositorSupport()->createFilterAnimationCurve();
-            addKeyframesToCurve(*filterCurve, values, *timingFunction);
+            addKeyframesToCurve(*filterCurve, values, compositorTiming.reverse);
             curve = adoptPtr(filterCurve);
             break;
         }
         case CSSPropertyWebkitTransform: {
             targetProperty = blink::WebAnimation::TargetPropertyTransform;
             blink::WebTransformAnimationCurve* transformCurve = blink::Platform::current()->compositorSupport()->createTransformAnimationCurve();
-            addKeyframesToCurve(*transformCurve, values, *timingFunction.get());
+            addKeyframesToCurve(*transformCurve, values, compositorTiming.reverse);
             curve = adoptPtr(transformCurve);
             break;
         }
diff --git a/Source/core/animation/CompositorAnimations.h b/Source/core/animation/CompositorAnimations.h
index 76c6b17..05aa23f 100644
--- a/Source/core/animation/CompositorAnimations.h
+++ b/Source/core/animation/CompositorAnimations.h
@@ -49,7 +49,6 @@
 public:
     static PassRefPtr<TimingFunction> reverse(const LinearTimingFunction* timefunc);
     static PassRefPtr<TimingFunction> reverse(const CubicBezierTimingFunction* timefunc);
-    static PassRefPtr<TimingFunction> reverse(const ChainedTimingFunction* timefunc);
     static PassRefPtr<TimingFunction> reverse(const TimingFunction* timefunc);
 };
 
diff --git a/Source/core/animation/CompositorAnimationsImpl.h b/Source/core/animation/CompositorAnimationsImpl.h
index 9bf8889..4ad07bd 100644
--- a/Source/core/animation/CompositorAnimationsImpl.h
+++ b/Source/core/animation/CompositorAnimationsImpl.h
@@ -52,7 +52,7 @@
 
     static void getAnimationOnCompositor(const Timing&, const KeyframeEffectModel&, Vector<OwnPtr<blink::WebAnimation> >& animations);
 
-    static void addKeyframesToCurve(blink::WebAnimationCurve&, const KeyframeVector&, const TimingFunction&);
+    static void addKeyframesToCurve(blink::WebAnimationCurve&, const KeyframeVector&, bool reverse);
 
     friend class CompositorAnimations;
     friend class AnimationCompositorAnimationsTest;
diff --git a/Source/core/animation/CompositorAnimationsTest.cpp b/Source/core/animation/CompositorAnimationsTest.cpp
index e06fdf9..23a98e3 100644
--- a/Source/core/animation/CompositorAnimationsTest.cpp
+++ b/Source/core/animation/CompositorAnimationsTest.cpp
@@ -38,7 +38,6 @@
 #include "core/animation/AnimatableValueTestHelper.h"
 #include "core/animation/CompositorAnimationsImpl.h"
 #include "core/animation/CompositorAnimationsTestHelper.h"
-#include "platform/animation/TimingFunctionTestHelper.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/graphics/filters/FilterOperations.h"
 #include "platform/transforms/TransformOperations.h"
@@ -62,7 +61,6 @@
 using ::testing::_;
 
 class AnimationCompositorAnimationsTest : public AnimationCompositorAnimationsTestBase {
-
 protected:
     RefPtr<TimingFunction> m_linearTimingFunction;
     RefPtr<TimingFunction> m_cubicEaseTimingFunction;
@@ -71,19 +69,19 @@
 
     Timing m_timing;
     CompositorAnimationsImpl::CompositorTiming m_compositorTiming;
-    KeyframeEffectModel::KeyframeVector m_keyframeVector2;
-    RefPtr<KeyframeEffectModel> m_keyframeAnimationEffect2;
-    KeyframeEffectModel::KeyframeVector m_keyframeVector5;
-    RefPtr<KeyframeEffectModel> m_keyframeAnimationEffect5;
+    OwnPtrWillBePersistent<KeyframeEffectModel::KeyframeVector> m_keyframeVector2;
+    RefPtrWillBePersistent<KeyframeEffectModel> m_keyframeAnimationEffect2;
+    OwnPtrWillBePersistent<KeyframeEffectModel::KeyframeVector> m_keyframeVector5;
+    RefPtrWillBePersistent<KeyframeEffectModel> m_keyframeAnimationEffect5;
 
     virtual void SetUp()
     {
         AnimationCompositorAnimationsTestBase::SetUp();
 
-        m_linearTimingFunction = LinearTimingFunction::create();
+        m_linearTimingFunction = LinearTimingFunction::preset();
         m_cubicEaseTimingFunction = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
         m_cubicCustomTimingFunction = CubicBezierTimingFunction::create(1, 2, 3, 4);
-        m_stepTimingFunction = StepsTimingFunction::create(1, false);
+        m_stepTimingFunction = StepsTimingFunction::create(1, StepsTimingFunction::StepAtEnd);
 
         m_timing = createCompositableTiming();
         m_compositorTiming = CompositorAnimationsImpl::CompositorTiming();
@@ -92,10 +90,10 @@
         ASSERT(convertTimingForCompositor(m_timing, m_compositorTiming));
 
         m_keyframeVector2 = createCompositableFloatKeyframeVector(2);
-        m_keyframeAnimationEffect2 = KeyframeEffectModel::create(m_keyframeVector2);
+        m_keyframeAnimationEffect2 = KeyframeEffectModel::create(*m_keyframeVector2.get());
 
         m_keyframeVector5 = createCompositableFloatKeyframeVector(5);
-        m_keyframeAnimationEffect5 = KeyframeEffectModel::create(m_keyframeVector5);
+        m_keyframeAnimationEffect5 = KeyframeEffectModel::create(*m_keyframeVector5.get());
     }
 
 public:
@@ -118,8 +116,8 @@
         EXPECT_EQ(frame->offset(), 0);
         KeyframeEffectModel::KeyframeVector frames;
         frames.append(frame);
-        EXPECT_EQ(m_keyframeVector2[1]->offset(), 1.0);
-        frames.append(m_keyframeVector2[1]);
+        EXPECT_EQ((*m_keyframeVector2)[1]->offset(), 1.0);
+        frames.append((*m_keyframeVector2)[1]);
         return isCandidateForAnimationOnCompositor(m_timing, *KeyframeEffectModel::create(frames).get());
     }
 
@@ -140,16 +138,17 @@
         return timing;
     }
 
-    PassRefPtr<Keyframe> createReplaceOpKeyframe(CSSPropertyID id, AnimatableValue* value, double offset = 0)
+    PassRefPtrWillBeRawPtr<Keyframe> createReplaceOpKeyframe(CSSPropertyID id, AnimatableValue* value, double offset = 0)
     {
-        RefPtr<Keyframe> keyframe = Keyframe::create();
+        RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create();
         keyframe->setPropertyValue(id, value);
         keyframe->setComposite(AnimationEffect::CompositeReplace);
         keyframe->setOffset(offset);
+        keyframe->setEasing(LinearTimingFunction::preset());
         return keyframe;
     }
 
-    PassRefPtr<Keyframe> createDefaultKeyframe(CSSPropertyID id, AnimationEffect::CompositeOperation op, double offset = 0)
+    PassRefPtrWillBeRawPtr<Keyframe> createDefaultKeyframe(CSSPropertyID id, AnimationEffect::CompositeOperation op, double offset = 0)
     {
         RefPtr<AnimatableValue> value;
         if (id == CSSPropertyWebkitTransform)
@@ -157,12 +156,12 @@
         else
             value = AnimatableDouble::create(10.0);
 
-        RefPtr<Keyframe> keyframe = createReplaceOpKeyframe(id, value.get(), offset);
+        RefPtrWillBeRawPtr<Keyframe> keyframe = createReplaceOpKeyframe(id, value.get(), offset);
         keyframe->setComposite(op);
         return keyframe;
     }
 
-    KeyframeEffectModel::KeyframeVector createCompositableFloatKeyframeVector(size_t n)
+    PassOwnPtrWillBeRawPtr<KeyframeEffectModel::KeyframeVector> createCompositableFloatKeyframeVector(size_t n)
     {
         Vector<double> values;
         for (size_t i = 0; i < n; i++) {
@@ -171,23 +170,23 @@
         return createCompositableFloatKeyframeVector(values);
     }
 
-    KeyframeEffectModel::KeyframeVector createCompositableFloatKeyframeVector(Vector<double>& values)
+    PassOwnPtrWillBeRawPtr<KeyframeEffectModel::KeyframeVector> createCompositableFloatKeyframeVector(Vector<double>& values)
     {
-        KeyframeEffectModel::KeyframeVector frames;
+        OwnPtrWillBeRawPtr<KeyframeEffectModel::KeyframeVector> frames = adoptPtrWillBeNoop(new KeyframeEffectModel::KeyframeVector);
         for (size_t i = 0; i < values.size(); i++) {
             double offset = 1.0 / (values.size() - 1) * i;
             RefPtr<AnimatableDouble> value = AnimatableDouble::create(values[i]);
-            frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, value.get(), offset).get());
+            frames->append(createReplaceOpKeyframe(CSSPropertyOpacity, value.get(), offset).get());
         }
-        return frames;
+        return frames.release();
     }
 
-    PassRefPtr<KeyframeEffectModel> createKeyframeEffectModel(PassRefPtr<Keyframe> prpFrom, PassRefPtr<Keyframe> prpTo, PassRefPtr<Keyframe> prpC = 0, PassRefPtr<Keyframe> prpD = 0)
+    PassRefPtrWillBeRawPtr<KeyframeEffectModel> createKeyframeEffectModel(PassRefPtrWillBeRawPtr<Keyframe> prpFrom, PassRefPtrWillBeRawPtr<Keyframe> prpTo, PassRefPtrWillBeRawPtr<Keyframe> prpC = nullptr, PassRefPtrWillBeRawPtr<Keyframe> prpD = nullptr)
     {
-        RefPtr<Keyframe> from = prpFrom;
-        RefPtr<Keyframe> to = prpTo;
-        RefPtr<Keyframe> c = prpC;
-        RefPtr<Keyframe> d = prpD;
+        RefPtrWillBeRawPtr<Keyframe> from = prpFrom;
+        RefPtrWillBeRawPtr<Keyframe> to = prpTo;
+        RefPtrWillBeRawPtr<Keyframe> c = prpC;
+        RefPtrWillBeRawPtr<Keyframe> d = prpD;
 
         EXPECT_EQ(from->offset(), 0);
         KeyframeEffectModel::KeyframeVector frames;
@@ -208,7 +207,7 @@
         if (!HasFatalFailure()) {
             return KeyframeEffectModel::create(frames);
         }
-        return PassRefPtr<KeyframeEffectModel>();
+        return PassRefPtrWillBeRawPtr<KeyframeEffectModel>();
     }
 
 };
@@ -218,15 +217,15 @@
 
 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorKeyframeMultipleCSSProperties)
 {
-    RefPtr<Keyframe> keyframeGoodMultiple = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace);
+    RefPtrWillBeRawPtr<Keyframe> keyframeGoodMultiple = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace);
     keyframeGoodMultiple->setPropertyValue(CSSPropertyWebkitTransform, AnimatableTransform::create(TransformOperations()).get());
     EXPECT_TRUE(isCandidateHelperForSingleKeyframe(keyframeGoodMultiple.get()));
 
-    RefPtr<Keyframe> keyframeBadMultipleOp = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeAdd);
+    RefPtrWillBeRawPtr<Keyframe> keyframeBadMultipleOp = createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeAdd);
     keyframeBadMultipleOp->setPropertyValue(CSSPropertyWebkitTransform, AnimatableDouble::create(10.0).get());
     EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultipleOp.get()));
 
-    RefPtr<Keyframe> keyframeBadMultipleID = createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace);
+    RefPtrWillBeRawPtr<Keyframe> keyframeBadMultipleID = createDefaultKeyframe(CSSPropertyColor, AnimationEffect::CompositeReplace);
     keyframeBadMultipleID->setPropertyValue(CSSPropertyOpacity, AnimatableDouble::create(10.0).get());
     EXPECT_FALSE(isCandidateHelperForSingleKeyframe(keyframeBadMultipleID.get()));
 }
@@ -235,17 +234,17 @@
 {
     TransformOperations ops;
     ops.operations().append(TranslateTransformOperation::create(Length(2, WebCore::Fixed), Length(2, WebCore::Fixed), TransformOperation::TranslateX));
-    RefPtr<Keyframe> goodKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get());
+    RefPtrWillBeRawPtr<Keyframe> goodKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get());
     EXPECT_TRUE(isCandidateHelperForSingleKeyframe(goodKeyframe.get()));
 
     ops.operations().append(TranslateTransformOperation::create(Length(50, WebCore::Percent), Length(2, WebCore::Fixed), TransformOperation::TranslateX));
-    RefPtr<Keyframe> badKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get());
+    RefPtrWillBeRawPtr<Keyframe> badKeyframe = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops).get());
     EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe.get()));
 
     TransformOperations ops2;
     Length calcLength = Length(100, WebCore::Percent).blend(Length(100, WebCore::Fixed), 0.5, WebCore::ValueRangeAll);
     ops2.operations().append(TranslateTransformOperation::create(calcLength, Length(0, WebCore::Fixed), TransformOperation::TranslateX));
-    RefPtr<Keyframe> badKeyframe2 = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops2).get());
+    RefPtrWillBeRawPtr<Keyframe> badKeyframe2 = createReplaceOpKeyframe(CSSPropertyWebkitTransform, AnimatableTransform::create(ops2).get());
     EXPECT_FALSE(isCandidateHelperForSingleKeyframe(badKeyframe2.get()));
 }
 
@@ -451,191 +450,65 @@
     EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
 }
 
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedEmpty)
-{
-    RefPtr<ChainedTimingFunction> chainedEmpty = ChainedTimingFunction::create();
-    m_timing.timingFunction = chainedEmpty;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedLinear)
 {
-    RefPtr<ChainedTimingFunction> chainedLinearSingle = ChainedTimingFunction::create();
-    chainedLinearSingle->appendSegment(1.0, m_linearTimingFunction.get());
-    m_timing.timingFunction = chainedLinearSingle;
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
-
-    RefPtr<ChainedTimingFunction> chainedLinearMultiple = ChainedTimingFunction::create();
-    chainedLinearMultiple->appendSegment(0.25, m_linearTimingFunction.get());
-    chainedLinearMultiple->appendSegment(0.5, m_linearTimingFunction.get());
-    chainedLinearMultiple->appendSegment(0.75, m_linearTimingFunction.get());
-    chainedLinearMultiple->appendSegment(1.0, m_linearTimingFunction.get());
-    m_timing.timingFunction = chainedLinearMultiple;
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
-    // FIXME: Technically a chained timing function of linear functions don't
-    // have to be aligned to keyframes. We don't support that currently as
-    // nothing generates that yet.
 }
 
 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedCubicMatchingOffsets)
 {
-    RefPtr<ChainedTimingFunction> chainedSingleAGood = ChainedTimingFunction::create();
-    chainedSingleAGood->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chainedSingleAGood;
+    (*m_keyframeVector2)[0]->setEasing(m_cubicEaseTimingFunction.get());
+    m_keyframeAnimationEffect2 = KeyframeEffectModel::create(*m_keyframeVector2);
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
 
-    RefPtr<ChainedTimingFunction> chainedSingleBGood = ChainedTimingFunction::create();
-    chainedSingleBGood->appendSegment(1.0, m_cubicCustomTimingFunction.get());
-    m_timing.timingFunction = chainedSingleBGood;
+    (*m_keyframeVector2)[0]->setEasing(m_cubicCustomTimingFunction.get());
+    m_keyframeAnimationEffect2 = KeyframeEffectModel::create(*m_keyframeVector2);
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
 
-    RefPtr<ChainedTimingFunction> chainedMultipleGood = ChainedTimingFunction::create();
-    chainedMultipleGood->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chainedMultipleGood->appendSegment(0.5, m_cubicCustomTimingFunction.get());
-    chainedMultipleGood->appendSegment(0.75, m_cubicCustomTimingFunction.get());
-    chainedMultipleGood->appendSegment(1.0, m_cubicCustomTimingFunction.get());
-    m_timing.timingFunction = chainedMultipleGood;
+    (*m_keyframeVector5)[0]->setEasing(m_cubicEaseTimingFunction.get());
+    (*m_keyframeVector5)[1]->setEasing(m_cubicCustomTimingFunction.get());
+    (*m_keyframeVector5)[2]->setEasing(m_cubicCustomTimingFunction.get());
+    (*m_keyframeVector5)[3]->setEasing(m_cubicCustomTimingFunction.get());
+    m_keyframeAnimationEffect5 = KeyframeEffectModel::create(*m_keyframeVector5);
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
 }
 
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionChainedCubicNonMatchingOffsets)
-{
-    RefPtr<ChainedTimingFunction> chained0 = ChainedTimingFunction::create();
-    chained0->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained0;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
-
-    RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create();
-    chained1->appendSegment(0.24, m_cubicEaseTimingFunction.get());
-    chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chained1->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chained1->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained1;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
-    RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create();
-    chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(0.51, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained2;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
-    RefPtr<ChainedTimingFunction> chained3 = ChainedTimingFunction::create();
-    chained3->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chained3->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chained3->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chained3->appendSegment(0.8, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained3;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
-    RefPtr<ChainedTimingFunction> chained4 = ChainedTimingFunction::create();
-    chained4->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chained4->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chained4->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chained4->appendSegment(1.1, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained4;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionMissingFrames)
-{
-    // Missing first
-    RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create();
-    chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chained1->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chained1->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained1;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
-    // Missing middle
-    RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create();
-    chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained2;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-
-    // Missing last
-    RefPtr<ChainedTimingFunction> chained3 = ChainedTimingFunction::create();
-    chained3->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chained3->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chained3->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained3;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionToManyFrames)
-{
-    RefPtr<ChainedTimingFunction> chained1 = ChainedTimingFunction::create();
-    chained1->appendSegment(0.1, m_cubicEaseTimingFunction.get());
-    chained1->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained1;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
-
-    RefPtr<ChainedTimingFunction> chained2 = ChainedTimingFunction::create();
-    chained2->appendSegment(0.1, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chained2->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chained2;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionMixedGood)
 {
-    RefPtr<ChainedTimingFunction> chainedMixed = ChainedTimingFunction::create();
-    chainedMixed->appendSegment(0.25, m_linearTimingFunction.get());
-    chainedMixed->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chainedMixed->appendSegment(0.75, m_cubicEaseTimingFunction.get());
-    chainedMixed->appendSegment(1.0, m_linearTimingFunction.get());
-    m_timing.timingFunction = chainedMixed;
+    (*m_keyframeVector5)[0]->setEasing(m_linearTimingFunction.get());
+    (*m_keyframeVector5)[1]->setEasing(m_cubicEaseTimingFunction.get());
+    (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+    (*m_keyframeVector5)[3]->setEasing(m_linearTimingFunction.get());
+    m_keyframeAnimationEffect5 = KeyframeEffectModel::create(*m_keyframeVector5);
     EXPECT_TRUE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
 }
 
 TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionWithStepNotOkay)
 {
-    RefPtr<ChainedTimingFunction> chainedStepSingle = ChainedTimingFunction::create();
-    chainedStepSingle->appendSegment(1.0, m_stepTimingFunction.get());
-    m_timing.timingFunction = chainedStepSingle;
+    (*m_keyframeVector2)[0]->setEasing(m_stepTimingFunction.get());
+    m_keyframeAnimationEffect2 = KeyframeEffectModel::create(*m_keyframeVector2);
     EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect2.get()));
 
-    RefPtr<ChainedTimingFunction> chainedStepMixedA = ChainedTimingFunction::create();
-    chainedStepMixedA->appendSegment(0.25, m_stepTimingFunction.get());
-    chainedStepMixedA->appendSegment(0.5, m_linearTimingFunction.get());
-    chainedStepMixedA->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chainedStepMixedA;
+    (*m_keyframeVector5)[0]->setEasing(m_stepTimingFunction.get());
+    (*m_keyframeVector5)[1]->setEasing(m_linearTimingFunction.get());
+    (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+    (*m_keyframeVector5)[3]->setEasing(m_linearTimingFunction.get());
+    m_keyframeAnimationEffect5 = KeyframeEffectModel::create(*m_keyframeVector5);
     EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
 
-    RefPtr<ChainedTimingFunction> chainedStepMixedB = ChainedTimingFunction::create();
-    chainedStepMixedB->appendSegment(0.25, m_linearTimingFunction.get());
-    chainedStepMixedB->appendSegment(0.5, m_stepTimingFunction.get());
-    chainedStepMixedB->appendSegment(1.0, m_cubicEaseTimingFunction.get());
-    m_timing.timingFunction = chainedStepMixedB;
+    (*m_keyframeVector5)[0]->setEasing(m_linearTimingFunction.get());
+    (*m_keyframeVector5)[1]->setEasing(m_stepTimingFunction.get());
+    (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+    (*m_keyframeVector5)[3]->setEasing(m_linearTimingFunction.get());
+    m_keyframeAnimationEffect5 = KeyframeEffectModel::create(*m_keyframeVector5);
     EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
 
-    RefPtr<ChainedTimingFunction> chainedStepMixedC = ChainedTimingFunction::create();
-    chainedStepMixedC->appendSegment(0.25, m_linearTimingFunction.get());
-    chainedStepMixedC->appendSegment(0.5, m_cubicEaseTimingFunction.get());
-    chainedStepMixedC->appendSegment(1.0, m_stepTimingFunction.get());
-    m_timing.timingFunction = chainedStepMixedC;
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
-}
-
-TEST_F(AnimationCompositorAnimationsTest, isCandidateForAnimationOnCompositorTimingFunctionNestedNotOkay)
-{
-    RefPtr<ChainedTimingFunction> chainedChild = ChainedTimingFunction::create();
-    chainedChild->appendSegment(1.0, m_linearTimingFunction.get());
-
-    RefPtr<ChainedTimingFunction> chainedParent = ChainedTimingFunction::create();
-    chainedParent->appendSegment(0.25, m_linearTimingFunction.get());
-    chainedParent->appendSegment(0.5, chainedChild.get());
-    chainedParent->appendSegment(0.75, m_linearTimingFunction.get());
-    chainedParent->appendSegment(1.0, m_linearTimingFunction.get());
-    m_timing.timingFunction = chainedParent;
+    (*m_keyframeVector5)[0]->setEasing(m_linearTimingFunction.get());
+    (*m_keyframeVector5)[1]->setEasing(m_cubicEaseTimingFunction.get());
+    (*m_keyframeVector5)[2]->setEasing(m_cubicEaseTimingFunction.get());
+    (*m_keyframeVector5)[3]->setEasing(m_stepTimingFunction.get());
+    m_keyframeAnimationEffect5 = KeyframeEffectModel::create(*m_keyframeVector5);
     EXPECT_FALSE(isCandidateForAnimationOnCompositor(m_timing, *m_keyframeAnimationEffect5.get()));
 }
 
@@ -643,35 +516,27 @@
 {
     Timing linearTiming(createCompositableTiming());
 
-    RefPtr<TimingFunction> cubicTimingFunc = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
-    Timing cubicTiming(createCompositableTiming());
-    cubicTiming.timingFunction = cubicTimingFunc;
-
-    RefPtr<ChainedTimingFunction> chainedTimingFunc = ChainedTimingFunction::create();
-    chainedTimingFunc->appendSegment(0.5, m_linearTimingFunction.get());
-    chainedTimingFunc->appendSegment(1.0, cubicTimingFunc.get());
-    Timing chainedTiming(createCompositableTiming());
-    chainedTiming.timingFunction = chainedTimingFunc;
-
     KeyframeEffectModel::KeyframeVector basicFramesVector;
     basicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
     basicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get());
-    RefPtr<KeyframeEffectModel> basicFrames = KeyframeEffectModel::create(basicFramesVector).get();
-
-    EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames.get()));
-    EXPECT_TRUE(isCandidateForAnimationOnCompositor(cubicTiming, *basicFrames.get()));
-    // number of timing function and keyframes don't match
-    EXPECT_FALSE(isCandidateForAnimationOnCompositor(chainedTiming, *basicFrames.get()));
 
     KeyframeEffectModel::KeyframeVector nonBasicFramesVector;
     nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.0).get());
     nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 0.5).get());
     nonBasicFramesVector.append(createDefaultKeyframe(CSSPropertyOpacity, AnimationEffect::CompositeReplace, 1.0).get());
-    RefPtr<KeyframeEffectModel> nonBasicFrames = KeyframeEffectModel::create(nonBasicFramesVector).get();
 
+    basicFramesVector[0]->setEasing(m_linearTimingFunction.get());
+    RefPtrWillBeRawPtr<KeyframeEffectModel> basicFrames = KeyframeEffectModel::create(basicFramesVector).get();
+    EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames.get()));
+
+    basicFramesVector[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+    basicFrames = KeyframeEffectModel::create(basicFramesVector).get();
+    EXPECT_TRUE(isCandidateForAnimationOnCompositor(linearTiming, *basicFrames.get()));
+
+    nonBasicFramesVector[0]->setEasing(m_linearTimingFunction.get());
+    nonBasicFramesVector[1]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> nonBasicFrames = KeyframeEffectModel::create(nonBasicFramesVector).get();
     EXPECT_TRUE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(linearTiming, *nonBasicFrames.get()));
-    EXPECT_FALSE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(cubicTiming, *nonBasicFrames.get()));
-    EXPECT_TRUE(CompositorAnimations::instance()->isCandidateForAnimationOnCompositor(chainedTiming, *nonBasicFrames.get()));
 }
 
 // -----------------------------------------------------------------------
@@ -680,7 +545,7 @@
 TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimation)
 {
     // Animation to convert
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
     // --
@@ -725,7 +590,7 @@
 TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationDuration)
 {
     // Animation to convert
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
 
@@ -772,7 +637,7 @@
 TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationLinear)
 {
     // Animation to convert
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25),
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5),
@@ -825,7 +690,7 @@
 TEST_F(AnimationCompositorAnimationsTest, createSimpleOpacityAnimationStartDelay)
 {
     // Animation to convert
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
 
@@ -874,18 +739,17 @@
 TEST_F(AnimationCompositorAnimationsTest, createMultipleKeyframeOpacityAnimationChained)
 {
     // Animation to convert
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25),
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5),
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
+    KeyframeEffectModel::KeyframeVector frames;
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0));
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25));
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5));
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
+    frames[0]->setEasing(m_cubicEaseTimingFunction.get());
+    frames[1]->setEasing(m_linearTimingFunction.get());
+    frames[2]->setEasing(m_cubicCustomTimingFunction.get());
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(frames);
 
-    RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
-    chainedTimingFunction->appendSegment(0.25, m_cubicEaseTimingFunction.get());
-    chainedTimingFunction->appendSegment(0.5, m_linearTimingFunction.get());
-    chainedTimingFunction->appendSegment(1.0, m_cubicCustomTimingFunction.get());
-
-    m_timing.timingFunction = chainedTimingFunction;
+    m_timing.timingFunction = m_linearTimingFunction.get();
     m_timing.iterationDuration = 2.0;
     m_timing.iterationCount = 10;
     m_timing.direction = Timing::PlaybackDirectionAlternate;
@@ -933,20 +797,20 @@
 
 TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimation)
 {
-    // Animation to convert
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25),
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5),
-        createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
-
     RefPtr<TimingFunction> cubicEasyFlipTimingFunction = CubicBezierTimingFunction::create(0.0, 0.0, 0.0, 1.0);
-    RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
-    chainedTimingFunction->appendSegment(0.25, CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
-    chainedTimingFunction->appendSegment(0.5, m_linearTimingFunction.get());
-    chainedTimingFunction->appendSegment(1.0, cubicEasyFlipTimingFunction.get());
 
-    m_timing.timingFunction = chainedTimingFunction;
+    // Animation to convert
+    KeyframeEffectModel::KeyframeVector frames;
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0));
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(-1.0).get(), 0.25));
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(20.0).get(), 0.5));
+    frames.append(createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
+    frames[0]->setEasing(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn));
+    frames[1]->setEasing(m_linearTimingFunction.get());
+    frames[2]->setEasing(cubicEasyFlipTimingFunction.get());
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(frames);
+
+    m_timing.timingFunction = m_linearTimingFunction.get();
     m_timing.iterationCount = 10;
     m_timing.direction = Timing::PlaybackDirectionAlternateReverse;
     // --
@@ -994,7 +858,7 @@
 TEST_F(AnimationCompositorAnimationsTest, createReversedOpacityAnimationNegativeStartDelay)
 {
     // Animation to convert
-    RefPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = createKeyframeEffectModel(
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(2.0).get(), 0),
         createReplaceOpKeyframe(CSSPropertyOpacity, AnimatableDouble::create(5.0).get(), 1.0));
 
diff --git a/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp b/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp
index 102f4ef..ae36fbe 100644
--- a/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp
+++ b/Source/core/animation/CompositorAnimationsTimingFunctionReverserTest.cpp
@@ -32,8 +32,6 @@
 
 #include "core/animation/CompositorAnimations.h"
 
-#include "platform/animation/TimingFunctionTestHelper.h"
-
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
 
@@ -60,7 +58,7 @@
 
 TEST_F(AnimationCompositorAnimationsTimingFunctionReverserTest, LinearReverse)
 {
-    RefPtr<TimingFunction> linearTiming = LinearTimingFunction::create();
+    RefPtr<TimingFunction> linearTiming = LinearTimingFunction::preset();
     EXPECT_REFV_EQ(linearTiming, reverse(linearTiming));
 }
 
@@ -84,24 +82,4 @@
     EXPECT_REFV_EQ(cubicEaseTimingReversed, reverse(cubicEaseTiming));
 }
 
-TEST_F(AnimationCompositorAnimationsTimingFunctionReverserTest, ChainedReverse)
-{
-    RefPtr<TimingFunction> linearTiming = LinearTimingFunction::create();
-    RefPtr<ChainedTimingFunction> chainedLinearSingle = ChainedTimingFunction::create();
-    chainedLinearSingle->appendSegment(1.0, linearTiming.get());
-    EXPECT_REFV_EQ(chainedLinearSingle, reverse(chainedLinearSingle));
-
-    RefPtr<TimingFunction> cubicEaseInTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn);
-    RefPtr<TimingFunction> cubicEaseOutTiming = CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut);
-
-    RefPtr<ChainedTimingFunction> chainedMixed = ChainedTimingFunction::create();
-    chainedMixed->appendSegment(0.75, chainedLinearSingle.get());
-    chainedMixed->appendSegment(1.0, cubicEaseInTiming.get());
-
-    RefPtr<ChainedTimingFunction> chainedMixedReversed = ChainedTimingFunction::create();
-    chainedMixedReversed->appendSegment(0.25, cubicEaseOutTiming.get());
-    chainedMixedReversed->appendSegment(1.0, chainedLinearSingle.get());
-    EXPECT_REFV_EQ(chainedMixedReversed, reverse(chainedMixed));
-}
-
 } // namespace
diff --git a/Source/core/animation/DocumentAnimation.h b/Source/core/animation/DocumentAnimation.h
index 4591091..7ca1234 100644
--- a/Source/core/animation/DocumentAnimation.h
+++ b/Source/core/animation/DocumentAnimation.h
@@ -11,7 +11,7 @@
 
 class DocumentAnimation {
 public:
-    static DocumentTimeline* timeline(Document* document) { return document->timeline(); }
+    static DocumentTimeline* timeline(Document& document) { return &document.timeline(); }
 };
 
 } // namespace WebCore
diff --git a/Source/core/animation/DocumentAnimations.cpp b/Source/core/animation/DocumentAnimations.cpp
index 57770ca..86f9286 100644
--- a/Source/core/animation/DocumentAnimations.cpp
+++ b/Source/core/animation/DocumentAnimations.cpp
@@ -37,10 +37,10 @@
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/Node.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
-#include "core/rendering/RenderLayerCompositor.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 
 namespace WebCore {
 
@@ -48,39 +48,24 @@
 
 void updateAnimationTiming(Document& document)
 {
-    bool didTriggerStyleRecalc = document.timeline()->serviceAnimations();
-    didTriggerStyleRecalc |= document.transitionTimeline()->serviceAnimations();
-    if (!didTriggerStyleRecalc)
-        document.animationClock().unfreeze();
-}
-
-void dispatchAnimationEvents(Document& document)
-{
-    document.timeline()->dispatchEvents();
-    document.transitionTimeline()->dispatchEvents();
-}
-
-void dispatchAnimationEventsAsync(Document& document)
-{
-    document.timeline()->dispatchEventsAsync();
-    document.transitionTimeline()->dispatchEventsAsync();
+    document.timeline().serviceAnimations();
+    document.transitionTimeline().serviceAnimations();
 }
 
 } // namespace
 
-void DocumentAnimations::serviceOnAnimationFrame(Document& document, double monotonicAnimationStartTime)
+void DocumentAnimations::updateAnimationTimingForAnimationFrame(Document& document, double monotonicAnimationStartTime)
 {
     document.animationClock().updateTime(monotonicAnimationStartTime);
     updateAnimationTiming(document);
-    dispatchAnimationEvents(document);
 }
 
-void DocumentAnimations::serviceBeforeGetComputedStyle(Node& node, CSSPropertyID property)
+void DocumentAnimations::updateAnimationTimingForGetComputedStyle(Node& node, CSSPropertyID property)
 {
     if (!node.isElementNode())
         return;
     const Element& element = toElement(node);
-    if (element.document().timeline()->hasPlayerNeedingUpdate()) {
+    if (element.document().timeline().hasOutdatedAnimationPlayer()) {
         updateAnimationTiming(element.document());
         return;
     }
@@ -90,13 +75,15 @@
     }
 }
 
-void DocumentAnimations::serviceAfterStyleRecalc(Document& document)
+void DocumentAnimations::startPendingAnimations(Document& document)
 {
-    if (document.cssPendingAnimations().startPendingAnimations() && document.view())
+    ASSERT(document.lifecycle().state() == DocumentLifecycle::CompositingClean);
+    if (document.cssPendingAnimations().startPendingAnimations()) {
+        ASSERT(document.view());
         document.view()->scheduleAnimation();
+    }
 
     document.animationClock().unfreeze();
-    dispatchAnimationEventsAsync(document);
 }
 
 } // namespace WebCore
diff --git a/Source/core/animation/DocumentAnimations.h b/Source/core/animation/DocumentAnimations.h
index b952c53..567174d 100644
--- a/Source/core/animation/DocumentAnimations.h
+++ b/Source/core/animation/DocumentAnimations.h
@@ -41,9 +41,9 @@
 
 class DocumentAnimations  {
 public:
-    static void serviceOnAnimationFrame(Document&, double monotonicAnimationStartTime);
-    static void serviceBeforeGetComputedStyle(Node&, CSSPropertyID);
-    static void serviceAfterStyleRecalc(Document&);
+    static void updateAnimationTimingForAnimationFrame(Document&, double monotonicAnimationStartTime);
+    static void updateAnimationTimingForGetComputedStyle(Node&, CSSPropertyID);
+    static void startPendingAnimations(Document&);
 
 private:
     DocumentAnimations() { }
diff --git a/Source/core/animation/DocumentTimeline.cpp b/Source/core/animation/DocumentTimeline.cpp
index ba4b1e3..8f2d489 100644
--- a/Source/core/animation/DocumentTimeline.cpp
+++ b/Source/core/animation/DocumentTimeline.cpp
@@ -35,6 +35,8 @@
 #include "core/animation/AnimationClock.h"
 #include "core/dom/Document.h"
 #include "core/frame/FrameView.h"
+#include "core/page/Page.h"
+#include "platform/TraceEvent.h"
 
 namespace WebCore {
 
@@ -51,7 +53,6 @@
 DocumentTimeline::DocumentTimeline(Document* document, PassOwnPtr<PlatformTiming> timing)
     : m_zeroTime(nullValue())
     , m_document(document)
-    , m_eventDistpachTimer(this, &DocumentTimeline::eventDispatchTimerFired)
 {
     if (!timing)
         m_timing = adoptPtr(new DocumentTimelineTiming(this));
@@ -63,23 +64,22 @@
 
 DocumentTimeline::~DocumentTimeline()
 {
-    for (HashSet<Player*>::iterator it = m_players.begin(); it != m_players.end(); ++it)
+    for (HashSet<AnimationPlayer*>::iterator it = m_players.begin(); it != m_players.end(); ++it)
         (*it)->timelineDestroyed();
 }
 
-Player* DocumentTimeline::createPlayer(TimedItem* child)
+AnimationPlayer* DocumentTimeline::createAnimationPlayer(TimedItem* child)
 {
-    RefPtr<Player> player = Player::create(*this, child);
-    Player* result = player.get();
+    RefPtr<AnimationPlayer> player = AnimationPlayer::create(*this, child);
+    AnimationPlayer* result = player.get();
     m_players.add(result);
-    m_currentPlayers.append(player.release());
-    setHasPlayerNeedingUpdate();
+    setOutdatedAnimationPlayer(result);
     return result;
 }
 
-Player* DocumentTimeline::play(TimedItem* child)
+AnimationPlayer* DocumentTimeline::play(TimedItem* child)
 {
-    Player* player = createPlayer(child);
+    AnimationPlayer* player = createAnimationPlayer(child);
     player->setStartTime(currentTime());
     return player;
 }
@@ -89,32 +89,35 @@
     m_timing->serviceOnNextFrame();
 }
 
-bool DocumentTimeline::serviceAnimations()
+void DocumentTimeline::serviceAnimations()
 {
     TRACE_EVENT0("webkit", "DocumentTimeline::serviceAnimations");
 
     m_timing->cancelWake();
+    m_hasOutdatedAnimationPlayer = false;
 
     double timeToNextEffect = std::numeric_limits<double>::infinity();
-    bool didTriggerStyleRecalc = false;
-    for (int i = m_currentPlayers.size() - 1; i >= 0; --i) {
-        RefPtr<Player> player = m_currentPlayers[i].get();
-        bool playerDidTriggerStyleRecalc;
-        if (!player->update(&playerDidTriggerStyleRecalc))
-            m_currentPlayers.remove(i);
-        timeToNextEffect = std::min(timeToNextEffect, player->timeToEffectChange());
-        didTriggerStyleRecalc |= playerDidTriggerStyleRecalc;
+    Vector<AnimationPlayer*> players;
+    for (HashSet<RefPtr<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it)
+        players.append(it->get());
+
+    std::sort(players.begin(), players.end(), AnimationPlayer::hasLowerPriority);
+
+    for (size_t i = 0; i < players.size(); ++i) {
+        AnimationPlayer* player = players[i];
+        if (player->update())
+            timeToNextEffect = std::min(timeToNextEffect, player->timeToEffectChange());
+        else
+            m_playersNeedingUpdate.remove(player);
     }
 
-    if (!m_currentPlayers.isEmpty()) {
-        if (timeToNextEffect < s_minimumDelay)
-            m_timing->serviceOnNextFrame();
-        else if (timeToNextEffect != std::numeric_limits<double>::infinity())
-            m_timing->wakeAfter(timeToNextEffect - s_minimumDelay);
-    }
+    ASSERT(!m_playersNeedingUpdate.isEmpty() || timeToNextEffect == std::numeric_limits<double>::infinity());
+    if (timeToNextEffect < s_minimumDelay)
+        m_timing->serviceOnNextFrame();
+    else if (timeToNextEffect != std::numeric_limits<double>::infinity())
+        m_timing->wakeAfter(timeToNextEffect - s_minimumDelay);
 
-    m_hasPlayerNeedingUpdate = false;
-    return didTriggerStyleRecalc;
+    ASSERT(!m_hasOutdatedAnimationPlayer);
 }
 
 void DocumentTimeline::setZeroTime(double zeroTime)
@@ -127,7 +130,7 @@
 
 void DocumentTimeline::DocumentTimelineTiming::wakeAfter(double duration)
 {
-    m_timer.startOneShot(duration);
+    m_timer.startOneShot(duration, FROM_HERE);
 }
 
 void DocumentTimeline::DocumentTimelineTiming::cancelWake()
@@ -150,38 +153,19 @@
 
 void DocumentTimeline::pauseAnimationsForTesting(double pauseTime)
 {
-    for (size_t i = 0; i < m_currentPlayers.size(); i++)
-        m_currentPlayers[i]->pauseForTesting(pauseTime);
+    for (HashSet<RefPtr<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it)
+        (*it)->pauseForTesting(pauseTime);
     serviceAnimations();
 }
 
-void DocumentTimeline::setHasPlayerNeedingUpdate()
+void DocumentTimeline::setOutdatedAnimationPlayer(AnimationPlayer* player)
 {
-    m_hasPlayerNeedingUpdate = true;
-    if (m_document && m_document->view() && !m_document->view()->isServicingAnimations())
+    m_playersNeedingUpdate.add(player);
+    m_hasOutdatedAnimationPlayer = true;
+    if (m_document && m_document->page() && !m_document->page()->animator().isServicingAnimations())
         m_timing->serviceOnNextFrame();
 }
 
-void DocumentTimeline::dispatchEvents()
-{
-    Vector<EventToDispatch> events = m_events;
-    m_events.clear();
-    for (size_t i = 0; i < events.size(); i++)
-        events[i].target->dispatchEvent(events[i].event.release());
-}
-
-void DocumentTimeline::dispatchEventsAsync()
-{
-    if (m_events.isEmpty() || m_eventDistpachTimer.isActive())
-        return;
-    m_eventDistpachTimer.startOneShot(0);
-}
-
-void DocumentTimeline::eventDispatchTimerFired(Timer<DocumentTimeline>*)
-{
-    dispatchEvents();
-}
-
 size_t DocumentTimeline::numberOfActiveAnimationsForTesting() const
 {
     if (isNull(m_zeroTime))
@@ -191,9 +175,9 @@
     if (isNull(m_zeroTime))
         return 0;
     size_t count = 0;
-    for (size_t i = 0; i < m_currentPlayers.size(); ++i) {
-        const TimedItem* timedItem = m_currentPlayers[i]->source();
-        if (m_currentPlayers[i]->hasStartTime())
+    for (HashSet<RefPtr<AnimationPlayer> >::iterator it = m_playersNeedingUpdate.begin(); it != m_playersNeedingUpdate.end(); ++it) {
+        const TimedItem* timedItem = (*it)->source();
+        if ((*it)->hasStartTime())
             count += (timedItem && (timedItem->isCurrent() || timedItem->isInEffect()));
     }
     return count;
diff --git a/Source/core/animation/DocumentTimeline.h b/Source/core/animation/DocumentTimeline.h
index c334bd6..09b8b2e 100644
--- a/Source/core/animation/DocumentTimeline.h
+++ b/Source/core/animation/DocumentTimeline.h
@@ -32,7 +32,7 @@
 #define DocumentTimeline_h
 
 #include "core/animation/AnimationEffect.h"
-#include "core/animation/Player.h"
+#include "core/animation/AnimationPlayer.h"
 #include "core/dom/Element.h"
 #include "core/events/Event.h"
 #include "platform/Timer.h"
@@ -61,14 +61,14 @@
 
     static PassRefPtr<DocumentTimeline> create(Document*, PassOwnPtr<PlatformTiming> = nullptr);
     ~DocumentTimeline();
-    // Returns whether style recalc was triggered.
-    bool serviceAnimations();
+
+    void serviceAnimations();
 
     // Creates a player attached to this timeline, but without a start time.
-    Player* createPlayer(TimedItem*);
-    Player* play(TimedItem*);
+    AnimationPlayer* createAnimationPlayer(TimedItem*);
+    AnimationPlayer* play(TimedItem*);
 
-    void playerDestroyed(Player* player)
+    void playerDestroyed(AnimationPlayer* player)
     {
         ASSERT(m_players.contains(player));
         m_players.remove(player);
@@ -78,22 +78,14 @@
     // performance.timing.domInteractive
     void setZeroTime(double);
     bool hasStarted() const { return !isNull(m_zeroTime); }
+    bool hasPendingUpdates() const { return !m_playersNeedingUpdate.isEmpty(); }
     double zeroTime() const { return m_zeroTime; }
     double currentTime();
     void pauseAnimationsForTesting(double);
     size_t numberOfActiveAnimationsForTesting() const;
-    const Vector<RefPtr<Player> >& currentPlayers() const { return m_currentPlayers; }
 
-    void setHasPlayerNeedingUpdate();
-    bool hasPlayerNeedingUpdate() const { return m_hasPlayerNeedingUpdate; }
-
-    void addEventToDispatch(EventTarget* target, PassRefPtr<Event> event)
-    {
-        m_events.append(EventToDispatch(target, event));
-    }
-
-    void dispatchEvents();
-    void dispatchEventsAsync();
+    void setOutdatedAnimationPlayer(AnimationPlayer*);
+    bool hasOutdatedAnimationPlayer() const { return m_hasOutdatedAnimationPlayer; }
 
     void detachFromDocument();
 
@@ -103,25 +95,15 @@
 private:
     double m_zeroTime;
     Document* m_document;
-    Timer<DocumentTimeline> m_eventDistpachTimer;
-    Vector<RefPtr<Player> > m_currentPlayers;
-    HashSet<Player*> m_players;
-    bool m_hasPlayerNeedingUpdate;
+    // AnimationPlayers which will be updated on the next frame
+    // i.e. current, in effect, or had timing changed
+    HashSet<RefPtr<AnimationPlayer> > m_playersNeedingUpdate;
+    HashSet<AnimationPlayer*> m_players;
+    bool m_hasOutdatedAnimationPlayer;
 
-    void eventDispatchTimerFired(Timer<DocumentTimeline>*);
     void wake();
 
-    struct EventToDispatch {
-        EventToDispatch(EventTarget* target, PassRefPtr<Event> event)
-            : target(target)
-            , event(event)
-        {
-        }
-        RefPtr<EventTarget> target;
-        RefPtr<Event> event;
-    };
-    Vector<EventToDispatch> m_events;
-
+    friend class SMILTimeContainer;
     static const double s_minimumDelay;
 
     OwnPtr<PlatformTiming> m_timing;
diff --git a/Source/core/animation/DocumentTimelineTest.cpp b/Source/core/animation/DocumentTimelineTest.cpp
index b3c850e..ed90062 100644
--- a/Source/core/animation/DocumentTimelineTest.cpp
+++ b/Source/core/animation/DocumentTimelineTest.cpp
@@ -132,7 +132,7 @@
 
 TEST_F(AnimationDocumentTimelineTest, EmptyKeyframeAnimation)
 {
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
     RefPtr<Animation> anim = Animation::create(element.get(), effect, timing);
 
     timeline->play(anim.get());
@@ -149,7 +149,7 @@
 
 TEST_F(AnimationDocumentTimelineTest, EmptyForwardsKeyframeAnimation)
 {
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
     timing.fillMode = Timing::FillModeForwards;
     RefPtr<Animation> anim = Animation::create(element.get(), effect, timing);
 
@@ -166,42 +166,6 @@
     EXPECT_FLOAT_EQ(100, timeline->currentTime());
 }
 
-TEST_F(AnimationDocumentTimelineTest, EmptyTimelineDoesNotTriggerStyleRecalc)
-{
-    document->animationClock().updateTime(100);
-    EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyPlayerDoesNotTriggerStyleRecalc)
-{
-    timeline->play(0);
-    document->animationClock().updateTime(100);
-    EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyTargetDoesNotTriggerStyleRecalc)
-{
-    timing.iterationDuration = 200;
-    timeline->play(Animation::create(0, KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing).get());
-    document->animationClock().updateTime(100);
-    EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, EmptyEffectDoesNotTriggerStyleRecalc)
-{
-    timeline->play(Animation::create(element.get(), 0, timing).get());
-    document->animationClock().updateTime(100);
-    EXPECT_FALSE(timeline->serviceAnimations());
-}
-
-TEST_F(AnimationDocumentTimelineTest, TriggerStyleRecalc)
-{
-    timing.iterationDuration = 200;
-    timeline->play(Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing).get());
-    document->animationClock().updateTime(100);
-    EXPECT_TRUE(timeline->serviceAnimations());
-}
-
 TEST_F(AnimationDocumentTimelineTest, ZeroTime)
 {
     timeline = DocumentTimeline::create(document.get());
@@ -226,8 +190,8 @@
     timing.fillMode = Timing::FillModeForwards;
     RefPtr<Animation> anim1 = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing);
     RefPtr<Animation> anim2  = Animation::create(element.get(), KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector()), timing);
-    Player* player1 = timeline->play(anim1.get());
-    Player* player2 = timeline->play(anim2.get());
+    AnimationPlayer* player1 = timeline->play(anim1.get());
+    AnimationPlayer* player2 = timeline->play(anim2.get());
     timeline->pauseAnimationsForTesting(seekTime);
 
     EXPECT_FLOAT_EQ(seekTime, player1->currentTime());
@@ -288,7 +252,7 @@
     timing.iterationDuration = 2;
     timing.startDelay = 5;
 
-    RefPtr<Animation> anim = Animation::create(element.get(), 0, timing);
+    RefPtr<Animation> anim = Animation::create(element.get(), nullptr, timing);
 
     timeline->play(anim.get());
 
@@ -311,18 +275,18 @@
     timing.iterationDuration = 2;
     timing.startDelay = 5;
 
-    timeline = document->timeline();
-    element = 0;
-    document = 0;
+    timeline = &document->timeline();
+    element = nullptr;
+    document = nullptr;
 
-    RefPtr<Animation> anim = Animation::create(0, 0, timing);
+    RefPtr<Animation> anim = Animation::create(nullptr, nullptr, timing);
     // Test passes if this does not crash.
     timeline->play(anim.get());
 }
 
-TEST_F(AnimationDocumentTimelineTest, UsePlayerAfterTimelineDeref)
+TEST_F(AnimationDocumentTimelineTest, UseAnimationPlayerAfterTimelineDeref)
 {
-    RefPtr<Player> player = timeline->createPlayer(0);
+    RefPtr<AnimationPlayer> player = timeline->createAnimationPlayer(0);
     timeline.clear();
     // Test passes if this does not crash.
     player->setStartTime(0);
diff --git a/Source/core/animation/EffectInput.cpp b/Source/core/animation/EffectInput.cpp
new file mode 100644
index 0000000..2f87c28
--- /dev/null
+++ b/Source/core/animation/EffectInput.cpp
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/animation/EffectInput.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/animation/AnimationHelpers.h"
+#include "core/animation/css/CSSAnimations.h"
+#include "core/css/parser/BisonCSSParser.h"
+#include "core/css/resolver/StyleResolver.h"
+#include "core/dom/Element.h"
+
+namespace WebCore {
+
+static bool checkDocumentAndRenderer(Element* element)
+{
+    if (!element->inActiveDocument())
+        return false;
+    element->document().updateStyleIfNeeded();
+    return element->renderer();
+}
+
+PassRefPtrWillBeRawPtr<AnimationEffect> EffectInput::convert(Element* element, const Vector<Dictionary>& keyframeDictionaryVector, bool unsafe)
+{
+    // FIXME: This test will not be neccessary once resolution of keyframe values occurs at
+    // animation application time.
+    if (!unsafe && !checkDocumentAndRenderer(element))
+        return nullptr;
+
+    // FIXME: Move this code into KeyframeEffectModel, it will be used by the IDL constructor for that class.
+    KeyframeEffectModel::KeyframeVector keyframes;
+    Vector<RefPtr<MutableStylePropertySet> > propertySetVector;
+
+    for (size_t i = 0; i < keyframeDictionaryVector.size(); ++i) {
+        RefPtr<MutableStylePropertySet> propertySet = MutableStylePropertySet::create();
+        propertySetVector.append(propertySet);
+
+        RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create();
+        keyframes.append(keyframe);
+
+        double offset;
+        if (keyframeDictionaryVector[i].get("offset", offset))
+            keyframe->setOffset(offset);
+
+        String compositeString;
+        keyframeDictionaryVector[i].get("composite", compositeString);
+        if (compositeString == "add")
+            keyframe->setComposite(AnimationEffect::CompositeAdd);
+
+        String timingFunctionString;
+        if (keyframeDictionaryVector[i].get("easing", timingFunctionString)) {
+            RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString);
+            if (timingFunctionValue)
+                keyframe->setEasing(CSSToStyleMap::animationTimingFunction(timingFunctionValue.get(), false));
+        }
+
+        Vector<String> keyframeProperties;
+        keyframeDictionaryVector[i].getOwnPropertyNames(keyframeProperties);
+
+        for (size_t j = 0; j < keyframeProperties.size(); ++j) {
+            String property = keyframeProperties[j];
+            CSSPropertyID id = camelCaseCSSPropertyNameToID(property);
+
+            // FIXME: There is no way to store invalid properties or invalid values
+            // in a Keyframe object, so for now I just skip over them. Eventually we
+            // will need to support getFrames(), which should return exactly the
+            // keyframes that were input through the API. We will add a layer to wrap
+            // KeyframeEffectModel, store input keyframes and implement getFrames.
+            if (id == CSSPropertyInvalid || !CSSAnimations::isAnimatableProperty(id))
+                continue;
+
+            String value;
+            keyframeDictionaryVector[i].get(property, value);
+            propertySet->setProperty(id, value);
+        }
+    }
+
+    // FIXME: Replace this with code that just parses, when that code is available.
+    return StyleResolver::createKeyframeEffectModel(*element, propertySetVector, keyframes);
+}
+
+} // namespace WebCore
diff --git a/Source/core/animation/EffectInput.h b/Source/core/animation/EffectInput.h
new file mode 100644
index 0000000..0d316f7
--- /dev/null
+++ b/Source/core/animation/EffectInput.h
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef EffectInput_h
+#define EffectInput_h
+
+#include "core/animation/AnimationEffect.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class AnimationEffect;
+class Dictionary;
+class Element;
+
+class EffectInput {
+public:
+    static PassRefPtrWillBeRawPtr<AnimationEffect> convert(Element*, const Vector<Dictionary>& keyframeDictionaryVector, bool unsafe = false);
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/animation/ElementAnimation.cpp b/Source/core/animation/ElementAnimation.cpp
deleted file mode 100644
index 24c7b7a..0000000
--- a/Source/core/animation/ElementAnimation.cpp
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/ElementAnimation.h"
-
-#include "bindings/v8/Dictionary.h"
-#include "core/animation/DocumentTimeline.h"
-#include "core/animation/css/CSSAnimations.h"
-
-namespace WebCore {
-
-Animation* ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector, Dictionary timingInput)
-{
-    ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
-
-    RefPtr<Animation> animation = Animation::create(element, keyframeDictionaryVector, timingInput);
-    DocumentTimeline* timeline = element->document().timeline();
-    ASSERT(timeline);
-    timeline->play(animation.get());
-
-    return animation.get();
-}
-
-Animation* ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector, double timingInput)
-{
-    ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
-
-    RefPtr<Animation> animation = Animation::create(element, keyframeDictionaryVector, timingInput);
-    DocumentTimeline* timeline = element->document().timeline();
-    ASSERT(timeline);
-    timeline->play(animation.get());
-
-    return animation.get();
-}
-
-Animation* ElementAnimation::animate(Element* element, Vector<Dictionary> keyframeDictionaryVector)
-{
-    ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
-
-    RefPtr<Animation> animation = Animation::create(element, keyframeDictionaryVector);
-    DocumentTimeline* timeline = element->document().timeline();
-    ASSERT(timeline);
-    timeline->play(animation.get());
-
-    return animation.get();
-}
-
-} // namespace WebCore
diff --git a/Source/core/animation/ElementAnimation.h b/Source/core/animation/ElementAnimation.h
index 66921a4..52ade2b 100644
--- a/Source/core/animation/ElementAnimation.h
+++ b/Source/core/animation/ElementAnimation.h
@@ -31,19 +31,56 @@
 #ifndef ElementAnimation_h
 #define ElementAnimation_h
 
-#include "wtf/Vector.h"
+#include "RuntimeEnabledFeatures.h"
+#include "core/animation/Animation.h"
+#include "core/animation/DocumentTimeline.h"
+#include "core/animation/EffectInput.h"
+#include "core/animation/TimingInput.h"
+#include "core/dom/Element.h"
 
 namespace WebCore {
 
-class Animation;
 class Dictionary;
-class Element;
 
 class ElementAnimation {
 public:
-    static Animation* animate(Element*, Vector<Dictionary> keyframesDictionaryVector, Dictionary timingInput);
-    static Animation* animate(Element*, Vector<Dictionary> keyframesDictionaryVector, double timingInput);
-    static Animation* animate(Element*, Vector<Dictionary> keyframesDictionaryVector);
+    static AnimationPlayer* animate(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Dictionary& timingInputDictionary)
+    {
+        return animateInternal(element, effect, TimingInput::convert(timingInputDictionary));
+    }
+
+    static AnimationPlayer* animate(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, double duration)
+    {
+        return animateInternal(element, effect, TimingInput::convert(duration));
+    }
+
+    static AnimationPlayer* animate(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect)
+    {
+        return animateInternal(element, effect, Timing());
+    }
+
+    static AnimationPlayer* animate(Element& element, const Vector<Dictionary>& keyframeDictionaryVector, const Dictionary& timingInputDictionary)
+    {
+        return animateInternal(element, EffectInput::convert(&element, keyframeDictionaryVector), TimingInput::convert(timingInputDictionary));
+    }
+
+    static AnimationPlayer* animate(Element& element, const Vector<Dictionary>& keyframeDictionaryVector, double duration)
+    {
+        return animateInternal(element, EffectInput::convert(&element, keyframeDictionaryVector), TimingInput::convert(duration));
+    }
+
+    static AnimationPlayer* animate(Element& element, const Vector<Dictionary>& keyframeDictionaryVector)
+    {
+        return animateInternal(element, EffectInput::convert(&element, keyframeDictionaryVector), Timing());
+    }
+
+private:
+    static AnimationPlayer* animateInternal(Element& element, PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing)
+    {
+        ASSERT(RuntimeEnabledFeatures::webAnimationsAPIEnabled());
+        RefPtr<Animation> animation = Animation::create(&element, effect, timing);
+        return element.document().timeline().play(animation.get());
+    }
 };
 
 } // namespace WebCore
diff --git a/Source/core/animation/ElementAnimation.idl b/Source/core/animation/ElementAnimation.idl
index e5c5137..d1c3c3e 100644
--- a/Source/core/animation/ElementAnimation.idl
+++ b/Source/core/animation/ElementAnimation.idl
@@ -31,7 +31,7 @@
 [
     RuntimeEnabled=WebAnimationsAPI,
 ] partial interface Element {
-    Animation animate(sequence<Dictionary> keyframes, Dictionary timingInput);
-    Animation animate(sequence<Dictionary> keyframes, double timingInput);
-    Animation animate(sequence<Dictionary> keyframes);
+    [MeasureAs=ElementAnimateKeyframeListEffectObjectTiming] AnimationPlayer animate(sequence<Dictionary> keyframes, Dictionary timingInput);
+    [MeasureAs=ElementAnimateKeyframeListEffectDoubleTiming] AnimationPlayer animate(sequence<Dictionary> keyframes, double timingInput);
+    [MeasureAs=ElementAnimateKeyframeListEffectNoTiming] AnimationPlayer animate(sequence<Dictionary> keyframes);
 };
diff --git a/Source/core/animation/InertAnimation.cpp b/Source/core/animation/InertAnimation.cpp
index 7343523..18a922b 100644
--- a/Source/core/animation/InertAnimation.cpp
+++ b/Source/core/animation/InertAnimation.cpp
@@ -33,12 +33,12 @@
 
 namespace WebCore {
 
-PassRefPtr<InertAnimation> InertAnimation::create(PassRefPtr<AnimationEffect> effect, const Timing& timing, bool paused)
+PassRefPtr<InertAnimation> InertAnimation::create(PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, bool paused)
 {
     return adoptRef(new InertAnimation(effect, timing, paused));
 }
 
-InertAnimation::InertAnimation(PassRefPtr<AnimationEffect> effect, const Timing& timing, bool paused)
+InertAnimation::InertAnimation(PassRefPtrWillBeRawPtr<AnimationEffect> effect, const Timing& timing, bool paused)
     : TimedItem(timing)
     , m_effect(effect)
     , m_paused(paused)
diff --git a/Source/core/animation/InertAnimation.h b/Source/core/animation/InertAnimation.h
index 7b220a5..49a91a6 100644
--- a/Source/core/animation/InertAnimation.h
+++ b/Source/core/animation/InertAnimation.h
@@ -40,19 +40,19 @@
 class InertAnimation FINAL : public TimedItem {
 
 public:
-    static PassRefPtr<InertAnimation> create(PassRefPtr<AnimationEffect>, const Timing&, bool paused);
+    static PassRefPtr<InertAnimation> create(PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, bool paused);
     PassOwnPtr<AnimationEffect::CompositableValueList> sample();
     AnimationEffect* effect() const { return m_effect.get(); }
     bool paused() const { return m_paused; }
 
 protected:
-    virtual bool updateChildrenAndEffects() const OVERRIDE { return false; }
+    virtual void updateChildrenAndEffects() const OVERRIDE { }
     virtual void willDetach() OVERRIDE { }
     virtual double calculateTimeToEffectChange(bool forwards, double inheritedTime, double timeToNextIteration) const OVERRIDE;
 
 private:
-    InertAnimation(PassRefPtr<AnimationEffect>, const Timing&, bool paused);
-    RefPtr<AnimationEffect> m_effect;
+    InertAnimation(PassRefPtrWillBeRawPtr<AnimationEffect>, const Timing&, bool paused);
+    RefPtrWillBePersistent<AnimationEffect> m_effect;
     bool m_paused;
 };
 
diff --git a/Source/core/animation/InterpolableValue.cpp b/Source/core/animation/InterpolableValue.cpp
new file mode 100644
index 0000000..03f4b20
--- /dev/null
+++ b/Source/core/animation/InterpolableValue.cpp
@@ -0,0 +1,59 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolableValue.h"
+
+namespace WebCore {
+
+PassOwnPtr<InterpolableValue> InterpolableNumber::interpolate(const InterpolableValue &to, const double progress) const
+{
+    const InterpolableNumber* toNumber = toInterpolableNumber(&to);
+    if (!progress)
+        return create(m_value);
+    if (progress == 1)
+        return create(toNumber->m_value);
+    return create(m_value * (1 - progress) + toNumber->m_value * progress);
+}
+
+PassOwnPtr<InterpolableValue> InterpolableBool::interpolate(const InterpolableValue &to, const double progress) const
+{
+    if (progress < 0.5) {
+        return clone();
+    }
+    return to.clone();
+}
+
+PassOwnPtr<InterpolableValue> InterpolableList::interpolate(const InterpolableValue &to, const double progress) const
+{
+    const InterpolableList* toList = toInterpolableList(&to);
+    ASSERT(toList->m_size == m_size);
+
+    if (!progress) {
+        return create(*this);
+    }
+    if (progress == 1) {
+        return InterpolableList::create(*toList);
+    }
+
+    OwnPtr<InterpolableList> result = create(m_size);
+    for (size_t i = 0; i < m_size; i++) {
+        ASSERT(m_values.get()[i]);
+        ASSERT(toList->m_values.get()[i]);
+        result->set(i, m_values.get()[i]->interpolate(*(toList->m_values.get()[i]), progress));
+    }
+    return result.release();
+}
+
+PassOwnPtr<InterpolableValue> InterpolableAnimatableValue::interpolate(const InterpolableValue &other, const double percentage) const
+{
+    const InterpolableAnimatableValue *otherValue = toInterpolableAnimatableValue(&other);
+    if (!percentage)
+        return create(m_value);
+    if (percentage == 1)
+        return create(otherValue->m_value);
+    return create(AnimatableValue::interpolate(m_value.get(), otherValue->m_value.get(), percentage));
+}
+
+}
diff --git a/Source/core/animation/InterpolableValue.h b/Source/core/animation/InterpolableValue.h
new file mode 100644
index 0000000..b54a32a
--- /dev/null
+++ b/Source/core/animation/InterpolableValue.h
@@ -0,0 +1,152 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef InterpolableValue_h
+#define InterpolableValue_h
+
+#include "core/animation/AnimatableValue.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace WebCore {
+
+class InterpolableValue {
+public:
+    virtual bool isNumber() const { return false; }
+    virtual bool isBool() const { return false; }
+    virtual bool isList() const { return false; }
+    virtual bool isAnimatableValue() const { return false; }
+
+    virtual ~InterpolableValue() { }
+    virtual PassOwnPtr<InterpolableValue> clone() const = 0;
+
+private:
+    virtual PassOwnPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const = 0;
+
+    friend class Interpolation;
+
+    // Keep interpolate private, but allow calls within the hierarchy without
+    // knowledge of type.
+    friend class InterpolableNumber;
+    friend class InterpolableBool;
+    friend class InterpolableList;
+};
+
+class InterpolableNumber : public InterpolableValue {
+public:
+    static PassOwnPtr<InterpolableNumber> create(double value)
+    {
+        return adoptPtr(new InterpolableNumber(value));
+    }
+
+    virtual bool isNumber() const OVERRIDE FINAL { return true; }
+    double value() const { return m_value; }
+    virtual PassOwnPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
+
+private:
+    virtual PassOwnPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
+    double m_value;
+
+    InterpolableNumber(double value)
+        : m_value(value)
+    { }
+
+};
+
+class InterpolableBool : public InterpolableValue {
+public:
+    static PassOwnPtr<InterpolableBool> create(bool value)
+    {
+        return adoptPtr(new InterpolableBool(value));
+    }
+
+    virtual bool isBool() const OVERRIDE FINAL { return true; }
+    bool value() const { return m_value; }
+    virtual PassOwnPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
+
+private:
+    virtual PassOwnPtr<InterpolableValue> interpolate(const InterpolableValue &to, const double progress) const OVERRIDE FINAL;
+    bool m_value;
+
+    InterpolableBool(bool value)
+        : m_value(value)
+    { }
+
+};
+
+class InterpolableList : public InterpolableValue {
+public:
+    static PassOwnPtr<InterpolableList> create(const InterpolableList &other)
+    {
+        return adoptPtr(new InterpolableList(other));
+    }
+
+    static PassOwnPtr<InterpolableList> create(size_t size)
+    {
+        return adoptPtr(new InterpolableList(size));
+    }
+
+    virtual bool isList() const OVERRIDE FINAL { return true; }
+    void set(size_t position, PassOwnPtr<InterpolableValue> value)
+    {
+        ASSERT(position < m_size);
+        m_values.get()[position] = value;
+    }
+    const InterpolableValue* get(size_t position) const
+    {
+        ASSERT(position < m_size);
+        return m_values.get()[position].get();
+    }
+    size_t length() const { return m_size; }
+    virtual PassOwnPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(*this); }
+
+private:
+    virtual PassOwnPtr<InterpolableValue> interpolate(const InterpolableValue &other, const double progress) const OVERRIDE FINAL;
+    InterpolableList(size_t size)
+        : m_size(size)
+    {
+        m_values = adoptArrayPtr(new OwnPtr<InterpolableValue>[size]);
+    }
+
+    InterpolableList(const InterpolableList& other)
+        : m_size(other.m_size)
+    {
+        m_values = adoptArrayPtr(new OwnPtr<InterpolableValue>[m_size]);
+        for (size_t i = 0; i < m_size; i++)
+            set(i, other.m_values.get()[i]->clone());
+    }
+
+    size_t m_size;
+    OwnPtr<OwnPtr<InterpolableValue>[]> m_values;
+};
+
+// FIXME: Remove this when we can.
+class InterpolableAnimatableValue : public InterpolableValue {
+public:
+    static PassOwnPtr<InterpolableAnimatableValue> create(PassRefPtr<AnimatableValue> value)
+    {
+        return adoptPtr(new InterpolableAnimatableValue(value));
+    }
+
+    virtual bool isAnimatableValue() const OVERRIDE FINAL { return true; }
+    AnimatableValue* value() const { return m_value.get(); }
+    virtual PassOwnPtr<InterpolableValue> clone() const OVERRIDE FINAL { return create(m_value); }
+
+private:
+    virtual PassOwnPtr<InterpolableValue> interpolate(const InterpolableValue &other, const double progress) const OVERRIDE FINAL;
+    RefPtr<AnimatableValue> m_value;
+
+    InterpolableAnimatableValue(PassRefPtr<AnimatableValue> value)
+        : m_value(value)
+    { }
+};
+
+DEFINE_TYPE_CASTS(InterpolableNumber, InterpolableValue, value, value->isNumber(), value.isNumber());
+DEFINE_TYPE_CASTS(InterpolableBool, InterpolableValue, value, value->isBool(), value.isBool());
+DEFINE_TYPE_CASTS(InterpolableList, InterpolableValue, value, value->isList(), value.isList());
+DEFINE_TYPE_CASTS(InterpolableAnimatableValue, InterpolableValue, value, value->isAnimatableValue(), value.isAnimatableValue());
+
+}
+
+#endif
diff --git a/Source/core/animation/InterpolableValueTest.cpp b/Source/core/animation/InterpolableValueTest.cpp
new file mode 100644
index 0000000..b4dcd21
--- /dev/null
+++ b/Source/core/animation/InterpolableValueTest.cpp
@@ -0,0 +1,105 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolableValue.h"
+
+#include "core/animation/Interpolation.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class AnimationInterpolableValueTest : public ::testing::Test {
+protected:
+    InterpolableValue* interpolationValue(Interpolation& interpolation)
+    {
+        return interpolation.getCachedValueForTesting();
+    }
+
+    double interpolateNumbers(double a, double b, double progress)
+    {
+        RefPtr<Interpolation> i = Interpolation::create(InterpolableNumber::create(a), InterpolableNumber::create(b));
+        i->interpolate(0, progress);
+        return toInterpolableNumber(interpolationValue(*i.get()))->value();
+    }
+
+    bool interpolateBools(bool a, bool b, double progress)
+    {
+        RefPtr<Interpolation> i = Interpolation::create(InterpolableBool::create(a), InterpolableBool::create(b));
+        i->interpolate(0, progress);
+        return toInterpolableBool(interpolationValue(*i.get()))->value();
+    }
+
+    PassRefPtr<Interpolation> interpolateLists(PassOwnPtr<InterpolableList> listA, PassOwnPtr<InterpolableList> listB, double progress)
+    {
+        RefPtr<Interpolation> i = Interpolation::create(listA, listB);
+        i->interpolate(0, progress);
+        return i;
+    }
+};
+
+TEST_F(AnimationInterpolableValueTest, InterpolateNumbers)
+{
+    EXPECT_FLOAT_EQ(126, interpolateNumbers(42, 0, -2));
+    EXPECT_FLOAT_EQ(42, interpolateNumbers(42, 0, 0));
+    EXPECT_FLOAT_EQ(29.4f, interpolateNumbers(42, 0, 0.3));
+    EXPECT_FLOAT_EQ(21, interpolateNumbers(42, 0, 0.5));
+    EXPECT_FLOAT_EQ(0, interpolateNumbers(42, 0, 1));
+    EXPECT_FLOAT_EQ(-21, interpolateNumbers(42, 0, 1.5));
+}
+
+TEST_F(AnimationInterpolableValueTest, InterpolateBools)
+{
+    EXPECT_FALSE(interpolateBools(false, true, -1));
+    EXPECT_FALSE(interpolateBools(false, true, 0));
+    EXPECT_FALSE(interpolateBools(false, true, 0.3));
+    EXPECT_TRUE(interpolateBools(false, true, 0.5));
+    EXPECT_TRUE(interpolateBools(false, true, 1));
+    EXPECT_TRUE(interpolateBools(false, true, 2));
+}
+
+TEST_F(AnimationInterpolableValueTest, SimpleList)
+{
+    OwnPtr<InterpolableList> listA = InterpolableList::create(3);
+    listA->set(0, InterpolableNumber::create(0));
+    listA->set(1, InterpolableNumber::create(42));
+    listA->set(2, InterpolableNumber::create(20.5));
+
+    OwnPtr<InterpolableList> listB = InterpolableList::create(3);
+    listB->set(0, InterpolableNumber::create(100));
+    listB->set(1, InterpolableNumber::create(-200));
+    listB->set(2, InterpolableNumber::create(300));
+
+    RefPtr<Interpolation> i = interpolateLists(listA.release(), listB.release(), 0.3);
+    InterpolableList* outList = toInterpolableList(interpolationValue(*i.get()));
+    EXPECT_FLOAT_EQ(30, toInterpolableNumber(outList->get(0))->value());
+    EXPECT_FLOAT_EQ(-30.6f, toInterpolableNumber(outList->get(1))->value());
+    EXPECT_FLOAT_EQ(104.35f, toInterpolableNumber(outList->get(2))->value());
+}
+
+TEST_F(AnimationInterpolableValueTest, NestedList)
+{
+    OwnPtr<InterpolableList> listA = InterpolableList::create(3);
+    listA->set(0, InterpolableNumber::create(0));
+    OwnPtr<InterpolableList> subListA = InterpolableList::create(1);
+    subListA->set(0, InterpolableNumber::create(100));
+    listA->set(1, subListA.release());
+    listA->set(2, InterpolableBool::create(false));
+
+    OwnPtr<InterpolableList> listB = InterpolableList::create(3);
+    listB->set(0, InterpolableNumber::create(100));
+    OwnPtr<InterpolableList> subListB = InterpolableList::create(1);
+    subListB->set(0, InterpolableNumber::create(50));
+    listB->set(1, subListB.release());
+    listB->set(2, InterpolableBool::create(true));
+
+    RefPtr<Interpolation> i = interpolateLists(listA.release(), listB.release(), 0.5);
+    InterpolableList* outList = toInterpolableList(interpolationValue(*i.get()));
+    EXPECT_FLOAT_EQ(50, toInterpolableNumber(outList->get(0))->value());
+    EXPECT_FLOAT_EQ(75, toInterpolableNumber(toInterpolableList(outList->get(1))->get(0))->value());
+    EXPECT_TRUE(toInterpolableBool(outList->get(2))->value());
+}
+
+}
diff --git a/Source/core/animation/Interpolation.cpp b/Source/core/animation/Interpolation.cpp
new file mode 100644
index 0000000..b552e0f
--- /dev/null
+++ b/Source/core/animation/Interpolation.cpp
@@ -0,0 +1,52 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/Interpolation.h"
+
+namespace WebCore {
+
+namespace {
+
+bool typesMatch(const InterpolableValue* start, const InterpolableValue* end)
+{
+    if (start->isNumber())
+        return end->isNumber();
+    if (start->isBool())
+        return end->isBool();
+    if (!(start->isList() && end->isList()))
+        return false;
+    const InterpolableList* startList = toInterpolableList(start);
+    const InterpolableList* endList = toInterpolableList(end);
+    if (startList->length() != endList->length())
+        return false;
+    for (size_t i = 0; i < startList->length(); ++i) {
+        if (!typesMatch(startList->get(i), endList->get(i)))
+            return false;
+    }
+    return true;
+}
+
+}
+
+Interpolation::Interpolation(PassOwnPtr<InterpolableValue> start, PassOwnPtr<InterpolableValue> end)
+    : m_start(start)
+    , m_end(end)
+    , m_cachedFraction(0)
+    , m_cachedIteration(0)
+    , m_cachedValue(m_start->clone())
+{
+    RELEASE_ASSERT(typesMatch(m_start.get(), m_end.get()));
+}
+
+void Interpolation::interpolate(int iteration, double fraction) const
+{
+    if (m_cachedFraction != fraction || m_cachedIteration != iteration) {
+        m_cachedValue = m_start->interpolate(*m_end, fraction);
+        m_cachedIteration = iteration;
+        m_cachedFraction = fraction;
+    }
+}
+
+}
diff --git a/Source/core/animation/Interpolation.h b/Source/core/animation/Interpolation.h
new file mode 100644
index 0000000..206dab0
--- /dev/null
+++ b/Source/core/animation/Interpolation.h
@@ -0,0 +1,60 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef Interpolation_h
+#define Interpolation_h
+
+#include "core/animation/InterpolableValue.h"
+#include "core/css/resolver/StyleResolverState.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class Interpolation : public RefCounted<Interpolation> {
+public:
+    static PassRefPtr<Interpolation> create(PassOwnPtr<InterpolableValue> start, PassOwnPtr<InterpolableValue> end)
+    {
+        return adoptRef(new Interpolation(start, end));
+    }
+
+    void interpolate(int iteration, double fraction) const;
+
+protected:
+    const OwnPtr<InterpolableValue> m_start;
+    const OwnPtr<InterpolableValue> m_end;
+
+    mutable double m_cachedFraction;
+    mutable int m_cachedIteration;
+    mutable OwnPtr<InterpolableValue> m_cachedValue;
+
+    Interpolation(PassOwnPtr<InterpolableValue> start, PassOwnPtr<InterpolableValue> end);
+
+private:
+    InterpolableValue* getCachedValueForTesting() const { return m_cachedValue.get(); }
+
+    friend class AnimationInterpolableValueTest;
+    friend class AnimationInterpolationEffectTest;
+};
+
+class StyleInterpolation : public Interpolation {
+public:
+    // 1) convert m_cachedValue into an X
+    // 2) shove X into StyleResolverState
+    // X can be:
+    // (1) a CSSValue (and applied via StyleBuilder::applyProperty)
+    // (2) an AnimatableValue (and applied via // AnimatedStyleBuilder::applyProperty)
+    // (3) a custom value that is inserted directly into the StyleResolverState.
+    virtual void apply(StyleResolverState&) = 0;
+
+protected:
+    CSSPropertyID m_id;
+
+    StyleInterpolation(PassOwnPtr<InterpolableValue> start, PassOwnPtr<InterpolableValue> end, CSSPropertyID id)
+        : Interpolation(start, end)
+        , m_id(id)
+    { }
+};
+
+}
+#endif
diff --git a/Source/core/animation/InterpolationEffect.cpp b/Source/core/animation/InterpolationEffect.cpp
new file mode 100644
index 0000000..579e9c5
--- /dev/null
+++ b/Source/core/animation/InterpolationEffect.cpp
@@ -0,0 +1,34 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolationEffect.h"
+
+namespace WebCore {
+
+namespace {
+    const double accuracyForKeyframeEasing = 0.0000001;
+}
+
+PassOwnPtr<Vector<RefPtr<Interpolation> > > InterpolationEffect::getActiveInterpolations(double fraction) const
+{
+
+    Vector<RefPtr<Interpolation> >* result = new Vector<RefPtr<Interpolation> >();
+
+    for (size_t i = 0; i < m_interpolations.size(); ++i) {
+        const InterpolationRecord* record = m_interpolations[i].get();
+        if (fraction >= record->m_applyFrom && fraction < record->m_applyTo) {
+            RefPtr<Interpolation> interpolation = record->m_interpolation;
+            double localFraction = (fraction - record->m_start) / (record->m_end - record->m_start);
+            if (record->m_easing)
+                localFraction = record->m_easing->evaluate(localFraction, accuracyForKeyframeEasing);
+            interpolation->interpolate(0, localFraction);
+            result->append(interpolation);
+        }
+    }
+
+    return adoptPtr(result);
+}
+
+}
diff --git a/Source/core/animation/InterpolationEffect.h b/Source/core/animation/InterpolationEffect.h
new file mode 100644
index 0000000..ace3aae
--- /dev/null
+++ b/Source/core/animation/InterpolationEffect.h
@@ -0,0 +1,60 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef InterpolationEffect_h
+#define InterpolationEffect_h
+
+#include "core/animation/Interpolation.h"
+#include "platform/animation/TimingFunction.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/RefCounted.h"
+
+
+namespace WebCore {
+
+class InterpolationEffect : public RefCounted<InterpolationEffect> {
+
+public:
+    static PassRefPtr<InterpolationEffect> create() { return adoptRef(new InterpolationEffect()); }
+
+    PassOwnPtr<Vector<RefPtr<Interpolation> > > getActiveInterpolations(double fraction) const;
+
+    void addInterpolation(PassRefPtr<Interpolation> interpolation, PassRefPtr<TimingFunction> easing, double start, double end, double applyFrom, double applyTo)
+    {
+        m_interpolations.append(InterpolationRecord::create(interpolation, easing, start, end, applyFrom, applyTo));
+    }
+
+private:
+    InterpolationEffect()
+    { }
+
+    class InterpolationRecord {
+    public:
+        RefPtr<Interpolation> m_interpolation;
+        RefPtr<TimingFunction> m_easing;
+        double m_start;
+        double m_end;
+        double m_applyFrom;
+        double m_applyTo;
+        static PassOwnPtr<InterpolationRecord> create(PassRefPtr<Interpolation> interpolation, PassRefPtr<TimingFunction> easing, double start, double end, double applyFrom, double applyTo)
+        {
+            return adoptPtr(new InterpolationRecord(interpolation, easing, start, end, applyFrom, applyTo));
+        }
+    private:
+        InterpolationRecord(PassRefPtr<Interpolation> interpolation, PassRefPtr<TimingFunction> easing, double start, double end, double applyFrom, double applyTo)
+            : m_interpolation(interpolation)
+            , m_easing(easing)
+            , m_start(start)
+            , m_end(end)
+            , m_applyFrom(applyFrom)
+            , m_applyTo(applyTo)
+        { }
+    };
+
+    Vector<OwnPtr<InterpolationRecord> > m_interpolations;
+};
+
+}
+
+#endif
diff --git a/Source/core/animation/InterpolationEffectTest.cpp b/Source/core/animation/InterpolationEffectTest.cpp
new file mode 100644
index 0000000..22a70b7
--- /dev/null
+++ b/Source/core/animation/InterpolationEffectTest.cpp
@@ -0,0 +1,87 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/InterpolationEffect.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class AnimationInterpolationEffectTest : public ::testing::Test {
+protected:
+    InterpolableValue* interpolationValue(Interpolation& interpolation)
+    {
+        return interpolation.getCachedValueForTesting();
+    }
+
+    double getInterpolableNumber(PassRefPtr<Interpolation> value)
+    {
+        return toInterpolableNumber(interpolationValue(*value.get()))->value();
+    }
+};
+
+TEST_F(AnimationInterpolationEffectTest, SingleInterpolation)
+{
+    RefPtr<InterpolationEffect> interpolationEffect = InterpolationEffect::create();
+    interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(0), InterpolableNumber::create(10)),
+        RefPtr<TimingFunction>(), 0, 1, -1, 2);
+
+    OwnPtr<Vector<RefPtr<Interpolation> > > activeInterpolations = interpolationEffect->getActiveInterpolations(-2);
+    EXPECT_EQ(0ul, activeInterpolations->size());
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(-0.5);
+    EXPECT_EQ(1ul, activeInterpolations->size());
+    EXPECT_EQ(-5, getInterpolableNumber(activeInterpolations->at(0)));
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(0.5);
+    EXPECT_EQ(1ul, activeInterpolations->size());
+    EXPECT_FLOAT_EQ(5, getInterpolableNumber(activeInterpolations->at(0)));
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(1.5);
+    EXPECT_EQ(1ul, activeInterpolations->size());
+    EXPECT_FLOAT_EQ(15, getInterpolableNumber(activeInterpolations->at(0)));
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(3);
+    EXPECT_EQ(0ul, activeInterpolations->size());
+}
+
+TEST_F(AnimationInterpolationEffectTest, MultipleInterpolations)
+{
+    RefPtr<InterpolationEffect> interpolationEffect = InterpolationEffect::create();
+    interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(10), InterpolableNumber::create(15)),
+        RefPtr<TimingFunction>(), 1, 2, 1, 3);
+    interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(0), InterpolableNumber::create(1)),
+        LinearTimingFunction::preset(), 0, 1, 0, 1);
+    interpolationEffect->addInterpolation(Interpolation::create(InterpolableNumber::create(1), InterpolableNumber::create(6)),
+        CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease), 0.5, 1.5, 0.5, 1.5);
+
+    OwnPtr<Vector<RefPtr<Interpolation> > > activeInterpolations = interpolationEffect->getActiveInterpolations(-0.5);
+    EXPECT_EQ(0ul, activeInterpolations->size());
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(0);
+    EXPECT_EQ(1ul, activeInterpolations->size());
+    EXPECT_FLOAT_EQ(0, getInterpolableNumber(activeInterpolations->at(0)));
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(0.5);
+    EXPECT_EQ(2ul, activeInterpolations->size());
+    EXPECT_FLOAT_EQ(0.5f, getInterpolableNumber(activeInterpolations->at(0)));
+    EXPECT_FLOAT_EQ(1, getInterpolableNumber(activeInterpolations->at(1)));
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(1);
+    EXPECT_EQ(2ul, activeInterpolations->size());
+    EXPECT_FLOAT_EQ(10, getInterpolableNumber(activeInterpolations->at(0)));
+    EXPECT_FLOAT_EQ(5.0120168f, getInterpolableNumber(activeInterpolations->at(1)));
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(1.5);
+    EXPECT_EQ(1ul, activeInterpolations->size());
+    EXPECT_FLOAT_EQ(12.5f, getInterpolableNumber(activeInterpolations->at(0)));
+
+    activeInterpolations = interpolationEffect->getActiveInterpolations(2);
+    EXPECT_EQ(1ul, activeInterpolations->size());
+    EXPECT_FLOAT_EQ(15, getInterpolableNumber(activeInterpolations->at(0)));
+}
+
+}
+
diff --git a/Source/core/animation/KeyframeEffectModel.cpp b/Source/core/animation/KeyframeEffectModel.cpp
index 82afcfa..aec264d 100644
--- a/Source/core/animation/KeyframeEffectModel.cpp
+++ b/Source/core/animation/KeyframeEffectModel.cpp
@@ -97,6 +97,7 @@
 Keyframe::Keyframe()
     : m_offset(nullValue())
     , m_composite(AnimationEffect::CompositeReplace)
+    , m_easing(LinearTimingFunction::preset())
 { }
 
 Keyframe::Keyframe(const Keyframe& copyFrom)
@@ -104,10 +105,17 @@
     , m_composite(copyFrom.m_composite)
     , m_easing(copyFrom.m_easing)
 {
+    ASSERT(m_easing);
     for (PropertyValueMap::const_iterator iter = copyFrom.m_propertyValues.begin(); iter != copyFrom.m_propertyValues.end(); ++iter)
         setPropertyValue(iter->key, iter->value.get());
 }
 
+void Keyframe::setEasing(PassRefPtr<TimingFunction> easing)
+{
+    ASSERT(easing);
+    m_easing = easing;
+}
+
 void Keyframe::setPropertyValue(CSSPropertyID property, const AnimatableValue* value)
 {
     m_propertyValues.add(property, const_cast<AnimatableValue*>(value));
@@ -134,9 +142,9 @@
     return properties;
 }
 
-PassRefPtr<Keyframe> Keyframe::cloneWithOffset(double offset) const
+PassRefPtrWillBeRawPtr<Keyframe> Keyframe::cloneWithOffset(double offset) const
 {
-    RefPtr<Keyframe> theClone = clone();
+    RefPtrWillBeRawPtr<Keyframe> theClone = clone();
     theClone->setOffset(offset);
     return theClone.release();
 }
@@ -334,7 +342,7 @@
     if (!offset)
         appendKeyframe(m_keyframes.first()->cloneWithOffset(1.0));
     else
-        m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, 0, AnimatableValue::neutralValue(), CompositeAdd)));
+        m_keyframes.insert(0, adoptPtr(new PropertySpecificKeyframe(0.0, nullptr, AnimatableValue::neutralValue(), CompositeAdd)));
 }
 
 PassRefPtr<AnimationEffect::CompositableValue> KeyframeEffectModel::PropertySpecificKeyframeGroup::sample(int iteration, double offset) const
@@ -389,4 +397,9 @@
     return BlendedCompositableValue::create((*before)->value(), (*after)->value(), fraction);
 }
 
+void KeyframeEffectModel::trace(Visitor* visitor)
+{
+    visitor->trace(m_keyframes);
+}
+
 } // namespace
diff --git a/Source/core/animation/KeyframeEffectModel.h b/Source/core/animation/KeyframeEffectModel.h
index 78359d4..9e896f5 100644
--- a/Source/core/animation/KeyframeEffectModel.h
+++ b/Source/core/animation/KeyframeEffectModel.h
@@ -33,6 +33,7 @@
 
 #include "core/animation/AnimatableValue.h"
 #include "core/animation/AnimationEffect.h"
+#include "heap/Handle.h"
 #include "platform/animation/TimingFunction.h"
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
@@ -48,13 +49,13 @@
 class KeyframeEffectModelTest;
 
 // Represents the keyframes set through the API.
-class Keyframe : public RefCounted<Keyframe> {
+class Keyframe : public RefCountedWillBeGarbageCollectedFinalized<Keyframe> {
 public:
-    static PassRefPtr<Keyframe> create()
+    static PassRefPtrWillBeRawPtr<Keyframe> create()
     {
-        return adoptRef(new Keyframe);
+        return adoptRefWillBeNoop(new Keyframe);
     }
-    static bool compareOffsets(const RefPtr<Keyframe>& a, const RefPtr<Keyframe>& b)
+    static bool compareOffsets(const RefPtrWillBeRawPtr<Keyframe>& a, const RefPtrWillBeRawPtr<Keyframe>& b)
     {
         return a->offset() < b->offset();
     }
@@ -62,14 +63,16 @@
     double offset() const { return m_offset; }
     void setComposite(AnimationEffect::CompositeOperation composite) { m_composite = composite; }
     AnimationEffect::CompositeOperation composite() const { return m_composite; }
-    void setEasing(PassRefPtr<TimingFunction> easing) { m_easing = easing; }
+    void setEasing(PassRefPtr<TimingFunction>);
     TimingFunction* easing() const { return m_easing.get(); }
     void setPropertyValue(CSSPropertyID, const AnimatableValue*);
     void clearPropertyValue(CSSPropertyID);
     const AnimatableValue* propertyValue(CSSPropertyID) const;
     PropertySet properties() const;
-    PassRefPtr<Keyframe> clone() const { return adoptRef(new Keyframe(*this)); }
-    PassRefPtr<Keyframe> cloneWithOffset(double offset) const;
+    PassRefPtrWillBeRawPtr<Keyframe> clone() const { return adoptRefWillBeNoop(new Keyframe(*this)); }
+    PassRefPtrWillBeRawPtr<Keyframe> cloneWithOffset(double offset) const;
+
+    void trace(Visitor*) { }
 private:
     Keyframe();
     Keyframe(const Keyframe&);
@@ -83,12 +86,12 @@
 class KeyframeEffectModel FINAL : public AnimationEffect {
 public:
     class PropertySpecificKeyframe;
-    typedef Vector<RefPtr<Keyframe> > KeyframeVector;
+    typedef WillBeHeapVector<RefPtrWillBeMember<Keyframe> > KeyframeVector;
     typedef Vector<OwnPtr<PropertySpecificKeyframe> > PropertySpecificKeyframeVector;
     // FIXME: Implement accumulation.
-    static PassRefPtr<KeyframeEffectModel> create(const KeyframeVector& keyframes)
+    static PassRefPtrWillBeRawPtr<KeyframeEffectModel> create(const KeyframeVector& keyframes)
     {
-        return adoptRef(new KeyframeEffectModel(keyframes));
+        return adoptRefWillBeNoop(new KeyframeEffectModel(keyframes));
     }
 
     virtual bool affects(CSSPropertyID property) OVERRIDE
@@ -141,6 +144,8 @@
         return m_keyframeGroups->get(id)->keyframes();
     }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     KeyframeEffectModel(const KeyframeVector& keyframes);
 
diff --git a/Source/core/animation/KeyframeEffectModelTest.cpp b/Source/core/animation/KeyframeEffectModelTest.cpp
index 75a6b21..0eabb5b 100644
--- a/Source/core/animation/KeyframeEffectModelTest.cpp
+++ b/Source/core/animation/KeyframeEffectModelTest.cpp
@@ -42,25 +42,25 @@
 
 namespace {
 
-AnimatableValue* unknownAnimatableValue(double n)
+PassRefPtr<AnimatableValue> unknownAnimatableValue(double n)
 {
-    return AnimatableUnknown::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_UNKNOWN).get()).leakRef();
+    return AnimatableUnknown::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_UNKNOWN).get());
 }
 
-AnimatableValue* pixelAnimatableValue(double n)
+PassRefPtr<AnimatableValue> pixelAnimatableValue(double n)
 {
-    return AnimatableLength::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_PX).get()).leakRef();
+    return AnimatableLength::create(CSSPrimitiveValue::create(n, CSSPrimitiveValue::CSS_PX).get());
 }
 
-KeyframeEffectModel::KeyframeVector keyframesAtZeroAndOne(AnimatableValue* zeroValue, AnimatableValue* oneValue)
+KeyframeEffectModel::KeyframeVector keyframesAtZeroAndOne(PassRefPtr<AnimatableValue> zeroValue, PassRefPtr<AnimatableValue> oneValue)
 {
     KeyframeEffectModel::KeyframeVector keyframes(2);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, zeroValue);
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, zeroValue.get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(1.0);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, oneValue);
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, oneValue.get());
     return keyframes;
 }
 
@@ -91,11 +91,11 @@
 TEST(AnimationKeyframeEffectModel, BasicOperation)
 {
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
     OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
     ASSERT_EQ(1UL, values->size());
     EXPECT_EQ(CSSPropertyLeft, values->at(0).first);
-    expectDoubleValue(5.0, values->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    expectDoubleValue(5.0, values->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, CompositeReplaceNonInterpolable)
@@ -103,8 +103,8 @@
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
     keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
     keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, CompositeReplace)
@@ -112,8 +112,8 @@
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
     keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
     keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(3.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(3.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, CompositeAdd)
@@ -121,48 +121,48 @@
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
     keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
     keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, CompositeEaseIn)
 {
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
-    RefPtr<CSSValue> timingFunction = BisonCSSParser::parseAnimationTimingFunctionValue("ease-in");
+    RefPtrWillBeRawPtr<CSSValue> timingFunction = BisonCSSParser::parseAnimationTimingFunctionValue("ease-in");
     keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
     keyframes[0]->setEasing(CSSToStyleMap::animationTimingFunction(timingFunction.get(), false));
     keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(3.8582394, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(3.8582394, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, CompositeCubicBezier)
 {
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
-    RefPtr<CSSValue> timingFunction = BisonCSSParser::parseAnimationTimingFunctionValue("cubic-bezier(0.42, 0, 0.58, 1)");
+    RefPtrWillBeRawPtr<CSSValue> timingFunction = BisonCSSParser::parseAnimationTimingFunctionValue("cubic-bezier(0.42, 0, 0.58, 1)");
     keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
     keyframes[0]->setEasing(CSSToStyleMap::animationTimingFunction(timingFunction.get(), false));
     keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(4.3362322, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(4.3362322, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, ExtrapolateReplaceNonInterpolable)
 {
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(unknownAnimatableValue(3.0), unknownAnimatableValue(5.0));
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
     keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
     keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
-    expectDoubleValue(5.0, effect->sample(0, 1.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    expectDoubleValue(5.0, effect->sample(0, 1.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, ExtrapolateReplace)
 {
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
     keyframes[0]->setComposite(AnimationEffect::CompositeReplace);
     keyframes[1]->setComposite(AnimationEffect::CompositeReplace);
-    expectDoubleValue(3.0 * -0.6 + 5.0 * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
+    expectDoubleValue(3.0 * -0.6 + 5.0 * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, ExtrapolateAdd)
@@ -170,13 +170,13 @@
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
     keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
     keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue((7.0 + 3.0) * -0.6 + (7.0 + 5.0) * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue((7.0 + 3.0) * -0.6 + (7.0 + 5.0) * 1.6, effect->sample(0, 1.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, ZeroKeyframes)
 {
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(KeyframeEffectModel::KeyframeVector());
     EXPECT_TRUE(effect->sample(0, 0.5)->isEmpty());
 }
 
@@ -185,10 +185,10 @@
     KeyframeEffectModel::KeyframeVector keyframes(1);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(3.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(3.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, SingleKeyframeAtOffsetOne)
@@ -196,10 +196,10 @@
     KeyframeEffectModel::KeyframeVector keyframes(1);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(1.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(7.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(7.0 * 0.4 + 5.0 * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, MoreThanTwoKeyframes)
@@ -207,34 +207,34 @@
     KeyframeEffectModel::KeyframeVector keyframes(3);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(0.5);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
     keyframes[2] = Keyframe::create();
     keyframes[2]->setOffset(1.0);
-    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
+    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(4.0, effect->sample(0, 0.3)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    expectDoubleValue(5.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(4.0, effect->sample(0, 0.3)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    expectDoubleValue(5.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, EndKeyframeOffsetsUnspecified)
 {
     KeyframeEffectModel::KeyframeVector keyframes(3);
     keyframes[0] = Keyframe::create();
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(0.5);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
     keyframes[2] = Keyframe::create();
-    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
+    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(3.0, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    expectDoubleValue(4.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    expectDoubleValue(5.0, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(3.0, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    expectDoubleValue(4.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    expectDoubleValue(5.0, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, SampleOnKeyframe)
@@ -242,46 +242,46 @@
     KeyframeEffectModel::KeyframeVector keyframes(3);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(0.5);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
     keyframes[2] = Keyframe::create();
     keyframes[2]->setOffset(1.0);
-    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
+    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(3.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    expectDoubleValue(4.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    expectDoubleValue(5.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(3.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    expectDoubleValue(4.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    expectDoubleValue(5.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 // Note that this tests an implementation detail, not behaviour defined by the spec.
 TEST(AnimationKeyframeEffectModel, SampleReturnsSameAnimatableValueInstance)
 {
-    AnimatableValue* threePixelsValue = unknownAnimatableValue(3.0);
-    AnimatableValue* fourPixelsValue = unknownAnimatableValue(4.0);
-    AnimatableValue* fivePixelsValue = unknownAnimatableValue(5.0);
+    RefPtr<AnimatableValue> threePixelsValue = unknownAnimatableValue(3.0);
+    RefPtr<AnimatableValue> fourPixelsValue = unknownAnimatableValue(4.0);
+    RefPtr<AnimatableValue> fivePixelsValue = unknownAnimatableValue(5.0);
 
     KeyframeEffectModel::KeyframeVector keyframes(3);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, threePixelsValue);
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, threePixelsValue.get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(0.5);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, fourPixelsValue);
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, fourPixelsValue.get());
     keyframes[2] = Keyframe::create();
     keyframes[2]->setOffset(1.0);
-    keyframes[2]->setPropertyValue(CSSPropertyLeft, fivePixelsValue);
+    keyframes[2]->setPropertyValue(CSSPropertyLeft, fivePixelsValue.get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    EXPECT_EQ(threePixelsValue, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    EXPECT_EQ(threePixelsValue, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    EXPECT_EQ(fivePixelsValue, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
-    EXPECT_EQ(fivePixelsValue, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    EXPECT_EQ(threePixelsValue, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    EXPECT_EQ(threePixelsValue, effect->sample(0, 0.1)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    EXPECT_EQ(fourPixelsValue, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    EXPECT_EQ(fivePixelsValue, effect->sample(0, 0.9)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
+    EXPECT_EQ(fivePixelsValue, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, MultipleKeyframesWithSameOffset)
@@ -289,34 +289,34 @@
     KeyframeEffectModel::KeyframeVector keyframes(7);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.1);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(1.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(1.0).get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(0.1);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(2.0));
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(2.0).get());
     keyframes[2] = Keyframe::create();
     keyframes[2]->setOffset(0.5);
-    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
+    keyframes[2]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
     keyframes[3] = Keyframe::create();
     keyframes[3]->setOffset(0.5);
-    keyframes[3]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0));
+    keyframes[3]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(4.0).get());
     keyframes[4] = Keyframe::create();
     keyframes[4]->setOffset(0.5);
-    keyframes[4]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
+    keyframes[4]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
     keyframes[5] = Keyframe::create();
     keyframes[5]->setOffset(0.9);
-    keyframes[5]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(6.0));
+    keyframes[5]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(6.0).get());
     keyframes[6] = Keyframe::create();
     keyframes[6]->setOffset(0.9);
-    keyframes[6]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(7.0));
+    keyframes[6]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(7.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(2.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
-    expectDoubleValue(2.0, effect->sample(0, 0.2)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
-    expectDoubleValue(3.0, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
-    expectDoubleValue(5.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
-    expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
-    expectDoubleValue(6.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
-    expectDoubleValue(6.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(2.0, effect->sample(0, 0.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0).get()));
+    expectDoubleValue(2.0, effect->sample(0, 0.2)->at(0).second->compositeOnto(unknownAnimatableValue(8.0).get()));
+    expectDoubleValue(3.0, effect->sample(0, 0.4)->at(0).second->compositeOnto(unknownAnimatableValue(8.0).get()));
+    expectDoubleValue(5.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(8.0).get()));
+    expectDoubleValue(5.0, effect->sample(0, 0.6)->at(0).second->compositeOnto(unknownAnimatableValue(8.0).get()));
+    expectDoubleValue(6.0, effect->sample(0, 0.8)->at(0).second->compositeOnto(unknownAnimatableValue(8.0).get()));
+    expectDoubleValue(6.0, effect->sample(0, 1.0)->at(0).second->compositeOnto(unknownAnimatableValue(8.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, PerKeyframeComposite)
@@ -324,14 +324,14 @@
     KeyframeEffectModel::KeyframeVector keyframes(2);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(3.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(3.0).get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(1.0);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0));
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(5.0).get());
     keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(3.0 * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(3.0 * 0.4 + (7.0 + 5.0) * 0.6, effect->sample(0, 0.6)->at(0).second->compositeOnto(pixelAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, MultipleProperties)
@@ -339,22 +339,22 @@
     KeyframeEffectModel::KeyframeVector keyframes(2);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0));
-    keyframes[0]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(4.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(3.0).get());
+    keyframes[0]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(4.0).get());
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(1.0);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0));
-    keyframes[1]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(6.0));
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, unknownAnimatableValue(5.0).get());
+    keyframes[1]->setPropertyValue(CSSPropertyRight, unknownAnimatableValue(6.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
     OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
     EXPECT_EQ(2UL, values->size());
     const AnimationEffect::CompositableValue* leftValue = findValue(*values.get(), CSSPropertyLeft);
     ASSERT_TRUE(leftValue);
-    expectDoubleValue(5.0, leftValue->compositeOnto(unknownAnimatableValue(7.0)));
+    expectDoubleValue(5.0, leftValue->compositeOnto(unknownAnimatableValue(7.0).get()));
     const AnimationEffect::CompositableValue* rightValue = findValue(*values.get(), CSSPropertyRight);
     ASSERT_TRUE(rightValue);
-    expectDoubleValue(6.0, rightValue->compositeOnto(unknownAnimatableValue(7.0)));
+    expectDoubleValue(6.0, rightValue->compositeOnto(unknownAnimatableValue(7.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, RecompositeCompositableValue)
@@ -362,19 +362,19 @@
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(3.0), pixelAnimatableValue(5.0));
     keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
     keyframes[1]->setComposite(AnimationEffect::CompositeAdd);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
     OwnPtr<AnimationEffect::CompositableValueList> values = effect->sample(0, 0.6);
-    expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(7.0)));
-    expectDoubleValue((9.0 + 3.0) * 0.4 + (9.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(9.0)));
+    expectDoubleValue((7.0 + 3.0) * 0.4 + (7.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(7.0).get()));
+    expectDoubleValue((9.0 + 3.0) * 0.4 + (9.0 + 5.0) * 0.6, values->at(0).second->compositeOnto(pixelAnimatableValue(9.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, MultipleIterations)
 {
     KeyframeEffectModel::KeyframeVector keyframes = keyframesAtZeroAndOne(pixelAnimatableValue(1.0), pixelAnimatableValue(3.0));
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
-    expectDoubleValue(2.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
-    expectDoubleValue(2.0, effect->sample(1, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
-    expectDoubleValue(2.0, effect->sample(2, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0)));
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    expectDoubleValue(2.0, effect->sample(0, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0).get()));
+    expectDoubleValue(2.0, effect->sample(1, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0).get()));
+    expectDoubleValue(2.0, effect->sample(2, 0.5)->at(0).second->compositeOnto(unknownAnimatableValue(0.0).get()));
 }
 
 TEST(AnimationKeyframeEffectModel, DependsOnUnderlyingValue)
@@ -382,16 +382,16 @@
     KeyframeEffectModel::KeyframeVector keyframes(3);
     keyframes[0] = Keyframe::create();
     keyframes[0]->setOffset(0.0);
-    keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0));
+    keyframes[0]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0).get());
     keyframes[0]->setComposite(AnimationEffect::CompositeAdd);
     keyframes[1] = Keyframe::create();
     keyframes[1]->setOffset(0.5);
-    keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0));
+    keyframes[1]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0).get());
     keyframes[2] = Keyframe::create();
     keyframes[2]->setOffset(1.0);
-    keyframes[2]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0));
+    keyframes[2]->setPropertyValue(CSSPropertyLeft, pixelAnimatableValue(1.0).get());
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
     EXPECT_TRUE(effect->sample(0, 0)->at(0).second->dependsOnUnderlyingValue());
     EXPECT_TRUE(effect->sample(0, 0.1)->at(0).second->dependsOnUnderlyingValue());
     EXPECT_TRUE(effect->sample(0, 0.25)->at(0).second->dependsOnUnderlyingValue());
@@ -406,7 +406,7 @@
 TEST(AnimationKeyframeEffectModel, ToKeyframeEffectModel)
 {
     KeyframeEffectModel::KeyframeVector keyframes(0);
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
 
     AnimationEffect* baseEffect = effect.get();
     EXPECT_TRUE(toKeyframeEffectModel(baseEffect));
diff --git a/Source/core/animation/TimedItem.cpp b/Source/core/animation/TimedItem.cpp
index d837b66..74d8006 100644
--- a/Source/core/animation/TimedItem.cpp
+++ b/Source/core/animation/TimedItem.cpp
@@ -31,8 +31,9 @@
 #include "config.h"
 #include "core/animation/TimedItem.h"
 
-#include "core/animation/Player.h"
+#include "core/animation/AnimationPlayer.h"
 #include "core/animation/TimedItemCalculations.h"
+#include "core/animation/TimedItemTiming.h"
 
 namespace WebCore {
 
@@ -80,7 +81,7 @@
 double TimedItem::activeDuration() const
 {
     const double result = m_specified.playbackRate
-        ? repeatedDuration() / abs(m_specified.playbackRate)
+        ? repeatedDuration() / std::abs(m_specified.playbackRate)
         : std::numeric_limits<double>::infinity();
     ASSERT(result >= 0);
     return result;
@@ -91,10 +92,10 @@
     m_specified = timing;
     invalidate();
     if (m_player)
-        m_player->setNeedsUpdate();
+        m_player->setOutdated();
 }
 
-bool TimedItem::updateInheritedTime(double inheritedTime) const
+void TimedItem::updateInheritedTime(double inheritedTime) const
 {
     bool needsUpdate = m_needsUpdate || (m_lastUpdateTime != inheritedTime && !(isNull(m_lastUpdateTime) && isNull(inheritedTime)));
     m_needsUpdate = false;
@@ -125,7 +126,7 @@
             timeFraction = calculateTransformedTime(currentIteration, iterationDuration, iterationTime, m_specified) / iterationDuration;
 
             if (!isNull(iterationTime)) {
-                timeToNextIteration = (iterationDuration - iterationTime) / abs(m_specified.playbackRate);
+                timeToNextIteration = (iterationDuration - iterationTime) / std::abs(m_specified.playbackRate);
                 if (activeDuration - activeTime < timeToNextIteration)
                     timeToNextIteration = std::numeric_limits<double>::infinity();
             }
@@ -133,7 +134,7 @@
             const double localIterationDuration = 1;
             const double localRepeatedDuration = localIterationDuration * m_specified.iterationCount;
             ASSERT(localRepeatedDuration >= 0);
-            const double localActiveDuration = m_specified.playbackRate ? localRepeatedDuration / abs(m_specified.playbackRate) : std::numeric_limits<double>::infinity();
+            const double localActiveDuration = m_specified.playbackRate ? localRepeatedDuration / std::abs(m_specified.playbackRate) : std::numeric_limits<double>::infinity();
             ASSERT(localActiveDuration >= 0);
             const double localLocalTime = localTime < m_specified.startDelay ? localTime : localActiveDuration + m_specified.startDelay;
             const TimedItem::Phase localCurrentPhase = calculatePhase(localActiveDuration, localLocalTime, m_specified);
@@ -167,24 +168,27 @@
         m_isFirstSample = false;
     }
 
-    bool didTriggerStyleRecalc = false;
     if (needsUpdate)  {
         // FIXME: This probably shouldn't be recursive.
-        didTriggerStyleRecalc = updateChildrenAndEffects();
+        updateChildrenAndEffects();
         m_calculated.timeToForwardsEffectChange = calculateTimeToEffectChange(true, localTime, timeToNextIteration);
         m_calculated.timeToReverseEffectChange = calculateTimeToEffectChange(false, localTime, timeToNextIteration);
     }
-    return didTriggerStyleRecalc;
 }
 
 const TimedItem::CalculatedTiming& TimedItem::ensureCalculated() const
 {
     if (!m_player)
         return m_calculated;
-    if (m_player->needsUpdate())
+    if (m_player->outdated())
         m_player->update();
-    ASSERT(!m_player->needsUpdate());
+    ASSERT(!m_player->outdated());
     return m_calculated;
 }
 
+PassRefPtr<TimedItemTiming> TimedItem::specified()
+{
+    return TimedItemTiming::create(this);
+}
+
 } // namespace WebCore
diff --git a/Source/core/animation/TimedItem.h b/Source/core/animation/TimedItem.h
index 80ca2f0..89dfa28 100644
--- a/Source/core/animation/TimedItem.h
+++ b/Source/core/animation/TimedItem.h
@@ -31,7 +31,6 @@
 #ifndef TimedItem_h
 #define TimedItem_h
 
-#include "core/animation/TimedItemTiming.h"
 #include "core/animation/Timing.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
@@ -39,8 +38,9 @@
 
 namespace WebCore {
 
-class Player;
+class AnimationPlayer;
 class TimedItem;
+class TimedItemTiming;
 
 static inline bool isNull(double value)
 {
@@ -53,7 +53,7 @@
 }
 
 class TimedItem : public RefCounted<TimedItem> {
-    friend class Player; // Calls attach/detach, updateInheritedTime.
+    friend class AnimationPlayer; // Calls attach/detach, updateInheritedTime.
 public:
     // Note that logic in CSSAnimations depends on the order of these values.
     enum Phase {
@@ -87,11 +87,11 @@
     double startTime() const { return m_startTime; }
     double endTime() const { return startTime() + specifiedTiming().startDelay + activeDuration() + specifiedTiming().endDelay; }
 
-    const Player* player() const { return m_player; }
-    Player* player() { return m_player; }
-    Player* player(bool& isNull) { isNull = !m_player; return m_player; }
+    const AnimationPlayer* player() const { return m_player; }
+    AnimationPlayer* player() { return m_player; }
+    AnimationPlayer* player(bool& isNull) { isNull = !m_player; return m_player; }
     const Timing& specifiedTiming() const { return m_specified; }
-    PassRefPtr<TimedItemTiming> specified() { return TimedItemTiming::create(this); }
+    PassRefPtr<TimedItemTiming> specified();
     void updateSpecifiedTiming(const Timing&);
 
     double localTime(bool& isNull) const { isNull = !m_player; return ensureCalculated().localTime; }
@@ -103,8 +103,7 @@
     // When TimedItem receives a new inherited time via updateInheritedTime
     // it will (if necessary) recalculate timings and (if necessary) call
     // updateChildrenAndEffects.
-    // Returns whether style recalc was triggered.
-    bool updateInheritedTime(double inheritedTime) const;
+    void updateInheritedTime(double inheritedTime) const;
     void invalidate() const { m_needsUpdate = true; };
 
 private:
@@ -112,14 +111,13 @@
     double iterationDuration() const;
     double repeatedDuration() const;
 
-    // Returns whether style recalc was triggered.
-    virtual bool updateChildrenAndEffects() const = 0;
+    virtual void updateChildrenAndEffects() const = 0;
     virtual double intrinsicIterationDuration() const { return 0; };
     virtual double calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const = 0;
     virtual void didAttach() { };
     virtual void willDetach() { };
 
-    void attach(Player* player)
+    void attach(AnimationPlayer* player)
     {
         m_player = player;
         didAttach();
@@ -135,7 +133,7 @@
     // FIXME: m_parent and m_startTime are placeholders, they depend on timing groups.
     TimedItem* const m_parent;
     const double m_startTime;
-    Player* m_player;
+    AnimationPlayer* m_player;
     Timing m_specified;
     OwnPtr<EventDelegate> m_eventDelegate;
 
diff --git a/Source/core/animation/TimedItem.idl b/Source/core/animation/TimedItem.idl
index 34fa04d..f2388f1 100644
--- a/Source/core/animation/TimedItem.idl
+++ b/Source/core/animation/TimedItem.idl
@@ -42,5 +42,5 @@
     readonly attribute double endTime;
 
     readonly attribute Timing specified;
-    readonly attribute Player? player;
+    readonly attribute AnimationPlayer? player;
 };
diff --git a/Source/core/animation/TimedItemCalculations.h b/Source/core/animation/TimedItemCalculations.h
index 5226395..75b949a 100644
--- a/Source/core/animation/TimedItemCalculations.h
+++ b/Source/core/animation/TimedItemCalculations.h
@@ -190,9 +190,7 @@
         return directedTime;
     double timeFraction = directedTime / iterationDuration;
     ASSERT(timeFraction >= 0 && timeFraction <= 1);
-    return specified.timingFunction
-        ? multiplyZeroAlwaysGivesZero(iterationDuration, specified.timingFunction->evaluate(timeFraction, accuracyForDuration(iterationDuration)))
-        : directedTime;
+    return multiplyZeroAlwaysGivesZero(iterationDuration, specified.timingFunction->evaluate(timeFraction, accuracyForDuration(iterationDuration)));
 }
 
 } // namespace WebCore
diff --git a/Source/core/animation/TimedItemCalculationsTest.cpp b/Source/core/animation/TimedItemCalculationsTest.cpp
index e88c7d1..488c040 100644
--- a/Source/core/animation/TimedItemCalculationsTest.cpp
+++ b/Source/core/animation/TimedItemCalculationsTest.cpp
@@ -184,18 +184,18 @@
     EXPECT_EQ(12, calculateTransformedTime(1, 20, 12, timing));
 
     // PlaybackDirectionForwards with timing function
-    timing.timingFunction = StepsTimingFunction::create(4, false /* stepAtStart */);
+    timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::StepAtEnd);
     EXPECT_EQ(10, calculateTransformedTime(0, 20, 12, timing));
     EXPECT_EQ(10, calculateTransformedTime(1, 20, 12, timing));
 
     // PlaybackDirectionReverse
-    timing.timingFunction = 0;
+    timing.timingFunction = Timing::defaults().timingFunction;
     timing.direction = Timing::PlaybackDirectionReverse;
     EXPECT_EQ(8, calculateTransformedTime(0, 20, 12, timing));
     EXPECT_EQ(8, calculateTransformedTime(1, 20, 12, timing));
 
     // PlaybackDirectionReverse with timing function
-    timing.timingFunction = StepsTimingFunction::create(4, false /* stepAtStart */);
+    timing.timingFunction = StepsTimingFunction::create(4, StepsTimingFunction::StepAtEnd);
     EXPECT_EQ(5, calculateTransformedTime(0, 20, 12, timing));
     EXPECT_EQ(5, calculateTransformedTime(1, 20, 12, timing));
 
diff --git a/Source/core/animation/TimedItemTest.cpp b/Source/core/animation/TimedItemTest.cpp
index 3a6fec4..76dcc8f 100644
--- a/Source/core/animation/TimedItemTest.cpp
+++ b/Source/core/animation/TimedItemTest.cpp
@@ -75,7 +75,7 @@
         TimedItem::updateInheritedTime(time);
     }
 
-    virtual bool updateChildrenAndEffects() const OVERRIDE { return false; }
+    virtual void updateChildrenAndEffects() const OVERRIDE { }
     void willDetach() { }
     TestTimedItemEventDelegate* eventDelegate() { return m_eventDelegate; }
     virtual double calculateTimeToEffectChange(bool forwards, double localTime, double timeToNextIteration) const OVERRIDE
diff --git a/Source/core/animation/TimedItemTiming.cpp b/Source/core/animation/TimedItemTiming.cpp
index 4aa0894..cb5e0b9 100644
--- a/Source/core/animation/TimedItemTiming.cpp
+++ b/Source/core/animation/TimedItemTiming.cpp
@@ -109,35 +109,35 @@
 void TimedItemTiming::setDelay(double delay)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setStartDelay(timing, delay);
+    TimingInput::setStartDelay(timing, delay);
     m_parent->updateSpecifiedTiming(timing);
 }
 
 void TimedItemTiming::setEndDelay(double endDelay)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setEndDelay(timing, endDelay);
+    TimingInput::setEndDelay(timing, endDelay);
     m_parent->updateSpecifiedTiming(timing);
 }
 
 void TimedItemTiming::setFill(String fill)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setFillMode(timing, fill);
+    TimingInput::setFillMode(timing, fill);
     m_parent->updateSpecifiedTiming(timing);
 }
 
 void TimedItemTiming::setIterationStart(double iterationStart)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setIterationStart(timing, iterationStart);
+    TimingInput::setIterationStart(timing, iterationStart);
     m_parent->updateSpecifiedTiming(timing);
 }
 
 void TimedItemTiming::setIterations(double iterations)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setIterationCount(timing, iterations);
+    TimingInput::setIterationCount(timing, iterations);
     m_parent->updateSpecifiedTiming(timing);
 }
 
@@ -146,7 +146,7 @@
     if (name != "duration")
         return false;
     Timing timing = m_parent->specifiedTiming();
-    Animation::setIterationDuration(timing, duration);
+    TimingInput::setIterationDuration(timing, duration);
     m_parent->updateSpecifiedTiming(timing);
     return true;
 }
@@ -154,21 +154,21 @@
 void TimedItemTiming::setPlaybackRate(double playbackRate)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setPlaybackRate(timing, playbackRate);
+    TimingInput::setPlaybackRate(timing, playbackRate);
     m_parent->updateSpecifiedTiming(timing);
 }
 
 void TimedItemTiming::setDirection(String direction)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setPlaybackDirection(timing, direction);
+    TimingInput::setPlaybackDirection(timing, direction);
     m_parent->updateSpecifiedTiming(timing);
 }
 
 void TimedItemTiming::setEasing(String easing)
 {
     Timing timing = m_parent->specifiedTiming();
-    Animation::setTimingFunction(timing, easing);
+    TimingInput::setTimingFunction(timing, easing);
     m_parent->updateSpecifiedTiming(timing);
 }
 
diff --git a/Source/core/animation/TimedItemTiming.h b/Source/core/animation/TimedItemTiming.h
index 699fb41..94c1313 100644
--- a/Source/core/animation/TimedItemTiming.h
+++ b/Source/core/animation/TimedItemTiming.h
@@ -5,13 +5,12 @@
 #ifndef TimedItemTiming_h
 #define TimedItemTiming_h
 
+#include "core/animation/TimedItem.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-class TimedItem;
-
 class TimedItemTiming : public RefCounted<TimedItemTiming> {
 public:
     static PassRefPtr<TimedItemTiming> create(TimedItem* parent);
diff --git a/Source/core/animation/Timeline.idl b/Source/core/animation/Timeline.idl
index 47138f7..e244d39 100644
--- a/Source/core/animation/Timeline.idl
+++ b/Source/core/animation/Timeline.idl
@@ -6,5 +6,5 @@
     RuntimeEnabled=WebAnimationsAPI,
     ImplementedAs=DocumentTimeline,
 ] interface Timeline {
-    Player play(TimedItem source);
+    AnimationPlayer play(TimedItem source);
 };
diff --git a/Source/core/animation/Timing.h b/Source/core/animation/Timing.h
index fb2ef09..f3655ae 100644
--- a/Source/core/animation/Timing.h
+++ b/Source/core/animation/Timing.h
@@ -53,6 +53,12 @@
         PlaybackDirectionAlternateReverse
     };
 
+    static const Timing& defaults()
+    {
+        DEFINE_STATIC_LOCAL(Timing, timing, ());
+        return timing;
+    }
+
     Timing()
         : startDelay(0)
         , endDelay(0)
@@ -62,7 +68,7 @@
         , iterationDuration(std::numeric_limits<double>::quiet_NaN())
         , playbackRate(1)
         , direction(PlaybackDirectionNormal)
-        , timingFunction(LinearTimingFunction::create())
+        , timingFunction(LinearTimingFunction::preset())
     {
     }
 
@@ -84,7 +90,6 @@
     double iterationStart;
     double iterationCount;
     double iterationDuration;
-    // FIXME: Add activeDuration.
     double playbackRate;
     PlaybackDirection direction;
     RefPtr<TimingFunction> timingFunction;
diff --git a/Source/core/animation/TimingInput.cpp b/Source/core/animation/TimingInput.cpp
new file mode 100644
index 0000000..e8e325c
--- /dev/null
+++ b/Source/core/animation/TimingInput.cpp
@@ -0,0 +1,160 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/TimingInput.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/css/parser/BisonCSSParser.h"
+#include "core/css/resolver/CSSToStyleMap.h"
+
+namespace WebCore {
+
+void TimingInput::setStartDelay(Timing& timing, double startDelay)
+{
+    if (std::isfinite(startDelay))
+        timing.startDelay = startDelay;
+    else
+        timing.startDelay = Timing::defaults().startDelay;
+}
+
+void TimingInput::setEndDelay(Timing& timing, double endDelay)
+{
+    if (std::isfinite(endDelay))
+        timing.endDelay = endDelay;
+    else
+        timing.endDelay = Timing::defaults().endDelay;
+}
+
+void TimingInput::setFillMode(Timing& timing, const String& fillMode)
+{
+    if (fillMode == "none") {
+        timing.fillMode = Timing::FillModeNone;
+    } else if (fillMode == "backwards") {
+        timing.fillMode = Timing::FillModeBackwards;
+    } else if (fillMode == "both") {
+        timing.fillMode = Timing::FillModeBoth;
+    } else if (fillMode == "forwards") {
+        timing.fillMode = Timing::FillModeForwards;
+    } else {
+        timing.fillMode = Timing::defaults().fillMode;
+    }
+}
+
+void TimingInput::setIterationStart(Timing& timing, double iterationStart)
+{
+    if (std::isfinite(iterationStart))
+        timing.iterationStart = std::max<double>(iterationStart, 0);
+    else
+        timing.iterationStart = Timing::defaults().iterationStart;
+}
+
+void TimingInput::setIterationCount(Timing& timing, double iterationCount)
+{
+    if (!std::isnan(iterationCount))
+        timing.iterationCount = std::max<double>(iterationCount, 0);
+    else
+        timing.iterationCount = Timing::defaults().iterationCount;
+}
+
+void TimingInput::setIterationDuration(Timing& timing, double iterationDuration)
+{
+    if (!std::isnan(iterationDuration) && iterationDuration >= 0)
+        timing.iterationDuration = iterationDuration;
+    else
+        timing.iterationDuration = Timing::defaults().iterationDuration;
+}
+
+void TimingInput::setPlaybackRate(Timing& timing, double playbackRate)
+{
+    if (std::isfinite(playbackRate))
+        timing.playbackRate = playbackRate;
+    else
+        timing.playbackRate = Timing::defaults().playbackRate;
+}
+
+void TimingInput::setPlaybackDirection(Timing& timing, const String& direction)
+{
+    if (direction == "reverse") {
+        timing.direction = Timing::PlaybackDirectionReverse;
+    } else if (direction == "alternate") {
+        timing.direction = Timing::PlaybackDirectionAlternate;
+    } else if (direction == "alternate-reverse") {
+        timing.direction = Timing::PlaybackDirectionAlternateReverse;
+    } else {
+        timing.direction = Timing::defaults().direction;
+    }
+}
+
+void TimingInput::setTimingFunction(Timing& timing, const String& timingFunctionString)
+{
+    RefPtrWillBeRawPtr<CSSValue> timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue(timingFunctionString);
+    if (timingFunctionValue) {
+        RefPtr<TimingFunction> timingFunction = CSSToStyleMap::animationTimingFunction(timingFunctionValue.get(), false);
+        if (timingFunction) {
+            timing.timingFunction = timingFunction;
+            return;
+        }
+    }
+    timing.timingFunction = Timing::defaults().timingFunction;
+}
+
+Timing TimingInput::convert(const Dictionary& timingInputDictionary)
+{
+    Timing result;
+
+    // FIXME: This method needs to be refactored to handle invalid
+    // null, NaN, Infinity values better.
+    // See: http://www.w3.org/TR/WebIDL/#es-double
+    double startDelay = 0;
+    timingInputDictionary.get("delay", startDelay);
+    setStartDelay(result, startDelay);
+
+    double endDelay = 0;
+    timingInputDictionary.get("endDelay", endDelay);
+    setEndDelay(result, endDelay);
+
+    String fillMode;
+    timingInputDictionary.get("fill", fillMode);
+    setFillMode(result, fillMode);
+
+    double iterationStart = 0;
+    timingInputDictionary.get("iterationStart", iterationStart);
+    setIterationStart(result, iterationStart);
+
+    double iterationCount = 1;
+    timingInputDictionary.get("iterations", iterationCount);
+    setIterationCount(result, iterationCount);
+
+    v8::Local<v8::Value> iterationDurationValue;
+    if (timingInputDictionary.get("duration", iterationDurationValue)) {
+        double iterationDuration = iterationDurationValue->NumberValue();
+        setIterationDuration(result, iterationDuration);
+    }
+
+    double playbackRate = 1;
+    timingInputDictionary.get("playbackRate", playbackRate);
+    setPlaybackRate(result, playbackRate);
+
+    String direction;
+    timingInputDictionary.get("direction", direction);
+    setPlaybackDirection(result, direction);
+
+    String timingFunctionString;
+    timingInputDictionary.get("easing", timingFunctionString);
+    setTimingFunction(result, timingFunctionString);
+
+    result.assertValid();
+
+    return result;
+}
+
+Timing TimingInput::convert(double duration)
+{
+    Timing result;
+    setIterationDuration(result, duration);
+    return result;
+}
+
+} // namespace WebCore
diff --git a/Source/core/animation/TimingInput.h b/Source/core/animation/TimingInput.h
new file mode 100644
index 0000000..c338201
--- /dev/null
+++ b/Source/core/animation/TimingInput.h
@@ -0,0 +1,32 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef TimingInput_h
+#define TimingInput_h
+
+#include "core/animation/Timing.h"
+
+namespace WebCore {
+
+class Dictionary;
+
+class TimingInput {
+public:
+    static Timing convert(const Dictionary& timingInputDictionary);
+    static Timing convert(double duration);
+
+    static void setStartDelay(Timing&, double startDelay);
+    static void setEndDelay(Timing&, double endDelay);
+    static void setFillMode(Timing&, const String& fillMode);
+    static void setIterationStart(Timing&, double iterationStart);
+    static void setIterationCount(Timing&, double iterationCount);
+    static void setIterationDuration(Timing&, double iterationDuration);
+    static void setPlaybackRate(Timing&, double playbackRate);
+    static void setPlaybackDirection(Timing&, const String& direction);
+    static void setTimingFunction(Timing&, const String& timingFunctionString);
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/animation/TimingInputTest.cpp b/Source/core/animation/TimingInputTest.cpp
new file mode 100644
index 0000000..aa0e9c5
--- /dev/null
+++ b/Source/core/animation/TimingInputTest.cpp
@@ -0,0 +1,181 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/TimingInput.h"
+
+#include "bindings/v8/Dictionary.h"
+#include "core/animation/AnimationTestHelper.h"
+#include "core/animation/TimedItemTiming.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+class AnimationTimingInputTest : public ::testing::Test {
+protected:
+    AnimationTimingInputTest()
+        : m_isolate(v8::Isolate::GetCurrent())
+        , m_scope(V8ExecutionScope::create(m_isolate))
+    {
+    }
+
+    Timing applyTimingInputNumber(String timingProperty, double timingPropertyValue)
+    {
+        v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+        setV8ObjectPropertyAsNumber(timingInput, timingProperty, timingPropertyValue);
+        Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+        return TimingInput::convert(timingInputDictionary);
+    }
+
+    Timing applyTimingInputString(String timingProperty, String timingPropertyValue)
+    {
+        v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+        setV8ObjectPropertyAsString(timingInput, timingProperty, timingPropertyValue);
+        Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+        return TimingInput::convert(timingInputDictionary);
+    }
+
+    v8::Isolate* m_isolate;
+
+private:
+    OwnPtr<V8ExecutionScope> m_scope;
+};
+
+TEST_F(AnimationTimingInputTest, TimingInputStartDelay)
+{
+    EXPECT_EQ(1.1, applyTimingInputNumber("delay", 1.1).startDelay);
+    EXPECT_EQ(-1, applyTimingInputNumber("delay", -1).startDelay);
+    EXPECT_EQ(1, applyTimingInputString("delay", "1").startDelay);
+    EXPECT_EQ(0, applyTimingInputString("delay", "1s").startDelay);
+    EXPECT_EQ(0, applyTimingInputString("delay", "Infinity").startDelay);
+    EXPECT_EQ(0, applyTimingInputString("delay", "-Infinity").startDelay);
+    EXPECT_EQ(0, applyTimingInputString("delay", "NaN").startDelay);
+    EXPECT_EQ(0, applyTimingInputString("delay", "rubbish").startDelay);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputEndDelay)
+{
+    EXPECT_EQ(10, applyTimingInputNumber("endDelay", 10).endDelay);
+    EXPECT_EQ(-2.5, applyTimingInputNumber("endDelay", -2.5).endDelay);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputFillMode)
+{
+    Timing::FillMode defaultFillMode = Timing::FillModeAuto;
+
+    EXPECT_EQ(Timing::FillModeAuto, applyTimingInputString("fill", "auto").fillMode);
+    EXPECT_EQ(Timing::FillModeForwards, applyTimingInputString("fill", "forwards").fillMode);
+    EXPECT_EQ(Timing::FillModeNone, applyTimingInputString("fill", "none").fillMode);
+    EXPECT_EQ(Timing::FillModeBackwards, applyTimingInputString("fill", "backwards").fillMode);
+    EXPECT_EQ(Timing::FillModeBoth, applyTimingInputString("fill", "both").fillMode);
+    EXPECT_EQ(defaultFillMode, applyTimingInputString("fill", "everything!").fillMode);
+    EXPECT_EQ(defaultFillMode, applyTimingInputString("fill", "backwardsandforwards").fillMode);
+    EXPECT_EQ(defaultFillMode, applyTimingInputNumber("fill", 2).fillMode);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputIterationStart)
+{
+    EXPECT_EQ(1.1, applyTimingInputNumber("iterationStart", 1.1).iterationStart);
+    EXPECT_EQ(0, applyTimingInputNumber("iterationStart", -1).iterationStart);
+    EXPECT_EQ(0, applyTimingInputString("iterationStart", "Infinity").iterationStart);
+    EXPECT_EQ(0, applyTimingInputString("iterationStart", "-Infinity").iterationStart);
+    EXPECT_EQ(0, applyTimingInputString("iterationStart", "NaN").iterationStart);
+    EXPECT_EQ(0, applyTimingInputString("iterationStart", "rubbish").iterationStart);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputIterationCount)
+{
+    EXPECT_EQ(2.1, applyTimingInputNumber("iterations", 2.1).iterationCount);
+    EXPECT_EQ(0, applyTimingInputNumber("iterations", -1).iterationCount);
+
+    Timing timing = applyTimingInputString("iterations", "Infinity");
+    EXPECT_TRUE(std::isinf(timing.iterationCount));
+    EXPECT_GT(timing.iterationCount, 0);
+
+    EXPECT_EQ(0, applyTimingInputString("iterations", "-Infinity").iterationCount);
+    EXPECT_EQ(1, applyTimingInputString("iterations", "NaN").iterationCount);
+    EXPECT_EQ(1, applyTimingInputString("iterations", "rubbish").iterationCount);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputIterationDuration)
+{
+    EXPECT_EQ(1.1, applyTimingInputNumber("duration", 1.1).iterationDuration);
+    EXPECT_TRUE(std::isnan(applyTimingInputNumber("duration", -1).iterationDuration));
+    EXPECT_EQ(1, applyTimingInputString("duration", "1").iterationDuration);
+
+    Timing timing = applyTimingInputString("duration", "Infinity");
+    EXPECT_TRUE(std::isinf(timing.iterationDuration));
+    EXPECT_GT(timing.iterationDuration, 0);
+
+    EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "-Infinity").iterationDuration));
+    EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "NaN").iterationDuration));
+    EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "auto").iterationDuration));
+    EXPECT_TRUE(std::isnan(applyTimingInputString("duration", "rubbish").iterationDuration));
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputPlaybackRate)
+{
+    EXPECT_EQ(2.1, applyTimingInputNumber("playbackRate", 2.1).playbackRate);
+    EXPECT_EQ(-1, applyTimingInputNumber("playbackRate", -1).playbackRate);
+    EXPECT_EQ(1, applyTimingInputString("playbackRate", "Infinity").playbackRate);
+    EXPECT_EQ(1, applyTimingInputString("playbackRate", "-Infinity").playbackRate);
+    EXPECT_EQ(1, applyTimingInputString("playbackRate", "NaN").playbackRate);
+    EXPECT_EQ(1, applyTimingInputString("playbackRate", "rubbish").playbackRate);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputDirection)
+{
+    Timing::PlaybackDirection defaultPlaybackDirection = Timing::PlaybackDirectionNormal;
+
+    EXPECT_EQ(Timing::PlaybackDirectionNormal, applyTimingInputString("direction", "normal").direction);
+    EXPECT_EQ(Timing::PlaybackDirectionReverse, applyTimingInputString("direction", "reverse").direction);
+    EXPECT_EQ(Timing::PlaybackDirectionAlternate, applyTimingInputString("direction", "alternate").direction);
+    EXPECT_EQ(Timing::PlaybackDirectionAlternateReverse, applyTimingInputString("direction", "alternate-reverse").direction);
+    EXPECT_EQ(defaultPlaybackDirection, applyTimingInputString("direction", "rubbish").direction);
+    EXPECT_EQ(defaultPlaybackDirection, applyTimingInputNumber("direction", 2).direction);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputTimingFunction)
+{
+    const RefPtr<TimingFunction> defaultTimingFunction = LinearTimingFunction::preset();
+
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease), *applyTimingInputString("easing", "ease").timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseIn), *applyTimingInputString("easing", "ease-in").timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseOut), *applyTimingInputString("easing", "ease-out").timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::preset(CubicBezierTimingFunction::EaseInOut), *applyTimingInputString("easing", "ease-in-out").timingFunction);
+    EXPECT_EQ(*LinearTimingFunction::preset(), *applyTimingInputString("easing", "linear").timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::Start), *applyTimingInputString("easing", "step-start").timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::Middle), *applyTimingInputString("easing", "step-middle").timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::preset(StepsTimingFunction::End), *applyTimingInputString("easing", "step-end").timingFunction);
+    EXPECT_EQ(*CubicBezierTimingFunction::create(1, 1, 0.3, 0.3), *applyTimingInputString("easing", "cubic-bezier(1, 1, 0.3, 0.3)").timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::create(3, StepsTimingFunction::StepAtStart), *applyTimingInputString("easing", "steps(3, start)").timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepAtMiddle), *applyTimingInputString("easing", "steps(5, middle)").timingFunction);
+    EXPECT_EQ(*StepsTimingFunction::create(5, StepsTimingFunction::StepAtEnd), *applyTimingInputString("easing", "steps(5, end)").timingFunction);
+    EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "steps(5.6, end)").timingFunction);
+    EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "cubic-bezier(2, 2, 0.3, 0.3)").timingFunction);
+    EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "rubbish").timingFunction);
+    EXPECT_EQ(*defaultTimingFunction, *applyTimingInputNumber("easing", 2).timingFunction);
+    EXPECT_EQ(*defaultTimingFunction, *applyTimingInputString("easing", "initial").timingFunction);
+}
+
+TEST_F(AnimationTimingInputTest, TimingInputEmpty)
+{
+    Timing controlTiming;
+
+    v8::Handle<v8::Object> timingInput = v8::Object::New(m_isolate);
+    Dictionary timingInputDictionary = Dictionary(v8::Handle<v8::Value>::Cast(timingInput), m_isolate);
+    Timing updatedTiming = TimingInput::convert(timingInputDictionary);
+
+    EXPECT_EQ(controlTiming.startDelay, updatedTiming.startDelay);
+    EXPECT_EQ(controlTiming.fillMode, updatedTiming.fillMode);
+    EXPECT_EQ(controlTiming.iterationStart, updatedTiming.iterationStart);
+    EXPECT_EQ(controlTiming.iterationCount, updatedTiming.iterationCount);
+    EXPECT_TRUE(std::isnan(updatedTiming.iterationDuration));
+    EXPECT_EQ(controlTiming.playbackRate, updatedTiming.playbackRate);
+    EXPECT_EQ(controlTiming.direction, updatedTiming.direction);
+    EXPECT_EQ(*controlTiming.timingFunction, *updatedTiming.timingFunction);
+}
+
+} // namespace WebCore
diff --git a/Source/core/animation/css/CSSAnimatableValueFactory.cpp b/Source/core/animation/css/CSSAnimatableValueFactory.cpp
index 8701a23..6068a1b 100644
--- a/Source/core/animation/css/CSSAnimatableValueFactory.cpp
+++ b/Source/core/animation/css/CSSAnimatableValueFactory.cpp
@@ -84,10 +84,10 @@
     case DeviceWidth:
     case DeviceHeight:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 static PassRefPtr<AnimatableValue> createFromLineHeight(const Length& length, const RenderStyle& style)
@@ -171,7 +171,7 @@
         return AnimatableUnknown::create(CSSPrimitiveValue::create(fillSize.type));
     default:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 }
 
@@ -230,6 +230,38 @@
     return AnimatableUnknown::create(CSSValueAuto);
 }
 
+static double fontWeightToDouble(FontWeight fontWeight)
+{
+    switch (fontWeight) {
+    case FontWeight100:
+        return 100;
+    case FontWeight200:
+        return 200;
+    case FontWeight300:
+        return 300;
+    case FontWeight400:
+        return 400;
+    case FontWeight500:
+        return 500;
+    case FontWeight600:
+        return 600;
+    case FontWeight700:
+        return 700;
+    case FontWeight800:
+        return 800;
+    case FontWeight900:
+        return 900;
+    }
+
+    ASSERT_NOT_REACHED();
+    return 400;
+}
+
+static PassRefPtr<AnimatableValue> createFromFontWeight(FontWeight fontWeight)
+{
+    return createFromDouble(fontWeightToDouble(fontWeight));
+}
+
 // FIXME: Generate this function.
 PassRefPtr<AnimatableValue> CSSAnimatableValueFactory::create(CSSPropertyID property, const RenderStyle& style)
 {
@@ -311,6 +343,8 @@
         // FIXME: Should we introduce an option to pass the computed font size here, allowing consumers to
         // enable text zoom rather than Text Autosizing? See http://crbug.com/227545.
         return createFromDouble(style.specifiedFontSize());
+    case CSSPropertyFontWeight:
+        return createFromFontWeight(style.fontWeight());
     case CSSPropertyHeight:
         return createFromLength(style.height(), style);
     case CSSPropertyKerning:
@@ -462,7 +496,7 @@
     default:
         ASSERT_NOT_REACHED();
         // This return value is to avoid a release crash if possible.
-        return AnimatableUnknown::create(0);
+        return AnimatableUnknown::create(nullptr);
     }
 }
 
diff --git a/Source/core/animation/css/CSSAnimations.cpp b/Source/core/animation/css/CSSAnimations.cpp
index 6b4179a..567bc50 100644
--- a/Source/core/animation/css/CSSAnimations.cpp
+++ b/Source/core/animation/css/CSSAnimations.cpp
@@ -38,7 +38,7 @@
 #include "core/animation/KeyframeEffectModel.h"
 #include "core/animation/css/CSSAnimatableValueFactory.h"
 #include "core/animation/css/CSSAnimationDataList.h"
-#include "core/animation/css/CSSPropertyAnimation.h"
+#include "core/animation/css/CSSPropertyEquality.h"
 #include "core/css/CSSKeyframeRule.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Element.h"
@@ -73,28 +73,8 @@
     return target > reference;
 }
 
-static PassRefPtr<TimingFunction> generateTimingFunction(const KeyframeEffectModel::KeyframeVector keyframes, const HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions)
-{
-    // Generate the chained timing function. Note that timing functions apply
-    // from the keyframe in which they're specified to the next keyframe.
-    bool isTimingFunctionLinearThroughout = true;
-    RefPtr<ChainedTimingFunction> chainedTimingFunction = ChainedTimingFunction::create();
-    for (size_t i = 0; i < keyframes.size() - 1; ++i) {
-        double lowerBound = keyframes[i]->offset();
-        ASSERT(lowerBound >=0 && lowerBound < 1);
-        double upperBound = keyframes[i + 1]->offset();
-        ASSERT(upperBound > 0 && upperBound <= 1);
-        TimingFunction* timingFunction = perKeyframeTimingFunctions.get(lowerBound);
-        isTimingFunctionLinearThroughout &= timingFunction->type() == TimingFunction::LinearFunction;
-        chainedTimingFunction->appendSegment(upperBound, timingFunction);
-    }
-    if (isTimingFunctionLinearThroughout)
-        return LinearTimingFunction::create();
-    return chainedTimingFunction;
-}
-
 static void resolveKeyframes(StyleResolver* resolver, Element* element, const Element& parentElement, const RenderStyle& style, RenderStyle* parentStyle, const AtomicString& name, TimingFunction* defaultTimingFunction,
-    Vector<std::pair<KeyframeEffectModel::KeyframeVector, RefPtr<TimingFunction> > >& keyframesAndTimingFunctions)
+    WillBeHeapVector<KeyframeEffectModel::KeyframeVector>& resolvedKeyframes)
 {
     // When the element is null, use its parent for scoping purposes.
     const Element* elementForScoping = element ? element : &parentElement;
@@ -109,38 +89,32 @@
     // Construct and populate the style for each keyframe
     PropertySet specifiedProperties;
     KeyframeEffectModel::KeyframeVector keyframes;
-    HashMap<double, RefPtr<TimingFunction> > perKeyframeTimingFunctions;
     for (size_t i = 0; i < styleKeyframes.size(); ++i) {
         const StyleKeyframe* styleKeyframe = styleKeyframes[i].get();
         // It's OK to pass a null element here.
         RefPtr<RenderStyle> keyframeStyle = resolver->styleForKeyframe(element, style, parentStyle, styleKeyframe, name);
-        RefPtr<Keyframe> keyframe = Keyframe::create();
+        RefPtrWillBeRawPtr<Keyframe> keyframe = Keyframe::create();
         const Vector<double>& offsets = styleKeyframe->keys();
         ASSERT(!offsets.isEmpty());
         keyframe->setOffset(offsets[0]);
-        TimingFunction* timingFunction = defaultTimingFunction;
-        const StylePropertySet* properties = styleKeyframe->properties();
-        for (unsigned j = 0; j < properties->propertyCount(); j++) {
-            CSSPropertyID property = properties->propertyAt(j).id();
+        keyframe->setEasing(defaultTimingFunction);
+        const StylePropertySet& properties = styleKeyframe->properties();
+        for (unsigned j = 0; j < properties.propertyCount(); j++) {
+            CSSPropertyID property = properties.propertyAt(j).id();
             specifiedProperties.add(property);
             if (property == CSSPropertyWebkitAnimationTimingFunction || property == CSSPropertyAnimationTimingFunction)
-                timingFunction = KeyframeValue::timingFunction(*keyframeStyle);
+                keyframe->setEasing(KeyframeValue::timingFunction(*keyframeStyle));
             else if (CSSAnimations::isAnimatableProperty(property))
                 keyframe->setPropertyValue(property, CSSAnimatableValueFactory::create(property, *keyframeStyle).get());
         }
         keyframes.append(keyframe);
         // The last keyframe specified at a given offset is used.
-        perKeyframeTimingFunctions.set(offsets[0], timingFunction);
         for (size_t j = 1; j < offsets.size(); ++j) {
             keyframes.append(keyframe->cloneWithOffset(offsets[j]));
-            perKeyframeTimingFunctions.set(offsets[j], timingFunction);
         }
     }
     ASSERT(!keyframes.isEmpty());
 
-    if (!perKeyframeTimingFunctions.contains(0))
-        perKeyframeTimingFunctions.set(0, defaultTimingFunction);
-
     for (PropertySet::const_iterator iter = specifiedProperties.begin(); iter != specifiedProperties.end(); ++iter) {
         const CSSPropertyID property = *iter;
         ASSERT(property != CSSPropertyInvalid);
@@ -159,13 +133,13 @@
     keyframes.shrink(targetIndex + 1);
 
     // Add 0% and 100% keyframes if absent.
-    RefPtr<Keyframe> startKeyframe = keyframes[0];
+    RefPtrWillBeRawPtr<Keyframe> startKeyframe = keyframes[0];
     if (startKeyframe->offset()) {
         startKeyframe = Keyframe::create();
         startKeyframe->setOffset(0);
         keyframes.prepend(startKeyframe);
     }
-    RefPtr<Keyframe> endKeyframe = keyframes[keyframes.size() - 1];
+    RefPtrWillBeRawPtr<Keyframe> endKeyframe = keyframes[keyframes.size() - 1];
     if (endKeyframe->offset() != 1) {
         endKeyframe = Keyframe::create();
         endKeyframe->setOffset(1);
@@ -231,8 +205,9 @@
                 ASSERT(i && i != numKeyframes - 1);
                 continue;
             }
-            RefPtr<Keyframe> clonedKeyframe = Keyframe::create();
+            RefPtrWillBeRawPtr<Keyframe> clonedKeyframe = Keyframe::create();
             clonedKeyframe->setOffset(keyframe->offset());
+            clonedKeyframe->setEasing(keyframe->easing());
             clonedKeyframe->setComposite(keyframe->composite());
             clonedKeyframe->setPropertyValue(property, keyframe->propertyValue(property));
             splitOutKeyframes.append(clonedKeyframe);
@@ -248,7 +223,7 @@
         for (size_t j = 0; j < splitOutKeyframes.size(); ++j)
             ASSERT(splitOutKeyframes[j]->properties().size() == 1);
 #endif
-        keyframesAndTimingFunctions.append(std::make_pair(splitOutKeyframes, generateTimingFunction(splitOutKeyframes, perKeyframeTimingFunctions)));
+        resolvedKeyframes.append(splitOutKeyframes);
     }
 
     unsigned numPropertiesSpecifiedInAllKeyframes = keyframes.first()->properties().size();
@@ -259,8 +234,8 @@
 
     // If the animation specifies any keyframes, we always provide at least one
     // vector of resolved keyframes, even if no properties are animated.
-    if (numPropertiesSpecifiedInAllKeyframes || keyframesAndTimingFunctions.isEmpty())
-        keyframesAndTimingFunctions.append(std::make_pair(keyframes, generateTimingFunction(keyframes, perKeyframeTimingFunctions)));
+    if (numPropertiesSpecifiedInAllKeyframes || resolvedKeyframes.isEmpty())
+        resolvedKeyframes.append(keyframes);
 }
 
 // Returns the default timing function.
@@ -389,14 +364,14 @@
                 AnimationMap::const_iterator existing(cssAnimations->m_animations.find(animationName));
                 if (existing != cssAnimations->m_animations.end()) {
                     inactive.remove(animationName);
-                    const HashSet<RefPtr<Player> >& players = existing->value;
+                    const HashSet<RefPtr<AnimationPlayer> >& players = existing->value;
                     ASSERT(!players.isEmpty());
-                    bool isFirstPlayerPaused = (*players.begin())->paused();
+                    bool isFirstAnimationPlayerPaused = (*players.begin())->paused();
 #ifndef NDEBUG
-                    for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
-                        ASSERT((*iter)->paused() == isFirstPlayerPaused);
+                    for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+                        ASSERT((*iter)->paused() == isFirstAnimationPlayerPaused);
 #endif
-                    if ((animationData->playState() == AnimPlayStatePaused) != isFirstPlayerPaused) {
+                    if ((animationData->playState() == AnimPlayStatePaused) != isFirstAnimationPlayerPaused) {
                         ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
                         update->toggleAnimationPaused(animationName);
                     }
@@ -407,15 +382,15 @@
             Timing timing;
             bool isPaused;
             RefPtr<TimingFunction> defaultTimingFunction = timingFromAnimationData(animationData, timing, isPaused);
-            Vector<std::pair<KeyframeEffectModel::KeyframeVector, RefPtr<TimingFunction> > > keyframesAndTimingFunctions;
-            resolveKeyframes(resolver, element, parentElement, style, parentStyle, animationName, defaultTimingFunction.get(), keyframesAndTimingFunctions);
-            if (!keyframesAndTimingFunctions.isEmpty()) {
+            WillBeHeapVector<KeyframeEffectModel::KeyframeVector> resolvedKeyframes;
+            resolveKeyframes(resolver, element, parentElement, style, parentStyle, animationName, defaultTimingFunction.get(), resolvedKeyframes);
+            if (!resolvedKeyframes.isEmpty()) {
                 HashSet<RefPtr<InertAnimation> > animations;
-                for (size_t j = 0; j < keyframesAndTimingFunctions.size(); ++j) {
-                    ASSERT(!keyframesAndTimingFunctions[j].first.isEmpty());
-                    timing.timingFunction = keyframesAndTimingFunctions[j].second;
+                for (size_t j = 0; j < resolvedKeyframes.size(); ++j) {
+                    ASSERT(!resolvedKeyframes[j].isEmpty());
+                    timing.timingFunction = LinearTimingFunction::preset();
                     // FIXME: crbug.com/268791 - Keyframes are already normalized, perhaps there should be a flag on KeyframeEffectModel to skip normalization.
-                    animations.add(InertAnimation::create(KeyframeEffectModel::create(keyframesAndTimingFunctions[j].first), timing, isPaused));
+                    animations.add(InertAnimation::create(KeyframeEffectModel::create(resolvedKeyframes[j]), timing, isPaused));
                 }
                 ASSERT(!activeAnimations || !activeAnimations->isAnimationStyleChange());
                 update->startAnimation(animationName, animations);
@@ -447,19 +422,19 @@
     DisableCompositingQueryAsserts disabler;
 
     for (Vector<AtomicString>::const_iterator iter = update->cancelledAnimationNames().begin(); iter != update->cancelledAnimationNames().end(); ++iter) {
-        const HashSet<RefPtr<Player> >& players = m_animations.take(*iter);
-        for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+        const HashSet<RefPtr<AnimationPlayer> >& players = m_animations.take(*iter);
+        for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
             (*iter)->cancel();
     }
 
     for (Vector<AtomicString>::const_iterator iter = update->animationsWithPauseToggled().begin(); iter != update->animationsWithPauseToggled().end(); ++iter) {
-        const HashSet<RefPtr<Player> >& players = m_animations.get(*iter);
+        const HashSet<RefPtr<AnimationPlayer> >& players = m_animations.get(*iter);
         ASSERT(!players.isEmpty());
-        bool isFirstPlayerPaused = (*players.begin())->paused();
-        for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter) {
-            Player* player = iter->get();
-            ASSERT(player->paused() == isFirstPlayerPaused);
-            if (isFirstPlayerPaused)
+        bool isFirstAnimationPlayerPaused = (*players.begin())->paused();
+        for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.begin(); iter != players.end(); ++iter) {
+            AnimationPlayer* player = iter->get();
+            ASSERT(player->paused() == isFirstAnimationPlayerPaused);
+            if (isFirstAnimationPlayerPaused)
                 player->unpause();
             else
                 player->pause();
@@ -468,13 +443,13 @@
 
     for (Vector<CSSAnimationUpdate::NewAnimation>::const_iterator iter = update->newAnimations().begin(); iter != update->newAnimations().end(); ++iter) {
         OwnPtr<AnimationEventDelegate> eventDelegate = adoptPtr(new AnimationEventDelegate(element, iter->name));
-        HashSet<RefPtr<Player> > players;
+        HashSet<RefPtr<AnimationPlayer> > players;
         for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = iter->animations.begin(); animationsIter != iter->animations.end(); ++animationsIter) {
             const InertAnimation* inertAnimation = animationsIter->get();
             // The event delegate is set on the the first animation only. We
             // rely on the behavior of OwnPtr::release() to achieve this.
             RefPtr<Animation> animation = Animation::create(element, inertAnimation->effect(), inertAnimation->specifiedTiming(), Animation::DefaultPriority, eventDelegate.release());
-            Player* player = element->document().timeline()->createPlayer(animation.get());
+            AnimationPlayer* player = element->document().timeline().createAnimationPlayer(animation.get());
             if (inertAnimation->paused())
                 player->pause();
             element->document().cssPendingAnimations().add(player);
@@ -494,7 +469,7 @@
     for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().begin(); iter != update->cancelledTransitions().end(); ++iter) {
         CSSPropertyID id = *iter;
         ASSERT(m_transitions.contains(id));
-        Player* player = m_transitions.take(id).transition->player();
+        AnimationPlayer* player = m_transitions.take(id).transition->player();
         if (activeAnimations && activeAnimations->hasActiveAnimationsOnCompositor(id) && update->newTransitions().find(id) != update->newTransitions().end())
             retargetedCompositorTransitions.add(id, std::pair<RefPtr<Animation>, double>(toAnimation(player->source()), player->startTime()));
         player->cancel();
@@ -511,13 +486,13 @@
         InertAnimation* inertAnimation = newTransition.animation.get();
         OwnPtr<TransitionEventDelegate> eventDelegate = adoptPtr(new TransitionEventDelegate(element, id));
 
-        RefPtr<AnimationEffect> effect = inertAnimation->effect();
+        RefPtrWillBeRawPtr<AnimationEffect> effect = inertAnimation->effect();
 
         if (retargetedCompositorTransitions.contains(id)) {
             const std::pair<RefPtr<Animation>, double>& oldTransition = retargetedCompositorTransitions.get(id);
             RefPtr<Animation> oldAnimation = oldTransition.first;
             double oldStartTime = oldTransition.second;
-            double inheritedTime = isNull(oldStartTime) ? 0 : element->document().transitionTimeline()->currentTime() - oldStartTime;
+            double inheritedTime = isNull(oldStartTime) ? 0 : element->document().transitionTimeline().currentTime() - oldStartTime;
             oldAnimation->updateInheritedTime(inheritedTime);
             KeyframeEffectModel* oldEffect = toKeyframeEffectModel(inertAnimation->effect());
             const KeyframeEffectModel::KeyframeVector& frames = oldEffect->getFrames();
@@ -532,7 +507,7 @@
             effect = KeyframeEffectModel::create(newFrames);
         }
         RefPtr<Animation> transition = Animation::create(element, effect, inertAnimation->specifiedTiming(), Animation::TransitionPriority, eventDelegate.release());
-        RefPtr<Player> player = element->document().transitionTimeline()->createPlayer(transition.get());
+        RefPtr<AnimationPlayer> player = element->document().transitionTimeline().createAnimationPlayer(transition.get());
         player->update();
         element->document().cssPendingAnimations().add(player.get());
         runningTransition.transition = transition.get();
@@ -560,7 +535,7 @@
     if (anim->duration() + anim->delay() <= 0)
         return;
 
-    if (CSSPropertyAnimation::propertiesEqual(id, &oldStyle, &style))
+    if (CSSPropertyEquality::propertiesEqual(id, oldStyle, style))
         return;
     if (!to)
         to = CSSAnimatableValueFactory::create(id, style);
@@ -573,17 +548,17 @@
 
     KeyframeEffectModel::KeyframeVector keyframes;
 
-    RefPtr<Keyframe> startKeyframe = Keyframe::create();
+    RefPtrWillBeRawPtr<Keyframe> startKeyframe = Keyframe::create();
     startKeyframe->setPropertyValue(id, from.get());
     startKeyframe->setOffset(0);
     keyframes.append(startKeyframe);
 
-    RefPtr<Keyframe> endKeyframe = Keyframe::create();
+    RefPtrWillBeRawPtr<Keyframe> endKeyframe = Keyframe::create();
     endKeyframe->setPropertyValue(id, to.get());
     endKeyframe->setOffset(1);
     keyframes.append(endKeyframe);
 
-    RefPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
+    RefPtrWillBeRawPtr<KeyframeEffectModel> effect = KeyframeEffectModel::create(keyframes);
 
     Timing timing;
     bool isPaused;
@@ -666,8 +641,8 @@
 void CSSAnimations::cancel()
 {
     for (AnimationMap::iterator iter = m_animations.begin(); iter != m_animations.end(); ++iter) {
-        const HashSet<RefPtr<Player> >& players = iter->value;
-        for (HashSet<RefPtr<Player> >::const_iterator animationsIter = players.begin(); animationsIter != players.end(); ++animationsIter)
+        const HashSet<RefPtr<AnimationPlayer> >& players = iter->value;
+        for (HashSet<RefPtr<AnimationPlayer> >::const_iterator animationsIter = players.begin(); animationsIter != players.end(); ++animationsIter)
             (*animationsIter)->cancel();
     }
 
@@ -684,7 +659,7 @@
     ActiveAnimations* activeAnimations = element ? element->activeAnimations() : 0;
     AnimationStack* animationStack = activeAnimations ? &activeAnimations->defaultStack() : 0;
 
-    if (update->newAnimations().isEmpty() && update->cancelledAnimationPlayers().isEmpty()) {
+    if (update->newAnimations().isEmpty() && update->cancelledAnimationAnimationPlayers().isEmpty()) {
         AnimationEffect::CompositableValueMap compositableValuesForAnimations(AnimationStack::compositableValues(animationStack, 0, 0, Animation::DefaultPriority));
         update->adoptCompositableValuesForAnimations(compositableValuesForAnimations);
         return;
@@ -696,7 +671,7 @@
         for (HashSet<RefPtr<InertAnimation> >::const_iterator animationsIter = animations.begin(); animationsIter != animations.end(); ++animationsIter)
             newAnimations.append(animationsIter->get());
     }
-    AnimationEffect::CompositableValueMap compositableValuesForAnimations(AnimationStack::compositableValues(animationStack, &newAnimations, &update->cancelledAnimationPlayers(), Animation::DefaultPriority));
+    AnimationEffect::CompositableValueMap compositableValuesForAnimations(AnimationStack::compositableValues(animationStack, &newAnimations, &update->cancelledAnimationAnimationPlayers(), Animation::DefaultPriority));
     update->adoptCompositableValuesForAnimations(compositableValuesForAnimations);
 }
 
@@ -713,17 +688,17 @@
         for (CSSAnimationUpdate::NewTransitionMap::const_iterator iter = update->newTransitions().begin(); iter != update->newTransitions().end(); ++iter)
             newTransitions.append(iter->value.animation.get());
 
-        HashSet<const Player*> cancelledPlayers;
+        HashSet<const AnimationPlayer*> cancelledAnimationPlayers;
         if (!update->cancelledTransitions().isEmpty()) {
             ASSERT(activeAnimations);
             const TransitionMap& transitionMap = activeAnimations->cssAnimations().m_transitions;
             for (HashSet<CSSPropertyID>::iterator iter = update->cancelledTransitions().begin(); iter != update->cancelledTransitions().end(); ++iter) {
                 ASSERT(transitionMap.contains(*iter));
-                cancelledPlayers.add(transitionMap.get(*iter).transition->player());
+                cancelledAnimationPlayers.add(transitionMap.get(*iter).transition->player());
             }
         }
 
-        compositableValuesForTransitions = AnimationStack::compositableValues(animationStack, &newTransitions, &cancelledPlayers, Animation::TransitionPriority);
+        compositableValuesForTransitions = AnimationStack::compositableValues(animationStack, &newTransitions, &cancelledAnimationPlayers, Animation::TransitionPriority);
     }
 
     // Properties being animated by animations don't get values from transitions applied.
@@ -736,16 +711,15 @@
 
 void CSSAnimations::AnimationEventDelegate::maybeDispatch(Document::ListenerType listenerType, const AtomicString& eventName, double elapsedTime)
 {
-    if (m_target->document().hasListenerType(listenerType))
-        m_target->document().timeline()->addEventToDispatch(m_target, WebKitAnimationEvent::create(eventName, m_name, elapsedTime));
+    if (m_target->document().hasListenerType(listenerType)) {
+        RefPtr<WebKitAnimationEvent> event = WebKitAnimationEvent::create(eventName, m_name, elapsedTime);
+        event->setTarget(m_target);
+        m_target->document().enqueueAnimationFrameEvent(event);
+    }
 }
 
 void CSSAnimations::AnimationEventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
 {
-    // Events for a single document are queued and dispatched as a group at
-    // the end of DocumentTimeline::serviceAnimations.
-    // FIXME: Events which are queued outside of serviceAnimations should
-    // trigger a timer to dispatch when control is released.
     const TimedItem::Phase currentPhase = timedItem->phase();
     const double currentIteration = timedItem->currentIteration();
 
@@ -775,10 +749,6 @@
 
 void CSSAnimations::TransitionEventDelegate::onEventCondition(const TimedItem* timedItem, bool isFirstSample, TimedItem::Phase previousPhase, double previousIteration)
 {
-    // Events for a single document are queued and dispatched as a group at
-    // the end of DocumentTimeline::serviceAnimations.
-    // FIXME: Events which are queued outside of serviceAnimations should
-    // trigger a timer to dispatch when control is released.
     const TimedItem::Phase currentPhase = timedItem->phase();
     if (currentPhase == TimedItem::PhaseAfter && (isFirstSample || previousPhase != currentPhase) && m_target->document().hasListenerType(Document::TRANSITIONEND_LISTENER)) {
         String propertyName = getPropertyNameString(m_property);
@@ -786,7 +756,9 @@
         double elapsedTime = timing.iterationDuration;
         const AtomicString& eventType = EventTypeNames::transitionend;
         String pseudoElement = PseudoElement::pseudoElementNameForEvents(m_target->pseudoId());
-        m_target->document().transitionTimeline()->addEventToDispatch(m_target, TransitionEvent::create(eventType, propertyName, elapsedTime, pseudoElement));
+        RefPtr<TransitionEvent> event = TransitionEvent::create(eventType, propertyName, elapsedTime, pseudoElement);
+        event->setTarget(m_target);
+        m_target->document().enqueueAnimationFrameEvent(event);
     }
 }
 
@@ -828,6 +800,7 @@
     case CSSPropertyFloodColor:
     case CSSPropertyFloodOpacity:
     case CSSPropertyFontSize:
+    case CSSPropertyFontWeight:
     case CSSPropertyHeight:
     case CSSPropertyKerning:
     case CSSPropertyLeft:
diff --git a/Source/core/animation/css/CSSAnimations.h b/Source/core/animation/css/CSSAnimations.h
index 22b7a1f..85fe32f 100644
--- a/Source/core/animation/css/CSSAnimations.h
+++ b/Source/core/animation/css/CSSAnimations.h
@@ -32,8 +32,8 @@
 #define CSSAnimations_h
 
 #include "core/animation/Animation.h"
+#include "core/animation/AnimationPlayer.h"
 #include "core/animation/InertAnimation.h"
-#include "core/animation/Player.h"
 #include "core/animation/css/CSSAnimationData.h"
 #include "core/css/StylePropertySet.h"
 #include "core/dom/Document.h"
@@ -61,12 +61,12 @@
         m_newAnimations.append(newAnimation);
     }
     // Returns whether player has been cancelled and should be filtered during style application.
-    bool isCancelledAnimation(const Player* player) const { return m_cancelledAnimationPlayers.contains(player); }
-    void cancelAnimation(const AtomicString& name, const HashSet<RefPtr<Player> >& players)
+    bool isCancelledAnimation(const AnimationPlayer* player) const { return m_cancelledAnimationAnimationPlayers.contains(player); }
+    void cancelAnimation(const AtomicString& name, const HashSet<RefPtr<AnimationPlayer> >& players)
     {
         m_cancelledAnimationNames.append(name);
-        for (HashSet<RefPtr<Player> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
-            m_cancelledAnimationPlayers.add(iter->get());
+        for (HashSet<RefPtr<AnimationPlayer> >::const_iterator iter = players.begin(); iter != players.end(); ++iter)
+            m_cancelledAnimationAnimationPlayers.add(iter->get());
     }
     void toggleAnimationPaused(const AtomicString& name)
     {
@@ -91,7 +91,7 @@
     };
     const Vector<NewAnimation>& newAnimations() const { return m_newAnimations; }
     const Vector<AtomicString>& cancelledAnimationNames() const { return m_cancelledAnimationNames; }
-    const HashSet<const Player*>& cancelledAnimationPlayers() const { return m_cancelledAnimationPlayers; }
+    const HashSet<const AnimationPlayer*>& cancelledAnimationAnimationPlayers() const { return m_cancelledAnimationAnimationPlayers; }
     const Vector<AtomicString>& animationsWithPauseToggled() const { return m_animationsWithPauseToggled; }
 
     struct NewTransition {
@@ -114,7 +114,7 @@
     {
         return m_newAnimations.isEmpty()
             && m_cancelledAnimationNames.isEmpty()
-            && m_cancelledAnimationPlayers.isEmpty()
+            && m_cancelledAnimationAnimationPlayers.isEmpty()
             && m_animationsWithPauseToggled.isEmpty()
             && m_newTransitions.isEmpty()
             && m_cancelledTransitions.isEmpty()
@@ -128,7 +128,7 @@
     // incomplete keyframes.
     Vector<NewAnimation> m_newAnimations;
     Vector<AtomicString> m_cancelledAnimationNames;
-    HashSet<const Player*> m_cancelledAnimationPlayers;
+    HashSet<const AnimationPlayer*> m_cancelledAnimationAnimationPlayers;
     Vector<AtomicString> m_animationsWithPauseToggled;
 
     NewTransitionMap m_newTransitions;
@@ -160,10 +160,10 @@
     // Note that a single animation name may map to multiple players due to
     // the way in which we split up animations with incomplete keyframes.
     // FIXME: Once the Web Animations model supports groups, we could use a
-    // ParGroup to drive multiple animations from a single Player.
-    typedef HashMap<AtomicString, HashSet<RefPtr<Player> > > AnimationMap;
+    // ParGroup to drive multiple animations from a single AnimationPlayer.
+    typedef HashMap<AtomicString, HashSet<RefPtr<AnimationPlayer> > > AnimationMap;
     struct RunningTransition {
-        Animation* transition; // The TransitionTimeline keeps the Players alive
+        Animation* transition; // The TransitionTimeline keeps the AnimationPlayers alive
         const AnimatableValue* from;
         const AnimatableValue* to;
     };
diff --git a/Source/core/animation/css/CSSPendingAnimations.cpp b/Source/core/animation/css/CSSPendingAnimations.cpp
index eac01ad..86fcff5 100644
--- a/Source/core/animation/css/CSSPendingAnimations.cpp
+++ b/Source/core/animation/css/CSSPendingAnimations.cpp
@@ -38,25 +38,17 @@
 
 namespace WebCore {
 
-void CSSPendingAnimations::add(Player* player)
+void CSSPendingAnimations::add(AnimationPlayer* player)
 {
     ASSERT(player->source()->isAnimation());
-    // The actual start time is either this value, or the time that
-    // this animation, or an animation that it is synchronized with
-    // is started on the compositor.
-    const double defaultStartTime = player->timeline()->currentTime();
-    m_pending.append(std::make_pair(player, defaultStartTime));
+    m_pending.append(player);
 }
 
 bool CSSPendingAnimations::startPendingAnimations()
 {
-    // FIXME: This is called from within style recalc, at which point compositor state is not up to date.
-    // https://code.google.com/p/chromium/issues/detail?id=339847
-    DisableCompositingQueryAsserts disabler;
-
     bool startedOnCompositor = false;
     for (size_t i = 0; i < m_pending.size(); ++i) {
-        if (m_pending[i].first->maybeStartAnimationOnCompositor())
+        if (m_pending[i]->maybeStartAnimationOnCompositor())
             startedOnCompositor = true;
     }
 
@@ -65,11 +57,11 @@
     // start immediately.
     if (startedOnCompositor) {
         for (size_t i = 0; i < m_pending.size(); ++i)
-            m_waitingForCompositorAnimationStart.append(m_pending[i].first);
+            m_waitingForCompositorAnimationStart.append(m_pending[i]);
     } else {
         for (size_t i = 0; i < m_pending.size(); ++i) {
-            m_pending[i].first->setStartTime(m_pending[i].second);
-            m_pending[i].first->update();
+            m_pending[i]->setStartTime(m_pending[i]->timeline()->currentTime());
+            m_pending[i]->update();
         }
     }
     m_pending.clear();
@@ -91,7 +83,7 @@
 void CSSPendingAnimations::notifyCompositorAnimationStarted(double monotonicAnimationStartTime)
 {
     for (size_t i = 0; i < m_waitingForCompositorAnimationStart.size(); ++i) {
-        Player* player = m_waitingForCompositorAnimationStart[i].get();
+        AnimationPlayer* player = m_waitingForCompositorAnimationStart[i].get();
         player->setStartTime(monotonicAnimationStartTime - player->timeline()->zeroTime());
         player->update();
     }
diff --git a/Source/core/animation/css/CSSPendingAnimations.h b/Source/core/animation/css/CSSPendingAnimations.h
index ae04fc5..b2ce4d1 100644
--- a/Source/core/animation/css/CSSPendingAnimations.h
+++ b/Source/core/animation/css/CSSPendingAnimations.h
@@ -35,21 +35,21 @@
 
 namespace WebCore {
 
-class Player;
+class AnimationPlayer;
 
 // Used to synchronize the start of main-thread animations with compositor
 // animations when both classes of CSS Animations are triggered by the same recalc
 class CSSPendingAnimations FINAL {
 public:
-    void add(Player*);
+    void add(AnimationPlayer*);
     // Returns whether we are waiting for an animation to start and should
     // service again on the next frame.
     bool startPendingAnimations();
     void notifyCompositorAnimationStarted(double monotonicAnimationStartTime);
 
 private:
-    Vector<std::pair<RefPtr<Player>, double> > m_pending;
-    Vector<RefPtr<Player> > m_waitingForCompositorAnimationStart;
+    Vector<RefPtr<AnimationPlayer> > m_pending;
+    Vector<RefPtr<AnimationPlayer> > m_waitingForCompositorAnimationStart;
 };
 
 } // namespace WebCore
diff --git a/Source/core/animation/css/CSSPropertyAnimation.cpp b/Source/core/animation/css/CSSPropertyAnimation.cpp
deleted file mode 100644
index bfc0885..0000000
--- a/Source/core/animation/css/CSSPropertyAnimation.cpp
+++ /dev/null
@@ -1,610 +0,0 @@
-/*
- * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/animation/css/CSSPropertyAnimation.h"
-
-#include <algorithm>
-#include "StylePropertyShorthand.h"
-#include "core/animation/css/CSSAnimations.h"
-#include "core/css/CSSCrossfadeValue.h"
-#include "core/css/CSSImageValue.h"
-#include "core/css/CSSPrimitiveValue.h"
-#include "core/fetch/ImageResource.h"
-#include "core/rendering/ClipPathOperation.h"
-#include "core/rendering/RenderBox.h"
-#include "core/rendering/style/RenderStyle.h"
-#include "core/rendering/style/ShadowList.h"
-#include "core/rendering/style/StyleFetchedImage.h"
-#include "core/rendering/style/StyleGeneratedImage.h"
-#include "platform/FloatConversion.h"
-#include "wtf/Noncopyable.h"
-
-namespace WebCore {
-
-class AnimationPropertyWrapperBase {
-    WTF_MAKE_NONCOPYABLE(AnimationPropertyWrapperBase);
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    AnimationPropertyWrapperBase(CSSPropertyID prop)
-        : m_prop(prop)
-    {
-    }
-
-    virtual ~AnimationPropertyWrapperBase() { }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const = 0;
-
-    CSSPropertyID property() const { return m_prop; }
-
-private:
-    CSSPropertyID m_prop;
-};
-
-static int gPropertyWrapperMap[numCSSProperties];
-static const int cInvalidPropertyWrapperIndex = -1;
-static Vector<AnimationPropertyWrapperBase*>* gPropertyWrappers = 0;
-
-static AnimationPropertyWrapperBase* wrapperForProperty(CSSPropertyID propertyID)
-{
-    int propIndex = propertyID - firstCSSProperty;
-    if (propIndex >= 0 && propIndex < numCSSProperties) {
-        int wrapperIndex = gPropertyWrapperMap[propIndex];
-        if (wrapperIndex >= 0)
-            return (*gPropertyWrappers)[wrapperIndex];
-    }
-    return 0;
-}
-
-template <typename T>
-class PropertyWrapperGetter : public AnimationPropertyWrapperBase {
-public:
-    PropertyWrapperGetter(CSSPropertyID prop, T (RenderStyle::*getter)() const)
-        : AnimationPropertyWrapperBase(prop)
-        , m_getter(getter)
-    {
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
-    {
-        // If the style pointers are the same, don't bother doing the test.
-        // If either is null, return false. If both are null, return true.
-        if ((!a && !b) || a == b)
-            return true;
-        if (!a || !b)
-            return false;
-        return (a->*m_getter)() == (b->*m_getter)();
-    }
-
-protected:
-    T (RenderStyle::*m_getter)() const;
-};
-
-template <typename T>
-class PropertyWrapper : public PropertyWrapperGetter<T> {
-public:
-    PropertyWrapper(CSSPropertyID prop, T (RenderStyle::*getter)() const)
-        : PropertyWrapperGetter<T>(prop, getter)
-    {
-    }
-};
-
-template <typename T>
-class RefCountedPropertyWrapper : public PropertyWrapperGetter<T*> {
-public:
-    RefCountedPropertyWrapper(CSSPropertyID prop, T* (RenderStyle::*getter)() const)
-        : PropertyWrapperGetter<T*>(prop, getter)
-    {
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-        if (a == b)
-            return true;
-        if (!a || !b)
-            return false;
-        const T* aValue = (a->*this->m_getter)();
-        const T* bValue = (b->*this->m_getter)();
-        if (aValue == bValue)
-            return true;
-        if (!aValue || !bValue)
-            return false;
-        return *aValue == *bValue;
-    }
-};
-
-
-class StyleImagePropertyWrapper FINAL : public RefCountedPropertyWrapper<StyleImage> {
-public:
-    StyleImagePropertyWrapper(CSSPropertyID prop, StyleImage* (RenderStyle::*getter)() const)
-        : RefCountedPropertyWrapper<StyleImage>(prop, getter)
-    {
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-       // If the style pointers are the same, don't bother doing the test.
-       // If either is null, return false. If both are null, return true.
-       if (a == b)
-           return true;
-       if (!a || !b)
-            return false;
-
-        StyleImage* imageA = (a->*m_getter)();
-        StyleImage* imageB = (b->*m_getter)();
-        return StyleImage::imagesEquivalent(imageA, imageB);
-    }
-};
-
-class PropertyWrapperShadow FINAL : public AnimationPropertyWrapperBase {
-public:
-    PropertyWrapperShadow(CSSPropertyID prop, ShadowList* (RenderStyle::*getter)() const)
-        : AnimationPropertyWrapperBase(prop)
-        , m_getter(getter)
-    {
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-        const ShadowList* shadowA = (a->*m_getter)();
-        const ShadowList* shadowB = (b->*m_getter)();
-        if (shadowA == shadowB)
-            return true;
-        if (shadowA && shadowB)
-            return *shadowA == *shadowB;
-        return false;
-    }
-
-    ShadowList* (RenderStyle::*m_getter)() const;
-};
-
-class PropertyWrapperMaybeInvalidStyleColor FINAL : public AnimationPropertyWrapperBase {
-public:
-    PropertyWrapperMaybeInvalidStyleColor(CSSPropertyID prop, StyleColor (RenderStyle::*getter)() const)
-        : AnimationPropertyWrapperBase(prop)
-        , m_getter(getter)
-    {
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-        StyleColor fromColor = (a->*m_getter)();
-        StyleColor toColor = (b->*m_getter)();
-
-        if (fromColor.isCurrentColor() && toColor.isCurrentColor())
-            return true;
-
-        return fromColor.resolve(a->color()) == toColor.resolve(b->color());
-    }
-
-private:
-    StyleColor (RenderStyle::*m_getter)() const;
-};
-
-
-class PropertyWrapperVisitedAffectedColor FINAL : public AnimationPropertyWrapperBase {
-public:
-    PropertyWrapperVisitedAffectedColor(CSSPropertyID prop, Color (RenderStyle::*getter)() const, Color (RenderStyle::*visitedGetter)() const)
-        : AnimationPropertyWrapperBase(prop)
-        , m_wrapper(adoptPtr(new PropertyWrapper<Color>(prop, getter)))
-        , m_visitedWrapper(adoptPtr(new PropertyWrapper<Color>(prop, visitedGetter)))
-    {
-    }
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const
-    {
-        return m_wrapper->equals(a, b) && m_visitedWrapper->equals(a, b);
-    }
-
-private:
-    OwnPtr<AnimationPropertyWrapperBase> m_wrapper;
-    OwnPtr<AnimationPropertyWrapperBase> m_visitedWrapper;
-};
-
-class PropertyWrapperVisitedAffectedStyleColor FINAL : public AnimationPropertyWrapperBase {
-public:
-    PropertyWrapperVisitedAffectedStyleColor(CSSPropertyID prop, StyleColor (RenderStyle::*getter)() const, StyleColor (RenderStyle::*visitedGetter)() const)
-        : AnimationPropertyWrapperBase(prop)
-        , m_wrapper(adoptPtr(new PropertyWrapperMaybeInvalidStyleColor(prop, getter)))
-        , m_visitedWrapper(adoptPtr(new PropertyWrapperMaybeInvalidStyleColor(prop, visitedGetter)))
-    {
-    }
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-        return m_wrapper->equals(a, b) && m_visitedWrapper->equals(a, b);
-    }
-
-private:
-    OwnPtr<AnimationPropertyWrapperBase> m_wrapper;
-    OwnPtr<AnimationPropertyWrapperBase> m_visitedWrapper;
-};
-
-// Wrapper base class for an animatable property in a FillLayer
-class FillLayerAnimationPropertyWrapperBase {
-public:
-    FillLayerAnimationPropertyWrapperBase()
-    {
-    }
-
-    virtual ~FillLayerAnimationPropertyWrapperBase() { }
-
-    virtual bool equals(const FillLayer*, const FillLayer*) const = 0;
-};
-
-template <typename T>
-class FillLayerPropertyWrapperGetter : public FillLayerAnimationPropertyWrapperBase {
-    WTF_MAKE_NONCOPYABLE(FillLayerPropertyWrapperGetter);
-public:
-    FillLayerPropertyWrapperGetter(T (FillLayer::*getter)() const)
-        : m_getter(getter)
-    {
-    }
-
-    virtual bool equals(const FillLayer* a, const FillLayer* b) const
-    {
-       // If the style pointers are the same, don't bother doing the test.
-       // If either is null, return false. If both are null, return true.
-       if ((!a && !b) || a == b)
-           return true;
-       if (!a || !b)
-            return false;
-        return (a->*m_getter)() == (b->*m_getter)();
-    }
-
-protected:
-    T (FillLayer::*m_getter)() const;
-};
-
-template <typename T>
-class FillLayerPropertyWrapper FINAL : public FillLayerPropertyWrapperGetter<T> {
-public:
-    FillLayerPropertyWrapper(T (FillLayer::*getter)() const)
-        : FillLayerPropertyWrapperGetter<T>(getter)
-    {
-    }
-};
-
-template <typename T>
-class FillLayerRefCountedPropertyWrapper : public FillLayerPropertyWrapperGetter<T*> {
-public:
-    FillLayerRefCountedPropertyWrapper(T* (FillLayer::*getter)() const)
-        : FillLayerPropertyWrapperGetter<T*>(getter)
-    {
-    }
-};
-
-class FillLayerStyleImagePropertyWrapper FINAL : public FillLayerRefCountedPropertyWrapper<StyleImage> {
-public:
-    FillLayerStyleImagePropertyWrapper(StyleImage* (FillLayer::*getter)() const)
-        : FillLayerRefCountedPropertyWrapper<StyleImage>(getter)
-    {
-    }
-
-    virtual bool equals(const FillLayer* a, const FillLayer* b) const OVERRIDE
-    {
-       // If the style pointers are the same, don't bother doing the test.
-       // If either is null, return false. If both are null, return true.
-       if (a == b)
-           return true;
-       if (!a || !b)
-            return false;
-
-        StyleImage* imageA = (a->*m_getter)();
-        StyleImage* imageB = (b->*m_getter)();
-        return StyleImage::imagesEquivalent(imageA, imageB);
-    }
-};
-
-
-class FillLayersPropertyWrapper FINAL : public AnimationPropertyWrapperBase {
-public:
-    typedef const FillLayer* (RenderStyle::*LayersGetter)() const;
-
-    FillLayersPropertyWrapper(CSSPropertyID prop, LayersGetter getter)
-        : AnimationPropertyWrapperBase(prop)
-        , m_layersGetter(getter)
-    {
-        switch (prop) {
-        case CSSPropertyBackgroundPositionX:
-        case CSSPropertyWebkitMaskPositionX:
-            m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::xPosition);
-            break;
-        case CSSPropertyBackgroundPositionY:
-        case CSSPropertyWebkitMaskPositionY:
-            m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<Length>(&FillLayer::yPosition);
-            break;
-        case CSSPropertyBackgroundSize:
-        case CSSPropertyWebkitBackgroundSize:
-        case CSSPropertyWebkitMaskSize:
-            m_fillLayerPropertyWrapper = new FillLayerPropertyWrapper<LengthSize>(&FillLayer::sizeLength);
-            break;
-        case CSSPropertyBackgroundImage:
-            m_fillLayerPropertyWrapper = new FillLayerStyleImagePropertyWrapper(&FillLayer::image);
-            break;
-        default:
-            break;
-        }
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-        const FillLayer* fromLayer = (a->*m_layersGetter)();
-        const FillLayer* toLayer = (b->*m_layersGetter)();
-
-        while (fromLayer && toLayer) {
-            if (!m_fillLayerPropertyWrapper->equals(fromLayer, toLayer))
-                return false;
-
-            fromLayer = fromLayer->next();
-            toLayer = toLayer->next();
-        }
-
-        return true;
-    }
-
-private:
-    FillLayerAnimationPropertyWrapperBase* m_fillLayerPropertyWrapper;
-
-    LayersGetter m_layersGetter;
-};
-
-class PropertyWrapperSVGPaint FINAL : public AnimationPropertyWrapperBase {
-public:
-    PropertyWrapperSVGPaint(CSSPropertyID prop, const SVGPaint::SVGPaintType& (RenderStyle::*paintTypeGetter)() const, Color (RenderStyle::*getter)() const)
-        : AnimationPropertyWrapperBase(prop)
-        , m_paintTypeGetter(paintTypeGetter)
-        , m_getter(getter)
-    {
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-        if ((a->*m_paintTypeGetter)() != (b->*m_paintTypeGetter)())
-            return false;
-
-        // We only support animations between SVGPaints that are pure Color values.
-        // For everything else we must return true for this method, otherwise
-        // we will try to animate between values forever.
-        if ((a->*m_paintTypeGetter)() == SVGPaint::SVG_PAINTTYPE_RGBCOLOR) {
-            Color fromColor = (a->*m_getter)();
-            Color toColor = (b->*m_getter)();
-            return fromColor == toColor;
-        }
-        return true;
-    }
-
-private:
-    const SVGPaint::SVGPaintType& (RenderStyle::*m_paintTypeGetter)() const;
-    Color (RenderStyle::*m_getter)() const;
-};
-
-template <typename T>
-class RefCountedSVGPropertyWrapper : public AnimationPropertyWrapperBase {
-public:
-    RefCountedSVGPropertyWrapper(CSSPropertyID prop, PassRefPtr<T> (RenderStyle::*getter)() const)
-        : AnimationPropertyWrapperBase(prop)
-        , m_getter(getter)
-    {
-    }
-
-    virtual bool equals(const RenderStyle* a, const RenderStyle* b) const OVERRIDE
-    {
-        if (a == b)
-            return true;
-        if (!a || !b)
-            return false;
-        RefPtr<T> aValue = (a->*this->m_getter)();
-        RefPtr<T> bValue = (b->*this->m_getter)();
-        if (aValue == bValue)
-            return true;
-        if (!aValue || !bValue)
-            return false;
-        return *aValue == *bValue;
-    }
-
-protected:
-    PassRefPtr<T> (RenderStyle::*m_getter)() const;
-};
-
-void CSSPropertyAnimation::ensurePropertyMap()
-{
-    // FIXME: This data is never destroyed. Maybe we should ref count it and toss it when the last AnimationController is destroyed?
-    if (gPropertyWrappers)
-        return;
-
-    gPropertyWrappers = new Vector<AnimationPropertyWrapperBase*>();
-
-    // build the list of property wrappers to do the comparisons and blends
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLeft, &RenderStyle::left));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyRight, &RenderStyle::right));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyTop, &RenderStyle::top));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyBottom, &RenderStyle::bottom));
-
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWidth, &RenderStyle::width));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMinWidth, &RenderStyle::minWidth));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMaxWidth, &RenderStyle::maxWidth));
-
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyHeight, &RenderStyle::height));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMinHeight, &RenderStyle::minHeight));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMaxHeight, &RenderStyle::maxHeight));
-
-    gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderLeftWidth, &RenderStyle::borderLeftWidth));
-    gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderRightWidth, &RenderStyle::borderRightWidth));
-    gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderTopWidth, &RenderStyle::borderTopWidth));
-    gPropertyWrappers->append(new PropertyWrapper<unsigned>(CSSPropertyBorderBottomWidth, &RenderStyle::borderBottomWidth));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginLeft, &RenderStyle::marginLeft));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginRight, &RenderStyle::marginRight));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginTop, &RenderStyle::marginTop));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyMarginBottom, &RenderStyle::marginBottom));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingLeft, &RenderStyle::paddingLeft));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingRight, &RenderStyle::paddingRight));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingTop, &RenderStyle::paddingTop));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyPaddingBottom, &RenderStyle::paddingBottom));
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedColor(CSSPropertyColor, &RenderStyle::color, &RenderStyle::visitedLinkColor));
-
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyBackgroundColor, &RenderStyle::backgroundColor, &RenderStyle::visitedLinkBackgroundColor));
-
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundImage, &RenderStyle::backgroundLayers));
-    gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyListStyleImage, &RenderStyle::listStyleImage));
-    gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskImage, &RenderStyle::maskImage));
-
-    gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyBorderImageSource, &RenderStyle::borderImageSource));
-    gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyBorderImageSlice, &RenderStyle::borderImageSlices));
-    gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyBorderImageWidth, &RenderStyle::borderImageWidth));
-    gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyBorderImageOutset, &RenderStyle::borderImageOutset));
-
-    gPropertyWrappers->append(new StyleImagePropertyWrapper(CSSPropertyWebkitMaskBoxImageSource, &RenderStyle::maskBoxImageSource));
-    gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyWebkitMaskBoxImageSlice, &RenderStyle::maskBoxImageSlices));
-    gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyWebkitMaskBoxImageWidth, &RenderStyle::maskBoxImageWidth));
-    gPropertyWrappers->append(new PropertyWrapper<const BorderImageLengthBox&>(CSSPropertyWebkitMaskBoxImageOutset, &RenderStyle::maskBoxImageOutset));
-
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionX, &RenderStyle::backgroundLayers));
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundPositionY, &RenderStyle::backgroundLayers));
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyBackgroundSize, &RenderStyle::backgroundLayers));
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitBackgroundSize, &RenderStyle::backgroundLayers));
-
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionX, &RenderStyle::maskLayers));
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskPositionY, &RenderStyle::maskLayers));
-    gPropertyWrappers->append(new FillLayersPropertyWrapper(CSSPropertyWebkitMaskSize, &RenderStyle::maskLayers));
-
-    gPropertyWrappers->append(new PropertyWrapper<LengthPoint>(CSSPropertyObjectPosition, &RenderStyle::objectPosition));
-
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFontSize,
-        // Must pass a specified size to setFontSize if Text Autosizing is enabled, but a computed size
-        // if text zoom is enabled (if neither is enabled it's irrelevant as they're probably the same).
-        // FIXME: Should we introduce an option to pass the computed font size here, allowing consumers to
-        // enable text zoom rather than Text Autosizing? See http://crbug.com/227545.
-        &RenderStyle::specifiedFontSize));
-    gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnRuleWidth, &RenderStyle::columnRuleWidth));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnGap, &RenderStyle::columnGap));
-    gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyWebkitColumnCount, &RenderStyle::columnCount));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitColumnWidth, &RenderStyle::columnWidth));
-    gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderHorizontalSpacing, &RenderStyle::horizontalBorderSpacing));
-    gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWebkitBorderVerticalSpacing, &RenderStyle::verticalBorderSpacing));
-    gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyZIndex, &RenderStyle::zIndex));
-    gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyOrphans, &RenderStyle::orphans));
-    gPropertyWrappers->append(new PropertyWrapper<short>(CSSPropertyWidows, &RenderStyle::widows));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyLineHeight, &RenderStyle::specifiedLineHeight));
-    gPropertyWrappers->append(new PropertyWrapper<int>(CSSPropertyOutlineOffset, &RenderStyle::outlineOffset));
-    gPropertyWrappers->append(new PropertyWrapper<unsigned short>(CSSPropertyOutlineWidth, &RenderStyle::outlineWidth));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyLetterSpacing, &RenderStyle::letterSpacing));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWordSpacing, &RenderStyle::wordSpacing));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyTextIndent, &RenderStyle::textIndent));
-
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitPerspective, &RenderStyle::perspective));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginX, &RenderStyle::perspectiveOriginX));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitPerspectiveOriginY, &RenderStyle::perspectiveOriginY));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginX, &RenderStyle::transformOriginX));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyWebkitTransformOriginY, &RenderStyle::transformOriginY));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyWebkitTransformOriginZ, &RenderStyle::transformOriginZ));
-    gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderTopLeftRadius, &RenderStyle::borderTopLeftRadius));
-    gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderTopRightRadius, &RenderStyle::borderTopRightRadius));
-    gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderBottomLeftRadius, &RenderStyle::borderBottomLeftRadius));
-    gPropertyWrappers->append(new PropertyWrapper<LengthSize>(CSSPropertyBorderBottomRightRadius, &RenderStyle::borderBottomRightRadius));
-    gPropertyWrappers->append(new PropertyWrapper<EVisibility>(CSSPropertyVisibility, &RenderStyle::visibility));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyZoom, &RenderStyle::zoom));
-
-    gPropertyWrappers->append(new PropertyWrapper<LengthBox>(CSSPropertyClip, &RenderStyle::clip));
-
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyOpacity, &RenderStyle::opacity));
-    gPropertyWrappers->append(new PropertyWrapper<const TransformOperations&>(CSSPropertyWebkitTransform, &RenderStyle::transform));
-    gPropertyWrappers->append(new PropertyWrapper<const FilterOperations&>(CSSPropertyWebkitFilter, &RenderStyle::filter));
-
-    gPropertyWrappers->append(new RefCountedPropertyWrapper<ClipPathOperation>(CSSPropertyWebkitClipPath, &RenderStyle::clipPath));
-
-    gPropertyWrappers->append(new RefCountedPropertyWrapper<ShapeValue>(CSSPropertyShapeInside, &RenderStyle::shapeInside));
-    gPropertyWrappers->append(new RefCountedPropertyWrapper<ShapeValue>(CSSPropertyShapeOutside, &RenderStyle::shapeOutside));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyShapeMargin, &RenderStyle::shapeMargin));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyShapeImageThreshold, &RenderStyle::shapeImageThreshold));
-
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyWebkitColumnRuleColor, &RenderStyle::columnRuleColor, &RenderStyle::visitedLinkColumnRuleColor));
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyWebkitTextStrokeColor, &RenderStyle::textStrokeColor, &RenderStyle::visitedLinkTextStrokeColor));
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyBorderLeftColor, &RenderStyle::borderLeftColor, &RenderStyle::visitedLinkBorderLeftColor));
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyBorderRightColor, &RenderStyle::borderRightColor, &RenderStyle::visitedLinkBorderRightColor));
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyBorderTopColor, &RenderStyle::borderTopColor, &RenderStyle::visitedLinkBorderTopColor));
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyBorderBottomColor, &RenderStyle::borderBottomColor, &RenderStyle::visitedLinkBorderBottomColor));
-    gPropertyWrappers->append(new PropertyWrapperVisitedAffectedStyleColor(CSSPropertyOutlineColor, &RenderStyle::outlineColor, &RenderStyle::visitedLinkOutlineColor));
-
-    gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyBoxShadow, &RenderStyle::boxShadow));
-    gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyWebkitBoxShadow, &RenderStyle::boxShadow));
-    gPropertyWrappers->append(new PropertyWrapperShadow(CSSPropertyTextShadow, &RenderStyle::textShadow));
-
-    gPropertyWrappers->append(new PropertyWrapperSVGPaint(CSSPropertyFill, &RenderStyle::fillPaintType, &RenderStyle::fillPaintColor));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFillOpacity, &RenderStyle::fillOpacity));
-
-    gPropertyWrappers->append(new PropertyWrapperSVGPaint(CSSPropertyStroke, &RenderStyle::strokePaintType, &RenderStyle::strokePaintColor));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStrokeOpacity, &RenderStyle::strokeOpacity));
-    gPropertyWrappers->append(new RefCountedSVGPropertyWrapper<SVGLength>(CSSPropertyStrokeWidth, &RenderStyle::strokeWidth));
-    gPropertyWrappers->append(new RefCountedSVGPropertyWrapper<SVGLengthList>(CSSPropertyStrokeDasharray, &RenderStyle::strokeDashArray));
-    gPropertyWrappers->append(new RefCountedSVGPropertyWrapper<SVGLength>(CSSPropertyStrokeDashoffset, &RenderStyle::strokeDashOffset));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStrokeMiterlimit, &RenderStyle::strokeMiterLimit));
-
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFloodOpacity, &RenderStyle::floodOpacity));
-    gPropertyWrappers->append(new PropertyWrapper<Color>(CSSPropertyFloodColor, &RenderStyle::floodColor));
-
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyStopOpacity, &RenderStyle::stopOpacity));
-    gPropertyWrappers->append(new PropertyWrapper<Color>(CSSPropertyStopColor, &RenderStyle::stopColor));
-
-    gPropertyWrappers->append(new PropertyWrapper<Color>(CSSPropertyLightingColor, &RenderStyle::lightingColor));
-
-    gPropertyWrappers->append(new RefCountedSVGPropertyWrapper<SVGLength>(CSSPropertyBaselineShift, &RenderStyle::baselineShiftValue));
-    gPropertyWrappers->append(new RefCountedSVGPropertyWrapper<SVGLength>(CSSPropertyKerning, &RenderStyle::kerning));
-
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFlexGrow, &RenderStyle::flexGrow));
-    gPropertyWrappers->append(new PropertyWrapper<float>(CSSPropertyFlexShrink, &RenderStyle::flexShrink));
-    gPropertyWrappers->append(new PropertyWrapper<Length>(CSSPropertyFlexBasis, &RenderStyle::flexBasis));
-
-    // TODO:
-    //
-    //  CSSPropertyVerticalAlign
-
-    // Make sure unused slots have a value
-    for (unsigned int i = 0; i < static_cast<unsigned int>(numCSSProperties); ++i)
-        gPropertyWrapperMap[i] = cInvalidPropertyWrapperIndex;
-
-    size_t n = gPropertyWrappers->size();
-    for (unsigned int i = 0; i < n; ++i) {
-        CSSPropertyID property = (*gPropertyWrappers)[i]->property();
-        ASSERT_WITH_MESSAGE(CSSAnimations::isAnimatableProperty(property), "%s is not whitelisted for animation", getPropertyNameString(property).utf8().data());
-        ASSERT(property - firstCSSProperty < numCSSProperties);
-        gPropertyWrapperMap[property - firstCSSProperty] = i;
-    }
-}
-
-bool CSSPropertyAnimation::propertiesEqual(CSSPropertyID prop, const RenderStyle* a, const RenderStyle* b)
-{
-    // FIXME: transitions of text-decoration-color are broken
-    if (prop == CSSPropertyTextDecorationColor)
-        return true;
-
-    ensurePropertyMap();
-    return wrapperForProperty(prop)->equals(a, b);
-}
-
-
-}
diff --git a/Source/core/animation/css/CSSPropertyAnimation.h b/Source/core/animation/css/CSSPropertyAnimation.h
deleted file mode 100644
index 148c9ca..0000000
--- a/Source/core/animation/css/CSSPropertyAnimation.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
- *     its contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef CSSPropertyAnimation_h
-#define CSSPropertyAnimation_h
-
-#include "CSSPropertyNames.h"
-
-namespace WebCore {
-
-class RenderStyle;
-
-class CSSPropertyAnimation {
-public:
-    static bool propertiesEqual(CSSPropertyID, const RenderStyle*, const RenderStyle*);
-
-private:
-    static void ensurePropertyMap();
-};
-
-} // namespace WebCore
-
-#endif // CSSPropertyAnimation_h
diff --git a/Source/core/animation/css/CSSPropertyEquality.cpp b/Source/core/animation/css/CSSPropertyEquality.cpp
new file mode 100644
index 0000000..b386ec1
--- /dev/null
+++ b/Source/core/animation/css/CSSPropertyEquality.cpp
@@ -0,0 +1,310 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/animation/css/CSSPropertyEquality.h"
+
+#include "core/animation/css/CSSAnimations.h"
+#include "core/rendering/style/RenderStyle.h"
+#include "core/rendering/style/ShadowList.h"
+
+namespace WebCore {
+
+namespace {
+
+template <CSSPropertyID property>
+bool fillLayersEqual(const FillLayer* aLayer, const FillLayer* bLayer)
+{
+    if (aLayer == bLayer)
+        return true;
+    if (!aLayer || !bLayer)
+        return false;
+    while (aLayer && bLayer) {
+        switch (property) {
+        case CSSPropertyBackgroundPositionX:
+        case CSSPropertyWebkitMaskPositionX:
+            if (aLayer->xPosition() != bLayer->xPosition())
+                return false;
+            break;
+        case CSSPropertyBackgroundPositionY:
+        case CSSPropertyWebkitMaskPositionY:
+            if (aLayer->yPosition() != bLayer->yPosition())
+                return false;
+            break;
+        case CSSPropertyBackgroundSize:
+        case CSSPropertyWebkitBackgroundSize:
+        case CSSPropertyWebkitMaskSize:
+            if (!(aLayer->sizeLength() == bLayer->sizeLength()))
+                return false;
+            break;
+        case CSSPropertyBackgroundImage:
+            if (!StyleImage::imagesEquivalent(aLayer->image(), bLayer->image()))
+                return false;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+            return true;
+        }
+
+        aLayer = aLayer->next();
+        bLayer = bLayer->next();
+    }
+
+    // FIXME: Shouldn't this be return !aLayer && !bLayer; ?
+    return true;
+}
+
+template <typename T>
+bool ptrsOrValuesEqual(T a, T b)
+{
+    return a == b || (a && b && *a == *b);
+}
+
+}
+
+bool CSSPropertyEquality::propertiesEqual(CSSPropertyID prop, const RenderStyle& a, const RenderStyle& b)
+{
+    switch (prop) {
+    case CSSPropertyBackgroundColor:
+        return a.backgroundColor().resolve(a.color()) == b.backgroundColor().resolve(b.color())
+            && a.visitedLinkBackgroundColor().resolve(a.color()) == b.visitedLinkBackgroundColor().resolve(b.color());
+    case CSSPropertyBackgroundImage:
+        return fillLayersEqual<CSSPropertyBackgroundImage>(a.backgroundLayers(), b.backgroundLayers());
+    case CSSPropertyBackgroundPositionX:
+        return fillLayersEqual<CSSPropertyBackgroundPositionX>(a.backgroundLayers(), b.backgroundLayers());
+    case CSSPropertyBackgroundPositionY:
+        return fillLayersEqual<CSSPropertyBackgroundPositionY>(a.backgroundLayers(), b.backgroundLayers());
+    case CSSPropertyBackgroundSize:
+        return fillLayersEqual<CSSPropertyBackgroundSize>(a.backgroundLayers(), b.backgroundLayers());
+    case CSSPropertyBaselineShift:
+        return ptrsOrValuesEqual<PassRefPtr<SVGLength> >(a.baselineShiftValue(), b.baselineShiftValue());
+    case CSSPropertyBorderBottomColor:
+        return a.borderBottomColor().resolve(a.color()) == b.borderBottomColor().resolve(b.color())
+            && a.visitedLinkBorderBottomColor().resolve(a.color()) == b.visitedLinkBorderBottomColor().resolve(b.color());
+    case CSSPropertyBorderBottomLeftRadius:
+        return a.borderBottomLeftRadius() == b.borderBottomLeftRadius();
+    case CSSPropertyBorderBottomRightRadius:
+        return a.borderBottomRightRadius() == b.borderBottomRightRadius();
+    case CSSPropertyBorderBottomWidth:
+        return a.borderBottomWidth() == b.borderBottomWidth();
+    case CSSPropertyBorderImageOutset:
+        return a.borderImageOutset() == b.borderImageOutset();
+    case CSSPropertyBorderImageSlice:
+        return a.borderImageSlices() == b.borderImageSlices();
+    case CSSPropertyBorderImageSource:
+        return ptrsOrValuesEqual<StyleImage*>(a.borderImageSource(), b.borderImageSource());
+    case CSSPropertyBorderImageWidth:
+        return a.borderImageWidth() == b.borderImageWidth();
+    case CSSPropertyBorderLeftColor:
+        return a.borderLeftColor().resolve(a.color()) == b.borderLeftColor().resolve(b.color())
+            && a.visitedLinkBorderLeftColor().resolve(a.color()) == b.visitedLinkBorderLeftColor().resolve(b.color());
+    case CSSPropertyBorderLeftWidth:
+        return a.borderLeftWidth() == b.borderLeftWidth();
+    case CSSPropertyBorderRightColor:
+        return a.borderRightColor().resolve(a.color()) == b.borderRightColor().resolve(b.color())
+            && a.visitedLinkBorderRightColor().resolve(a.color()) == b.visitedLinkBorderRightColor().resolve(b.color());
+    case CSSPropertyBorderRightWidth:
+        return a.borderRightWidth() == b.borderRightWidth();
+    case CSSPropertyBorderTopColor:
+        return a.borderTopColor().resolve(a.color()) == b.borderTopColor().resolve(b.color())
+            && a.visitedLinkBorderTopColor().resolve(a.color()) == b.visitedLinkBorderTopColor().resolve(b.color());
+    case CSSPropertyBorderTopLeftRadius:
+        return a.borderTopLeftRadius() == b.borderTopLeftRadius();
+    case CSSPropertyBorderTopRightRadius:
+        return a.borderTopRightRadius() == b.borderTopRightRadius();
+    case CSSPropertyBorderTopWidth:
+        return a.borderTopWidth() == b.borderTopWidth();
+    case CSSPropertyBottom:
+        return a.bottom() == b.bottom();
+    case CSSPropertyBoxShadow:
+        return ptrsOrValuesEqual<ShadowList*>(a.boxShadow(), b.boxShadow());
+    case CSSPropertyClip:
+        return a.clip() == b.clip();
+    case CSSPropertyColor:
+        return a.color() == b.color() && a.visitedLinkColor() == b.visitedLinkColor();
+    case CSSPropertyFill:
+        return a.fillPaintType() == b.fillPaintType()
+            && (a.fillPaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || a.fillPaintColor() == b.fillPaintColor());
+    case CSSPropertyFillOpacity:
+        return a.fillOpacity() == b.fillOpacity();
+    case CSSPropertyFlexBasis:
+        return a.flexBasis() == b.flexBasis();
+    case CSSPropertyFlexGrow:
+        return a.flexGrow() == b.flexGrow();
+    case CSSPropertyFlexShrink:
+        return a.flexShrink() == b.flexShrink();
+    case CSSPropertyFloodColor:
+        return a.floodColor() == b.floodColor();
+    case CSSPropertyFloodOpacity:
+        return a.floodOpacity() == b.floodOpacity();
+    case CSSPropertyFontSize:
+        // CSSPropertyFontSize: Must pass a specified size to setFontSize if Text Autosizing is enabled, but a computed size
+        // if text zoom is enabled (if neither is enabled it's irrelevant as they're probably the same).
+        // FIXME: Should we introduce an option to pass the computed font size here, allowing consumers to
+        // enable text zoom rather than Text Autosizing? See http://crbug.com/227545.
+        return a.specifiedFontSize() == b.specifiedFontSize();
+    case CSSPropertyFontWeight:
+        return a.fontWeight() == b.fontWeight();
+    case CSSPropertyHeight:
+        return a.height() == b.height();
+    case CSSPropertyKerning:
+        return ptrsOrValuesEqual<PassRefPtr<SVGLength> >(a.kerning(), b.kerning());
+    case CSSPropertyLeft:
+        return a.left() == b.left();
+    case CSSPropertyLetterSpacing:
+        return a.letterSpacing() == b.letterSpacing();
+    case CSSPropertyLightingColor:
+        return a.lightingColor() == b.lightingColor();
+    case CSSPropertyLineHeight:
+        return a.specifiedLineHeight() == b.specifiedLineHeight();
+    case CSSPropertyListStyleImage:
+        return ptrsOrValuesEqual<StyleImage*>(a.listStyleImage(), b.listStyleImage());
+    case CSSPropertyMarginBottom:
+        return a.marginBottom() == b.marginBottom();
+    case CSSPropertyMarginLeft:
+        return a.marginLeft() == b.marginLeft();
+    case CSSPropertyMarginRight:
+        return a.marginRight() == b.marginRight();
+    case CSSPropertyMarginTop:
+        return a.marginTop() == b.marginTop();
+    case CSSPropertyMaxHeight:
+        return a.maxHeight() == b.maxHeight();
+    case CSSPropertyMaxWidth:
+        return a.maxWidth() == b.maxWidth();
+    case CSSPropertyMinHeight:
+        return a.minHeight() == b.minHeight();
+    case CSSPropertyMinWidth:
+        return a.minWidth() == b.minWidth();
+    case CSSPropertyObjectPosition:
+        return a.objectPosition() == b.objectPosition();
+    case CSSPropertyOpacity:
+        return a.opacity() == b.opacity();
+    case CSSPropertyOrphans:
+        return a.orphans() == b.orphans();
+    case CSSPropertyOutlineColor:
+        return a.outlineColor().resolve(a.color()) == b.outlineColor().resolve(b.color())
+            && a.visitedLinkOutlineColor().resolve(a.color()) == b.visitedLinkOutlineColor().resolve(b.color());
+    case CSSPropertyOutlineOffset:
+        return a.outlineOffset() == b.outlineOffset();
+    case CSSPropertyOutlineWidth:
+        return a.outlineWidth() == b.outlineWidth();
+    case CSSPropertyPaddingBottom:
+        return a.paddingBottom() == b.paddingBottom();
+    case CSSPropertyPaddingLeft:
+        return a.paddingLeft() == b.paddingLeft();
+    case CSSPropertyPaddingRight:
+        return a.paddingRight() == b.paddingRight();
+    case CSSPropertyPaddingTop:
+        return a.paddingTop() == b.paddingTop();
+    case CSSPropertyRight:
+        return a.right() == b.right();
+    case CSSPropertyShapeImageThreshold:
+        return a.shapeImageThreshold() == b.shapeImageThreshold();
+    case CSSPropertyShapeInside:
+        return ptrsOrValuesEqual<ShapeValue*>(a.shapeInside(), b.shapeInside());
+    case CSSPropertyShapeMargin:
+        return a.shapeMargin() == b.shapeMargin();
+    case CSSPropertyShapeOutside:
+        return ptrsOrValuesEqual<ShapeValue*>(a.shapeOutside(), b.shapeOutside());
+    case CSSPropertyStopColor:
+        return a.stopColor() == b.stopColor();
+    case CSSPropertyStopOpacity:
+        return a.stopOpacity() == b.stopOpacity();
+    case CSSPropertyStroke:
+        return a.strokePaintType() == b.strokePaintType()
+            && (a.strokePaintType() != SVGPaint::SVG_PAINTTYPE_RGBCOLOR || a.strokePaintColor() == b.strokePaintColor());
+    case CSSPropertyStrokeDasharray:
+        return ptrsOrValuesEqual<PassRefPtr<SVGLengthList> >(a.strokeDashArray(), b.strokeDashArray());
+    case CSSPropertyStrokeDashoffset:
+        return ptrsOrValuesEqual<PassRefPtr<SVGLength> >(a.strokeDashOffset(), b.strokeDashOffset());
+    case CSSPropertyStrokeMiterlimit:
+        return a.strokeMiterLimit() == b.strokeMiterLimit();
+    case CSSPropertyStrokeOpacity:
+        return a.strokeOpacity() == b.strokeOpacity();
+    case CSSPropertyStrokeWidth:
+        return ptrsOrValuesEqual<PassRefPtr<SVGLength> >(a.strokeWidth(), b.strokeWidth());
+    case CSSPropertyTextDecorationColor:
+        return a.textDecorationColor().resolve(a.color()) == b.textDecorationColor().resolve(b.color())
+            && a.visitedLinkTextDecorationColor().resolve(a.color()) == b.visitedLinkTextDecorationColor().resolve(b.color());
+    case CSSPropertyTextIndent:
+        return a.textIndent() == b.textIndent();
+    case CSSPropertyTextShadow:
+        return ptrsOrValuesEqual<ShadowList*>(a.textShadow(), b.textShadow());
+    case CSSPropertyTop:
+        return a.top() == b.top();
+    case CSSPropertyVisibility:
+        return a.visibility() == b.visibility();
+    case CSSPropertyWebkitBackgroundSize:
+        return fillLayersEqual<CSSPropertyWebkitBackgroundSize>(a.backgroundLayers(), b.backgroundLayers());
+    case CSSPropertyWebkitBorderHorizontalSpacing:
+        return a.horizontalBorderSpacing() == b.horizontalBorderSpacing();
+    case CSSPropertyWebkitBorderVerticalSpacing:
+        return a.verticalBorderSpacing() == b.verticalBorderSpacing();
+    case CSSPropertyWebkitBoxShadow:
+        return ptrsOrValuesEqual<ShadowList*>(a.boxShadow(), b.boxShadow());
+    case CSSPropertyWebkitClipPath:
+        return ptrsOrValuesEqual<ClipPathOperation*>(a.clipPath(), b.clipPath());
+    case CSSPropertyWebkitColumnCount:
+        return a.columnCount() == b.columnCount();
+    case CSSPropertyWebkitColumnGap:
+        return a.columnGap() == b.columnGap();
+    case CSSPropertyWebkitColumnRuleColor:
+        return a.columnRuleColor().resolve(a.color()) == b.columnRuleColor().resolve(b.color())
+            && a.visitedLinkColumnRuleColor().resolve(a.color()) == b.visitedLinkColumnRuleColor().resolve(b.color());
+    case CSSPropertyWebkitColumnRuleWidth:
+        return a.columnRuleWidth() == b.columnRuleWidth();
+    case CSSPropertyWebkitColumnWidth:
+        return a.columnWidth() == b.columnWidth();
+    case CSSPropertyWebkitFilter:
+        return a.filter() == b.filter();
+    case CSSPropertyWebkitMaskBoxImageOutset:
+        return a.maskBoxImageOutset() == b.maskBoxImageOutset();
+    case CSSPropertyWebkitMaskBoxImageSlice:
+        return a.maskBoxImageSlices() == b.maskBoxImageSlices();
+    case CSSPropertyWebkitMaskBoxImageSource:
+        return ptrsOrValuesEqual<StyleImage*>(a.maskBoxImageSource(), b.maskBoxImageSource());
+    case CSSPropertyWebkitMaskBoxImageWidth:
+        return a.maskBoxImageWidth() == b.maskBoxImageWidth();
+    case CSSPropertyWebkitMaskImage:
+        return ptrsOrValuesEqual<StyleImage*>(a.maskImage(), b.maskImage());
+    case CSSPropertyWebkitMaskPositionX:
+        return fillLayersEqual<CSSPropertyWebkitMaskPositionX>(a.maskLayers(), b.maskLayers());
+    case CSSPropertyWebkitMaskPositionY:
+        return fillLayersEqual<CSSPropertyWebkitMaskPositionY>(a.maskLayers(), b.maskLayers());
+    case CSSPropertyWebkitMaskSize:
+        return fillLayersEqual<CSSPropertyWebkitMaskSize>(a.maskLayers(), b.maskLayers());
+    case CSSPropertyWebkitPerspective:
+        return a.perspective() == b.perspective();
+    case CSSPropertyWebkitPerspectiveOriginX:
+        return a.perspectiveOriginX() == b.perspectiveOriginX();
+    case CSSPropertyWebkitPerspectiveOriginY:
+        return a.perspectiveOriginY() == b.perspectiveOriginY();
+    case CSSPropertyWebkitTextStrokeColor:
+        return a.textStrokeColor().resolve(a.color()) == b.textStrokeColor().resolve(b.color())
+            && a.visitedLinkTextStrokeColor().resolve(a.color()) == b.visitedLinkTextStrokeColor().resolve(b.color());
+    case CSSPropertyWebkitTransform:
+        return a.transform() == b.transform();
+    case CSSPropertyWebkitTransformOriginX:
+        return a.transformOriginX() == b.transformOriginX();
+    case CSSPropertyWebkitTransformOriginY:
+        return a.transformOriginY() == b.transformOriginY();
+    case CSSPropertyWebkitTransformOriginZ:
+        return a.transformOriginZ() == b.transformOriginZ();
+    case CSSPropertyWidows:
+        return a.widows() == b.widows();
+    case CSSPropertyWidth:
+        return a.width() == b.width();
+    case CSSPropertyWordSpacing:
+        return a.wordSpacing() == b.wordSpacing();
+    case CSSPropertyZIndex:
+        return a.zIndex() == b.zIndex();
+    case CSSPropertyZoom:
+        return a.zoom() == b.zoom();
+    default:
+        ASSERT_NOT_REACHED();
+        return true;
+    }
+}
+
+}
diff --git a/Source/core/animation/css/CSSPropertyEquality.h b/Source/core/animation/css/CSSPropertyEquality.h
new file mode 100644
index 0000000..50723b2
--- /dev/null
+++ b/Source/core/animation/css/CSSPropertyEquality.h
@@ -0,0 +1,21 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSSPropertyEquality_h
+#define CSSPropertyEquality_h
+
+#include "CSSPropertyNames.h"
+
+namespace WebCore {
+
+class RenderStyle;
+
+class CSSPropertyEquality {
+public:
+    static bool propertiesEqual(CSSPropertyID, const RenderStyle&, const RenderStyle&);
+};
+
+} // namespace WebCore
+
+#endif // CSSPropertyEquality_h
diff --git a/Source/core/clipboard/Clipboard.cpp b/Source/core/clipboard/Clipboard.cpp
index 34f9e5c..388efc5 100644
--- a/Source/core/clipboard/Clipboard.cpp
+++ b/Source/core/clipboard/Clipboard.cpp
@@ -33,7 +33,7 @@
 #include "core/editing/markup.h"
 #include "core/fetch/ImageResource.h"
 #include "core/fileapi/FileList.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/rendering/RenderImage.h"
 #include "core/rendering/RenderObject.h"
@@ -107,9 +107,9 @@
     return cleanType;
 }
 
-PassRefPtr<Clipboard> Clipboard::create(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtr<DataObject> dataObject)
+PassRefPtrWillBeRawPtr<Clipboard> Clipboard::create(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtrWillBeRawPtr<DataObject> dataObject)
 {
-    return adoptRef(new Clipboard(type, policy , dataObject));
+    return adoptRefWillBeNoop(new Clipboard(type, policy , dataObject));
 }
 
 Clipboard::~Clipboard()
@@ -194,15 +194,15 @@
     return types;
 }
 
-PassRefPtr<FileList> Clipboard::files() const
+PassRefPtrWillBeRawPtr<FileList> Clipboard::files() const
 {
-    RefPtr<FileList> files = FileList::create();
+    RefPtrWillBeRawPtr<FileList> files = FileList::create();
     if (!canReadData())
         return files.release();
 
     for (size_t i = 0; i < m_dataObject->length(); ++i) {
         if (m_dataObject->item(i)->kind() == DataObjectItem::FileKind) {
-            RefPtr<Blob> blob = m_dataObject->item(i)->getAsFile();
+            RefPtrWillBeRawPtr<Blob> blob = m_dataObject->item(i)->getAsFile();
             if (blob && blob->isFile())
                 files->append(toFile(blob.get()));
         }
@@ -221,8 +221,8 @@
         return;
     }
     IntPoint location(x, y);
-    if (image->hasTagName(HTMLNames::imgTag) && !image->inDocument())
-        setDragImageResource(toHTMLImageElement(image)->cachedImage(), location);
+    if (isHTMLImageElement(*image) && !image->inDocument())
+        setDragImageResource(toHTMLImageElement(*image).cachedImage(), location);
     else
         setDragImageElement(image, location);
 }
@@ -237,7 +237,7 @@
     setDragImage(0, node, loc);
 }
 
-PassOwnPtr<DragImage> Clipboard::createDragImage(IntPoint& loc, Frame* frame) const
+PassOwnPtr<DragImage> Clipboard::createDragImage(IntPoint& loc, LocalFrame* frame) const
 {
     if (m_dragImageElement) {
         loc = m_dragLoc;
@@ -339,7 +339,7 @@
     m_dataObject->setHTMLAndBaseURL(urlToMarkup(url, title), url);
 }
 
-void Clipboard::writeRange(Range* selectedRange, Frame* frame)
+void Clipboard::writeRange(Range* selectedRange, LocalFrame* frame)
 {
     ASSERT(selectedRange);
     if (!m_dataObject)
@@ -440,7 +440,7 @@
     return false;
 }
 
-PassRefPtr<DataTransferItemList> Clipboard::items()
+PassRefPtrWillBeRawPtr<DataTransferItemList> Clipboard::items()
 {
     // FIXME: According to the spec, we are supposed to return the same collection of items each
     // time. We now return a wrapper that always wraps the *same* set of items, so JS shouldn't be
@@ -448,12 +448,12 @@
     return DataTransferItemList::create(this, m_dataObject);
 }
 
-PassRefPtr<DataObject> Clipboard::dataObject() const
+PassRefPtrWillBeRawPtr<DataObject> Clipboard::dataObject() const
 {
     return m_dataObject;
 }
 
-Clipboard::Clipboard(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtr<DataObject> dataObject)
+Clipboard::Clipboard(ClipboardType type, ClipboardAccessPolicy policy, PassRefPtrWillBeRawPtr<DataObject> dataObject)
     : m_policy(policy)
     , m_dropEffect("uninitialized")
     , m_effectAllowed("uninitialized")
@@ -478,7 +478,7 @@
     if (!canReadTypes())
         return false;
 
-    RefPtr<FileList> fileList = files();
+    RefPtrWillBeRawPtr<FileList> fileList = files();
     if (fileList->isEmpty())
         return false;
 
@@ -522,4 +522,9 @@
     }
 }
 
+void Clipboard::trace(Visitor* visitor)
+{
+    visitor->trace(m_dataObject);
+}
+
 } // namespace WebCore
diff --git a/Source/core/clipboard/Clipboard.h b/Source/core/clipboard/Clipboard.h
index cca9fe8..cbe8877 100644
--- a/Source/core/clipboard/Clipboard.h
+++ b/Source/core/clipboard/Clipboard.h
@@ -28,6 +28,7 @@
 #include "core/clipboard/ClipboardAccessPolicy.h"
 #include "core/fetch/ResourcePtr.h"
 #include "core/page/DragActions.h"
+#include "heap/Handle.h"
 #include "platform/geometry/IntPoint.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
@@ -42,13 +43,13 @@
 class Element;
 class ExceptionState;
 class FileList;
-class Frame;
+class LocalFrame;
 class ImageResource;
 class Node;
 class Range;
 
 // State available during IE's events for drag and drop and copy/paste
-class Clipboard : public RefCounted<Clipboard>, public ScriptWrappable {
+class Clipboard : public RefCountedWillBeGarbageCollectedFinalized<Clipboard>, public ScriptWrappable {
 public:
     // Whether this clipboard is serving a drag-drop or copy-paste request.
     enum ClipboardType {
@@ -56,7 +57,7 @@
         DragAndDrop,
     };
 
-    static PassRefPtr<Clipboard> create(ClipboardType, ClipboardAccessPolicy, PassRefPtr<DataObject>);
+    static PassRefPtrWillBeRawPtr<Clipboard> create(ClipboardType, ClipboardAccessPolicy, PassRefPtrWillBeRawPtr<DataObject>);
     ~Clipboard();
 
     bool isForCopyAndPaste() const { return m_clipboardType == CopyAndPaste; }
@@ -74,7 +75,7 @@
 
     // extensions beyond IE's API
     Vector<String> types() const;
-    PassRefPtr<FileList> files() const;
+    PassRefPtrWillBeRawPtr<FileList> files() const;
 
     IntPoint dragLocation() const { return m_dragLoc; }
     void setDragImage(Element*, int x, int y, ExceptionState&);
@@ -83,10 +84,10 @@
     Node* dragImageElement() const { return m_dragImageElement.get(); }
     void setDragImageElement(Node*, const IntPoint&);
 
-    PassOwnPtr<DragImage> createDragImage(IntPoint& dragLocation, Frame*) const;
+    PassOwnPtr<DragImage> createDragImage(IntPoint& dragLocation, LocalFrame*) const;
     void declareAndWriteDragImage(Element*, const KURL&, const String& title);
     void writeURL(const KURL&, const String&);
-    void writeRange(Range*, Frame*);
+    void writeRange(Range*, LocalFrame*);
     void writePlainText(const String&);
 
     bool hasData();
@@ -108,12 +109,14 @@
 
     bool hasDropZoneType(const String&);
 
-    PassRefPtr<DataTransferItemList> items();
+    PassRefPtrWillBeRawPtr<DataTransferItemList> items();
 
-    PassRefPtr<DataObject> dataObject() const;
+    PassRefPtrWillBeRawPtr<DataObject> dataObject() const;
+
+    void trace(Visitor*);
 
 private:
-    Clipboard(ClipboardType, ClipboardAccessPolicy, PassRefPtr<DataObject>);
+    Clipboard(ClipboardType, ClipboardAccessPolicy, PassRefPtrWillBeRawPtr<DataObject>);
 
     void setDragImage(ImageResource*, Node*, const IntPoint&);
 
@@ -125,7 +128,7 @@
     String m_dropEffect;
     String m_effectAllowed;
     ClipboardType m_clipboardType;
-    RefPtr<DataObject> m_dataObject;
+    RefPtrWillBeMember<DataObject> m_dataObject;
 
     IntPoint m_dragLoc;
     ResourcePtr<ImageResource> m_dragImage;
diff --git a/Source/core/clipboard/DataObject.cpp b/Source/core/clipboard/DataObject.cpp
index e3fb8a2..2b664ab 100644
--- a/Source/core/clipboard/DataObject.cpp
+++ b/Source/core/clipboard/DataObject.cpp
@@ -39,9 +39,9 @@
 
 namespace WebCore {
 
-PassRefPtr<DataObject> DataObject::createFromPasteboard(PasteMode pasteMode)
+PassRefPtrWillBeRawPtr<DataObject> DataObject::createFromPasteboard(PasteMode pasteMode)
 {
-    RefPtr<DataObject> dataObject = create();
+    RefPtrWillBeRawPtr<DataObject> dataObject = create();
     blink::WebClipboard::Buffer buffer = Pasteboard::generalPasteboard()->buffer();
     uint64_t sequenceNumber = blink::Platform::current()->clipboard()->sequenceNumber(buffer);
     bool ignored;
@@ -57,14 +57,14 @@
     return dataObject.release();
 }
 
-PassRefPtr<DataObject> DataObject::create()
+PassRefPtrWillBeRawPtr<DataObject> DataObject::create()
 {
-    return adoptRef(new DataObject());
+    return adoptRefWillBeNoop(new DataObject());
 }
 
-PassRefPtr<DataObject> DataObject::copy() const
+PassRefPtrWillBeRawPtr<DataObject> DataObject::copy() const
 {
-    return adoptRef(new DataObject(*this));
+    return adoptRefWillBeNoop(new DataObject(*this));
 }
 
 size_t DataObject::length() const
@@ -72,10 +72,10 @@
     return m_itemList.size();
 }
 
-PassRefPtr<DataObjectItem> DataObject::item(unsigned long index)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::item(unsigned long index)
 {
     if (index >= length())
-        return 0;
+        return nullptr;
     return m_itemList[index];
 }
 
@@ -91,20 +91,20 @@
     m_itemList.clear();
 }
 
-PassRefPtr<DataObjectItem> DataObject::add(const String& data, const String& type)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::add(const String& data, const String& type)
 {
-    RefPtr<DataObjectItem> item = DataObjectItem::createFromString(type, data);
+    RefPtrWillBeRawPtr<DataObjectItem> item = DataObjectItem::createFromString(type, data);
     if (!internalAddStringItem(item))
-        return 0;
+        return nullptr;
     return item;
 }
 
-PassRefPtr<DataObjectItem> DataObject::add(PassRefPtr<File> file)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::add(PassRefPtrWillBeRawPtr<File> file)
 {
     if (!file)
-        return 0;
+        return nullptr;
 
-    RefPtr<DataObjectItem> item = DataObjectItem::createFromFile(file);
+    RefPtrWillBeRawPtr<DataObjectItem> item = DataObjectItem::createFromFile(file);
     m_itemList.append(item);
     return item;
 }
@@ -169,7 +169,7 @@
 
 void DataObject::urlAndTitle(String& url, String* title) const
 {
-    RefPtr<DataObjectItem> item = findStringItem(mimeTypeTextURIList);
+    RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextURIList);
     if (!item)
         return;
     url = convertURIListToURL(item->getAsString());
@@ -185,7 +185,7 @@
 
 void DataObject::htmlAndBaseURL(String& html, KURL& baseURL) const
 {
-    RefPtr<DataObjectItem> item = findStringItem(mimeTypeTextHTML);
+    RefPtrWillBeRawPtr<DataObjectItem> item = findStringItem(mimeTypeTextHTML);
     if (!item)
         return;
     html = item->getAsString();
@@ -233,22 +233,21 @@
 }
 
 DataObject::DataObject(const DataObject& other)
-    : RefCounted<DataObject>()
-    , m_itemList(other.m_itemList)
+    : m_itemList(other.m_itemList)
     , m_modifierKeyState(0)
 {
 }
 
-PassRefPtr<DataObjectItem> DataObject::findStringItem(const String& type) const
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObject::findStringItem(const String& type) const
 {
     for (size_t i = 0; i < m_itemList.size(); ++i) {
         if (m_itemList[i]->kind() == DataObjectItem::StringKind && m_itemList[i]->type() == type)
             return m_itemList[i];
     }
-    return 0;
+    return nullptr;
 }
 
-bool DataObject::internalAddStringItem(PassRefPtr<DataObjectItem> item)
+bool DataObject::internalAddStringItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
 {
     ASSERT(item->kind() == DataObjectItem::StringKind);
     for (size_t i = 0; i < m_itemList.size(); ++i) {
@@ -260,10 +259,15 @@
     return true;
 }
 
-void DataObject::internalAddFileItem(PassRefPtr<DataObjectItem> item)
+void DataObject::internalAddFileItem(PassRefPtrWillBeRawPtr<DataObjectItem> item)
 {
     ASSERT(item->kind() == DataObjectItem::FileKind);
     m_itemList.append(item);
 }
 
+void DataObject::trace(Visitor* visitor)
+{
+    visitor->trace(m_itemList);
+}
+
 } // namespace WebCore
diff --git a/Source/core/clipboard/DataObject.h b/Source/core/clipboard/DataObject.h
index 7c489f9..6c5e1cf 100644
--- a/Source/core/clipboard/DataObject.h
+++ b/Source/core/clipboard/DataObject.h
@@ -32,6 +32,7 @@
 #define DataObject_h
 
 #include "core/clipboard/DataObjectItem.h"
+#include "heap/Handle.h"
 #include "platform/PasteMode.h"
 #include "platform/Supplementable.h"
 #include "wtf/ListHashSet.h"
@@ -49,22 +50,22 @@
 // A data object for holding data that would be in a clipboard or moved
 // during a drag-n-drop operation. This is the data that WebCore is aware
 // of and is not specific to a platform.
-class DataObject : public RefCounted<DataObject>, public Supplementable<DataObject> {
+class DataObject : public RefCountedWillBeGarbageCollectedFinalized<DataObject>, public Supplementable<DataObject> {
 public:
-    static PassRefPtr<DataObject> createFromPasteboard(PasteMode);
-    static PassRefPtr<DataObject> create();
+    static PassRefPtrWillBeRawPtr<DataObject> createFromPasteboard(PasteMode);
+    static PassRefPtrWillBeRawPtr<DataObject> create();
 
-    PassRefPtr<DataObject> copy() const;
+    PassRefPtrWillBeRawPtr<DataObject> copy() const;
 
     // DataTransferItemList support.
     size_t length() const;
-    PassRefPtr<DataObjectItem> item(unsigned long index);
+    PassRefPtrWillBeRawPtr<DataObjectItem> item(unsigned long index);
     // FIXME: Implement V8DataTransferItemList::indexedPropertyDeleter to get this called.
     void deleteItem(unsigned long index);
     void clearAll();
     // Returns null if an item already exists with the provided type.
-    PassRefPtr<DataObjectItem> add(const String& data, const String& type);
-    PassRefPtr<DataObjectItem> add(PassRefPtr<File>);
+    PassRefPtrWillBeRawPtr<DataObjectItem> add(const String& data, const String& type);
+    PassRefPtrWillBeRawPtr<DataObjectItem> add(PassRefPtrWillBeRawPtr<File>);
 
     // WebCore helpers.
     void clearData(const String& type);
@@ -90,15 +91,18 @@
     int modifierKeyState() const { return m_modifierKeyState; }
     void setModifierKeyState(int modifierKeyState) { m_modifierKeyState = modifierKeyState; }
 
+    // FIXME: oilpan: This trace() has to trace Supplementable.
+    void trace(Visitor*);
+
 private:
     DataObject();
     explicit DataObject(const DataObject&);
 
-    PassRefPtr<DataObjectItem> findStringItem(const String& type) const;
-    bool internalAddStringItem(PassRefPtr<DataObjectItem>);
-    void internalAddFileItem(PassRefPtr<DataObjectItem>);
+    PassRefPtrWillBeRawPtr<DataObjectItem> findStringItem(const String& type) const;
+    bool internalAddStringItem(PassRefPtrWillBeRawPtr<DataObjectItem>);
+    void internalAddFileItem(PassRefPtrWillBeRawPtr<DataObjectItem>);
 
-    Vector<RefPtr<DataObjectItem> > m_itemList;
+    WillBeHeapVector<RefPtrWillBeMember<DataObjectItem> > m_itemList;
 
     // State of Shift/Ctrl/Alt/Meta keys.
     int m_modifierKeyState;
diff --git a/Source/core/clipboard/DataObjectItem.cpp b/Source/core/clipboard/DataObjectItem.cpp
index c384eb4..542d0d9 100644
--- a/Source/core/clipboard/DataObjectItem.cpp
+++ b/Source/core/clipboard/DataObjectItem.cpp
@@ -39,49 +39,49 @@
 
 namespace WebCore {
 
-PassRefPtr<DataObjectItem> DataObjectItem::createFromString(const String& type, const String& data)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromString(const String& type, const String& data)
 {
-    RefPtr<DataObjectItem> item = adoptRef(new DataObjectItem(StringKind, type));
+    RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, type));
     item->m_data = data;
     return item.release();
 }
 
-PassRefPtr<DataObjectItem> DataObjectItem::createFromFile(PassRefPtr<File> file)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromFile(PassRefPtrWillBeRawPtr<File> file)
 {
-    RefPtr<DataObjectItem> item = adoptRef(new DataObjectItem(FileKind, file->type()));
+    RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(FileKind, file->type()));
     item->m_file = file;
     return item.release();
 }
 
-PassRefPtr<DataObjectItem> DataObjectItem::createFromURL(const String& url, const String& title)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromURL(const String& url, const String& title)
 {
-    RefPtr<DataObjectItem> item = adoptRef(new DataObjectItem(StringKind, mimeTypeTextURIList));
+    RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, mimeTypeTextURIList));
     item->m_data = url;
     item->m_title = title;
     return item.release();
 }
 
-PassRefPtr<DataObjectItem> DataObjectItem::createFromHTML(const String& html, const KURL& baseURL)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromHTML(const String& html, const KURL& baseURL)
 {
-    RefPtr<DataObjectItem> item = adoptRef(new DataObjectItem(StringKind, mimeTypeTextHTML));
+    RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(StringKind, mimeTypeTextHTML));
     item->m_data = html;
     item->m_baseURL = baseURL;
     return item.release();
 }
 
-PassRefPtr<DataObjectItem> DataObjectItem::createFromSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromSharedBuffer(const String& name, PassRefPtr<SharedBuffer> buffer)
 {
-    RefPtr<DataObjectItem> item = adoptRef(new DataObjectItem(FileKind, String()));
+    RefPtrWillBeRawPtr<DataObjectItem> item = adoptRefWillBeNoop(new DataObjectItem(FileKind, String()));
     item->m_sharedBuffer = buffer;
     item->m_title = name;
     return item.release();
 }
 
-PassRefPtr<DataObjectItem> DataObjectItem::createFromPasteboard(const String& type, uint64_t sequenceNumber)
+PassRefPtrWillBeRawPtr<DataObjectItem> DataObjectItem::createFromPasteboard(const String& type, uint64_t sequenceNumber)
 {
     if (type == mimeTypeImagePng)
-        return adoptRef(new DataObjectItem(FileKind, type, sequenceNumber));
-    return adoptRef(new DataObjectItem(StringKind, type, sequenceNumber));
+        return adoptRefWillBeNoop(new DataObjectItem(FileKind, type, sequenceNumber));
+    return adoptRefWillBeNoop(new DataObjectItem(StringKind, type, sequenceNumber));
 }
 
 DataObjectItem::DataObjectItem(Kind kind, const String& type)
@@ -100,19 +100,19 @@
 {
 }
 
-PassRefPtr<Blob> DataObjectItem::getAsFile() const
+PassRefPtrWillBeRawPtr<Blob> DataObjectItem::getAsFile() const
 {
     if (kind() != FileKind)
-        return 0;
+        return nullptr;
 
     if (m_source == InternalSource) {
         if (m_file)
-            return m_file;
+            return m_file.get();
         ASSERT(m_sharedBuffer);
         // FIXME: This code is currently impossible--we never populate m_sharedBuffer when dragging
         // in. At some point though, we may need to support correctly converting a shared buffer
         // into a file.
-        return 0;
+        return nullptr;
     }
 
     ASSERT(m_source == PasteboardSource);
@@ -135,7 +135,7 @@
         return Blob::create(BlobDataHandle::create(blobData.release(), data->size()));
     }
 
-    return 0;
+    return nullptr;
 }
 
 String DataObjectItem::getAsString() const
@@ -170,5 +170,10 @@
     return m_kind == FileKind && m_file;
 }
 
+void DataObjectItem::trace(Visitor* visitor)
+{
+    visitor->trace(m_file);
+}
+
 } // namespace WebCore
 
diff --git a/Source/core/clipboard/DataObjectItem.h b/Source/core/clipboard/DataObjectItem.h
index 6896a93..d43cf8b 100644
--- a/Source/core/clipboard/DataObjectItem.h
+++ b/Source/core/clipboard/DataObjectItem.h
@@ -32,6 +32,7 @@
 #define DataObjectItem_h
 
 #include "core/fileapi/File.h"
+#include "heap/Handle.h"
 #include "platform/SharedBuffer.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/RefCounted.h"
@@ -42,24 +43,24 @@
 
 class Blob;
 
-class DataObjectItem : public RefCounted<DataObjectItem> {
+class DataObjectItem : public RefCountedWillBeGarbageCollectedFinalized<DataObjectItem> {
 public:
     enum Kind {
         StringKind,
         FileKind
     };
 
-    static PassRefPtr<DataObjectItem> createFromString(const String& type, const String& data);
-    static PassRefPtr<DataObjectItem> createFromFile(PassRefPtr<File>);
-    static PassRefPtr<DataObjectItem> createFromURL(const String& url, const String& title);
-    static PassRefPtr<DataObjectItem> createFromHTML(const String& html, const KURL& baseURL);
-    static PassRefPtr<DataObjectItem> createFromSharedBuffer(const String& filename, PassRefPtr<SharedBuffer>);
-    static PassRefPtr<DataObjectItem> createFromPasteboard(const String& type, uint64_t sequenceNumber);
+    static PassRefPtrWillBeRawPtr<DataObjectItem> createFromString(const String& type, const String& data);
+    static PassRefPtrWillBeRawPtr<DataObjectItem> createFromFile(PassRefPtrWillBeRawPtr<File>);
+    static PassRefPtrWillBeRawPtr<DataObjectItem> createFromURL(const String& url, const String& title);
+    static PassRefPtrWillBeRawPtr<DataObjectItem> createFromHTML(const String& html, const KURL& baseURL);
+    static PassRefPtrWillBeRawPtr<DataObjectItem> createFromSharedBuffer(const String& filename, PassRefPtr<SharedBuffer>);
+    static PassRefPtrWillBeRawPtr<DataObjectItem> createFromPasteboard(const String& type, uint64_t sequenceNumber);
 
     Kind kind() const { return m_kind; }
     String type() const { return m_type; }
     String getAsString() const;
-    PassRefPtr<Blob> getAsFile() const;
+    PassRefPtrWillBeRawPtr<Blob> getAsFile() const;
 
     // Used to support legacy DataTransfer APIs and renderer->browser serialization.
     PassRefPtr<SharedBuffer> sharedBuffer() const { return m_sharedBuffer; }
@@ -67,6 +68,8 @@
     KURL baseURL() const { return m_baseURL; }
     bool isFilename() const;
 
+    void trace(Visitor*);
+
 private:
     enum DataSource {
         PasteboardSource,
@@ -81,7 +84,7 @@
     String m_type;
 
     String m_data;
-    RefPtr<File> m_file;
+    RefPtrWillBeMember<File> m_file;
     RefPtr<SharedBuffer> m_sharedBuffer;
     // Optional metadata. Currently used for URL, HTML, and dragging files in.
     String m_title;
diff --git a/Source/core/clipboard/Clipboard.idl b/Source/core/clipboard/DataTransfer.idl
similarity index 95%
rename from Source/core/clipboard/Clipboard.idl
rename to Source/core/clipboard/DataTransfer.idl
index 695f70d..497bfdf 100644
--- a/Source/core/clipboard/Clipboard.idl
+++ b/Source/core/clipboard/DataTransfer.idl
@@ -27,7 +27,9 @@
  */
 
 [
-] interface Clipboard {
+    ImplementedAs=Clipboard,
+    WillBeGarbageCollected
+] interface DataTransfer {
              [TreatReturnedNullStringAs=Undefined] attribute DOMString dropEffect;
              [TreatReturnedNullStringAs=Undefined] attribute DOMString effectAllowed;
     readonly attribute DOMString[] types;
diff --git a/Source/core/clipboard/DataTransferItem.cpp b/Source/core/clipboard/DataTransferItem.cpp
index 0ae522f..392feaf 100644
--- a/Source/core/clipboard/DataTransferItem.cpp
+++ b/Source/core/clipboard/DataTransferItem.cpp
@@ -39,9 +39,9 @@
 
 namespace WebCore {
 
-PassRefPtr<DataTransferItem> DataTransferItem::create(PassRefPtr<Clipboard> clipboard, PassRefPtr<DataObjectItem> item)
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItem::create(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObjectItem> item)
 {
-    return adoptRef(new DataTransferItem(clipboard, item));
+    return adoptRefWillBeNoop(new DataTransferItem(clipboard, item));
 }
 
 DataTransferItem::~DataTransferItem()
@@ -81,21 +81,26 @@
     StringCallback::scheduleCallback(callback, context, m_item->getAsString());
 }
 
-PassRefPtr<Blob> DataTransferItem::getAsFile() const
+PassRefPtrWillBeRawPtr<Blob> DataTransferItem::getAsFile() const
 {
     if (!m_clipboard->canReadData())
-        return 0;
+        return nullptr;
 
     return m_item->getAsFile();
 }
 
-DataTransferItem::DataTransferItem(PassRefPtr<Clipboard> clipboard, PassRefPtr<DataObjectItem> item)
+DataTransferItem::DataTransferItem(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObjectItem> item)
     : m_clipboard(clipboard)
     , m_item(item)
 {
     ScriptWrappable::init(this);
 }
 
+void DataTransferItem::trace(Visitor* visitor)
+{
+    visitor->trace(m_clipboard);
+    visitor->trace(m_item);
+}
 
 } // namespace WebCore
 
diff --git a/Source/core/clipboard/DataTransferItem.h b/Source/core/clipboard/DataTransferItem.h
index 74dd384..f802ab8 100644
--- a/Source/core/clipboard/DataTransferItem.h
+++ b/Source/core/clipboard/DataTransferItem.h
@@ -32,6 +32,7 @@
 #define DataTransferItem_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -45,25 +46,27 @@
 class StringCallback;
 class ExecutionContext;
 
-class DataTransferItem : public RefCounted<DataTransferItem>, public ScriptWrappable {
+class DataTransferItem : public RefCountedWillBeGarbageCollectedFinalized<DataTransferItem>, public ScriptWrappable {
 public:
-    static PassRefPtr<DataTransferItem> create(PassRefPtr<Clipboard>, PassRefPtr<DataObjectItem>);
+    static PassRefPtrWillBeRawPtr<DataTransferItem> create(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObjectItem>);
     ~DataTransferItem();
 
     String kind() const;
     String type() const;
 
     void getAsString(ExecutionContext*, PassOwnPtr<StringCallback>) const;
-    PassRefPtr<Blob> getAsFile() const;
+    PassRefPtrWillBeRawPtr<Blob> getAsFile() const;
 
     Clipboard* clipboard() { return m_clipboard.get(); }
     DataObjectItem* dataObjectItem() { return m_item.get(); }
 
-private:
-    DataTransferItem(PassRefPtr<Clipboard>, PassRefPtr<DataObjectItem>);
+    void trace(Visitor*);
 
-    RefPtr<Clipboard> m_clipboard;
-    RefPtr<DataObjectItem> m_item;
+private:
+    DataTransferItem(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObjectItem>);
+
+    RefPtrWillBeMember<Clipboard> m_clipboard;
+    RefPtrWillBeMember<DataObjectItem> m_item;
 };
 
 } // namespace WebCore
diff --git a/Source/core/clipboard/DataTransferItem.idl b/Source/core/clipboard/DataTransferItem.idl
index 8499652..32e6904 100644
--- a/Source/core/clipboard/DataTransferItem.idl
+++ b/Source/core/clipboard/DataTransferItem.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject
 ] interface DataTransferItem {
     readonly attribute DOMString kind;
diff --git a/Source/core/clipboard/DataTransferItemList.cpp b/Source/core/clipboard/DataTransferItemList.cpp
index 063a740..3785f99 100644
--- a/Source/core/clipboard/DataTransferItemList.cpp
+++ b/Source/core/clipboard/DataTransferItemList.cpp
@@ -35,9 +35,9 @@
 
 namespace WebCore {
 
-PassRefPtr<DataTransferItemList> DataTransferItemList::create(PassRefPtr<Clipboard> clipboard, PassRefPtr<DataObject> list)
+PassRefPtrWillBeRawPtr<DataTransferItemList> DataTransferItemList::create(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObject> list)
 {
-    return adoptRef(new DataTransferItemList(clipboard, list));
+    return adoptRefWillBeNoop(new DataTransferItemList(clipboard, list));
 }
 
 DataTransferItemList::~DataTransferItemList()
@@ -51,13 +51,13 @@
     return m_dataObject->length();
 }
 
-PassRefPtr<DataTransferItem> DataTransferItemList::item(unsigned long index)
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItemList::item(unsigned long index)
 {
     if (!m_clipboard->canReadTypes())
-        return 0;
-    RefPtr<DataObjectItem> item = m_dataObject->item(index);
+        return nullptr;
+    RefPtrWillBeRawPtr<DataObjectItem> item = m_dataObject->item(index);
     if (!item)
-        return 0;
+        return nullptr;
 
     return DataTransferItem::create(m_clipboard, item);
 }
@@ -78,33 +78,39 @@
     m_dataObject->clearAll();
 }
 
-PassRefPtr<DataTransferItem> DataTransferItemList::add(const String& data, const String& type, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItemList::add(const String& data, const String& type, ExceptionState& exceptionState)
 {
     if (!m_clipboard->canWriteData())
-        return 0;
-    RefPtr<DataObjectItem> item = m_dataObject->add(data, type);
+        return nullptr;
+    RefPtrWillBeRawPtr<DataObjectItem> item = m_dataObject->add(data, type);
     if (!item) {
         exceptionState.throwDOMException(NotSupportedError, "An item already exists for type '" + type + "'.");
-        return 0;
+        return nullptr;
     }
     return DataTransferItem::create(m_clipboard, item);
 }
 
-PassRefPtr<DataTransferItem> DataTransferItemList::add(PassRefPtr<File> file)
+PassRefPtrWillBeRawPtr<DataTransferItem> DataTransferItemList::add(PassRefPtrWillBeRawPtr<File> file)
 {
     if (!m_clipboard->canWriteData())
-        return 0;
-    RefPtr<DataObjectItem> item = m_dataObject->add(file);
+        return nullptr;
+    RefPtrWillBeRawPtr<DataObjectItem> item = m_dataObject->add(file);
     if (!item)
-        return 0;
+        return nullptr;
     return DataTransferItem::create(m_clipboard, item);
 }
 
-DataTransferItemList::DataTransferItemList(PassRefPtr<Clipboard> clipboard, PassRefPtr<DataObject> dataObject)
+DataTransferItemList::DataTransferItemList(PassRefPtrWillBeRawPtr<Clipboard> clipboard, PassRefPtrWillBeRawPtr<DataObject> dataObject)
     : m_clipboard(clipboard)
     , m_dataObject(dataObject)
 {
     ScriptWrappable::init(this);
 }
 
+void DataTransferItemList::trace(Visitor* visitor)
+{
+    visitor->trace(m_clipboard);
+    visitor->trace(m_dataObject);
+}
+
 } // namespace WebCore
diff --git a/Source/core/clipboard/DataTransferItemList.h b/Source/core/clipboard/DataTransferItemList.h
index 04c521a..e001e0c 100644
--- a/Source/core/clipboard/DataTransferItemList.h
+++ b/Source/core/clipboard/DataTransferItemList.h
@@ -32,6 +32,7 @@
 #define DataTransferItemList_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -45,23 +46,25 @@
 
 class ExceptionState;
 
-class DataTransferItemList : public RefCounted<DataTransferItemList>, public ScriptWrappable {
+class DataTransferItemList : public RefCountedWillBeGarbageCollectedFinalized<DataTransferItemList>, public ScriptWrappable {
 public:
-    static PassRefPtr<DataTransferItemList> create(PassRefPtr<Clipboard>, PassRefPtr<DataObject>);
+    static PassRefPtrWillBeRawPtr<DataTransferItemList> create(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObject>);
     ~DataTransferItemList();
 
     size_t length() const;
-    PassRefPtr<DataTransferItem> item(unsigned long index);
+    PassRefPtrWillBeRawPtr<DataTransferItem> item(unsigned long index);
     void deleteItem(unsigned long index, ExceptionState&);
     void clear();
-    PassRefPtr<DataTransferItem> add(const String& data, const String& type, ExceptionState&);
-    PassRefPtr<DataTransferItem> add(PassRefPtr<File>);
+    PassRefPtrWillBeRawPtr<DataTransferItem> add(const String& data, const String& type, ExceptionState&);
+    PassRefPtrWillBeRawPtr<DataTransferItem> add(PassRefPtrWillBeRawPtr<File>);
+
+    void trace(Visitor*);
 
 private:
-    DataTransferItemList(PassRefPtr<Clipboard>, PassRefPtr<DataObject>);
+    DataTransferItemList(PassRefPtrWillBeRawPtr<Clipboard>, PassRefPtrWillBeRawPtr<DataObject>);
 
-    RefPtr<Clipboard> m_clipboard;
-    RefPtr<DataObject> m_dataObject;
+    RefPtrWillBeMember<Clipboard> m_clipboard;
+    RefPtrWillBeMember<DataObject> m_dataObject;
 };
 
 } // namespace WebCore
diff --git a/Source/core/clipboard/DataTransferItemList.idl b/Source/core/clipboard/DataTransferItemList.idl
index 0babe03..e5a8d0c 100644
--- a/Source/core/clipboard/DataTransferItemList.idl
+++ b/Source/core/clipboard/DataTransferItemList.idl
@@ -28,7 +28,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface DataTransferItemList {
+[
+    WillBeGarbageCollected
+] interface DataTransferItemList {
     readonly attribute long length;
     [ImplementedAs=item] getter DataTransferItem (unsigned long index);
 
diff --git a/Source/core/clipboard/Pasteboard.cpp b/Source/core/clipboard/Pasteboard.cpp
index 46dc29c..4c38345 100644
--- a/Source/core/clipboard/Pasteboard.cpp
+++ b/Source/core/clipboard/Pasteboard.cpp
@@ -90,9 +90,9 @@
     blink::Platform::current()->clipboard()->writeImage(webImage, blink::WebURL(url), blink::WebString(title));
 }
 
-void Pasteboard::writeDataObject(PassRefPtr<DataObject> dataObject)
+void Pasteboard::writeDataObject(PassRefPtrWillBeRawPtr<DataObject> dataObject)
 {
-    blink::Platform::current()->clipboard()->writeDataObject(dataObject);
+    blink::Platform::current()->clipboard()->writeDataObject(blink::WebDragData(dataObject));
 }
 
 bool Pasteboard::canSmartReplace()
diff --git a/Source/core/clipboard/Pasteboard.h b/Source/core/clipboard/Pasteboard.h
index 93036ca..ae44a61 100644
--- a/Source/core/clipboard/Pasteboard.h
+++ b/Source/core/clipboard/Pasteboard.h
@@ -26,6 +26,7 @@
 #ifndef Pasteboard_h
 #define Pasteboard_h
 
+#include "heap/Handle.h"
 #include "public/platform/WebClipboard.h"
 #include "wtf/Forward.h"
 #include "wtf/Noncopyable.h"
@@ -49,7 +50,7 @@
     static Pasteboard* generalPasteboard();
     void writePlainText(const String&, SmartReplaceOption);
     void writeImage(Image*, const KURL&, const String& title);
-    void writeDataObject(PassRefPtr<DataObject>);
+    void writeDataObject(PassRefPtrWillBeRawPtr<DataObject>);
     bool canSmartReplace();
     bool isHTMLAvailable();
     String plainText();
diff --git a/Source/core/core.gyp b/Source/core/core.gyp
index dbbaddc..3caa3af 100644
--- a/Source/core/core.gyp
+++ b/Source/core/core.gyp
@@ -121,6 +121,7 @@
             '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorConsoleInstrumentationInl.h',
             '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationInl.h',
             '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorOverridesInl.h',
+            '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorPromiseInstrumentationInl.h',
             '<(SHARED_INTERMEDIATE_DIR)/blink/InstrumentingAgentsInl.h',
             '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationImpl.cpp',
           ],
@@ -284,6 +285,12 @@
         # Generated from HTMLEntityNames.in
         '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLEntityTable.cpp',
 
+        # Generated from MediaFeatureNames.in
+        '<(SHARED_INTERMEDIATE_DIR)/blink/MediaFeatureNames.cpp',
+
+        # Generated from MediaTypeNames.in
+        '<(SHARED_INTERMEDIATE_DIR)/blink/MediaTypeNames.cpp',
+
         # Generated from CSSTokenizer-in.cpp
         '<(SHARED_INTERMEDIATE_DIR)/blink/CSSTokenizer.cpp',
 
@@ -305,9 +312,9 @@
         # Additional .cpp files from the inspector_instrumentation_sources list.
         '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorCanvasInstrumentationInl.h',
         '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorConsoleInstrumentationInl.h',
-        '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorDatabaseInstrumentationInl.h',
         '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationInl.h',
         '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorOverridesInl.h',
+        '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorPromiseInstrumentationInl.h',
         '<(SHARED_INTERMEDIATE_DIR)/blink/InstrumentingAgentsInl.h',
         '<(SHARED_INTERMEDIATE_DIR)/blink/InspectorInstrumentationImpl.cpp',
 
@@ -550,6 +557,11 @@
         '<@(webcore_html_files)',
       ],
       'conditions': [
+        # Shard this taret into parts to work around linker limitations.
+        # on link time code generation builds.
+        ['OS=="win" and buildtype=="Official"', {
+          'msvs_shard': 5,
+        }],
         ['OS!="android"', {
           'sources/': [
             ['exclude', 'Android\\.cpp$'],
diff --git a/Source/core/core.gypi b/Source/core/core.gypi
index 8862cf7..ec14cb8 100644
--- a/Source/core/core.gypi
+++ b/Source/core/core.gypi
@@ -3,11 +3,11 @@
         # Files for which bindings (.cpp and .h files) will be generated
         'core_idl_files': [
             'animation/Animation.idl',
-            'animation/Player.idl',
+            'animation/AnimationPlayer.idl',
             'animation/TimedItem.idl',
             'animation/Timeline.idl',
             'animation/Timing.idl',
-            'clipboard/Clipboard.idl',
+            'clipboard/DataTransfer.idl',
             'clipboard/DataTransferItem.idl',
             'clipboard/DataTransferItemList.idl',
             'css/CSS.idl',
@@ -141,6 +141,7 @@
             'html/HTMLButtonElement.idl',
             'html/HTMLCanvasElement.idl',
             'html/HTMLCollection.idl',
+            'html/HTMLContentElement.idl',
             'html/HTMLDListElement.idl',
             'html/HTMLDataListElement.idl',
             'html/HTMLDetailsElement.idl',
@@ -188,6 +189,7 @@
             'html/HTMLQuoteElement.idl',
             'html/HTMLScriptElement.idl',
             'html/HTMLSelectElement.idl',
+            'html/HTMLShadowElement.idl',
             'html/HTMLSourceElement.idl',
             'html/HTMLSpanElement.idl',
             'html/HTMLStyleElement.idl',
@@ -218,7 +220,6 @@
             'html/canvas/Canvas2DContextAttributes.idl',
             'html/canvas/CanvasGradient.idl',
             'html/canvas/CanvasPattern.idl',
-            'html/canvas/CanvasRenderingContext.idl',
             'html/canvas/CanvasRenderingContext2D.idl',
             'html/canvas/EXTFragDepth.idl',
             'html/canvas/EXTTextureFilterAnisotropic.idl',
@@ -229,7 +230,7 @@
             'html/canvas/OESTextureHalfFloat.idl',
             'html/canvas/OESTextureHalfFloatLinear.idl',
             'html/canvas/OESVertexArrayObject.idl',
-            'html/canvas/Path.idl',
+            'html/canvas/Path2D.idl',
             'html/canvas/WebGLActiveInfo.idl',
             'html/canvas/WebGLBuffer.idl',
             'html/canvas/WebGLCompressedTextureATC.idl',
@@ -246,14 +247,13 @@
             'html/canvas/WebGLProgram.idl',
             'html/canvas/WebGLRenderbuffer.idl',
             'html/canvas/WebGLRenderingContext.idl',
+            'html/canvas/WebGLRenderingContextBase.idl',
             'html/canvas/WebGLShader.idl',
             'html/canvas/WebGLShaderPrecisionFormat.idl',
             'html/canvas/WebGLTexture.idl',
             'html/canvas/WebGLUniformLocation.idl',
             'html/canvas/WebGLVertexArrayObjectOES.idl',
             'html/ime/InputMethodContext.idl',
-            'html/shadow/HTMLContentElement.idl',
-            'html/shadow/HTMLShadowElement.idl',
             'html/track/TextTrack.idl',
             'html/track/TextTrackCue.idl',
             'html/track/TextTrackCueList.idl',
@@ -463,6 +463,7 @@
             'frame/WindowBase64.idl',
             'frame/WindowEventHandlers.idl',
             'frame/WindowTimers.idl',
+            'html/canvas/CanvasPathMethods.idl',
             'page/WindowPagePopup.idl',
             'svg/SVGDocument.idl',
             'svg/SVGFilterPrimitiveStandardAttributes.idl',
@@ -574,6 +575,7 @@
             'animation/AnimatableVisibility.h',
             'animation/Animation.cpp',
             'animation/Animation.h',
+            'animation/AnimationClock.cpp',
             'animation/AnimationClock.h',
             'animation/AnimationEffect.h',
             'animation/AnimationHelpers.h',
@@ -589,20 +591,29 @@
             'animation/DocumentAnimations.h',
             'animation/DocumentTimeline.cpp',
             'animation/DocumentTimeline.h',
-            'animation/ElementAnimation.cpp',
             'animation/ElementAnimation.h',
+            'animation/EffectInput.cpp',
+            'animation/EffectInput.h',
             'animation/InertAnimation.cpp',
             'animation/InertAnimation.h',
+            'animation/Interpolation.cpp',
+            'animation/Interpolation.h',
+            'animation/InterpolableValue.cpp',
+            'animation/InterpolableValue.h',
+            'animation/InterpolationEffect.cpp',
+            'animation/InterpolationEffect.h',
             'animation/KeyframeEffectModel.cpp',
             'animation/KeyframeEffectModel.h',
-            'animation/Player.cpp',
-            'animation/Player.h',
+            'animation/AnimationPlayer.cpp',
+            'animation/AnimationPlayer.h',
             'animation/TimedItem.cpp',
             'animation/TimedItem.h',
             'animation/TimedItemCalculations.h',
             'animation/TimedItemTiming.cpp',
             'animation/TimedItemTiming.h',
             'animation/Timing.h',
+            'animation/TimingInput.cpp',
+            'animation/TimingInput.h',
             'animation/css/CSSAnimatableValueFactory.cpp',
             'animation/css/CSSAnimatableValueFactory.h',
             'animation/css/CSSAnimations.cpp',
@@ -613,8 +624,8 @@
             'animation/css/CSSAnimationDataList.h',
             'animation/css/CSSPendingAnimations.cpp',
             'animation/css/CSSPendingAnimations.h',
-            'animation/css/CSSPropertyAnimation.cpp',
-            'animation/css/CSSPropertyAnimation.h',
+            'animation/css/CSSPropertyEquality.cpp',
+            'animation/css/CSSPropertyEquality.h',
             'animation/css/TransitionTimeline.cpp',
             'animation/css/TransitionTimeline.h',
             'clipboard/Clipboard.cpp',
@@ -630,6 +641,8 @@
             'clipboard/Pasteboard.cpp',
             'clipboard/Pasteboard.h',
             'css/BasicShapeFunctions.cpp',
+            'css/BinaryDataFontFaceSource.cpp',
+            'css/BinaryDataFontFaceSource.h',
             'css/CSSArrayFunctionValue.cpp',
             'css/CSSArrayFunctionValue.h',
             'css/CSSAspectRatioValue.cpp',
@@ -708,6 +721,12 @@
             'css/CSSPageRule.cpp',
             'css/CSSPageRule.h',
             'css/parser/BisonCSSParser.h',
+            'css/parser/CSSPropertyParser.cpp',
+            'css/parser/CSSPropertyParser.h',
+            'css/parser/MediaQueryTokenizer.cpp',
+            'css/parser/MediaQueryParser.cpp',
+            'css/parser/MediaQueryInputStream.cpp',
+            'css/parser/MediaQueryToken.cpp',
             'css/CSSParserMode.cpp',
             'css/CSSParserMode.h',
             'css/CSSParserValues.cpp',
@@ -769,8 +788,8 @@
             'css/FontSize.cpp',
             'css/FontSize.h',
             'css/HashTools.h',
-            'css/MediaFeatureNames.cpp',
-            'css/MediaFeatureNames.h',
+            'css/LocalFontFaceSource.cpp',
+            'css/LocalFontFaceSource.h',
             'css/MediaList.cpp',
             'css/MediaList.h',
             'css/MediaQuery.cpp',
@@ -794,7 +813,10 @@
             'css/PseudoStyleRequest.h',
             'css/RGBColor.cpp',
             'css/RGBColor.h',
+            'css/Rect.cpp',
             'css/Rect.h',
+            'css/RemoteFontFaceSource.cpp',
+            'css/RemoteFontFaceSource.h',
             'css/RuleFeature.cpp',
             'css/RuleFeature.h',
             'css/RuleSet.cpp',
@@ -802,7 +824,6 @@
             'css/RuntimeCSSEnabled.cpp',
             'css/RuntimeCSSEnabled.h',
             'css/SVGCSSComputedStyleDeclaration.cpp',
-            'css/SVGCSSParser.cpp',
             'css/SelectorChecker.cpp',
             'css/SelectorChecker.h',
             'css/SelectorCheckerFastPath.cpp',
@@ -976,7 +997,6 @@
             'editing/markup.cpp',
             'fetch/CSSStyleSheetResource.cpp',
             'fetch/CSSStyleSheetResource.h',
-            'fetch/CachedMetadata.cpp',
             'fetch/CachedMetadata.h',
             'fetch/CrossOriginAccessControl.cpp',
             'fetch/CrossOriginAccessControl.h',
@@ -1039,9 +1059,11 @@
             'frame/Console.h',
             'frame/ConsoleBase.cpp',
             'frame/ConsoleBase.h',
-            'frame/ContentSecurityPolicy.cpp',
-            'frame/ContentSecurityPolicyResponseHeaders.cpp',
             'frame/DOMPoint.h',
+            'frame/DeviceSensorEventController.cpp',
+            'frame/DeviceSensorEventController.h',
+            'frame/DeviceSensorEventDispatcher.cpp',
+            'frame/DeviceSensorEventDispatcher.h',
             'frame/DOMTimer.cpp',
             'frame/DOMTimer.h',
             'frame/DOMWindow.cpp',
@@ -1072,6 +1094,8 @@
             'frame/History.h',
             'frame/ImageBitmap.cpp',
             'frame/ImageBitmap.h',
+            'frame/LocalFrame.cpp',
+            'frame/LocalFrame.h',
             'frame/Location.cpp',
             'frame/Location.h',
             'frame/Navigator.cpp',
@@ -1081,6 +1105,10 @@
             'frame/NavigatorID.h',
             'frame/NavigatorOnLine.h',
             'frame/PageConsole.cpp',
+            'frame/PinchViewport.cpp',
+            'frame/PinchViewport.h',
+            'frame/RemoteFrame.cpp',
+            'frame/RemoteFrame.h',
             'frame/Screen.cpp',
             'frame/Screen.h',
             'frame/Settings.cpp',
@@ -1089,6 +1117,12 @@
             'frame/SuspendableTimer.cpp',
             'frame/SuspendableTimer.h',
             'frame/UseCounter.cpp',
+            'frame/csp/CSPDirectiveList.cpp',
+            'frame/csp/CSPSource.cpp',
+            'frame/csp/CSPSourceList.cpp',
+            'frame/csp/ContentSecurityPolicy.cpp',
+            'frame/csp/MediaListDirective.cpp',
+            'frame/csp/SourceListDirective.cpp',
             'inspector/AsyncCallStackTracker.cpp',
             'inspector/AsyncCallStackTracker.h',
             'inspector/BindingVisitors.h',
@@ -1162,6 +1196,7 @@
             'inspector/InspectorPageAgent.h',
             'inspector/InspectorProfilerAgent.cpp',
             'inspector/InspectorProfilerAgent.h',
+            'inspector/InspectorPromiseInstrumentation.h',
             'inspector/InspectorResourceAgent.cpp',
             'inspector/InspectorResourceAgent.h',
             'inspector/InspectorRuntimeAgent.cpp',
@@ -1190,6 +1225,8 @@
             'inspector/PageDebuggerAgent.h',
             'inspector/PageRuntimeAgent.cpp',
             'inspector/PageRuntimeAgent.h',
+            'inspector/PromiseTracker.cpp',
+            'inspector/PromiseTracker.h',
             'inspector/ScriptArguments.cpp',
             'inspector/ScriptArguments.h',
             'inspector/ScriptCallFrame.cpp',
@@ -1269,6 +1306,7 @@
             'loader/WorkerThreadableLoader.h',
             'loader/appcache/ApplicationCache.cpp',
             'loader/appcache/ApplicationCache.h',
+            'loader/appcache/ApplicationCacheHost.cpp',
             'loader/appcache/ApplicationCacheHost.h',
             'page/AutoscrollController.cpp',
             'page/AutoscrollController.h',
@@ -1309,9 +1347,9 @@
             'page/NetworkStateNotifier.cpp',
             'page/NetworkStateNotifier.h',
             'page/Page.cpp',
-            'page/PageGroup.cpp',
-            'page/PageGroupLoadDeferrer.cpp',
-            'page/PageGroupLoadDeferrer.h',
+            'page/Page.h',
+            'page/PageAnimator.cpp',
+            'page/PageAnimator.h',
             'page/PageLifecycleNotifier.cpp',
             'page/PageLifecycleNotifier.h',
             'page/PageLifecycleObserver.cpp',
@@ -1328,6 +1366,8 @@
             'page/PointerLockController.h',
             'page/PopupOpeningObserver.h',
             'page/PrintContext.cpp',
+            'page/ScopedPageLoadDeferrer.cpp',
+            'page/ScopedPageLoadDeferrer.h',
             'page/SpatialNavigation.cpp',
             'page/TouchAdjustment.cpp',
             'page/TouchAdjustment.h',
@@ -1357,9 +1397,6 @@
             'rendering/BidiRun.h',
             'rendering/ClipRect.cpp',
             'rendering/ClipRect.h',
-            'rendering/CompositedLayerMapping.cpp',
-            'rendering/CompositedLayerMapping.h',
-            'rendering/CompositedLayerMappingPtr.h',
             'rendering/CounterNode.cpp',
             'rendering/CounterNode.h',
             'rendering/EllipsisBox.cpp',
@@ -1392,7 +1429,6 @@
             'rendering/LayoutState.cpp',
             'rendering/OrderIterator.cpp',
             'rendering/OrderIterator.h',
-            'rendering/PartialLayoutState.h',
             'rendering/PointerEventsHitRules.cpp',
             'rendering/PointerEventsHitRules.h',
             'rendering/RenderApplet.cpp',
@@ -1446,8 +1482,6 @@
             'rendering/RenderLayer.cpp',
             'rendering/RenderLayerBlendInfo.cpp',
             'rendering/RenderLayerClipper.cpp',
-            'rendering/RenderLayerCompositor.cpp',
-            'rendering/RenderLayerCompositor.h',
             'rendering/RenderLayerFilterInfo.cpp',
             'rendering/RenderLayerFilterInfo.h',
             'rendering/RenderLayerModelObject.cpp',
@@ -1474,8 +1508,6 @@
             'rendering/RenderMenuList.h',
             'rendering/RenderMeter.cpp',
             'rendering/RenderMeter.h',
-            'rendering/RenderMultiColumnBlock.cpp',
-            'rendering/RenderMultiColumnBlock.h',
             'rendering/RenderMultiColumnFlowThread.cpp',
             'rendering/RenderMultiColumnFlowThread.h',
             'rendering/RenderMultiColumnSet.cpp',
@@ -1568,6 +1600,16 @@
             'rendering/VerticalPositionCache.h',
             'rendering/break_lines.cpp',
             'rendering/break_lines.h',
+            'rendering/compositing/CompositedLayerMapping.cpp',
+            'rendering/compositing/CompositedLayerMapping.h',
+            'rendering/compositing/CompositedLayerMappingPtr.h',
+            'rendering/compositing/CompositingReasonFinder.cpp',
+            'rendering/compositing/CompositingReasonFinder.h',
+            'rendering/compositing/CompositingState.h',
+            'rendering/compositing/GraphicsLayerUpdater.cpp',
+            'rendering/compositing/GraphicsLayerUpdater.h',
+            'rendering/compositing/RenderLayerCompositor.cpp',
+            'rendering/compositing/RenderLayerCompositor.h',
             'rendering/line/BreakingContext.cpp',
             'rendering/line/LineBreaker.cpp',
             'rendering/line/LineBreaker.h',
@@ -1630,6 +1672,7 @@
             'rendering/style/StyleSurroundData.cpp',
             'rendering/style/StyleTransformData.cpp',
             'rendering/style/StyleVisualData.cpp',
+            'rendering/style/StyleWillChangeData.cpp',
             'rendering/svg/SVGInlineFlowBox.cpp',
             'rendering/svg/SVGInlineFlowBox.h',
             'rendering/svg/SVGInlineTextBox.cpp',
@@ -1808,6 +1851,8 @@
             'xml/XSLTUnicodeSort.cpp',
             'xml/XSLTUnicodeSort.h',
             'xml/parser/MarkupTokenizerInlines.h',
+            'xml/parser/SharedBufferReader.cpp',
+            'xml/parser/SharedBufferReader.h',
             'xml/parser/XMLDocumentParser.cpp',
             'xml/parser/XMLDocumentParser.h',
             'xml/parser/XMLDocumentParserScope.cpp',
@@ -1904,13 +1949,14 @@
             'dom/ElementTraversal.h',
             'dom/EmptyNodeList.cpp',
             'dom/EmptyNodeList.h',
-            'dom/ExecutionContextTask.cpp',
             'dom/ExecutionContextTask.h',
             'dom/MainThreadTaskRunner.cpp',
             'dom/MainThreadTaskRunner.h',
             'dom/FullscreenElementStack.cpp',
             'dom/FullscreenElementStack.h',
             'dom/GlobalEventHandlers.h',
+            'dom/SiblingRuleHelper.cpp',
+            'dom/SiblingRuleHelper.h',
             'dom/IconURL.cpp',
             'dom/IconURL.h',
             'dom/IdTargetObserver.cpp',
@@ -1920,6 +1966,8 @@
             'dom/IgnoreDestructiveWriteCountIncrementer.h',
             'dom/LiveNodeList.cpp',
             'dom/LiveNodeList.h',
+            'dom/LiveNodeListBase.cpp',
+            'dom/LiveNodeListBase.h',
             'dom/MessageChannel.cpp',
             'dom/MessageChannel.h',
             'dom/MessagePort.cpp',
@@ -1948,6 +1996,8 @@
             'dom/NodeFilterCondition.h',
             'dom/NodeIterator.cpp',
             'dom/NodeIterator.h',
+            'dom/NodeIteratorBase.cpp',
+            'dom/NodeIteratorBase.h',
             'dom/NodeRareData.cpp',
             'dom/NodeRareData.h',
             'dom/RenderTreeBuilder.cpp',
@@ -2069,8 +2119,6 @@
             'dom/TouchList.h',
             'dom/TransformSource.h',
             'dom/TransformSourceLibxslt.cpp',
-            'dom/Traversal.cpp',
-            'dom/Traversal.h',
             'dom/TreeScope.cpp',
             'dom/TreeScope.h',
             'dom/TreeScopeAdopter.cpp',
@@ -2195,6 +2243,8 @@
             'html/HTMLCanvasElement.cpp',
             'html/HTMLCanvasElement.h',
             'html/HTMLCollection.cpp',
+            'html/HTMLContentElement.cpp',
+            'html/HTMLContentElement.h',
             'html/HTMLDListElement.cpp',
             'html/HTMLDListElement.h',
             'html/HTMLDataListElement.cpp',
@@ -2239,19 +2289,6 @@
             'html/HTMLImageElement.h',
             'html/HTMLImageLoader.cpp',
             'html/HTMLImageLoader.h',
-            'html/HTMLImport.cpp',
-            'html/HTMLImport.h',
-            'html/HTMLImportsController.cpp',
-            'html/HTMLImportsController.h',
-            'html/HTMLImportChild.cpp',
-            'html/HTMLImportChild.h',
-            'html/HTMLImportChildClient.h',
-            'html/HTMLImportLoader.cpp',
-            'html/HTMLImportLoader.h',
-            'html/HTMLImportLoaderClient.h',
-            'html/HTMLImportState.h',
-            'html/HTMLImportStateResolver.cpp',
-            'html/HTMLImportStateResolver.h',
             'html/HTMLInputElement.cpp',
             'html/HTMLKeygenElement.cpp',
             'html/HTMLKeygenElement.h',
@@ -2314,6 +2351,8 @@
             'html/HTMLSelectElement.cpp',
             'html/HTMLSelectElement.h',
             'html/HTMLSelectElementWin.cpp',
+            'html/HTMLShadowElement.cpp',
+            'html/HTMLShadowElement.h',
             'html/HTMLSourceElement.cpp',
             'html/HTMLSourceElement.h',
             'html/HTMLSpanElement.cpp',
@@ -2360,8 +2399,6 @@
             'html/LabelableElement.cpp',
             'html/LabelsNodeList.cpp',
             'html/LabelsNodeList.h',
-            'html/LinkImport.cpp',
-            'html/LinkImport.h',
             'html/LinkRelAttribute.cpp',
             'html/LinkRelAttribute.h',
             'html/LinkResource.cpp',
@@ -2400,6 +2437,7 @@
             'html/canvas/CanvasContextAttributes.h',
             'html/canvas/CanvasGradient.cpp',
             'html/canvas/CanvasGradient.h',
+            'html/canvas/CanvasImageSource.h',
             'html/canvas/CanvasPathMethods.cpp',
             'html/canvas/CanvasPathMethods.h',
             'html/canvas/CanvasPattern.cpp',
@@ -2412,7 +2450,7 @@
             'html/canvas/CanvasStyle.h',
             'html/canvas/DataView.cpp',
             'html/canvas/DataView.h',
-            'html/canvas/DOMPath.h',
+            'html/canvas/Path2D.h',
             'html/canvas/EXTFragDepth.cpp',
             'html/canvas/EXTFragDepth.h',
             'html/canvas/EXTTextureFilterAnisotropic.cpp',
@@ -2458,6 +2496,7 @@
             'html/canvas/WebGLDrawBuffers.h',
             'html/canvas/WebGLExtension.cpp',
             'html/canvas/WebGLExtension.h',
+            'html/canvas/WebGLExtensionName.h',
             'html/canvas/WebGLFramebuffer.cpp',
             'html/canvas/WebGLFramebuffer.h',
             'html/canvas/WebGLGetInfo.cpp',
@@ -2472,6 +2511,8 @@
             'html/canvas/WebGLRenderbuffer.h',
             'html/canvas/WebGLRenderingContext.cpp',
             'html/canvas/WebGLRenderingContext.h',
+            'html/canvas/WebGLRenderingContextBase.cpp',
+            'html/canvas/WebGLRenderingContextBase.h',
             'html/canvas/WebGLShader.cpp',
             'html/canvas/WebGLShader.h',
             'html/canvas/WebGLShaderPrecisionFormat.cpp',
@@ -2560,6 +2601,21 @@
             'html/forms/ValidationMessage.h',
             'html/forms/WeekInputType.cpp',
             'html/forms/WeekInputType.h',
+            'html/imports/HTMLImport.cpp',
+            'html/imports/HTMLImport.h',
+            'html/imports/HTMLImportsController.cpp',
+            'html/imports/HTMLImportsController.h',
+            'html/imports/HTMLImportChild.cpp',
+            'html/imports/HTMLImportChild.h',
+            'html/imports/HTMLImportChildClient.h',
+            'html/imports/HTMLImportLoader.cpp',
+            'html/imports/HTMLImportLoader.h',
+            'html/imports/HTMLImportLoaderClient.h',
+            'html/imports/HTMLImportState.h',
+            'html/imports/HTMLImportStateResolver.cpp',
+            'html/imports/HTMLImportStateResolver.h',
+            'html/imports/LinkImport.cpp',
+            'html/imports/LinkImport.h',
             'html/parser/AtomicHTMLToken.h',
             'html/parser/BackgroundHTMLParser.cpp',
             'html/parser/BackgroundHTMLParser.h',
@@ -2639,18 +2695,12 @@
             'html/shadow/DateTimeSymbolicFieldElement.h',
             'html/shadow/DetailsMarkerControl.cpp',
             'html/shadow/DetailsMarkerControl.h',
-            'html/shadow/HTMLContentElement.cpp',
-            'html/shadow/HTMLContentElement.h',
-            'html/shadow/HTMLShadowElement.cpp',
-            'html/shadow/HTMLShadowElement.h',
             'html/shadow/MediaControlElementTypes.cpp',
             'html/shadow/MediaControlElementTypes.h',
             'html/shadow/MediaControlElements.cpp',
             'html/shadow/MediaControlElements.h',
             'html/shadow/MediaControls.cpp',
             'html/shadow/MediaControls.h',
-            'html/shadow/MediaControlsAndroid.cpp',
-            'html/shadow/MediaControlsAndroid.h',
             'html/shadow/MeterShadowElement.cpp',
             'html/shadow/MeterShadowElement.h',
             'html/shadow/PasswordGeneratorButtonElement.cpp',
@@ -2824,18 +2874,16 @@
             'svg/SVGAltGlyphItemElement.cpp',
             'svg/SVGAltGlyphItemElement.h',
             'svg/SVGAngle.cpp',
+            'svg/SVGAngleTearOff.cpp',
             'svg/SVGAnimatedAngle.cpp',
             'svg/SVGAnimatedColor.cpp',
-            'svg/SVGAnimatedEnumeration.cpp',
+            'svg/SVGAnimatedEnumerationBase.cpp',
             'svg/SVGAnimatedInteger.cpp',
             'svg/SVGAnimatedIntegerOptionalInteger.cpp',
             'svg/SVGAnimatedLength.cpp',
-            'svg/SVGAnimatedNewPropertyAnimator.cpp',
             'svg/SVGAnimatedNumber.cpp',
             'svg/SVGAnimatedNumberOptionalNumber.cpp',
             'svg/SVGAnimatedPath.cpp',
-            'svg/SVGAnimatedTransformList.cpp',
-            'svg/SVGAnimatedType.cpp',
             'svg/SVGAnimatedTypeAnimator.cpp',
             'svg/SVGAnimatedTypeAnimator.h',
             'svg/SVGAnimateElement.cpp',
@@ -2852,7 +2900,6 @@
             'svg/SVGCircleElement.h',
             'svg/SVGClipPathElement.cpp',
             'svg/SVGClipPathElement.h',
-            'svg/SVGColor.cpp',
             'svg/SVGComponentTransferFunctionElement.cpp',
             'svg/SVGComponentTransferFunctionElement.h',
             'svg/SVGCursorElement.cpp',
@@ -2866,6 +2913,7 @@
             'svg/SVGDocument.cpp',
             'svg/SVGDocument.h',
             'svg/SVGDocumentExtensions.cpp',
+            'svg/SVGEnumeration.cpp',
             'svg/SVGElement.cpp',
             'svg/SVGElementInstance.cpp',
             'svg/SVGElementInstance.h',
@@ -2942,6 +2990,8 @@
             'svg/SVGFontFaceFormatElement.h',
             'svg/SVGFontFaceNameElement.cpp',
             'svg/SVGFontFaceNameElement.h',
+            'svg/SVGFontFaceSource.cpp',
+            'svg/SVGFontFaceSource.h',
             'svg/SVGFontFaceSrcElement.cpp',
             'svg/SVGFontFaceSrcElement.h',
             'svg/SVGFontFaceUriElement.cpp',
@@ -2979,8 +3029,8 @@
             'svg/SVGLineElement.h',
             'svg/SVGLinearGradientElement.cpp',
             'svg/SVGLinearGradientElement.h',
-            'svg/SVGMPathElement.cpp',
-            'svg/SVGMPathElement.h',
+            'svg/SVGMatrixTearOff.cpp',
+            'svg/SVGMatrixTearOff.h',
             'svg/SVGMarkerElement.cpp',
             'svg/SVGMarkerElement.h',
             'svg/SVGMaskElement.cpp',
@@ -2989,6 +3039,8 @@
             'svg/SVGMetadataElement.h',
             'svg/SVGMissingGlyphElement.cpp',
             'svg/SVGMissingGlyphElement.h',
+            'svg/SVGMPathElement.cpp',
+            'svg/SVGMPathElement.h',
             'svg/SVGNumber.h',
             'svg/SVGNumber.cpp',
             'svg/SVGNumberOptionalNumber.cpp',
@@ -3015,6 +3067,7 @@
             'svg/SVGPathElement.h',
             'svg/SVGPathParser.cpp',
             'svg/SVGPathParser.h',
+            'svg/SVGPathSeg.cpp',
             'svg/SVGPathSeg.h',
             'svg/SVGPathSegArc.h',
             'svg/SVGPathSegArcAbs.h',
@@ -3045,6 +3098,7 @@
             'svg/SVGPathSegListBuilder.h',
             'svg/SVGPathSegListSource.cpp',
             'svg/SVGPathSegListSource.h',
+            'svg/SVGPathSegListTearOff.h',
             'svg/SVGPathSegMovetoAbs.h',
             'svg/SVGPathSegMovetoRel.h',
             'svg/SVGPathSegWithContext.h',
@@ -3081,6 +3135,8 @@
             'svg/SVGRectElement.h',
             'svg/SVGRectTearOff.cpp',
             'svg/SVGRectTearOff.h',
+            'svg/SVGRemoteFontFaceSource.cpp',
+            'svg/SVGRemoteFontFaceSource.h',
             'svg/SVGRenderingIntent.h',
             'svg/SVGSVGElement.cpp',
             'svg/SVGSVGElement.h',
@@ -3119,11 +3175,14 @@
             'svg/SVGTitleElement.cpp',
             'svg/SVGTitleElement.h',
             'svg/SVGTransform.cpp',
+            'svg/SVGTransformTearOff.cpp',
             'svg/SVGTransformDistance.cpp',
             'svg/SVGTransformDistance.h',
             'svg/SVGTransformList.cpp',
+            'svg/SVGTransformListTearOff.cpp',
             'svg/SVGURIReference.cpp',
             'svg/SVGURIReference.h',
+            'svg/SVGUnitTypes.cpp',
             'svg/SVGUnitTypes.h',
             'svg/SVGUnknownElement.cpp',
             'svg/SVGUnknownElement.h',
@@ -3159,11 +3218,6 @@
             'svg/graphics/filters/SVGFilterBuilder.h',
             'svg/properties/NewSVGAnimatedProperty.cpp',
             'svg/properties/NewSVGPropertyTearOff.cpp',
-            'svg/properties/SVGAnimatedProperty.cpp',
-            'svg/properties/SVGAnimatedProperty.h',
-            'svg/properties/SVGAttributeToPropertyMap.cpp',
-            'svg/properties/SVGAnimatedPathSegListPropertyTearOff.h',
-            'svg/properties/SVGPathSegListPropertyTearOff.cpp',
         ],
         'webcore_testing_idl_files': [
           'testing/GCObservation.idl',
@@ -3217,16 +3271,24 @@
             'animation/AnimationClockTest.cpp',
             'animation/AnimationHelpersTest.cpp',
             'animation/AnimationTest.cpp',
+            'animation/AnimationTestHelper.cpp',
+            'animation/AnimationTestHelper.h',
             'animation/AnimationTranslationUtilTest.cpp',
             'animation/CompositorAnimationsTest.cpp',
             'animation/CompositorAnimationsTestHelper.h',
             'animation/CompositorAnimationsTimingFunctionReverserTest.cpp',
             'animation/DocumentTimelineTest.cpp',
+            'animation/InterpolableValueTest.cpp',
+            'animation/InterpolationEffectTest.cpp',
             'animation/KeyframeEffectModelTest.cpp',
-            'animation/PlayerTest.cpp',
+            'animation/AnimationPlayerTest.cpp',
             'animation/TimedItemCalculationsTest.cpp',
             'animation/TimedItemTest.cpp',
+            'animation/TimingInputTest.cpp',
+            'css/AffectedByFocusTest.cpp',
+            'css/parser/MediaQueryTokenizerTest.cpp',
             'css/CSSCalculationValueTest.cpp',
+            'css/CSSFontFaceTest.cpp',
             'css/CSSTestHelper.cpp',
             'css/CSSTestHelper.h',
             'css/CSSValueTestHelper.h',
@@ -3236,10 +3298,15 @@
             'css/DragUpdateTest.cpp',
             'css/HoverUpdateTest.cpp',
             'css/RuleSetTest.cpp',
+            'css/MediaQuerySetTest.cpp',
+            'css/analyzer/DescendantInvalidationSetTest.cpp',
+            'dom/ActiveDOMObjectTest.cpp',
             'dom/DOMImplementationTest.cpp',
+            'css/parser/BisonCSSParserTest.cpp',
             'dom/DocumentMarkerControllerTest.cpp',
             'dom/DocumentTest.cpp',
             'dom/MainThreadTaskRunnerTest.cpp',
+            'dom/RangeTest.cpp',
             'editing/TextIteratorTest.cpp',
             'fetch/CachingCorrectnessTest.cpp',
             'fetch/ImageResourceTest.cpp',
@@ -3257,6 +3324,7 @@
             'rendering/shapes/BoxShapeTest.cpp',
             'testing/UnitTestHelpers.cpp',
             'testing/UnitTestHelpers.h',
+            'xml/parser/SharedBufferReaderTest.cpp',
         ],
     }
 }
diff --git a/Source/core/core_generated.gyp b/Source/core/core_generated.gyp
index 90c8eea..ef7d700 100644
--- a/Source/core/core_generated.gyp
+++ b/Source/core/core_generated.gyp
@@ -180,6 +180,80 @@
           ],
         },
         {
+          'action_name': 'MediaFeatureNames',
+          'variables': {
+            'in_files': [
+              'css/MediaFeatureNames.in',
+            ],
+          },
+          'inputs': [
+            '<@(scripts_for_in_files)',
+            '../build/scripts/make_media_feature_names.py',
+            '<@(in_files)'
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/blink/MediaFeatureNames.cpp',
+            '<(SHARED_INTERMEDIATE_DIR)/blink/MediaFeatureNames.h',
+          ],
+          'action': [
+            'python',
+            '../build/scripts/make_media_feature_names.py',
+            '<@(in_files)',
+            '--output_dir',
+            '<(SHARED_INTERMEDIATE_DIR)/blink',
+            '--defines', '<(feature_defines)',
+          ],
+        },
+        {
+          'action_name': 'MediaFeatures',
+          'variables': {
+            'in_files': [
+              'css/MediaFeatureNames.in',
+            ],
+          },
+          'inputs': [
+            '<@(scripts_for_in_files)',
+            '../build/scripts/make_media_features.py',
+            '<@(in_files)'
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/blink/MediaFeatures.h',
+          ],
+          'action': [
+            'python',
+            '../build/scripts/make_media_features.py',
+            '<@(in_files)',
+            '--output_dir',
+            '<(SHARED_INTERMEDIATE_DIR)/blink',
+            '--defines', '<(feature_defines)',
+          ],
+        },
+        {
+          'action_name': 'MediaTypeNames',
+          'variables': {
+            'in_files': [
+              'css/MediaTypeNames.in',
+            ],
+          },
+          'inputs': [
+            '<@(scripts_for_in_files)',
+            '../build/scripts/make_names.py',
+            '<@(in_files)'
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/blink/MediaTypeNames.cpp',
+            '<(SHARED_INTERMEDIATE_DIR)/blink/MediaTypeNames.h',
+          ],
+          'action': [
+            'python',
+            '../build/scripts/make_names.py',
+            '<@(in_files)',
+            '--output_dir',
+            '<(SHARED_INTERMEDIATE_DIR)/blink',
+            '--defines', '<(feature_defines)',
+          ],
+        },
+        {
           'action_name': 'StylePropertyShorthand',
           'inputs': [
             '<@(scripts_for_in_files)',
@@ -275,6 +349,23 @@
           ],
         },
         {
+          'action_name': 'HTMLElementTypeHelpers',
+          'inputs': [
+            '<@(make_element_type_helpers_files)',
+            'html/HTMLTagNames.in',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/blink/HTMLElementTypeHelpers.h',
+          ],
+          'action': [
+            'python',
+            '../build/scripts/make_element_type_helpers.py',
+            'html/HTMLTagNames.in',
+            '--output_dir',
+            '<(SHARED_INTERMEDIATE_DIR)/blink',
+          ],
+        },
+        {
           'action_name': 'SVGNames',
           'inputs': [
             '<@(make_element_factory_files)',
@@ -299,6 +390,23 @@
           ],
         },
         {
+          'action_name': 'SVGElementTypeHelpers',
+          'inputs': [
+            '<@(make_element_type_helpers_files)',
+            'svg/SVGTagNames.in',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/blink/SVGElementTypeHelpers.h',
+          ],
+          'action': [
+            'python',
+            '../build/scripts/make_element_type_helpers.py',
+            'svg/SVGTagNames.in',
+            '--output_dir',
+            '<(SHARED_INTERMEDIATE_DIR)/blink',
+          ],
+        },
+        {
           'action_name': 'EventFactory',
           'inputs': [
             '<@(make_event_factory_files)',
@@ -409,6 +517,7 @@
               'css/themeChromiumAndroid.css',
               'css/themeChromiumLinux.css',
               'css/themeChromiumSkia.css',
+              'css/themeMac.css',
               'css/themeWin.css',
               'css/themeWinQuirks.css',
               'css/svg.css',
diff --git a/Source/core/css/AffectedByFocusTest.cpp b/Source/core/css/AffectedByFocusTest.cpp
new file mode 100644
index 0000000..c12f07c
--- /dev/null
+++ b/Source/core/css/AffectedByFocusTest.cpp
@@ -0,0 +1,253 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "HTMLNames.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/NodeRenderStyle.h"
+#include "core/frame/FrameView.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLElement.h"
+#include "core/testing/DummyPageHolder.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+using namespace HTMLNames;
+
+namespace {
+
+class AffectedByFocusTest : public ::testing::Test {
+
+protected:
+
+    struct ElementResult {
+        const WebCore::QualifiedName tag;
+        bool affectedBy;
+        bool childrenAffectedBy;
+    };
+
+    virtual void SetUp() OVERRIDE;
+
+    HTMLDocument& document() const { return *m_document; }
+
+    void setHtmlInnerHTML(const char* htmlContent);
+
+    void checkElements(ElementResult expected[], unsigned expectedCount) const;
+
+private:
+    OwnPtr<DummyPageHolder> m_dummyPageHolder;
+
+    HTMLDocument* m_document;
+};
+
+void AffectedByFocusTest::SetUp()
+{
+    m_dummyPageHolder = DummyPageHolder::create(IntSize(800, 600));
+    m_document = toHTMLDocument(&m_dummyPageHolder->document());
+    ASSERT(m_document);
+}
+
+void AffectedByFocusTest::setHtmlInnerHTML(const char* htmlContent)
+{
+    document().documentElement()->setInnerHTML(String::fromUTF8(htmlContent), ASSERT_NO_EXCEPTION);
+    document().view()->updateLayoutAndStyleIfNeededRecursive();
+}
+
+void AffectedByFocusTest::checkElements(ElementResult expected[], unsigned expectedCount) const
+{
+    unsigned i = 0;
+    Element* elm = document().body();
+
+    for (; elm && i < expectedCount; elm = ElementTraversal::next(*elm), ++i) {
+        ASSERT_TRUE(elm->hasTagName(expected[i].tag));
+        ASSERT(elm->renderStyle());
+        ASSERT_EQ(expected[i].affectedBy, elm->renderStyle()->affectedByFocus());
+        ASSERT_EQ(expected[i].childrenAffectedBy, elm->childrenAffectedByFocus());
+    }
+
+    ASSERT(!elm && i == expectedCount);
+}
+
+// A global :focus rule in html.css currently causes every single element to be
+// affectedByFocus. Check that all elements in a document with no :focus rules
+// gets the affectedByFocus set on RenderStyle and not childrenAffectedByFocus.
+TEST_F(AffectedByFocusTest, UAUniversalFocusRule)
+{
+    ElementResult expected[] = {
+        { bodyTag, true, false },
+        { divTag, true, false },
+        { divTag, true, false },
+        { divTag, true, false },
+        { spanTag, true, false }
+    };
+
+    setHtmlInnerHTML("<body>"
+        "<div><div></div></div>"
+        "<div><span></span></div>"
+        "</body>");
+
+    checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// ":focus div" will mark ascendants of all divs with childrenAffectedByFocus.
+TEST_F(AffectedByFocusTest, FocusedAscendant)
+{
+    ElementResult expected[] = {
+        { bodyTag, true, true },
+        { divTag, true, true },
+        { divTag, true, false },
+        { divTag, true, false },
+        { spanTag, true, false }
+    };
+
+    setHtmlInnerHTML("<head>"
+        "<style>:focus div { background-color: pink }</style>"
+        "</head>"
+        "<body>"
+        "<div><div></div></div>"
+        "<div><span></span></div>"
+        "</body>");
+
+    checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// "body:focus div" will mark the body element with childrenAffectedByFocus.
+TEST_F(AffectedByFocusTest, FocusedAscendantWithType)
+{
+    ElementResult expected[] = {
+        { bodyTag, true, true },
+        { divTag, true, false },
+        { divTag, true, false },
+        { divTag, true, false },
+        { spanTag, true, false }
+    };
+
+    setHtmlInnerHTML("<head>"
+        "<style>body:focus div { background-color: pink }</style>"
+        "</head>"
+        "<body>"
+        "<div><div></div></div>"
+        "<div><span></span></div>"
+        "</body>");
+
+    checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// ":not(body):focus div" should not mark the body element with childrenAffectedByFocus.
+// Note that currently ":focus:not(body)" does not do the same. Then the :focus is
+// checked and the childrenAffectedByFocus flag set before the negated type selector
+// is found.
+TEST_F(AffectedByFocusTest, FocusedAscendantWithNegatedType)
+{
+    ElementResult expected[] = {
+        { bodyTag, true, false },
+        { divTag, true, true },
+        { divTag, true, false },
+        { divTag, true, false },
+        { spanTag, true, false }
+    };
+
+    setHtmlInnerHTML("<head>"
+        "<style>:not(body):focus div { background-color: pink }</style>"
+        "</head>"
+        "<body>"
+        "<div><div></div></div>"
+        "<div><span></span></div>"
+        "</body>");
+
+    checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+// Checking current behavior for ":focus + div", but this is a BUG or at best
+// sub-optimal. The focused element will also in this case get childrenAffectedByFocus
+// even if it's really a sibling. Effectively, the whole sub-tree of the focused
+// element will have styles recalculated even though none of the children are
+// affected. There are other mechanisms that makes sure the sibling also gets its
+// styles recalculated.
+TEST_F(AffectedByFocusTest, FocusedSibling)
+{
+    ElementResult expected[] = {
+        { bodyTag, true, false },
+        { divTag, true, true },
+        { spanTag, true, false },
+        { divTag, true, false }
+    };
+
+    setHtmlInnerHTML("<head>"
+        "<style>:focus + div { background-color: pink }</style>"
+        "</head>"
+        "<body>"
+        "<div>"
+        "  <span></span>"
+        "</div>"
+        "<div></div>"
+        "</body>");
+
+    checkElements(expected, sizeof(expected) / sizeof(ElementResult));
+}
+
+TEST_F(AffectedByFocusTest, AffectedByFocusUpdate)
+{
+    // Check that when focussing the outer div in the document below, you only
+    // get a single element style recalc.
+
+    setHtmlInnerHTML("<style>:focus { border: 1px solid lime; }</style>"
+        "<div id=d tabIndex=1>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "</div>");
+
+    document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+    unsigned startCount = document().styleEngine()->resolverAccessCount();
+
+    document().getElementById("d")->focus();
+    document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+    unsigned accessCount = document().styleEngine()->resolverAccessCount() - startCount;
+
+    ASSERT_EQ(1U, accessCount);
+}
+
+TEST_F(AffectedByFocusTest, ChildrenAffectedByFocusUpdate)
+{
+    // Check that when focussing the outer div in the document below, you get a
+    // style recalc for the whole subtree.
+
+    setHtmlInnerHTML("<style>:focus div { border: 1px solid lime; }</style>"
+        "<div id=d tabIndex=1>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "<div></div>"
+        "</div>");
+
+    document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+    unsigned startCount = document().styleEngine()->resolverAccessCount();
+
+    document().getElementById("d")->focus();
+    document().view()->updateLayoutAndStyleIfNeededRecursive();
+
+    unsigned accessCount = document().styleEngine()->resolverAccessCount() - startCount;
+
+    ASSERT_EQ(11U, accessCount);
+}
+
+} // namespace
diff --git a/Source/core/css/BasicShapeFunctions.cpp b/Source/core/css/BasicShapeFunctions.cpp
index 5bd3a01..233ef63 100644
--- a/Source/core/css/BasicShapeFunctions.cpp
+++ b/Source/core/css/BasicShapeFunctions.cpp
@@ -40,25 +40,12 @@
 
 namespace WebCore {
 
-static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForCenterCoordinate(CSSValuePool& pool, const RenderStyle& style, const BasicShapeCenterCoordinate& center)
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForCenterCoordinate(CSSValuePool& pool, const RenderStyle& style, const BasicShapeCenterCoordinate& center, EBoxOrient orientation)
 {
-    CSSValueID keyword = CSSValueInvalid;
-    switch (center.keyword()) {
-    case BasicShapeCenterCoordinate::None:
+    if (center.direction() == BasicShapeCenterCoordinate::TopLeft)
         return pool.createValue(center.length(), style);
-    case BasicShapeCenterCoordinate::Top:
-        keyword = CSSValueTop;
-        break;
-    case BasicShapeCenterCoordinate::Right:
-        keyword = CSSValueRight;
-        break;
-    case BasicShapeCenterCoordinate::Bottom:
-        keyword = CSSValueBottom;
-        break;
-    case BasicShapeCenterCoordinate::Left:
-        keyword = CSSValueLeft;
-        break;
-    }
+
+    CSSValueID keyword = orientation == HORIZONTAL ? CSSValueRight : CSSValueBottom;
 
     return pool.createValue(Pair::create(pool.createIdentifierValue(keyword), pool.createValue(center.length(), style), Pair::DropIdenticalValues));
 }
@@ -75,18 +62,18 @@
     }
 
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
-PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
+PassRefPtrWillBeRawPtr<CSSValue> valueForBasicShape(const RenderStyle& style, const BasicShape* basicShape)
 {
     CSSValuePool& pool = cssValuePool();
 
-    RefPtr<CSSBasicShape> basicShapeValue;
+    RefPtrWillBeRawPtr<CSSBasicShape> basicShapeValue;
     switch (basicShape->type()) {
     case BasicShape::BasicShapeRectangleType: {
         const BasicShapeRectangle* rectangle = static_cast<const BasicShapeRectangle*>(basicShape);
-        RefPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();
+        RefPtrWillBeRawPtr<CSSBasicShapeRectangle> rectangleValue = CSSBasicShapeRectangle::create();
 
         rectangleValue->setX(pool.createValue(rectangle->x(), style));
         rectangleValue->setY(pool.createValue(rectangle->y(), style));
@@ -100,7 +87,7 @@
     }
     case BasicShape::DeprecatedBasicShapeCircleType: {
         const DeprecatedBasicShapeCircle* circle = static_cast<const DeprecatedBasicShapeCircle*>(basicShape);
-        RefPtr<CSSDeprecatedBasicShapeCircle> circleValue = CSSDeprecatedBasicShapeCircle::create();
+        RefPtrWillBeRawPtr<CSSDeprecatedBasicShapeCircle> circleValue = CSSDeprecatedBasicShapeCircle::create();
 
         circleValue->setCenterX(pool.createValue(circle->centerX(), style));
         circleValue->setCenterY(pool.createValue(circle->centerY(), style));
@@ -111,17 +98,17 @@
     }
     case BasicShape::BasicShapeCircleType: {
         const BasicShapeCircle* circle = static_cast<const BasicShapeCircle*>(basicShape);
-        RefPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
+        RefPtrWillBeRawPtr<CSSBasicShapeCircle> circleValue = CSSBasicShapeCircle::create();
 
-        circleValue->setCenterX(valueForCenterCoordinate(pool, style, circle->centerX()));
-        circleValue->setCenterY(valueForCenterCoordinate(pool, style, circle->centerY()));
+        circleValue->setCenterX(valueForCenterCoordinate(pool, style, circle->centerX(), HORIZONTAL));
+        circleValue->setCenterY(valueForCenterCoordinate(pool, style, circle->centerY(), VERTICAL));
         circleValue->setRadius(basicShapeRadiusToCSSValue(pool, style, circle->radius()));
         basicShapeValue = circleValue.release();
         break;
     }
     case BasicShape::DeprecatedBasicShapeEllipseType: {
         const DeprecatedBasicShapeEllipse* ellipse = static_cast<const DeprecatedBasicShapeEllipse*>(basicShape);
-        RefPtr<CSSDeprecatedBasicShapeEllipse> ellipseValue = CSSDeprecatedBasicShapeEllipse::create();
+        RefPtrWillBeRawPtr<CSSDeprecatedBasicShapeEllipse> ellipseValue = CSSDeprecatedBasicShapeEllipse::create();
 
         ellipseValue->setCenterX(pool.createValue(ellipse->centerX(), style));
         ellipseValue->setCenterY(pool.createValue(ellipse->centerY(), style));
@@ -133,10 +120,10 @@
     }
     case BasicShape::BasicShapeEllipseType: {
         const BasicShapeEllipse* ellipse = static_cast<const BasicShapeEllipse*>(basicShape);
-        RefPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
+        RefPtrWillBeRawPtr<CSSBasicShapeEllipse> ellipseValue = CSSBasicShapeEllipse::create();
 
-        ellipseValue->setCenterX(valueForCenterCoordinate(pool, style, ellipse->centerX()));
-        ellipseValue->setCenterY(valueForCenterCoordinate(pool, style, ellipse->centerY()));
+        ellipseValue->setCenterX(valueForCenterCoordinate(pool, style, ellipse->centerX(), HORIZONTAL));
+        ellipseValue->setCenterY(valueForCenterCoordinate(pool, style, ellipse->centerY(), VERTICAL));
         ellipseValue->setRadiusX(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusX()));
         ellipseValue->setRadiusY(basicShapeRadiusToCSSValue(pool, style, ellipse->radiusY()));
         basicShapeValue = ellipseValue.release();
@@ -144,7 +131,7 @@
     }
     case BasicShape::BasicShapePolygonType: {
         const BasicShapePolygon* polygon = static_cast<const BasicShapePolygon*>(basicShape);
-        RefPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
+        RefPtrWillBeRawPtr<CSSBasicShapePolygon> polygonValue = CSSBasicShapePolygon::create();
 
         polygonValue->setWindRule(polygon->windRule());
         const Vector<Length>& values = polygon->values();
@@ -156,7 +143,7 @@
     }
     case BasicShape::BasicShapeInsetRectangleType: {
         const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
-        RefPtr<CSSBasicShapeInsetRectangle> rectangleValue = CSSBasicShapeInsetRectangle::create();
+        RefPtrWillBeRawPtr<CSSBasicShapeInsetRectangle> rectangleValue = CSSBasicShapeInsetRectangle::create();
 
         rectangleValue->setTop(cssValuePool().createValue(rectangle->top()));
         rectangleValue->setRight(cssValuePool().createValue(rectangle->right()));
@@ -170,7 +157,7 @@
     }
     case BasicShape::BasicShapeInsetType: {
         const BasicShapeInset* inset = static_cast<const BasicShapeInset*>(basicShape);
-        RefPtr<CSSBasicShapeInset> insetValue = CSSBasicShapeInset::create();
+        RefPtrWillBeRawPtr<CSSBasicShapeInset> insetValue = CSSBasicShapeInset::create();
 
         insetValue->setTop(CSSPrimitiveValue::create(inset->top()));
         insetValue->setRight(CSSPrimitiveValue::create(inset->right()));
@@ -189,9 +176,6 @@
         break;
     }
 
-    if (basicShape->layoutBox() != BoxMissing)
-        basicShapeValue->setLayoutBox(pool.createValue(basicShape->layoutBox()));
-
     return pool.createValue(basicShapeValue.release());
 }
 
@@ -213,29 +197,41 @@
 
 static BasicShapeCenterCoordinate convertToCenterCoordinate(const StyleResolverState& state, CSSPrimitiveValue* value)
 {
-    if (Pair* pair = value->getPairValue()) {
-        BasicShapeCenterCoordinate::Keyword keyword = BasicShapeCenterCoordinate::None;
-        switch (pair->first()->getValueID()) {
-        case CSSValueTop:
-            keyword = BasicShapeCenterCoordinate::Top;
-            break;
-        case CSSValueRight:
-            keyword = BasicShapeCenterCoordinate::Right;
-            break;
-        case CSSValueBottom:
-            keyword = BasicShapeCenterCoordinate::Bottom;
-            break;
-        case CSSValueLeft:
-            keyword = BasicShapeCenterCoordinate::Left;
-            break;
-        default:
-            ASSERT_NOT_REACHED();
-            break;
-        }
-        return BasicShapeCenterCoordinate(keyword, convertToLength(state, pair->second()));
+    BasicShapeCenterCoordinate::Direction direction;
+    Length offset = Length(0, Fixed);
+
+    CSSValueID keyword = CSSValueTop;
+    if (!value) {
+        keyword = CSSValueCenter;
+    } else if (value->isValueID()) {
+        keyword = value->getValueID();
+    } else if (Pair* pair = value->getPairValue()) {
+        keyword = pair->first()->getValueID();
+        offset = convertToLength(state, pair->second());
+    } else {
+        offset = convertToLength(state, value);
     }
 
-    return BasicShapeCenterCoordinate(convertToLength(state, value));
+    switch (keyword) {
+    case CSSValueTop:
+    case CSSValueLeft:
+        direction = BasicShapeCenterCoordinate::TopLeft;
+        break;
+    case CSSValueRight:
+    case CSSValueBottom:
+        direction = BasicShapeCenterCoordinate::BottomRight;
+        break;
+    case CSSValueCenter:
+        direction = BasicShapeCenterCoordinate::TopLeft;
+        offset = Length(50, Percent);
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        direction = BasicShapeCenterCoordinate::TopLeft;
+        break;
+    }
+
+    return BasicShapeCenterCoordinate(direction, offset);
 }
 
 static BasicShapeRadius cssValueToBasicShapeRadius(const StyleResolverState& state, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius)
@@ -300,13 +296,8 @@
         const CSSBasicShapeCircle* circleValue = static_cast<const CSSBasicShapeCircle *>(basicShapeValue);
         RefPtr<BasicShapeCircle> circle = BasicShapeCircle::create();
 
-        if (circleValue->centerX() && circleValue->centerY()) {
-            circle->setCenterX(convertToCenterCoordinate(state, circleValue->centerX()));
-            circle->setCenterY(convertToCenterCoordinate(state, circleValue->centerY()));
-        } else {
-            circle->setCenterX(BasicShapeCenterCoordinate(Length(50, Percent)));
-            circle->setCenterY(BasicShapeCenterCoordinate(Length(50, Percent)));
-        }
+        circle->setCenterX(convertToCenterCoordinate(state, circleValue->centerX()));
+        circle->setCenterY(convertToCenterCoordinate(state, circleValue->centerY()));
         circle->setRadius(cssValueToBasicShapeRadius(state, circleValue->radius()));
 
         basicShape = circle.release();
@@ -328,13 +319,8 @@
         const CSSBasicShapeEllipse* ellipseValue = static_cast<const CSSBasicShapeEllipse *>(basicShapeValue);
         RefPtr<BasicShapeEllipse> ellipse = BasicShapeEllipse::create();
 
-        if (ellipseValue->centerX() && ellipseValue->centerY()) {
-            ellipse->setCenterX(convertToCenterCoordinate(state, ellipseValue->centerX()));
-            ellipse->setCenterY(convertToCenterCoordinate(state, ellipseValue->centerY()));
-        } else {
-            ellipse->setCenterX(BasicShapeCenterCoordinate(Length(50, Percent)));
-            ellipse->setCenterY(BasicShapeCenterCoordinate(Length(50, Percent)));
-        }
+        ellipse->setCenterX(convertToCenterCoordinate(state, ellipseValue->centerX()));
+        ellipse->setCenterY(convertToCenterCoordinate(state, ellipseValue->centerY()));
         ellipse->setRadiusX(cssValueToBasicShapeRadius(state, ellipseValue->radiusX()));
         ellipse->setRadiusY(cssValueToBasicShapeRadius(state, ellipseValue->radiusY()));
 
@@ -346,7 +332,7 @@
         RefPtr<BasicShapePolygon> polygon = BasicShapePolygon::create();
 
         polygon->setWindRule(polygonValue->windRule());
-        const Vector<RefPtr<CSSPrimitiveValue> >& values = polygonValue->values();
+        const WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> >& values = polygonValue->values();
         for (unsigned i = 0; i < values.size(); i += 2)
             polygon->appendPoint(convertToLength(state, values.at(i).get()), convertToLength(state, values.at(i + 1).get()));
 
@@ -396,9 +382,6 @@
         break;
     }
 
-    if (basicShapeValue->layoutBox())
-        basicShape->setLayoutBox(LayoutBox(*basicShapeValue->layoutBox()));
-
     return basicShape.release();
 }
 
@@ -406,31 +389,9 @@
 {
     FloatPoint p;
     float offset = floatValueForLength(centerX.length(), boxSize.width());
-    switch (centerX.keyword()) {
-    case BasicShapeCenterCoordinate::None:
-    case BasicShapeCenterCoordinate::Left:
-        p.setX(offset);
-        break;
-    case BasicShapeCenterCoordinate::Right:
-        p.setX(boxSize.width() - offset);
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
+    p.setX(centerX.direction() == BasicShapeCenterCoordinate::TopLeft ? offset : boxSize.width() - offset);
     offset = floatValueForLength(centerY.length(), boxSize.height());
-    switch (centerY.keyword()) {
-    case BasicShapeCenterCoordinate::None:
-    case BasicShapeCenterCoordinate::Top:
-        p.setY(offset);
-        break;
-    case BasicShapeCenterCoordinate::Bottom:
-        p.setY(boxSize.height() - offset);
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
+    p.setY(centerY.direction() == BasicShapeCenterCoordinate::TopLeft ? offset : boxSize.height() - offset);
     return p;
 }
 
diff --git a/Source/core/css/BasicShapeFunctions.h b/Source/core/css/BasicShapeFunctions.h
index f3565d9..20cfe59 100644
--- a/Source/core/css/BasicShapeFunctions.h
+++ b/Source/core/css/BasicShapeFunctions.h
@@ -31,6 +31,7 @@
 #define BasicShapeFunctions_h
 
 #include "core/rendering/style/BasicShapes.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 
 namespace WebCore {
@@ -42,7 +43,7 @@
 class StyleResolverState;
 class RenderStyle;
 
-PassRefPtr<CSSValue> valueForBasicShape(const RenderStyle&, const BasicShape*);
+PassRefPtrWillBeRawPtr<CSSValue> valueForBasicShape(const RenderStyle&, const BasicShape*);
 PassRefPtr<BasicShape> basicShapeForValue(const StyleResolverState&, const CSSBasicShape*);
 FloatPoint floatPointForCenterCoordinate(const BasicShapeCenterCoordinate&, const BasicShapeCenterCoordinate&, FloatSize);
 
diff --git a/Source/core/css/BinaryDataFontFaceSource.cpp b/Source/core/css/BinaryDataFontFaceSource.cpp
new file mode 100644
index 0000000..c32f8ed
--- /dev/null
+++ b/Source/core/css/BinaryDataFontFaceSource.cpp
@@ -0,0 +1,37 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/BinaryDataFontFaceSource.h"
+
+#include "platform/SharedBuffer.h"
+#include "platform/fonts/FontCustomPlatformData.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+
+namespace WebCore {
+
+BinaryDataFontFaceSource::BinaryDataFontFaceSource(SharedBuffer* data)
+    : m_customPlatformData(FontCustomPlatformData::create(data))
+{
+}
+
+BinaryDataFontFaceSource::~BinaryDataFontFaceSource()
+{
+}
+
+bool BinaryDataFontFaceSource::isValid() const
+{
+    return m_customPlatformData;
+}
+
+PassRefPtr<SimpleFontData> BinaryDataFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+    return SimpleFontData::create(
+        m_customPlatformData->fontPlatformData(fontDescription.effectiveFontSize(),
+            fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(),
+            fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create());
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/BinaryDataFontFaceSource.h b/Source/core/css/BinaryDataFontFaceSource.h
new file mode 100644
index 0000000..766bbbb
--- /dev/null
+++ b/Source/core/css/BinaryDataFontFaceSource.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef BinaryDataFontFaceSource_h
+#define BinaryDataFontFaceSource_h
+
+#include "core/css/CSSFontFaceSource.h"
+#include "wtf/OwnPtr.h"
+
+namespace WebCore {
+
+class FontCustomPlatformData;
+class SharedBuffer;
+
+class BinaryDataFontFaceSource FINAL : public CSSFontFaceSource {
+public:
+    explicit BinaryDataFontFaceSource(SharedBuffer*);
+    virtual ~BinaryDataFontFaceSource();
+    virtual bool isValid() const OVERRIDE;
+
+private:
+    virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+    OwnPtr<FontCustomPlatformData> m_customPlatformData;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/css/CSSArrayFunctionValue.cpp b/Source/core/css/CSSArrayFunctionValue.cpp
index ed55fc8..f2e0b62 100644
--- a/Source/core/css/CSSArrayFunctionValue.cpp
+++ b/Source/core/css/CSSArrayFunctionValue.cpp
@@ -49,7 +49,7 @@
 
 PassRefPtrWillBeRawPtr<CSSArrayFunctionValue> CSSArrayFunctionValue::cloneForCSSOM() const
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSArrayFunctionValue(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSArrayFunctionValue(*this));
 }
 
 bool CSSArrayFunctionValue::equals(const CSSArrayFunctionValue& other) const
diff --git a/Source/core/css/CSSArrayFunctionValue.h b/Source/core/css/CSSArrayFunctionValue.h
index b92e5d4..ca3d283 100644
--- a/Source/core/css/CSSArrayFunctionValue.h
+++ b/Source/core/css/CSSArrayFunctionValue.h
@@ -39,7 +39,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSArrayFunctionValue> create()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSArrayFunctionValue());
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSArrayFunctionValue());
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSAspectRatioValue.h b/Source/core/css/CSSAspectRatioValue.h
index fc9aa47..51fe977 100644
--- a/Source/core/css/CSSAspectRatioValue.h
+++ b/Source/core/css/CSSAspectRatioValue.h
@@ -37,7 +37,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSAspectRatioValue> create(float numeratorValue, float denominatorValue)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSAspectRatioValue(numeratorValue, denominatorValue));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSAspectRatioValue(numeratorValue, denominatorValue));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSBasicShapes.cpp b/Source/core/css/CSSBasicShapes.cpp
index f914c11..f91a608 100644
--- a/Source/core/css/CSSBasicShapes.cpp
+++ b/Source/core/css/CSSBasicShapes.cpp
@@ -30,13 +30,17 @@
 #include "config.h"
 #include "core/css/CSSBasicShapes.h"
 
+#include "core/css/CSSValuePool.h"
 #include "core/css/Pair.h"
+#include "platform/Length.h"
 #include "wtf/text/StringBuilder.h"
 
 using namespace WTF;
 
 namespace WebCore {
 
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSBasicShape)
+
 static String buildRectangleString(const String& x, const String& y, const String& width, const String& height, const String& radiusX, const String& radiusY, const String& layoutBox)
 {
     const char opening[] = "rectangle(";
@@ -94,6 +98,17 @@
         && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
 }
 
+void CSSBasicShapeRectangle::trace(Visitor* visitor)
+{
+    visitor->trace(m_y);
+    visitor->trace(m_x);
+    visitor->trace(m_width);
+    visitor->trace(m_height);
+    visitor->trace(m_radiusX);
+    visitor->trace(m_radiusY);
+    CSSBasicShape::trace(visitor);
+}
+
 static String buildCircleString(const String& radius, const String& centerX, const String& centerY, const String& layoutBox)
 {
     char at[] = "at";
@@ -120,11 +135,56 @@
     return result.toString();
 }
 
+static String serializePositionOffset(const Pair& offset, const Pair& other)
+{
+    if ((offset.first()->getValueID() == CSSValueLeft && other.first()->getValueID() == CSSValueTop)
+        || (offset.first()->getValueID() == CSSValueTop && other.first()->getValueID() == CSSValueLeft))
+        return offset.second()->cssText();
+    return offset.cssText();
+}
+
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> buildSerializablePositionOffset(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, CSSValueID defaultSide)
+{
+    CSSValueID side = defaultSide;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> amount;
+
+    if (!offset) {
+        side = CSSValueCenter;
+    } else if (offset->isValueID()) {
+        side = offset->getValueID();
+    } else if (Pair* pair = offset->getPairValue()) {
+        side = pair->first()->getValueID();
+        amount = pair->second();
+    } else {
+        amount = offset;
+    }
+
+    if (side == CSSValueCenter) {
+        side = defaultSide;
+        amount = cssValuePool().createValue(Length(50, Percent));
+    } else if ((side == CSSValueRight || side == CSSValueBottom)
+        && amount->isPercentage()) {
+        side = defaultSide;
+        amount = cssValuePool().createValue(Length(100 - amount->getFloatValue(), Percent));
+    } else if (amount->isLength() && !amount->getFloatValue()) {
+        if (side == CSSValueRight || side == CSSValueBottom)
+            amount = cssValuePool().createValue(Length(100, Percent));
+        else
+            amount = cssValuePool().createValue(Length(0, Percent));
+        side = defaultSide;
+    }
+
+    return cssValuePool().createValue(Pair::create(cssValuePool().createValue(side), amount.release(), Pair::KeepIdenticalValues));
+}
+
 String CSSBasicShapeCircle::cssText() const
 {
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCX = buildSerializablePositionOffset(m_centerX, CSSValueLeft);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCY = buildSerializablePositionOffset(m_centerY, CSSValueTop);
+
     return buildCircleString(m_radius ? m_radius->cssText() : String(),
-        m_centerX ? m_centerX->cssText() : String(),
-        m_centerY ? m_centerY->cssText() : String(),
+        serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
+        serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
         m_layoutBox ? m_layoutBox->cssText() : String());
 }
 
@@ -140,6 +200,14 @@
         && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
 }
 
+void CSSBasicShapeCircle::trace(Visitor* visitor)
+{
+    visitor->trace(m_centerX);
+    visitor->trace(m_centerY);
+    visitor->trace(m_radius);
+    CSSBasicShape::trace(visitor);
+}
+
 static String buildDeprecatedCircleString(const String& x, const String& y, const String& radius)
 {
     return "circle(" + x + ", " + y + ", " + radius + ')';
@@ -161,6 +229,14 @@
         && compareCSSValuePtr(m_radius, other.m_radius);
 }
 
+void CSSDeprecatedBasicShapeCircle::trace(Visitor* visitor)
+{
+    visitor->trace(m_centerX);
+    visitor->trace(m_centerY);
+    visitor->trace(m_radius);
+    CSSBasicShape::trace(visitor);
+}
+
 static String buildEllipseString(const String& radiusX, const String& radiusY, const String& centerX, const String& centerY, const String& box)
 {
     char at[] = "at";
@@ -198,10 +274,13 @@
 
 String CSSBasicShapeEllipse::cssText() const
 {
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCX = buildSerializablePositionOffset(m_centerX, CSSValueLeft);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> normalizedCY = buildSerializablePositionOffset(m_centerY, CSSValueTop);
+
     return buildEllipseString(m_radiusX ? m_radiusX->cssText() : String(),
         m_radiusY ? m_radiusY->cssText() : String(),
-        m_centerX ? m_centerX->cssText() : String(),
-        m_centerY ? m_centerY->cssText() : String(),
+        serializePositionOffset(*normalizedCX->getPairValue(), *normalizedCY->getPairValue()),
+        serializePositionOffset(*normalizedCY->getPairValue(), *normalizedCX->getPairValue()),
         m_layoutBox ? m_layoutBox->cssText() : String());
 }
 
@@ -218,6 +297,15 @@
         && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
 }
 
+void CSSBasicShapeEllipse::trace(Visitor* visitor)
+{
+    visitor->trace(m_centerX);
+    visitor->trace(m_centerY);
+    visitor->trace(m_radiusX);
+    visitor->trace(m_radiusY);
+    CSSBasicShape::trace(visitor);
+}
+
 static String buildDeprecatedEllipseString(const String& x, const String& y, const String& radiusX, const String& radiusY)
 {
     return "ellipse(" + x + ", " + y + ", " + radiusX + ", " + radiusY + ')';
@@ -240,15 +328,24 @@
         && compareCSSValuePtr(m_radiusY, other.m_radiusY);
 }
 
+void CSSDeprecatedBasicShapeEllipse::trace(Visitor* visitor)
+{
+    visitor->trace(m_centerX);
+    visitor->trace(m_centerY);
+    visitor->trace(m_radiusX);
+    visitor->trace(m_radiusY);
+    CSSBasicShape::trace(visitor);
+}
+
 static String buildPolygonString(const WindRule& windRule, const Vector<String>& points, const String& layoutBox)
 {
     ASSERT(!(points.size() % 2));
 
     StringBuilder result;
     const char evenOddOpening[] = "polygon(evenodd, ";
-    const char nonZeroOpening[] = "polygon(nonzero, ";
+    const char nonZeroOpening[] = "polygon(";
     const char commaSeparator[] = ", ";
-    COMPILE_ASSERT(sizeof(evenOddOpening) == sizeof(nonZeroOpening), polygon_string_openings_have_same_length);
+    COMPILE_ASSERT(sizeof(evenOddOpening) > sizeof(nonZeroOpening), polygon_string_openings_have_same_length);
 
     // Compute the required capacity in advance to reduce allocations.
     size_t length = sizeof(evenOddOpening) - 1;
@@ -306,7 +403,13 @@
     if (!compareCSSValuePtr(m_layoutBox, rhs.m_layoutBox))
         return false;
 
-    return compareCSSValueVector<CSSPrimitiveValue>(m_values, rhs.m_values);
+    return compareCSSValueVector(m_values, rhs.m_values);
+}
+
+void CSSBasicShapePolygon::trace(Visitor* visitor)
+{
+    visitor->trace(m_values);
+    CSSBasicShape::trace(visitor);
 }
 
 static String buildInsetRectangleString(const String& top, const String& right, const String& bottom, const String& left, const String& radiusX, const String& radiusY, const String& layoutBox)
@@ -368,6 +471,17 @@
         && compareCSSValuePtr(m_layoutBox, other.m_layoutBox);
 }
 
+void CSSBasicShapeInsetRectangle::trace(Visitor* visitor)
+{
+    visitor->trace(m_right);
+    visitor->trace(m_top);
+    visitor->trace(m_bottom);
+    visitor->trace(m_left);
+    visitor->trace(m_radiusX);
+    visitor->trace(m_radiusY);
+    CSSBasicShape::trace(visitor);
+}
+
 static String buildInsetString(const String& top, const String& right, const String& bottom, const String& left,
     const String& topLeftRadiusWidth, const String& topLeftRadiusHeight,
     const String& topRightRadiusWidth, const String& topRightRadiusHeight,
@@ -480,5 +594,18 @@
         && compareCSSValuePtr(m_bottomLeftRadius, other.m_bottomLeftRadius);
 }
 
+void CSSBasicShapeInset::trace(Visitor* visitor)
+{
+    visitor->trace(m_top);
+    visitor->trace(m_right);
+    visitor->trace(m_bottom);
+    visitor->trace(m_left);
+    visitor->trace(m_topLeftRadius);
+    visitor->trace(m_topRightRadius);
+    visitor->trace(m_bottomRightRadius);
+    visitor->trace(m_bottomLeftRadius);
+    CSSBasicShape::trace(visitor);
+}
+
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSBasicShapes.h b/Source/core/css/CSSBasicShapes.h
index 8b48fbb..fa6ce08 100644
--- a/Source/core/css/CSSBasicShapes.h
+++ b/Source/core/css/CSSBasicShapes.h
@@ -38,7 +38,8 @@
 
 namespace WebCore {
 
-class CSSBasicShape : public RefCounted<CSSBasicShape> {
+class CSSBasicShape : public RefCountedWillBeGarbageCollected<CSSBasicShape> {
+    DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(CSSBasicShape);
 public:
     enum Type {
         CSSBasicShapeRectangleType,
@@ -56,19 +57,18 @@
     virtual bool equals(const CSSBasicShape&) const = 0;
 
     CSSPrimitiveValue* layoutBox() const { return m_layoutBox.get(); }
-    void setLayoutBox(PassRefPtr<CSSPrimitiveValue> layoutBox) { m_layoutBox = layoutBox; }
+    void setLayoutBox(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> layoutBox) { m_layoutBox = layoutBox; }
 
-public:
-    virtual ~CSSBasicShape() { }
+    virtual void trace(Visitor* visitor) { visitor->trace(m_layoutBox); }
 
 protected:
     CSSBasicShape() { }
-    RefPtr<CSSPrimitiveValue> m_layoutBox;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_layoutBox;
 };
 
 class CSSBasicShapeRectangle FINAL : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSBasicShapeRectangle> create() { return adoptRef(new CSSBasicShapeRectangle); }
+    static PassRefPtrWillBeRawPtr<CSSBasicShapeRectangle> create() { return adoptRefWillBeNoop(new CSSBasicShapeRectangle); }
 
     CSSPrimitiveValue* x() const { return m_x.get(); }
     CSSPrimitiveValue* y() const { return m_y.get(); }
@@ -77,31 +77,33 @@
     CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
     CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
 
-    void setX(PassRefPtr<CSSPrimitiveValue> x) { m_x = x; }
-    void setY(PassRefPtr<CSSPrimitiveValue> y) { m_y = y; }
-    void setWidth(PassRefPtr<CSSPrimitiveValue> width) { m_width = width; }
-    void setHeight(PassRefPtr<CSSPrimitiveValue> height) { m_height = height; }
-    void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
-    void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
+    void setX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> x) { m_x = x; }
+    void setY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> y) { m_y = y; }
+    void setWidth(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> width) { m_width = width; }
+    void setHeight(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> height) { m_height = height; }
+    void setRadiusX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
+    void setRadiusY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
 
     virtual Type type() const OVERRIDE { return CSSBasicShapeRectangleType; }
     virtual String cssText() const OVERRIDE;
     virtual bool equals(const CSSBasicShape&) const OVERRIDE;
 
+    virtual void trace(Visitor*);
+
 private:
     CSSBasicShapeRectangle() { }
 
-    RefPtr<CSSPrimitiveValue> m_y;
-    RefPtr<CSSPrimitiveValue> m_x;
-    RefPtr<CSSPrimitiveValue> m_width;
-    RefPtr<CSSPrimitiveValue> m_height;
-    RefPtr<CSSPrimitiveValue> m_radiusX;
-    RefPtr<CSSPrimitiveValue> m_radiusY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_y;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_x;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_width;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_height;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusY;
 };
 
 class CSSBasicShapeInsetRectangle FINAL : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSBasicShapeInsetRectangle> create() { return adoptRef(new CSSBasicShapeInsetRectangle); }
+    static PassRefPtrWillBeRawPtr<CSSBasicShapeInsetRectangle> create() { return adoptRefWillBeNoop(new CSSBasicShapeInsetRectangle); }
 
     CSSPrimitiveValue* top() const { return m_top.get(); }
     CSSPrimitiveValue* right() const { return m_right.get(); }
@@ -110,31 +112,33 @@
     CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
     CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
 
-    void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; }
-    void setRight(PassRefPtr<CSSPrimitiveValue> right) { m_right = right; }
-    void setBottom(PassRefPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
-    void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; }
-    void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
-    void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
+    void setTop(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> top) { m_top = top; }
+    void setRight(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> right) { m_right = right; }
+    void setBottom(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
+    void setLeft(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> left) { m_left = left; }
+    void setRadiusX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
+    void setRadiusY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
 
     virtual Type type() const OVERRIDE { return CSSBasicShapeInsetRectangleType; }
     virtual String cssText() const OVERRIDE;
     virtual bool equals(const CSSBasicShape&) const OVERRIDE;
 
+    virtual void trace(Visitor*);
+
 private:
     CSSBasicShapeInsetRectangle() { }
 
-    RefPtr<CSSPrimitiveValue> m_right;
-    RefPtr<CSSPrimitiveValue> m_top;
-    RefPtr<CSSPrimitiveValue> m_bottom;
-    RefPtr<CSSPrimitiveValue> m_left;
-    RefPtr<CSSPrimitiveValue> m_radiusX;
-    RefPtr<CSSPrimitiveValue> m_radiusY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_right;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_top;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_bottom;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_left;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusY;
 };
 
 class CSSBasicShapeCircle FINAL : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSBasicShapeCircle> create() { return adoptRef(new CSSBasicShapeCircle); }
+    static PassRefPtrWillBeRawPtr<CSSBasicShapeCircle> create() { return adoptRefWillBeNoop(new CSSBasicShapeCircle); }
 
     virtual Type type() const OVERRIDE { return CSSBasicShapeCircleType; }
     virtual String cssText() const OVERRIDE;
@@ -144,46 +148,50 @@
     CSSPrimitiveValue* centerY() const { return m_centerY.get(); }
     CSSPrimitiveValue* radius() const { return m_radius.get(); }
 
-    void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
-    void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
-    void setRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_radius = radius; }
+    void setCenterX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
+    void setCenterY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
+    void setRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_radius = radius; }
+
+    virtual void trace(Visitor*);
 
 private:
     CSSBasicShapeCircle() { }
 
-    RefPtr<CSSPrimitiveValue> m_centerX;
-    RefPtr<CSSPrimitiveValue> m_centerY;
-    RefPtr<CSSPrimitiveValue> m_radius;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radius;
 };
 
 class CSSDeprecatedBasicShapeCircle FINAL : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSDeprecatedBasicShapeCircle> create() { return adoptRef(new CSSDeprecatedBasicShapeCircle); }
+    static PassRefPtrWillBeRawPtr<CSSDeprecatedBasicShapeCircle> create() { return adoptRefWillBeNoop(new CSSDeprecatedBasicShapeCircle); }
 
     CSSPrimitiveValue* centerX() const { return m_centerX.get(); }
     CSSPrimitiveValue* centerY() const { return m_centerY.get(); }
     CSSPrimitiveValue* radius() const { return m_radius.get(); }
 
-    void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
-    void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
-    void setRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_radius = radius; }
+    void setCenterX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
+    void setCenterY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
+    void setRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_radius = radius; }
 
     virtual Type type() const OVERRIDE { return CSSDeprecatedBasicShapeCircleType; }
 
     virtual String cssText() const OVERRIDE;
     virtual bool equals(const CSSBasicShape&) const OVERRIDE;
 
+    virtual void trace(Visitor*);
+
 private:
     CSSDeprecatedBasicShapeCircle() { }
 
-    RefPtr<CSSPrimitiveValue> m_centerY;
-    RefPtr<CSSPrimitiveValue> m_centerX;
-    RefPtr<CSSPrimitiveValue> m_radius;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radius;
 };
 
 class CSSBasicShapeEllipse FINAL : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSBasicShapeEllipse> create() { return adoptRef(new CSSBasicShapeEllipse); }
+    static PassRefPtrWillBeRawPtr<CSSBasicShapeEllipse> create() { return adoptRefWillBeNoop(new CSSBasicShapeEllipse); }
 
     virtual Type type() const OVERRIDE { return CSSBasicShapeEllipseType; }
     virtual String cssText() const OVERRIDE;
@@ -194,60 +202,64 @@
     CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
     CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
 
-    void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
-    void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
-    void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
-    void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
+    void setCenterX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
+    void setCenterY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
+    void setRadiusX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
+    void setRadiusY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
+
+    virtual void trace(Visitor*);
 
 private:
     CSSBasicShapeEllipse() { }
 
-    RefPtr<CSSPrimitiveValue> m_centerX;
-    RefPtr<CSSPrimitiveValue> m_centerY;
-    RefPtr<CSSPrimitiveValue> m_radiusX;
-    RefPtr<CSSPrimitiveValue> m_radiusY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusY;
 };
 
 class CSSDeprecatedBasicShapeEllipse FINAL : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSDeprecatedBasicShapeEllipse> create() { return adoptRef(new CSSDeprecatedBasicShapeEllipse); }
+    static PassRefPtrWillBeRawPtr<CSSDeprecatedBasicShapeEllipse> create() { return adoptRefWillBeNoop(new CSSDeprecatedBasicShapeEllipse); }
 
     CSSPrimitiveValue* centerX() const { return m_centerX.get(); }
     CSSPrimitiveValue* centerY() const { return m_centerY.get(); }
     CSSPrimitiveValue* radiusX() const { return m_radiusX.get(); }
     CSSPrimitiveValue* radiusY() const { return m_radiusY.get(); }
 
-    void setCenterX(PassRefPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
-    void setCenterY(PassRefPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
-    void setRadiusX(PassRefPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
-    void setRadiusY(PassRefPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
+    void setCenterX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerX) { m_centerX = centerX; }
+    void setCenterY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> centerY) { m_centerY = centerY; }
+    void setRadiusX(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusX) { m_radiusX = radiusX; }
+    void setRadiusY(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radiusY) { m_radiusY = radiusY; }
 
     virtual Type type() const OVERRIDE { return CSSDeprecatedBasicShapeEllipseType; }
     virtual String cssText() const OVERRIDE;
     virtual bool equals(const CSSBasicShape&) const OVERRIDE;
 
+    virtual void trace(Visitor*);
+
 private:
     CSSDeprecatedBasicShapeEllipse() { }
 
-    RefPtr<CSSPrimitiveValue> m_centerX;
-    RefPtr<CSSPrimitiveValue> m_centerY;
-    RefPtr<CSSPrimitiveValue> m_radiusX;
-    RefPtr<CSSPrimitiveValue> m_radiusY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_centerY;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusX;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_radiusY;
 };
 
 class CSSBasicShapePolygon FINAL : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSBasicShapePolygon> create() { return adoptRef(new CSSBasicShapePolygon); }
+    static PassRefPtrWillBeRawPtr<CSSBasicShapePolygon> create() { return adoptRefWillBeNoop(new CSSBasicShapePolygon); }
 
-    void appendPoint(PassRefPtr<CSSPrimitiveValue> x, PassRefPtr<CSSPrimitiveValue> y)
+    void appendPoint(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> x, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> y)
     {
         m_values.append(x);
         m_values.append(y);
     }
 
-    PassRefPtr<CSSPrimitiveValue> getXAt(unsigned i) const { return m_values.at(i * 2); }
-    PassRefPtr<CSSPrimitiveValue> getYAt(unsigned i) const { return m_values.at(i * 2 + 1); }
-    const Vector<RefPtr<CSSPrimitiveValue> >& values() const { return m_values; }
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> getXAt(unsigned i) const { return m_values.at(i * 2); }
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> getYAt(unsigned i) const { return m_values.at(i * 2 + 1); }
+    const WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> >& values() const { return m_values; }
 
     void setWindRule(WindRule w) { m_windRule = w; }
     WindRule windRule() const { return m_windRule; }
@@ -255,19 +267,22 @@
     virtual Type type() const OVERRIDE { return CSSBasicShapePolygonType; }
     virtual String cssText() const OVERRIDE;
     virtual bool equals(const CSSBasicShape&) const OVERRIDE;
+
+    virtual void trace(Visitor*);
+
 private:
     CSSBasicShapePolygon()
         : m_windRule(RULE_NONZERO)
     {
     }
 
-    Vector<RefPtr<CSSPrimitiveValue> > m_values;
+    WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> > m_values;
     WindRule m_windRule;
 };
 
 class CSSBasicShapeInset : public CSSBasicShape {
 public:
-    static PassRefPtr<CSSBasicShapeInset> create() { return adoptRef(new CSSBasicShapeInset); }
+    static PassRefPtrWillBeRawPtr<CSSBasicShapeInset> create() { return adoptRefWillBeNoop(new CSSBasicShapeInset); }
 
     CSSPrimitiveValue* top() const { return m_top.get(); }
     CSSPrimitiveValue* right() const { return m_right.get(); }
@@ -279,10 +294,10 @@
     CSSPrimitiveValue* bottomRightRadius() const { return m_bottomRightRadius.get(); }
     CSSPrimitiveValue* bottomLeftRadius() const { return m_bottomLeftRadius.get(); }
 
-    void setTop(PassRefPtr<CSSPrimitiveValue> top) { m_top = top; }
-    void setRight(PassRefPtr<CSSPrimitiveValue> right) { m_right = right; }
-    void setBottom(PassRefPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
-    void setLeft(PassRefPtr<CSSPrimitiveValue> left) { m_left = left; }
+    void setTop(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> top) { m_top = top; }
+    void setRight(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> right) { m_right = right; }
+    void setBottom(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> bottom) { m_bottom = bottom; }
+    void setLeft(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> left) { m_left = left; }
 
     void updateShapeSize4Values(CSSPrimitiveValue* top, CSSPrimitiveValue* right, CSSPrimitiveValue* bottom, CSSPrimitiveValue* left)
     {
@@ -308,27 +323,29 @@
     }
 
 
-    void setTopLeftRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_topLeftRadius = radius; }
-    void setTopRightRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_topRightRadius = radius; }
-    void setBottomRightRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_bottomRightRadius = radius; }
-    void setBottomLeftRadius(PassRefPtr<CSSPrimitiveValue> radius) { m_bottomLeftRadius = radius; }
+    void setTopLeftRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_topLeftRadius = radius; }
+    void setTopRightRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_topRightRadius = radius; }
+    void setBottomRightRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_bottomRightRadius = radius; }
+    void setBottomLeftRadius(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> radius) { m_bottomLeftRadius = radius; }
 
     virtual Type type() const OVERRIDE { return CSSBasicShapeInsetType; }
     virtual String cssText() const OVERRIDE;
     virtual bool equals(const CSSBasicShape&) const OVERRIDE;
 
+    virtual void trace(Visitor*);
+
 private:
     CSSBasicShapeInset() { }
 
-    RefPtr<CSSPrimitiveValue> m_top;
-    RefPtr<CSSPrimitiveValue> m_right;
-    RefPtr<CSSPrimitiveValue> m_bottom;
-    RefPtr<CSSPrimitiveValue> m_left;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_top;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_right;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_bottom;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_left;
 
-    RefPtr<CSSPrimitiveValue> m_topLeftRadius;
-    RefPtr<CSSPrimitiveValue> m_topRightRadius;
-    RefPtr<CSSPrimitiveValue> m_bottomRightRadius;
-    RefPtr<CSSPrimitiveValue> m_bottomLeftRadius;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_topLeftRadius;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_topRightRadius;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_bottomRightRadius;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_bottomLeftRadius;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSBorderImage.cpp b/Source/core/css/CSSBorderImage.cpp
index 9b7cab9..fd05d0f 100644
--- a/Source/core/css/CSSBorderImage.cpp
+++ b/Source/core/css/CSSBorderImage.cpp
@@ -22,8 +22,8 @@
 
 namespace WebCore {
 
-PassRefPtrWillBeRawPtr<CSSValueList> createBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSValue> imageSlice, PassRefPtr<CSSValue> borderSlice,
-                                                PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat)
+PassRefPtrWillBeRawPtr<CSSValueList> createBorderImageValue(PassRefPtrWillBeRawPtr<CSSValue> image, PassRefPtrWillBeRawPtr<CSSValue> imageSlice,
+    PassRefPtrWillBeRawPtr<CSSValue> borderSlice, PassRefPtrWillBeRawPtr<CSSValue> outset, PassRefPtrWillBeRawPtr<CSSValue> repeat)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     if (image)
diff --git a/Source/core/css/CSSBorderImage.h b/Source/core/css/CSSBorderImage.h
index 42d2a1f..b9066fa 100644
--- a/Source/core/css/CSSBorderImage.h
+++ b/Source/core/css/CSSBorderImage.h
@@ -26,8 +26,8 @@
 
 namespace WebCore {
 
-PassRefPtrWillBeRawPtr<CSSValueList> createBorderImageValue(PassRefPtr<CSSValue> image, PassRefPtr<CSSValue> imageSlice, PassRefPtr<CSSValue> borderSlice,
-    PassRefPtr<CSSValue> outset, PassRefPtr<CSSValue> repeat);
+PassRefPtrWillBeRawPtr<CSSValueList> createBorderImageValue(PassRefPtrWillBeRawPtr<CSSValue> image, PassRefPtrWillBeRawPtr<CSSValue> imageSlice, PassRefPtrWillBeRawPtr<CSSValue> borderSlice,
+    PassRefPtrWillBeRawPtr<CSSValue> outset, PassRefPtrWillBeRawPtr<CSSValue> repeat);
 
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSBorderImageSliceValue.h b/Source/core/css/CSSBorderImageSliceValue.h
index 6243cf4..3e321c4 100644
--- a/Source/core/css/CSSBorderImageSliceValue.h
+++ b/Source/core/css/CSSBorderImageSliceValue.h
@@ -38,7 +38,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> slices, bool fill)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSBorderImageSliceValue(slices, fill));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSBorderImageSliceValue(slices, fill));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSCalculationValue.cpp b/Source/core/css/CSSCalculationValue.cpp
index 58ce6d7..03eefe9 100644
--- a/Source/core/css/CSSCalculationValue.cpp
+++ b/Source/core/css/CSSCalculationValue.cpp
@@ -47,8 +47,6 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(CSSCalcExpressionNode);
-
 static CalculationCategory unitCategory(CSSPrimitiveValue::UnitTypes type)
 {
     switch (type) {
@@ -176,9 +174,7 @@
     return clampToPermittedRange(m_expression->computeLengthPx(conversionData));
 }
 
-CSSCalcExpressionNode::~CSSCalcExpressionNode()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(CSSCalcExpressionNode)
 
 class CSSCalcPrimitiveValue FINAL : public CSSCalcExpressionNode {
     WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
@@ -192,7 +188,7 @@
     static PassRefPtrWillBeRawPtr<CSSCalcPrimitiveValue> create(double value, CSSPrimitiveValue::UnitTypes type, bool isInteger)
     {
         if (std::isnan(value) || std::isinf(value))
-            return 0;
+            return nullptr;
         return adoptRefWillBeNoop(new CSSCalcPrimitiveValue(CSSPrimitiveValue::create(value, type).get(), isInteger));
     }
 
@@ -333,7 +329,7 @@
 
         CalculationCategory newCategory = determineCategory(*leftSide, *rightSide, op);
         if (newCategory == CalcOther)
-            return 0;
+            return nullptr;
 
         return adoptRefWillBeNoop(new CSSCalcBinaryOperation(leftSide, rightSide, op, newCategory));
     }
@@ -378,14 +374,14 @@
             if (!numberSide)
                 return create(leftSide, rightSide, op);
             if (numberSide == leftSide && op == CalcDivide)
-                return 0;
+                return nullptr;
             CSSCalcExpressionNode* otherSide = leftSide == numberSide ? rightSide.get() : leftSide.get();
 
             double number = numberSide->doubleValue();
             if (std::isnan(number) || std::isinf(number))
-                return 0;
+                return nullptr;
             if (op == CalcDivide && !number)
-                return 0;
+                return nullptr;
 
             CSSPrimitiveValue::UnitTypes otherType = otherSide->primitiveType();
             if (hasDoubleValue(otherType))
@@ -555,7 +551,7 @@
         bool ok = parseValueExpression(tokens, 0, &index, &result);
         ASSERT_WITH_SECURITY_IMPLICATION(index <= tokens->size());
         if (!ok || index != tokens->size())
-            return 0;
+            return nullptr;
         return result.value;
     }
 
@@ -583,7 +579,7 @@
         if (parserValue->unit == CSSParserValue::Operator)
             return false;
 
-        RefPtr<CSSValue> value = parserValue->createCSSValue();
+        RefPtrWillBeRawPtr<CSSValue> value = parserValue->createCSSValue();
         if (!value || !value->isPrimitiveValue())
             return false;
 
@@ -713,10 +709,10 @@
     }
     case CalcExpressionNodeUndefined:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> CSSCalcValue::createExpressionNode(const Length& length, float zoom)
@@ -739,10 +735,10 @@
     case DeviceHeight:
     case Undefined:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(CSSParserString name, CSSParserValueList* parserValueList, ValueRange range)
@@ -754,12 +750,12 @@
         expression = parser.parseCalc(parserValueList);
     // FIXME calc (http://webkit.org/b/16662) Add parsing for min and max here
 
-    return expression ? adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCalcValue(expression, range)) : 0;
+    return expression ? adoptRefWillBeRefCountedGarbageCollected(new CSSCalcValue(expression, range)) : nullptr;
 }
 
 PassRefPtrWillBeRawPtr<CSSCalcValue> CSSCalcValue::create(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> expression, ValueRange range)
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCalcValue(expression, range));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSCalcValue(expression, range));
 }
 
 void CSSCalcValue::traceAfterDispatch(Visitor* visitor)
diff --git a/Source/core/css/CSSCalculationValue.h b/Source/core/css/CSSCalculationValue.h
index 836cffc..e99d4a1 100644
--- a/Source/core/css/CSSCalculationValue.h
+++ b/Source/core/css/CSSCalculationValue.h
@@ -57,14 +57,13 @@
 };
 
 class CSSCalcExpressionNode : public RefCountedWillBeGarbageCollected<CSSCalcExpressionNode> {
-    DECLARE_GC_INFO;
+    DECLARE_EMPTY_VIRTUAL_DESTRUCTOR_WILL_BE_REMOVED(CSSCalcExpressionNode);
 public:
     enum Type {
         CssCalcPrimitiveValue = 1,
         CssCalcBinaryOperation
     };
 
-    virtual ~CSSCalcExpressionNode() = 0;
     virtual bool isZero() const = 0;
     virtual PassOwnPtr<CalcExpressionNode> toCalcValue(const CSSToLengthConversionData&) const = 0;
     virtual double doubleValue() const = 0;
@@ -94,7 +93,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSCalcValue> create(CSSParserString name, CSSParserValueList*, ValueRange);
     static PassRefPtrWillBeRawPtr<CSSCalcValue> create(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode>, ValueRange = ValueRangeAll);
-    static PassRefPtrWillBeRawPtr<CSSCalcValue> create(const CalculationValue* value, float zoom) { return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCalcValue(value, zoom)); }
+    static PassRefPtrWillBeRawPtr<CSSCalcValue> create(const CalculationValue* value, float zoom) { return adoptRefWillBeRefCountedGarbageCollected(new CSSCalcValue(value, zoom)); }
 
     static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, bool isInteger = false);
     static PassRefPtrWillBeRawPtr<CSSCalcExpressionNode> createExpressionNode(PassRefPtrWillBeRawPtr<CSSCalcExpressionNode>, PassRefPtrWillBeRawPtr<CSSCalcExpressionNode>, CalcOperator);
diff --git a/Source/core/css/CSSCanvasValue.cpp b/Source/core/css/CSSCanvasValue.cpp
index ce46f04..1514eac 100644
--- a/Source/core/css/CSSCanvasValue.cpp
+++ b/Source/core/css/CSSCanvasValue.cpp
@@ -77,9 +77,7 @@
 HTMLCanvasElement* CSSCanvasValue::element(Document* document)
 {
      if (!m_element) {
-        m_element = document->getCSSCanvasElement(m_name);
-        if (!m_element)
-            return 0;
+        m_element = &document->getCSSCanvasElement(m_name);
         m_element->addObserver(&m_canvasObserver);
     }
     return m_element;
@@ -90,7 +88,7 @@
     ASSERT(clients().contains(renderer));
     HTMLCanvasElement* elt = element(&renderer->document());
     if (!elt || !elt->buffer())
-        return 0;
+        return nullptr;
     return elt->copiedImage();
 }
 
diff --git a/Source/core/css/CSSCanvasValue.h b/Source/core/css/CSSCanvasValue.h
index df13d9d..7227945 100644
--- a/Source/core/css/CSSCanvasValue.h
+++ b/Source/core/css/CSSCanvasValue.h
@@ -37,7 +37,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSCanvasValue> create(const String& name)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCanvasValue(name));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSCanvasValue(name));
     }
     ~CSSCanvasValue();
 
diff --git a/Source/core/css/CSSCharsetRule.h b/Source/core/css/CSSCharsetRule.h
index ee91bd3..01c3a30 100644
--- a/Source/core/css/CSSCharsetRule.h
+++ b/Source/core/css/CSSCharsetRule.h
@@ -30,9 +30,9 @@
 
 class CSSCharsetRule FINAL : public CSSRule {
 public:
-    static PassRefPtr<CSSCharsetRule> create(CSSStyleSheet* parent, const String& encoding)
+    static PassRefPtrWillBeRawPtr<CSSCharsetRule> create(CSSStyleSheet* parent, const String& encoding)
     {
-        return adoptRef(new CSSCharsetRule(parent, encoding));
+        return adoptRefWillBeNoop(new CSSCharsetRule(parent, encoding));
     }
 
     virtual ~CSSCharsetRule() { }
@@ -44,6 +44,8 @@
     const String& encoding() const { return m_encoding; }
     void setEncoding(const String& encoding) { m_encoding = encoding; }
 
+    virtual void trace(Visitor* visitor) OVERRIDE { CSSRule::trace(visitor); }
+
 private:
     CSSCharsetRule(CSSStyleSheet* parent, const String& encoding);
 
diff --git a/Source/core/css/CSSComputedStyleDeclaration.cpp b/Source/core/css/CSSComputedStyleDeclaration.cpp
index d6912a5..ee643ad 100644
--- a/Source/core/css/CSSComputedStyleDeclaration.cpp
+++ b/Source/core/css/CSSComputedStyleDeclaration.cpp
@@ -205,6 +205,7 @@
     CSSPropertyWhiteSpace,
     CSSPropertyWidows,
     CSSPropertyWidth,
+    CSSPropertyWillChange,
     CSSPropertyWordBreak,
     CSSPropertyWordSpacing,
     CSSPropertyWordWrap,
@@ -437,7 +438,7 @@
         }
     }
 
-    RefPtr<Quad> quad = Quad::create();
+    RefPtrWillBeRawPtr<Quad> quad = Quad::create();
     quad->setTop(top);
     quad->setRight(right);
     quad->setBottom(bottom);
@@ -489,7 +490,7 @@
         }
     }
 
-    RefPtr<Quad> quad = Quad::create();
+    RefPtrWillBeRawPtr<Quad> quad = Quad::create();
     quad->setTop(top);
     quad->setRight(right);
     quad->setBottom(bottom);
@@ -498,7 +499,7 @@
     return cssValuePool().createValue(quad.release());
 }
 
-static PassRefPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForNinePieceImageRepeat(const NinePieceImage& image)
 {
     RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalRepeat;
     RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalRepeat;
@@ -511,13 +512,13 @@
     return cssValuePool().createValue(Pair::create(horizontalRepeat.release(), verticalRepeat.release(), Pair::DropIdenticalValues));
 }
 
-static PassRefPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForNinePieceImage(const NinePieceImage& image, const RenderStyle& style)
 {
     if (!image.hasImage())
         return cssValuePool().createIdentifierValue(CSSValueNone);
 
     // Image first.
-    RefPtr<CSSValue> imageValue;
+    RefPtrWillBeRawPtr<CSSValue> imageValue;
     if (image.image())
         imageValue = image.image()->cssValue();
 
@@ -525,13 +526,13 @@
     RefPtrWillBeRawPtr<CSSBorderImageSliceValue> imageSlices = valueForNinePieceImageSlice(image);
 
     // Create the border area slices.
-    RefPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style);
+    RefPtrWillBeRawPtr<CSSValue> borderSlices = valueForNinePieceImageQuad(image.borderSlices(), style);
 
     // Create the border outset.
-    RefPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset(), style);
+    RefPtrWillBeRawPtr<CSSValue> outset = valueForNinePieceImageQuad(image.outset(), style);
 
     // Create the repeat rules.
-    RefPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
+    RefPtrWillBeRawPtr<CSSValue> repeat = valueForNinePieceImageRepeat(image);
 
     return createBorderImageValue(imageValue.release(), imageSlices.release(), borderSlices.release(), outset.release(), repeat.release());
 }
@@ -553,7 +554,7 @@
     return cssValuePool().createValue(length, style);
 }
 
-static PassRefPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForReflection(const StyleReflection* reflection, const RenderStyle& style)
 {
     if (!reflection)
         return cssValuePool().createIdentifierValue(CSSValueNone);
@@ -599,7 +600,7 @@
     return positionList.release();
 }
 
-static PassRefPtr<CSSValue> valueForPositionOffset(RenderStyle& style, CSSPropertyID propertyID, const RenderObject* renderer)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForPositionOffset(RenderStyle& style, CSSPropertyID propertyID, const RenderObject* renderer)
 {
     Length l;
     switch (propertyID) {
@@ -616,7 +617,7 @@
             l = style.bottom();
             break;
         default:
-            return 0;
+            return nullptr;
     }
 
     if (l.isPercent() && renderer && renderer->isBox()) {
@@ -655,7 +656,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForBorderRadiusCorner(LengthSize radius, const RenderStyle& style)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = valuesForBorderRadiusCorner(radius, style);
     if (list->item(0)->equals(*list->item(1)))
@@ -754,7 +755,7 @@
     return transformValue.release();
 }
 
-static PassRefPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> computedTransform(RenderObject* renderer, const RenderStyle& style)
 {
     if (!renderer || !renderer->hasTransform() || !style.hasTransform())
         return cssValuePool().createIdentifierValue(CSSValueNone);
@@ -773,7 +774,7 @@
     return list.release();
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle& style) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::valueForFilter(const RenderObject* renderer, const RenderStyle& style) const
 {
     if (style.filter().operations().isEmpty())
         return cssValuePool().createIdentifierValue(CSSValueNone);
@@ -844,7 +845,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> specifiedValueForGridTrackBreadth(const GridLength& trackBreadth, const RenderStyle& style)
 {
     if (!trackBreadth.isLength())
         return cssValuePool().createValue(trackBreadth.flex(), CSSPrimitiveValue::CSS_FR);
@@ -855,7 +856,7 @@
     return zoomAdjustedPixelValueForLength(trackBreadthLength, style);
 }
 
-static PassRefPtr<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> specifiedValueForGridTrackSize(const GridTrackSize& trackSize, const RenderStyle& style)
 {
     switch (trackSize.type()) {
     case LengthTrackSizing:
@@ -867,7 +868,7 @@
         return CSSFunctionValue::create("minmax(", minMaxTrackBreadths);
     }
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 static void addValuesForNamedGridLinesAtIndex(const OrderedNamedGridLines& orderedNamedGridLines, size_t i, CSSValueList& list)
@@ -882,7 +883,7 @@
     list.append(lineNames.release());
 }
 
-static PassRefPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForGridTrackList(GridTrackSizingDirection direction, RenderObject* renderer, const RenderStyle& style)
 {
     const Vector<GridTrackSize>& trackSizes = direction == ForColumns ? style.gridTemplateColumns() : style.gridTemplateRows();
     const OrderedNamedGridLines& orderedNamedGridLines = direction == ForColumns ? style.orderedNamedGridColumnLines() : style.orderedNamedGridRowLines();
@@ -915,7 +916,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForGridPosition(const GridPosition& position)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForGridPosition(const GridPosition& position)
 {
     if (position.isAuto())
         return cssValuePool().createIdentifierValue(CSSValueAuto);
@@ -934,9 +935,9 @@
         list->append(cssValuePool().createValue(position.namedGridLine(), CSSPrimitiveValue::CSS_STRING));
     return list;
 }
-static PassRefPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation)
+static PassRefPtrWillBeRawPtr<CSSValue> createTransitionPropertyValue(const CSSAnimationData* animation)
 {
-    RefPtr<CSSValue> propertyValue;
+    RefPtrWillBeRawPtr<CSSValue> propertyValue;
     if (animation->animationMode() == CSSAnimationData::AnimateNone)
         propertyValue = cssValuePool().createIdentifierValue(CSSValueNone);
     else if (animation->animationMode() == CSSAnimationData::AnimateAll)
@@ -945,7 +946,7 @@
         propertyValue = cssValuePool().createValue(getPropertyNameString(animation->property()), CSSPrimitiveValue::CSS_STRING);
     return propertyValue.release();
 }
-static PassRefPtr<CSSValue> valueForTransitionProperty(const CSSAnimationDataList* animList)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForTransitionProperty(const CSSAnimationDataList* animList)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     if (animList) {
@@ -956,7 +957,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForAnimationDelay(const CSSAnimationDataList* animList)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationDelay(const CSSAnimationDataList* animList)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     if (animList) {
@@ -969,7 +970,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForAnimationDuration(const CSSAnimationDataList* animList)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationDuration(const CSSAnimationDataList* animList)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     if (animList) {
@@ -982,7 +983,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
+static PassRefPtrWillBeRawPtr<CSSValue> createTimingFunctionValue(const TimingFunction* timingFunction)
 {
     switch (timingFunction->type()) {
     case TimingFunction::CubicBezierFunction:
@@ -1005,7 +1006,7 @@
                     break;
                 default:
                     ASSERT_NOT_REACHED();
-                    return 0;
+                    return nullptr;
                 }
                 return cssValuePool().createIdentifierValue(valueId);
             }
@@ -1016,7 +1017,8 @@
         {
             const StepsTimingFunction* stepsTimingFunction = toStepsTimingFunction(timingFunction);
             if (stepsTimingFunction->subType() == StepsTimingFunction::Custom)
-                return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
+                return CSSStepsTimingFunctionValue::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtPosition());
+
             CSSValueID valueId;
             switch (stepsTimingFunction->subType()) {
             case StepsTimingFunction::Start:
@@ -1027,7 +1029,7 @@
                 break;
             default:
                 ASSERT_NOT_REACHED();
-                return 0;
+                return nullptr;
             }
             return cssValuePool().createIdentifierValue(valueId);
         }
@@ -1037,7 +1039,7 @@
     }
 }
 
-static PassRefPtr<CSSValue> valueForAnimationTimingFunction(const CSSAnimationDataList* animList)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationTimingFunction(const CSSAnimationDataList* animList)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
     if (animList) {
@@ -1049,7 +1051,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForAnimationFillMode(unsigned fillMode)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationFillMode(unsigned fillMode)
 {
     switch (fillMode) {
     case AnimationFillModeNone:
@@ -1062,11 +1064,11 @@
         return cssValuePool().createIdentifierValue(CSSValueBoth);
     default:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 }
 
-static PassRefPtr<CSSValue> valueForAnimationDirection(CSSAnimationData::AnimationDirection direction)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForAnimationDirection(CSSAnimationData::AnimationDirection direction)
 {
     switch (direction) {
     case CSSAnimationData::AnimationDirectionNormal:
@@ -1079,11 +1081,25 @@
         return cssValuePool().createIdentifierValue(CSSValueAlternateReverse);
     default:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 }
 
-static PassRefPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForWillChange(const Vector<CSSPropertyID>& willChangeProperties, bool willChangeContents, bool willChangeScrollPosition)
+{
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+    if (willChangeContents)
+        list->append(cssValuePool().createIdentifierValue(CSSValueContents));
+    if (willChangeScrollPosition)
+        list->append(cssValuePool().createIdentifierValue(CSSValueScrollPosition));
+    for (size_t i = 0; i < willChangeProperties.size(); ++i)
+        list->append(cssValuePool().createIdentifierValue(willChangeProperties[i]));
+    if (!list->length())
+        list->append(cssValuePool().createIdentifierValue(CSSValueAuto));
+    return list.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> createLineBoxContainValue(unsigned lineBoxContain)
 {
     if (!lineBoxContain)
         return cssValuePool().createIdentifierValue(CSSValueNone);
@@ -1145,16 +1161,16 @@
     return static_cast<CSSValueID>(CSSValueXxSmall + keywordSize - 1);
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getFontSizeCSSValuePreferringKeyword() const
 {
     if (!m_node)
-        return 0;
+        return nullptr;
 
     m_node->document().updateLayoutIgnorePendingStylesheets();
 
     RefPtr<RenderStyle> style = m_node->computedStyle(m_pseudoElementSpecifier);
     if (!style)
-        return 0;
+        return nullptr;
 
     if (int keywordSize = style->fontDescription().keywordSize())
         return cssValuePool().createIdentifierValue(cssIdentifierForFontSizeKeyword(keywordSize));
@@ -1175,7 +1191,7 @@
     return style->fontDescription().useFixedDefaultSize();
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowData(const ShadowData& shadow, const RenderStyle& style, bool useSpread) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowData(const ShadowData& shadow, const RenderStyle& style, bool useSpread) const
 {
     RefPtrWillBeRawPtr<CSSPrimitiveValue> x = zoomAdjustedPixelValue(shadow.x(), style);
     RefPtrWillBeRawPtr<CSSPrimitiveValue> y = zoomAdjustedPixelValue(shadow.y(), style);
@@ -1186,7 +1202,7 @@
     return CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), shadowStyle.release(), color.release());
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowList(const ShadowList* shadowList, const RenderStyle& style, bool useSpread) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::valueForShadowList(const ShadowList* shadowList, const RenderStyle& style, bool useSpread) const
 {
     if (!shadowList)
         return cssValuePool().createIdentifierValue(CSSValueNone);
@@ -1198,7 +1214,7 @@
     return list.release();
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID) const
 {
     return getPropertyCSSValue(propertyID, UpdateLayout);
 }
@@ -1227,7 +1243,7 @@
     return cssValuePool().createValue(family.string(), CSSPrimitiveValue::CSS_STRING);
 }
 
-static PassRefPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
+static PassRefPtrWillBeRawPtr<CSSValue> renderTextDecorationFlagsToCSSValue(int textDecoration)
 {
     // Blink value is ignored.
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
@@ -1243,7 +1259,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForTextDecorationStyle(TextDecorationStyle textDecorationStyle)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForTextDecorationStyle(TextDecorationStyle textDecorationStyle)
 {
     switch (textDecorationStyle) {
     case TextDecorationStyleSolid:
@@ -1262,7 +1278,7 @@
     return cssValuePool().createExplicitInitialValue();
 }
 
-static PassRefPtr<CSSValue> valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat yRepeat)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForFillRepeat(EFillRepeat xRepeat, EFillRepeat yRepeat)
 {
     // For backwards compatibility, if both values are equal, just return one of them. And
     // if the two values are equivalent to repeat-x or repeat-y, just return the shorthand.
@@ -1279,7 +1295,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForFillSourceType(EMaskSourceType type)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForFillSourceType(EMaskSourceType type)
 {
     switch (type) {
     case MaskAlpha:
@@ -1290,10 +1306,10 @@
 
     ASSERT_NOT_REACHED();
 
-    return 0;
+    return nullptr;
 }
 
-static PassRefPtr<CSSValue> valueForFillSize(const FillSize& fillSize, const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForFillSize(const FillSize& fillSize, const RenderStyle& style)
 {
     if (fillSize.type == Contain)
         return cssValuePool().createIdentifierValue(CSSValueContain);
@@ -1310,7 +1326,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForContentData(const RenderStyle& style)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForContentData(const RenderStyle& style)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     for (const ContentData* contentData = style.contentData(); contentData; contentData = contentData->next()) {
@@ -1328,11 +1344,11 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> valueForCounterDirectives(const RenderStyle& style, CSSPropertyID propertyID)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForCounterDirectives(const RenderStyle& style, CSSPropertyID propertyID)
 {
     const CounterDirectiveMap* map = style.counterDirectives();
     if (!map)
-        return 0;
+        return nullptr;
 
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     for (CounterDirectiveMap::const_iterator it = map->begin(); it != map->end(); ++it) {
@@ -1377,14 +1393,14 @@
 
 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontStyle(RenderStyle& style)
 {
-    if (style.fontDescription().italic())
+    if (style.fontDescription().style() == FontStyleItalic)
         return cssValuePool().createIdentifierValue(CSSValueItalic);
     return cssValuePool().createIdentifierValue(CSSValueNormal);
 }
 
 static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueForFontVariant(RenderStyle& style)
 {
-    if (style.fontDescription().smallCaps())
+    if (style.fontDescription().variant() == FontVariantSmallCaps)
         return cssValuePool().createIdentifierValue(CSSValueSmallCaps);
     return cssValuePool().createIdentifierValue(CSSValueNormal);
 }
@@ -1415,7 +1431,30 @@
     return cssValuePool().createIdentifierValue(CSSValueNormal);
 }
 
-static PassRefPtr<CSSValue> touchActionFlagsToCSSValue(TouchAction touchAction)
+static PassRefPtrWillBeRawPtr<CSSValue> valueForShape(const RenderStyle& style, ShapeValue* shapeValue)
+{
+    if (!shapeValue)
+        return cssValuePool().createIdentifierValue(CSSValueNone);
+    if (shapeValue->type() == ShapeValue::Outside)
+        return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
+    if (shapeValue->type() == ShapeValue::Box)
+        return cssValuePool().createValue(shapeValue->layoutBox());
+    if (shapeValue->type() == ShapeValue::Image) {
+        if (shapeValue->image())
+            return shapeValue->image()->cssValue();
+        return cssValuePool().createIdentifierValue(CSSValueNone);
+    }
+
+    ASSERT(shapeValue->type() == ShapeValue::Shape);
+
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    list->append(valueForBasicShape(style, shapeValue->shape()));
+    if (shapeValue->layoutBox() != BoxMissing)
+        list->append(cssValuePool().createValue(shapeValue->layoutBox()));
+    return list.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> touchActionFlagsToCSSValue(TouchAction touchAction)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     if (touchAction == TouchActionAuto)
@@ -1424,11 +1463,14 @@
         ASSERT(touchAction == TouchActionNone);
         list->append(cssValuePool().createIdentifierValue(CSSValueNone));
     }
-    if (touchAction & TouchActionPanX)
-        list->append(cssValuePool().createIdentifierValue(CSSValuePanX));
-    if (touchAction & TouchActionPanY)
-        list->append(cssValuePool().createIdentifierValue(CSSValuePanY));
-
+    if (touchAction == (TouchActionPanX | TouchActionPanY | TouchActionPinchZoom)) {
+        list->append(cssValuePool().createIdentifierValue(CSSValueManipulation));
+    } else {
+        if (touchAction & TouchActionPanX)
+            list->append(cssValuePool().createIdentifierValue(CSSValuePanX));
+        if (touchAction & TouchActionPanY)
+            list->append(cssValuePool().createIdentifierValue(CSSValuePanY));
+    }
     ASSERT(list->length());
     return list.release();
 }
@@ -1506,21 +1548,20 @@
     return result.release();
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
 {
     Node* styledNode = this->styledNode();
     if (!styledNode)
-        return 0;
+        return nullptr;
     RenderObject* renderer = styledNode->renderer();
     RefPtr<RenderStyle> style;
 
     if (updateLayout) {
         Document& document = styledNode->document();
 
-        // If a compositor animation is running or animations have been updated
-        // via the api we may need to service animations in order to generate
-        // an up to date value.
-        DocumentAnimations::serviceBeforeGetComputedStyle(*styledNode, propertyID);
+        // A timing update may be required if a compositor animation is running or animations
+        // have been updated via the api.
+        DocumentAnimations::updateAnimationTimingForGetComputedStyle(*styledNode, propertyID);
 
         document.updateStyleForNodeIfNeeded(styledNode);
 
@@ -1546,7 +1587,7 @@
     }
 
     if (!style)
-        return 0;
+        return nullptr;
 
     propertyID = CSSProperty::resolveDirectionAwareProperty(propertyID, style->direction(), style->writingMode());
 
@@ -1783,7 +1824,7 @@
         case CSSPropertyColumnFill:
             if (RuntimeEnabledFeatures::regionBasedColumnsEnabled())
                 return cssValuePool().createValue(style->columnFill());
-            return 0;
+            return nullptr;
         case CSSPropertyWebkitColumnGap:
             if (style->hasNormalColumnGap())
                 return cssValuePool().createIdentifierValue(CSSValueNormal);
@@ -1819,7 +1860,7 @@
                     if (StyleImage* image = cursors->at(i).image())
                         list->append(image->cssValue());
             }
-            RefPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
+            RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createValue(style->cursor());
             if (list) {
                 list->append(value.release());
                 return list.release();
@@ -2120,7 +2161,7 @@
             EPageBreak pageBreak = style->pageBreakInside();
             ASSERT(pageBreak != PBALWAYS);
             if (pageBreak == PBALWAYS)
-                return 0;
+                return nullptr;
             return cssValuePool().createValue(style->pageBreakInside());
         }
         case CSSPropertyPosition:
@@ -2178,7 +2219,7 @@
             }
             }
         case CSSPropertyTextIndent: {
-            RefPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
+            RefPtrWillBeRawPtr<CSSValue> textIndent = zoomAdjustedPixelValueForLength(style->textIndent(), *style);
             if (RuntimeEnabledFeatures::css3TextEnabled() && style->textIndentLine() == TextIndentEachLine) {
                 RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
                 list->append(textIndent.release());
@@ -2190,7 +2231,7 @@
         case CSSPropertyTextShadow:
             return valueForShadowList(style->textShadow(), *style, false);
         case CSSPropertyTextRendering:
-            return cssValuePool().createValue(style->fontDescription().textRenderingMode());
+            return cssValuePool().createValue(style->fontDescription().textRendering());
         case CSSPropertyTextOverflow:
             if (style->textOverflow())
                 return cssValuePool().createIdentifierValue(CSSValueEllipsis);
@@ -2235,7 +2276,7 @@
                     return cssValuePool().createValue(style->verticalAlignLength());
             }
             ASSERT_NOT_REACHED();
-            return 0;
+            return nullptr;
         case CSSPropertyVisibility:
             return cssValuePool().createValue(style->visibility());
         case CSSPropertyWhiteSpace:
@@ -2253,6 +2294,8 @@
                 return zoomAdjustedPixelValue(sizingBox(renderer).width(), *style);
             }
             return zoomAdjustedPixelValueForLength(style->width(), *style);
+        case CSSPropertyWillChange:
+            return valueForWillChange(style->willChangeProperties(), style->willChangeContents(), style->willChangeScrollPosition());
         case CSSPropertyWordBreak:
             return cssValuePool().createValue(style->wordBreak());
         case CSSPropertyWordSpacing:
@@ -2271,8 +2314,9 @@
             FontDescription::LigaturesState commonLigaturesState = style->fontDescription().commonLigaturesState();
             FontDescription::LigaturesState discretionaryLigaturesState = style->fontDescription().discretionaryLigaturesState();
             FontDescription::LigaturesState historicalLigaturesState = style->fontDescription().historicalLigaturesState();
+            FontDescription::LigaturesState contextualLigaturesState = style->fontDescription().contextualLigaturesState();
             if (commonLigaturesState == FontDescription::NormalLigaturesState && discretionaryLigaturesState == FontDescription::NormalLigaturesState
-                && historicalLigaturesState == FontDescription::NormalLigaturesState)
+                && historicalLigaturesState == FontDescription::NormalLigaturesState && contextualLigaturesState == FontDescription::NormalLigaturesState)
                 return cssValuePool().createIdentifierValue(CSSValueNormal);
 
             RefPtrWillBeRawPtr<CSSValueList> valueList = CSSValueList::createSpaceSeparated();
@@ -2282,6 +2326,8 @@
                 valueList->append(cssValuePool().createIdentifierValue(discretionaryLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
             if (historicalLigaturesState != FontDescription::NormalLigaturesState)
                 valueList->append(cssValuePool().createIdentifierValue(historicalLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
+            if (contextualLigaturesState != FontDescription::NormalLigaturesState)
+                valueList->append(cssValuePool().createIdentifierValue(contextualLigaturesState == FontDescription::DisabledLigaturesState ? CSSValueNoContextual : CSSValueContextual));
             return valueList;
         }
         case CSSPropertyZIndex:
@@ -2499,7 +2545,7 @@
         case CSSPropertyClip: {
             if (!style->hasClip())
                 return cssValuePool().createIdentifierValue(CSSValueAuto);
-            RefPtr<Rect> rect = Rect::create();
+            RefPtrWillBeRawPtr<Rect> rect = Rect::create();
             rect->setTop(zoomAdjustedPixelValue(style->clip().top().value(), *style));
             rect->setRight(zoomAdjustedPixelValue(style->clip().right().value(), *style));
             rect->setBottom(zoomAdjustedPixelValue(style->clip().bottom().value(), *style));
@@ -2601,31 +2647,9 @@
         case CSSPropertyShapeImageThreshold:
             return cssValuePool().createValue(style->shapeImageThreshold(), CSSPrimitiveValue::CSS_NUMBER);
         case CSSPropertyShapeInside:
-            if (!style->shapeInside())
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            if (style->shapeInside()->type() == ShapeValue::Box)
-                return cssValuePool().createValue(style->shapeInside()->layoutBox());
-            if (style->shapeInside()->type() == ShapeValue::Outside)
-                return cssValuePool().createIdentifierValue(CSSValueOutsideShape);
-            if (style->shapeInside()->type() == ShapeValue::Image) {
-                if (style->shapeInside()->image())
-                    return style->shapeInside()->image()->cssValue();
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            }
-            ASSERT(style->shapeInside()->type() == ShapeValue::Shape);
-            return valueForBasicShape(*style, style->shapeInside()->shape());
+            return valueForShape(*style, style->shapeInside());
         case CSSPropertyShapeOutside:
-            if (!style->shapeOutside())
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            if (style->shapeOutside()->type() == ShapeValue::Box)
-                return cssValuePool().createValue(style->shapeOutside()->layoutBox());
-            if (style->shapeOutside()->type() == ShapeValue::Image) {
-                if (style->shapeOutside()->image())
-                    return style->shapeOutside()->image()->cssValue();
-                return cssValuePool().createIdentifierValue(CSSValueNone);
-            }
-            ASSERT(style->shapeOutside()->type() == ShapeValue::Shape);
-            return valueForBasicShape(*style, style->shapeOutside()->shape());
+            return valueForShape(*style, style->shapeOutside());
         case CSSPropertyWebkitWrapThrough:
             return cssValuePool().createValue(style->wrapThrough());
         case CSSPropertyWebkitFilter:
@@ -2647,12 +2671,12 @@
         case CSSPropertyBackground:
             return valuesForBackgroundShorthand();
         case CSSPropertyBorder: {
-            RefPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
+            RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(CSSPropertyBorderTop, DoNotUpdateLayout);
             const CSSPropertyID properties[3] = { CSSPropertyBorderRight, CSSPropertyBorderBottom,
                                         CSSPropertyBorderLeft };
             for (size_t i = 0; i < WTF_ARRAY_LENGTH(properties); ++i) {
                 if (!compareCSSValuePtr<CSSValue>(value, getPropertyCSSValue(properties[i], DoNotUpdateLayout)))
-                    return 0;
+                    return nullptr;
             }
             return value.release();
         }
@@ -2692,7 +2716,7 @@
             break;
         case CSSPropertyInternalCallback:
             // This property is hidden from the web.
-            return 0;
+            return nullptr;
 
         /* Unimplemented CSS 3 properties (including CSS3 shorthand properties) */
         case CSSPropertyWebkitTextEmphasis:
@@ -2784,7 +2808,7 @@
         case CSSPropertyInternalMarqueeSpeed:
         case CSSPropertyInternalMarqueeStyle:
             ASSERT_NOT_REACHED();
-            return 0;
+            return nullptr;
 
         case CSSPropertyBufferedRendering:
         case CSSPropertyClipPath:
@@ -2832,12 +2856,12 @@
     }
 
     logUnimplementedPropertyID(propertyID);
-    return 0;
+    return nullptr;
 }
 
 String CSSComputedStyleDeclaration::getPropertyValue(CSSPropertyID propertyID) const
 {
-    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
     if (value)
         return value->cssText();
     return "";
@@ -2877,7 +2901,7 @@
                 return true;
         }
     }
-    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
     return value && propertyValue && value->equals(*propertyValue);
 }
 
@@ -2890,7 +2914,7 @@
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     for (size_t i = 0; i < shorthand.length(); ++i) {
-        RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
+        RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
         list->append(value);
     }
     return list.release();
@@ -2900,14 +2924,14 @@
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     // Assume the properties are in the usual order top, right, bottom, left.
-    RefPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
-    RefPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
-    RefPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
-    RefPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
+    RefPtrWillBeRawPtr<CSSValue> topValue = getPropertyCSSValue(shorthand.properties()[0], DoNotUpdateLayout);
+    RefPtrWillBeRawPtr<CSSValue> rightValue = getPropertyCSSValue(shorthand.properties()[1], DoNotUpdateLayout);
+    RefPtrWillBeRawPtr<CSSValue> bottomValue = getPropertyCSSValue(shorthand.properties()[2], DoNotUpdateLayout);
+    RefPtrWillBeRawPtr<CSSValue> leftValue = getPropertyCSSValue(shorthand.properties()[3], DoNotUpdateLayout);
 
     // All 4 properties must be specified.
     if (!topValue || !rightValue || !bottomValue || !leftValue)
-        return 0;
+        return nullptr;
 
     bool showLeft = !compareCSSValuePtr(rightValue, leftValue);
     bool showBottom = !compareCSSValuePtr(topValue, bottomValue) || showLeft;
@@ -2928,7 +2952,7 @@
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSlashSeparated();
     for (size_t i = 0; i < shorthand.length(); ++i) {
-        RefPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
+        RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(shorthand.properties()[i], DoNotUpdateLayout);
         list->append(value.release());
     }
     return list.release();
@@ -2936,10 +2960,10 @@
 
 PassRefPtr<MutableStylePropertySet> CSSComputedStyleDeclaration::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
 {
-    Vector<CSSProperty, 256> list;
+    WillBeHeapVector<CSSProperty, 256> list;
     list.reserveInitialCapacity(properties.size());
     for (unsigned i = 0; i < properties.size(); ++i) {
-        RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
+        RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
         if (value)
             list.append(CSSProperty(properties[i], value.release(), false));
     }
@@ -2951,13 +2975,13 @@
     return 0;
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValue(const String& propertyName)
 {
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (!propertyID)
-        return 0;
-    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
-    return value ? value->cloneForCSSOM() : 0;
+        return nullptr;
+    RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+    return value ? value->cloneForCSSOM() : nullptr;
 }
 
 String CSSComputedStyleDeclaration::getPropertyValue(const String& propertyName)
@@ -2995,7 +3019,7 @@
     return String();
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
 {
     return getPropertyCSSValue(propertyID);
 }
diff --git a/Source/core/css/CSSComputedStyleDeclaration.h b/Source/core/css/CSSComputedStyleDeclaration.h
index 04793a4..15b6f9e 100644
--- a/Source/core/css/CSSComputedStyleDeclaration.h
+++ b/Source/core/css/CSSComputedStyleDeclaration.h
@@ -58,16 +58,16 @@
     virtual void ref() OVERRIDE;
     virtual void deref() OVERRIDE;
 
-    PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
+    PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
     String getPropertyValue(CSSPropertyID) const;
     bool getPropertyPriority(CSSPropertyID) const;
 
     virtual PassRefPtr<MutableStylePropertySet> copyProperties() const OVERRIDE;
 
-    PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID, EUpdateLayout) const;
-    PassRefPtr<CSSValue> getFontSizeCSSValuePreferringKeyword() const;
+    PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(CSSPropertyID, EUpdateLayout) const;
+    PassRefPtrWillBeRawPtr<CSSValue> getFontSizeCSSValuePreferringKeyword() const;
     bool useFixedFontDefaultSize() const;
-    PassRefPtr<CSSValue> getSVGPropertyCSSValue(CSSPropertyID, EUpdateLayout) const;
+    PassRefPtrWillBeRawPtr<CSSValue> getSVGPropertyCSSValue(CSSPropertyID, EUpdateLayout) const;
 
     PassRefPtr<MutableStylePropertySet> copyPropertiesInSet(const Vector<CSSPropertyID>&) const;
 
@@ -86,7 +86,7 @@
     virtual unsigned length() const OVERRIDE;
     virtual String item(unsigned index) const OVERRIDE;
     PassRefPtr<RenderStyle> computeRenderStyle(CSSPropertyID) const;
-    virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName) OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(const String& propertyName) OVERRIDE;
     virtual String getPropertyValue(const String& propertyName) OVERRIDE;
     virtual String getPropertyPriority(const String& propertyName) OVERRIDE;
     virtual String getPropertyShorthand(const String& propertyName) OVERRIDE;
@@ -95,18 +95,18 @@
     virtual String removeProperty(const String& propertyName, ExceptionState&) OVERRIDE;
     virtual String cssText() const OVERRIDE;
     virtual void setCSSText(const String&, ExceptionState&) OVERRIDE;
-    virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) OVERRIDE;
     virtual String getPropertyValueInternal(CSSPropertyID) OVERRIDE;
     virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&) OVERRIDE;
 
     virtual bool cssPropertyMatches(CSSPropertyID, const CSSValue*) const OVERRIDE;
 
-    PassRefPtr<CSSValue> valueForShadowData(const ShadowData&, const RenderStyle&, bool useSpread) const;
-    PassRefPtr<CSSValue> valueForShadowList(const ShadowList*, const RenderStyle&, bool useSpread) const;
+    PassRefPtrWillBeRawPtr<CSSValue> valueForShadowData(const ShadowData&, const RenderStyle&, bool useSpread) const;
+    PassRefPtrWillBeRawPtr<CSSValue> valueForShadowList(const ShadowList*, const RenderStyle&, bool useSpread) const;
     PassRefPtrWillBeRawPtr<CSSPrimitiveValue> currentColorOrValidColor(const RenderStyle&, const StyleColor&) const;
     PassRefPtrWillBeRawPtr<SVGPaint> adjustSVGPaintForCurrentColor(PassRefPtrWillBeRawPtr<SVGPaint>, RenderStyle&) const;
 
-    PassRefPtr<CSSValue> valueForFilter(const RenderObject*, const RenderStyle&) const;
+    PassRefPtrWillBeRawPtr<CSSValue> valueForFilter(const RenderObject*, const RenderStyle&) const;
 
     PassRefPtrWillBeRawPtr<CSSValueList> valuesForShorthandProperty(const StylePropertyShorthand&) const;
     PassRefPtrWillBeRawPtr<CSSValueList> valuesForSidesShorthand(const StylePropertyShorthand&) const;
diff --git a/Source/core/css/CSSCrossfadeValue.cpp b/Source/core/css/CSSCrossfadeValue.cpp
index 2aec542..daa45df 100644
--- a/Source/core/css/CSSCrossfadeValue.cpp
+++ b/Source/core/css/CSSCrossfadeValue.cpp
@@ -167,7 +167,7 @@
 PassRefPtr<Image> CSSCrossfadeValue::image(RenderObject* renderer, const IntSize& size)
 {
     if (size.isEmpty())
-        return 0;
+        return nullptr;
 
     ResourceFetcher* fetcher = renderer->document().fetcher();
     ImageResource* cachedFromImage = cachedImageForCSSValue(m_fromValue.get(), fetcher);
@@ -220,6 +220,8 @@
 
 void CSSCrossfadeValue::traceAfterDispatch(Visitor* visitor)
 {
+    visitor->trace(m_fromValue);
+    visitor->trace(m_toValue);
     visitor->trace(m_percentageValue);
     CSSImageGeneratorValue::traceAfterDispatch(visitor);
 }
diff --git a/Source/core/css/CSSCrossfadeValue.h b/Source/core/css/CSSCrossfadeValue.h
index 8fc0bbf..1f256eb 100644
--- a/Source/core/css/CSSCrossfadeValue.h
+++ b/Source/core/css/CSSCrossfadeValue.h
@@ -43,9 +43,9 @@
 class CSSCrossfadeValue : public CSSImageGeneratorValue {
     friend class CrossfadeSubimageObserverProxy;
 public:
-    static PassRefPtrWillBeRawPtr<CSSCrossfadeValue> create(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
+    static PassRefPtrWillBeRawPtr<CSSCrossfadeValue> create(PassRefPtrWillBeRawPtr<CSSValue> fromValue, PassRefPtrWillBeRawPtr<CSSValue> toValue)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCrossfadeValue(fromValue, toValue));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSCrossfadeValue(fromValue, toValue));
     }
 
     ~CSSCrossfadeValue();
@@ -70,7 +70,7 @@
     void traceAfterDispatch(Visitor*);
 
 private:
-    CSSCrossfadeValue(PassRefPtr<CSSValue> fromValue, PassRefPtr<CSSValue> toValue)
+    CSSCrossfadeValue(PassRefPtrWillBeRawPtr<CSSValue> fromValue, PassRefPtrWillBeRawPtr<CSSValue> toValue)
         : CSSImageGeneratorValue(CrossfadeClass)
         , m_fromValue(fromValue)
         , m_toValue(toValue)
@@ -94,8 +94,8 @@
 
     void crossfadeChanged(const IntRect&);
 
-    RefPtr<CSSValue> m_fromValue;
-    RefPtr<CSSValue> m_toValue;
+    RefPtrWillBeMember<CSSValue> m_fromValue;
+    RefPtrWillBeMember<CSSValue> m_toValue;
     RefPtrWillBeMember<CSSPrimitiveValue> m_percentageValue;
 
     ResourcePtr<ImageResource> m_cachedFromImage;
diff --git a/Source/core/css/CSSCursorImageValue.cpp b/Source/core/css/CSSCursorImageValue.cpp
index 2deb9ae..c1ad612 100644
--- a/Source/core/css/CSSCursorImageValue.cpp
+++ b/Source/core/css/CSSCursorImageValue.cpp
@@ -42,13 +42,10 @@
 static inline SVGCursorElement* resourceReferencedByCursorElement(const String& url, Document& document)
 {
     Element* element = SVGURIReference::targetElementFromIRIString(url, document);
-    if (element && element->hasTagName(SVGNames::cursorTag))
-        return toSVGCursorElement(element);
-
-    return 0;
+    return isSVGCursorElement(element) ? toSVGCursorElement(element) : 0;
 }
 
-CSSCursorImageValue::CSSCursorImageValue(PassRefPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
+CSSCursorImageValue::CSSCursorImageValue(PassRefPtrWillBeRawPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
     : CSSValue(CursorImageClass)
     , m_imageValue(imageValue)
     , m_hasHotSpot(hasHotSpot)
@@ -181,7 +178,7 @@
 
 void CSSCursorImageValue::clearImageResource()
 {
-    m_image = 0;
+    m_image = nullptr;
     m_accessedImage = false;
 }
 
diff --git a/Source/core/css/CSSCursorImageValue.h b/Source/core/css/CSSCursorImageValue.h
index 4d343a2..9e42d62 100644
--- a/Source/core/css/CSSCursorImageValue.h
+++ b/Source/core/css/CSSCursorImageValue.h
@@ -32,9 +32,9 @@
 
 class CSSCursorImageValue : public CSSValue {
 public:
-    static PassRefPtrWillBeRawPtr<CSSCursorImageValue> create(PassRefPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
+    static PassRefPtrWillBeRawPtr<CSSCursorImageValue> create(PassRefPtrWillBeRawPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCursorImageValue(imageValue, hasHotSpot, hotSpot));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSCursorImageValue(imageValue, hasHotSpot, hotSpot));
     }
 
     ~CSSCursorImageValue();
@@ -61,12 +61,16 @@
     void traceAfterDispatch(Visitor*);
 
 private:
-    CSSCursorImageValue(PassRefPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot);
+    CSSCursorImageValue(PassRefPtrWillBeRawPtr<CSSValue> imageValue, bool hasHotSpot, const IntPoint& hotSpot);
 
     bool isSVGCursor() const;
     String cachedImageURL();
     void clearImageResource();
 
+    // FIXME: oilpan: This should be a Member but we need to resolve
+    // finalization order issues first. The CSSCursorImageValue
+    // destructor uses m_imageValue. Leaving it as a RefPtr as a
+    // workaround for now.
     RefPtr<CSSValue> m_imageValue;
 
     bool m_hasHotSpot;
diff --git a/Source/core/css/CSSCustomFontData.h b/Source/core/css/CSSCustomFontData.h
index 9436927..ec2bb6d 100644
--- a/Source/core/css/CSSCustomFontData.h
+++ b/Source/core/css/CSSCustomFontData.h
@@ -28,32 +28,45 @@
 
 class CSSCustomFontData FINAL : public CustomFontData {
 public:
-    static PassRefPtr<CSSCustomFontData> create(bool isLoadingFallback = false)
+    enum FallbackVisibility { InvisibleFallback, VisibleFallback };
+
+    static PassRefPtr<CSSCustomFontData> create(RemoteFontFaceSource* source, FallbackVisibility visibility)
     {
-        return adoptRef(new CSSCustomFontData(isLoadingFallback));
+        return adoptRef(new CSSCustomFontData(source, visibility));
     }
 
     virtual ~CSSCustomFontData() { }
 
+    virtual bool shouldSkipDrawing() const OVERRIDE
+    {
+        if (m_fontFaceSource)
+            m_fontFaceSource->paintRequested();
+        return m_fallbackVisibility == InvisibleFallback && m_isUsed;
+    }
+
     virtual void beginLoadIfNeeded() const OVERRIDE
     {
-        if (!m_isUsed && m_isLoadingFallback && m_fontFaceSource) {
+        if (!m_isUsed && m_fontFaceSource) {
             m_isUsed = true;
             m_fontFaceSource->beginLoadIfNeeded();
         }
     }
 
-    virtual void setCSSFontFaceSource(CSSFontFaceSource* source) OVERRIDE { m_fontFaceSource = source; }
-    virtual void clearCSSFontFaceSource() OVERRIDE { m_fontFaceSource = 0; }
+    virtual bool isLoading() const OVERRIDE { return m_isUsed; }
+    virtual bool isLoadingFallback() const OVERRIDE { return true; }
+    virtual void clearFontFaceSource() OVERRIDE { m_fontFaceSource = 0; }
 
 private:
-    CSSCustomFontData(bool isLoadingFallback)
-        : CustomFontData(isLoadingFallback)
-        , m_fontFaceSource(0)
+    CSSCustomFontData(RemoteFontFaceSource* source, FallbackVisibility visibility)
+        : m_fontFaceSource(source)
+        , m_fallbackVisibility(visibility)
+        , m_isUsed(false)
     {
     }
 
-    CSSFontFaceSource* m_fontFaceSource;
+    RemoteFontFaceSource* m_fontFaceSource;
+    FallbackVisibility m_fallbackVisibility;
+    mutable bool m_isUsed;
 };
 
 }
diff --git a/Source/core/css/CSSDefaultStyleSheets.cpp b/Source/core/css/CSSDefaultStyleSheets.cpp
index 574aca6..0e62816 100644
--- a/Source/core/css/CSSDefaultStyleSheets.cpp
+++ b/Source/core/css/CSSDefaultStyleSheets.cpp
@@ -44,8 +44,13 @@
 
 CSSDefaultStyleSheets& CSSDefaultStyleSheets::instance()
 {
+#if ENABLE(OILPAN)
+    DEFINE_STATIC_LOCAL(Persistent<CSSDefaultStyleSheets>, cssDefaultStyleSheets, (new CSSDefaultStyleSheets()));
+    return *cssDefaultStyleSheets;
+#else
     DEFINE_STATIC_LOCAL(CSSDefaultStyleSheets, cssDefaultStyleSheets, ());
     return cssDefaultStyleSheets;
+#endif
 }
 
 static const MediaQueryEvaluator& screenEval()
@@ -60,72 +65,76 @@
     return staticPrintEval;
 }
 
-static StyleSheetContents* parseUASheet(const String& str)
+static PassRefPtrWillBeRawPtr<StyleSheetContents> parseUASheet(const String& str)
 {
-    RefPtr<StyleSheetContents> sheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
+    RefPtrWillBeRawPtr<StyleSheetContents> sheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
     sheet->parseString(str);
-    return sheet.release().leakRef(); // leak the sheet on purpose
+    return sheet.release();
 }
 
-static StyleSheetContents* parseUASheet(const char* characters, unsigned size)
+static PassRefPtrWillBeRawPtr<StyleSheetContents> parseUASheet(const char* characters, unsigned size)
 {
     return parseUASheet(String(characters, size));
 }
 
 CSSDefaultStyleSheets::CSSDefaultStyleSheets()
-    : m_defaultStyle(0)
-    , m_defaultViewportStyle(0)
-    , m_defaultQuirksStyle(0)
-    , m_defaultPrintStyle(0)
-    , m_defaultViewSourceStyle(0)
-    , m_defaultXHTMLMobileProfileStyle(0)
-    , m_defaultStyleSheet(0)
-    , m_viewportStyleSheet(0)
-    , m_quirksStyleSheet(0)
-    , m_svgStyleSheet(0)
-    , m_mediaControlsStyleSheet(0)
-    , m_fullscreenStyleSheet(0)
+    : m_defaultStyle(nullptr)
+    , m_defaultViewportStyle(nullptr)
+    , m_defaultQuirksStyle(nullptr)
+    , m_defaultPrintStyle(nullptr)
+    , m_defaultViewSourceStyle(nullptr)
+    , m_defaultXHTMLMobileProfileStyle(nullptr)
+    , m_defaultStyleSheet(nullptr)
+    , m_viewportStyleSheet(nullptr)
+    , m_quirksStyleSheet(nullptr)
+    , m_svgStyleSheet(nullptr)
+    , m_mediaControlsStyleSheet(nullptr)
+    , m_fullscreenStyleSheet(nullptr)
 {
-    m_defaultStyle = RuleSet::create().leakPtr();
-    m_defaultViewportStyle = RuleSet::create().leakPtr();
-    m_defaultPrintStyle = RuleSet::create().leakPtr();
-    m_defaultQuirksStyle = RuleSet::create().leakPtr();
+    m_defaultStyle = RuleSet::create();
+    m_defaultViewportStyle = RuleSet::create();
+    m_defaultPrintStyle = RuleSet::create();
+    m_defaultQuirksStyle = RuleSet::create();
 
     // Strict-mode rules.
     String defaultRules = String(htmlUserAgentStyleSheet, sizeof(htmlUserAgentStyleSheet)) + RenderTheme::theme().extraDefaultStyleSheet();
     m_defaultStyleSheet = parseUASheet(defaultRules);
-    m_defaultStyle->addRulesFromSheet(m_defaultStyleSheet, screenEval());
+    m_defaultStyle->addRulesFromSheet(defaultStyleSheet(), screenEval());
 #if OS(ANDROID)
     String viewportRules(viewportAndroidUserAgentStyleSheet, sizeof(viewportAndroidUserAgentStyleSheet));
 #else
     String viewportRules;
 #endif
     m_viewportStyleSheet = parseUASheet(viewportRules);
-    m_defaultViewportStyle->addRulesFromSheet(m_viewportStyleSheet, screenEval());
-    m_defaultPrintStyle->addRulesFromSheet(m_defaultStyleSheet, printEval());
+    m_defaultViewportStyle->addRulesFromSheet(viewportStyleSheet(), screenEval());
+    m_defaultPrintStyle->addRulesFromSheet(defaultStyleSheet(), printEval());
 
     // Quirks-mode rules.
     String quirksRules = String(quirksUserAgentStyleSheet, sizeof(quirksUserAgentStyleSheet)) + RenderTheme::theme().extraQuirksStyleSheet();
     m_quirksStyleSheet = parseUASheet(quirksRules);
-    m_defaultQuirksStyle->addRulesFromSheet(m_quirksStyleSheet, screenEval());
+    m_defaultQuirksStyle->addRulesFromSheet(quirksStyleSheet(), screenEval());
 }
 
 RuleSet* CSSDefaultStyleSheets::defaultViewSourceStyle()
 {
     if (!m_defaultViewSourceStyle) {
-        m_defaultViewSourceStyle = RuleSet::create().leakPtr();
-        m_defaultViewSourceStyle->addRulesFromSheet(parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet)), screenEval());
+        m_defaultViewSourceStyle = RuleSet::create();
+        // Loaded stylesheet is leaked on purpose.
+        RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(sourceUserAgentStyleSheet, sizeof(sourceUserAgentStyleSheet));
+        m_defaultViewSourceStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval());
     }
-    return m_defaultViewSourceStyle;
+    return m_defaultViewSourceStyle.get();
 }
 
 RuleSet* CSSDefaultStyleSheets::defaultXHTMLMobileProfileStyle()
 {
     if (!m_defaultXHTMLMobileProfileStyle) {
-        m_defaultXHTMLMobileProfileStyle = RuleSet::create().leakPtr();
-        m_defaultXHTMLMobileProfileStyle->addRulesFromSheet(parseUASheet(xhtmlmpUserAgentStyleSheet, sizeof(xhtmlmpUserAgentStyleSheet)), screenEval());
+        m_defaultXHTMLMobileProfileStyle = RuleSet::create();
+        // Loaded stylesheet is leaked on purpose.
+        RefPtrWillBeRawPtr<StyleSheetContents> stylesheet = parseUASheet(xhtmlmpUserAgentStyleSheet, sizeof(xhtmlmpUserAgentStyleSheet));
+        m_defaultXHTMLMobileProfileStyle->addRulesFromSheet(stylesheet.release().leakRef(), screenEval());
     }
-    return m_defaultXHTMLMobileProfileStyle;
+    return m_defaultXHTMLMobileProfileStyle.get();
 }
 
 void CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(Element* element, bool& changedDefaultStyle)
@@ -133,27 +142,27 @@
     // FIXME: We should assert that the sheet only styles SVG elements.
     if (element->isSVGElement() && !m_svgStyleSheet) {
         m_svgStyleSheet = parseUASheet(svgUserAgentStyleSheet, sizeof(svgUserAgentStyleSheet));
-        m_defaultStyle->addRulesFromSheet(m_svgStyleSheet, screenEval());
-        m_defaultPrintStyle->addRulesFromSheet(m_svgStyleSheet, printEval());
+        m_defaultStyle->addRulesFromSheet(svgStyleSheet(), screenEval());
+        m_defaultPrintStyle->addRulesFromSheet(svgStyleSheet(), printEval());
         changedDefaultStyle = true;
     }
 
     // FIXME: We should assert that this sheet only contains rules for <video> and <audio>.
-    if (!m_mediaControlsStyleSheet && (element->hasTagName(videoTag) || element->hasTagName(audioTag))) {
+    if (!m_mediaControlsStyleSheet && (isHTMLVideoElement(*element) || isHTMLAudioElement(*element))) {
         String mediaRules = String(mediaControlsUserAgentStyleSheet, sizeof(mediaControlsUserAgentStyleSheet)) + RenderTheme::theme().extraMediaControlsStyleSheet();
         m_mediaControlsStyleSheet = parseUASheet(mediaRules);
-        m_defaultStyle->addRulesFromSheet(m_mediaControlsStyleSheet, screenEval());
-        m_defaultPrintStyle->addRulesFromSheet(m_mediaControlsStyleSheet, printEval());
+        m_defaultStyle->addRulesFromSheet(mediaControlsStyleSheet(), screenEval());
+        m_defaultPrintStyle->addRulesFromSheet(mediaControlsStyleSheet(), printEval());
         changedDefaultStyle = true;
     }
 
     // FIXME: This only works because we Force recalc the entire document so the new sheet
     // is loaded for <html> and the correct styles apply to everyone.
-    if (!m_fullscreenStyleSheet && FullscreenElementStack::isFullScreen(&element->document())) {
+    if (!m_fullscreenStyleSheet && FullscreenElementStack::isFullScreen(element->document())) {
         String fullscreenRules = String(fullscreenUserAgentStyleSheet, sizeof(fullscreenUserAgentStyleSheet)) + RenderTheme::theme().extraFullScreenStyleSheet();
         m_fullscreenStyleSheet = parseUASheet(fullscreenRules);
-        m_defaultStyle->addRulesFromSheet(m_fullscreenStyleSheet, screenEval());
-        m_defaultQuirksStyle->addRulesFromSheet(m_fullscreenStyleSheet, screenEval());
+        m_defaultStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval());
+        m_defaultQuirksStyle->addRulesFromSheet(fullscreenStyleSheet(), screenEval());
         changedDefaultStyle = true;
     }
 
@@ -161,4 +170,20 @@
     ASSERT(m_defaultStyle->features().siblingRules.isEmpty());
 }
 
+void CSSDefaultStyleSheets::trace(Visitor* visitor)
+{
+    visitor->trace(m_defaultStyle);
+    visitor->trace(m_defaultViewportStyle);
+    visitor->trace(m_defaultQuirksStyle);
+    visitor->trace(m_defaultPrintStyle);
+    visitor->trace(m_defaultViewSourceStyle);
+    visitor->trace(m_defaultXHTMLMobileProfileStyle);
+    visitor->trace(m_defaultStyleSheet);
+    visitor->trace(m_viewportStyleSheet);
+    visitor->trace(m_quirksStyleSheet);
+    visitor->trace(m_svgStyleSheet);
+    visitor->trace(m_mediaControlsStyleSheet);
+    visitor->trace(m_fullscreenStyleSheet);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSDefaultStyleSheets.h b/Source/core/css/CSSDefaultStyleSheets.h
index 69e69db..c427a4f 100644
--- a/Source/core/css/CSSDefaultStyleSheets.h
+++ b/Source/core/css/CSSDefaultStyleSheets.h
@@ -23,50 +23,54 @@
 #ifndef CSSDefaultStyleSheets_h
 #define CSSDefaultStyleSheets_h
 
+#include "heap/Handle.h"
+
 namespace WebCore {
 
 class Element;
 class RuleSet;
 class StyleSheetContents;
 
-class CSSDefaultStyleSheets {
+class CSSDefaultStyleSheets : public NoBaseWillBeGarbageCollected<CSSDefaultStyleSheets> {
 public:
     static CSSDefaultStyleSheets& instance();
 
     void ensureDefaultStyleSheetsForElement(Element*, bool& changedDefaultStyle);
 
-    RuleSet* defaultStyle() { return m_defaultStyle;}
-    RuleSet* defaultViewportStyle() { return m_defaultViewportStyle;}
-    RuleSet* defaultQuirksStyle() { return m_defaultQuirksStyle;}
-    RuleSet* defaultPrintStyle() { return m_defaultPrintStyle;}
+    RuleSet* defaultStyle() { return m_defaultStyle.get(); }
+    RuleSet* defaultViewportStyle() { return m_defaultViewportStyle.get(); }
+    RuleSet* defaultQuirksStyle() { return m_defaultQuirksStyle.get(); }
+    RuleSet* defaultPrintStyle() { return m_defaultPrintStyle.get(); }
     RuleSet* defaultViewSourceStyle();
 
     // FIXME: Remove WAP support.
     RuleSet* defaultXHTMLMobileProfileStyle();
 
-    StyleSheetContents* defaultStyleSheet() { return m_viewportStyleSheet; }
-    StyleSheetContents* viewportStyleSheet() { return m_viewportStyleSheet; }
-    StyleSheetContents* quirksStyleSheet() { return m_quirksStyleSheet; }
-    StyleSheetContents* svgStyleSheet() { return m_svgStyleSheet; }
-    StyleSheetContents* mediaControlsStyleSheet() { return m_mediaControlsStyleSheet; }
-    StyleSheetContents* fullscreenStyleSheet() { return m_fullscreenStyleSheet; }
+    StyleSheetContents* defaultStyleSheet() { return m_defaultStyleSheet.get(); }
+    StyleSheetContents* viewportStyleSheet() { return m_viewportStyleSheet.get(); }
+    StyleSheetContents* quirksStyleSheet() { return m_quirksStyleSheet.get(); }
+    StyleSheetContents* svgStyleSheet() { return m_svgStyleSheet.get(); }
+    StyleSheetContents* mediaControlsStyleSheet() { return m_mediaControlsStyleSheet.get(); }
+    StyleSheetContents* fullscreenStyleSheet() { return m_fullscreenStyleSheet.get(); }
+
+    void trace(Visitor*);
 
 private:
     CSSDefaultStyleSheets();
 
-    RuleSet* m_defaultStyle;
-    RuleSet* m_defaultViewportStyle;
-    RuleSet* m_defaultQuirksStyle;
-    RuleSet* m_defaultPrintStyle;
-    RuleSet* m_defaultViewSourceStyle;
-    RuleSet* m_defaultXHTMLMobileProfileStyle;
+    OwnPtrWillBeMember<RuleSet> m_defaultStyle;
+    OwnPtrWillBeMember<RuleSet> m_defaultViewportStyle;
+    OwnPtrWillBeMember<RuleSet> m_defaultQuirksStyle;
+    OwnPtrWillBeMember<RuleSet> m_defaultPrintStyle;
+    OwnPtrWillBeMember<RuleSet> m_defaultViewSourceStyle;
+    OwnPtrWillBeMember<RuleSet> m_defaultXHTMLMobileProfileStyle;
 
-    StyleSheetContents* m_defaultStyleSheet;
-    StyleSheetContents* m_viewportStyleSheet;
-    StyleSheetContents* m_quirksStyleSheet;
-    StyleSheetContents* m_svgStyleSheet;
-    StyleSheetContents* m_mediaControlsStyleSheet;
-    StyleSheetContents* m_fullscreenStyleSheet;
+    RefPtrWillBeMember<StyleSheetContents> m_defaultStyleSheet;
+    RefPtrWillBeMember<StyleSheetContents> m_viewportStyleSheet;
+    RefPtrWillBeMember<StyleSheetContents> m_quirksStyleSheet;
+    RefPtrWillBeMember<StyleSheetContents> m_svgStyleSheet;
+    RefPtrWillBeMember<StyleSheetContents> m_mediaControlsStyleSheet;
+    RefPtrWillBeMember<StyleSheetContents> m_fullscreenStyleSheet;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSFilterRule.cpp b/Source/core/css/CSSFilterRule.cpp
index dc44874..f533a51 100644
--- a/Source/core/css/CSSFilterRule.cpp
+++ b/Source/core/css/CSSFilterRule.cpp
@@ -65,7 +65,7 @@
     result.append(filterName);
     result.appendLiteral(" { ");
 
-    String descs = m_filterRule->properties()->asText();
+    String descs = m_filterRule->properties().asText();
     result.append(descs);
     if (!descs.isEmpty())
         result.append(' ');
@@ -82,5 +82,11 @@
         m_propertiesCSSOMWrapper->reattach(m_filterRule->mutableProperties());
 }
 
+void CSSFilterRule::trace(Visitor* visitor)
+{
+    visitor->trace(m_filterRule);
+    CSSRule::trace(visitor);
+}
+
 } // namespace WebCore
 
diff --git a/Source/core/css/CSSFilterRule.h b/Source/core/css/CSSFilterRule.h
index a8d5477..5031a5f 100644
--- a/Source/core/css/CSSFilterRule.h
+++ b/Source/core/css/CSSFilterRule.h
@@ -31,6 +31,7 @@
 #define CSSFilterRule_h
 
 #include "core/css/CSSRule.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -40,7 +41,10 @@
 
 class CSSFilterRule FINAL : public CSSRule {
 public:
-    static PassRefPtr<CSSFilterRule> create(StyleRuleFilter* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSFilterRule(rule, sheet)); }
+    static PassRefPtrWillBeRawPtr<CSSFilterRule> create(StyleRuleFilter* rule, CSSStyleSheet* sheet)
+    {
+        return adoptRefWillBeNoop(new CSSFilterRule(rule, sheet));
+    }
 
     virtual ~CSSFilterRule();
 
@@ -50,10 +54,12 @@
 
     CSSStyleDeclaration* style() const;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSFilterRule(StyleRuleFilter*, CSSStyleSheet* parent);
 
-    RefPtr<StyleRuleFilter> m_filterRule;
+    RefPtrWillBeMember<StyleRuleFilter> m_filterRule;
     mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
 };
 
diff --git a/Source/core/css/CSSFilterValue.cpp b/Source/core/css/CSSFilterValue.cpp
index 1515614..fceec83 100644
--- a/Source/core/css/CSSFilterValue.cpp
+++ b/Source/core/css/CSSFilterValue.cpp
@@ -90,7 +90,7 @@
 
 PassRefPtrWillBeRawPtr<CSSFilterValue> CSSFilterValue::cloneForCSSOM() const
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFilterValue(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSFilterValue(*this));
 }
 
 bool CSSFilterValue::equals(const CSSFilterValue& other) const
diff --git a/Source/core/css/CSSFilterValue.h b/Source/core/css/CSSFilterValue.h
index 1e3ab2a..151c4b7 100644
--- a/Source/core/css/CSSFilterValue.h
+++ b/Source/core/css/CSSFilterValue.h
@@ -53,7 +53,7 @@
 
     static PassRefPtrWillBeRawPtr<CSSFilterValue> create(FilterOperationType type)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFilterValue(type));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSFilterValue(type));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSFontFace.cpp b/Source/core/css/CSSFontFace.cpp
index bfb995e..cf0daf7 100644
--- a/Source/core/css/CSSFontFace.cpp
+++ b/Source/core/css/CSSFontFace.cpp
@@ -26,9 +26,11 @@
 #include "config.h"
 #include "core/css/CSSFontFace.h"
 
+#include "core/css/CSSFontFaceSource.h"
 #include "core/css/CSSFontSelector.h"
 #include "core/css/CSSSegmentedFontFace.h"
 #include "core/css/FontFaceSet.h"
+#include "core/css/RemoteFontFaceSource.h"
 #include "core/dom/Document.h"
 #include "core/frame/UseCounter.h"
 #include "platform/fonts/SimpleFontData.h"
@@ -62,8 +64,11 @@
         setLoadStatus(FontFace::Loading);
 }
 
-void CSSFontFace::fontLoaded(CSSFontFaceSource* source)
+void CSSFontFace::fontLoaded(RemoteFontFaceSource* source)
 {
+    if (m_segmentedFontFace)
+        m_segmentedFontFace->fontSelector()->fontLoaded();
+
     if (!isValid() || source != m_sources.first())
         return;
 
@@ -84,10 +89,18 @@
         m_segmentedFontFace->fontLoaded(this);
 }
 
+void CSSFontFace::fontLoadWaitLimitExceeded(RemoteFontFaceSource* source)
+{
+    if (!isValid() || source != m_sources.first())
+        return;
+    if (m_segmentedFontFace)
+        m_segmentedFontFace->fontLoadWaitLimitExceeded(this);
+}
+
 PassRefPtr<SimpleFontData> CSSFontFace::getFontData(const FontDescription& fontDescription)
 {
     if (!isValid())
-        return 0;
+        return nullptr;
 
     while (!m_sources.isEmpty()) {
         OwnPtr<CSSFontFaceSource>& source = m_sources.first();
@@ -105,7 +118,7 @@
         setLoadStatus(FontFace::Loading);
     if (loadStatus() == FontFace::Loading)
         setLoadStatus(FontFace::Error);
-    return 0;
+    return nullptr;
 }
 
 void CSSFontFace::willUseFontData(const FontDescription& fontDescription)
@@ -161,36 +174,60 @@
 
     switch (newStatus) {
     case FontFace::Loading:
-        FontFaceSet::from(document)->beginFontLoading(m_fontFace);
+        FontFaceSet::from(*document)->beginFontLoading(m_fontFace);
         break;
     case FontFace::Loaded:
-        FontFaceSet::from(document)->fontLoaded(m_fontFace);
+        FontFaceSet::from(*document)->fontLoaded(m_fontFace);
         break;
     case FontFace::Error:
-        FontFaceSet::from(document)->loadError(m_fontFace);
+        FontFaceSet::from(*document)->loadError(m_fontFace);
         break;
     default:
         break;
     }
 }
 
+CSSFontFace::UnicodeRangeSet::UnicodeRangeSet(const Vector<UnicodeRange>& ranges)
+    : m_ranges(ranges)
+{
+    if (m_ranges.isEmpty())
+        return;
+
+    std::sort(m_ranges.begin(), m_ranges.end());
+
+    // Unify overlapping ranges.
+    UChar32 from = m_ranges[0].from();
+    UChar32 to = m_ranges[0].to();
+    size_t targetIndex = 0;
+    for (size_t i = 1; i < m_ranges.size(); i++) {
+        if (to + 1 >= m_ranges[i].from()) {
+            to = std::max(to, m_ranges[i].to());
+        } else {
+            m_ranges[targetIndex++] = UnicodeRange(from, to);
+            from = m_ranges[i].from();
+            to = m_ranges[i].to();
+        }
+    }
+    m_ranges[targetIndex++] = UnicodeRange(from, to);
+    m_ranges.shrink(targetIndex);
+}
+
 bool CSSFontFace::UnicodeRangeSet::intersectsWith(const String& text) const
 {
     if (text.isEmpty())
         return false;
     if (isEntireRange())
         return true;
+    if (text.is8Bit() && m_ranges[0].from() >= 0x100)
+        return false;
 
-    // FIXME: This takes O(text.length() * m_ranges.size()) time. It would be
-    // better to make m_ranges sorted and use binary search.
     unsigned index = 0;
     while (index < text.length()) {
         UChar32 c = text.characterStartingAt(index);
         index += U16_LENGTH(c);
-        for (unsigned i = 0; i < m_ranges.size(); i++) {
-            if (m_ranges[i].contains(c))
-                return true;
-        }
+        Vector<UnicodeRange>::const_iterator it = std::lower_bound(m_ranges.begin(), m_ranges.end(), c);
+        if (it != m_ranges.end() && it->contains(c))
+            return true;
     }
     return false;
 }
diff --git a/Source/core/css/CSSFontFace.h b/Source/core/css/CSSFontFace.h
index 4ce02b2..3fbbe86 100644
--- a/Source/core/css/CSSFontFace.h
+++ b/Source/core/css/CSSFontFace.h
@@ -39,15 +39,18 @@
 class CSSSegmentedFontFace;
 class Document;
 class FontDescription;
+class RemoteFontFaceSource;
 class SimpleFontData;
 class StyleRuleFontFace;
 
 class CSSFontFace {
 public:
+    struct UnicodeRange;
     class UnicodeRangeSet;
 
-    CSSFontFace(FontFace* fontFace)
-        : m_segmentedFontFace(0)
+    CSSFontFace(FontFace* fontFace, Vector<UnicodeRange>& ranges)
+        : m_ranges(ranges)
+        , m_segmentedFontFace(0)
         , m_fontFace(fontFace)
     {
         ASSERT(m_fontFace);
@@ -65,7 +68,8 @@
     void addSource(PassOwnPtr<CSSFontFaceSource>);
 
     void beginLoadIfNeeded(CSSFontFaceSource*, CSSFontSelector* = 0);
-    void fontLoaded(CSSFontFaceSource*);
+    void fontLoaded(RemoteFontFaceSource*);
+    void fontLoadWaitLimitExceeded(RemoteFontFaceSource*);
 
     PassRefPtr<SimpleFontData> getFontData(const FontDescription&);
 
@@ -79,6 +83,8 @@
         UChar32 from() const { return m_from; }
         UChar32 to() const { return m_to; }
         bool contains(UChar32 c) const { return m_from <= c && c <= m_to; }
+        bool operator<(const UnicodeRange& other) const { return m_from < other.m_from; }
+        bool operator<(UChar32 c) const { return m_to < c; }
 
     private:
         UChar32 m_from;
@@ -87,7 +93,7 @@
 
     class UnicodeRangeSet {
     public:
-        void add(UChar32 from, UChar32 to) { m_ranges.append(UnicodeRange(from, to)); }
+        explicit UnicodeRangeSet(const Vector<UnicodeRange>&);
         bool intersectsWith(const String&) const;
         bool isEntireRange() const { return m_ranges.isEmpty(); }
         size_t size() const { return m_ranges.size(); }
@@ -100,6 +106,8 @@
     void willUseFontData(const FontDescription&);
     void load(const FontDescription&, CSSFontSelector* = 0);
 
+    bool hadBlankText() { return isValid() && m_sources.first()->hadBlankText(); }
+
 private:
     void setLoadStatus(FontFace::LoadStatus);
 
diff --git a/Source/core/css/CSSFontFaceLoadEvent.cpp b/Source/core/css/CSSFontFaceLoadEvent.cpp
index 95aa3b2..d89e2a7 100644
--- a/Source/core/css/CSSFontFaceLoadEvent.cpp
+++ b/Source/core/css/CSSFontFaceLoadEvent.cpp
@@ -61,4 +61,9 @@
     return EventNames::CSSFontFaceLoadEvent;
 }
 
+void CSSFontFaceLoadEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSFontFaceLoadEvent.h b/Source/core/css/CSSFontFaceLoadEvent.h
index 6d6b982..04d51f6 100644
--- a/Source/core/css/CSSFontFaceLoadEvent.h
+++ b/Source/core/css/CSSFontFaceLoadEvent.h
@@ -67,6 +67,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSFontFaceLoadEvent();
     CSSFontFaceLoadEvent(const AtomicString&, const FontFaceArray&);
diff --git a/Source/core/css/CSSFontFaceRule.cpp b/Source/core/css/CSSFontFaceRule.cpp
index d6357bd..c4f6e60 100644
--- a/Source/core/css/CSSFontFaceRule.cpp
+++ b/Source/core/css/CSSFontFaceRule.cpp
@@ -52,7 +52,7 @@
 {
     StringBuilder result;
     result.appendLiteral("@font-face { ");
-    String descs = m_fontFaceRule->properties()->asText();
+    String descs = m_fontFaceRule->properties().asText();
     result.append(descs);
     if (!descs.isEmpty())
         result.append(' ');
@@ -68,4 +68,10 @@
         m_propertiesCSSOMWrapper->reattach(m_fontFaceRule->mutableProperties());
 }
 
+void CSSFontFaceRule::trace(Visitor* visitor)
+{
+    visitor->trace(m_fontFaceRule);
+    CSSRule::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSFontFaceRule.h b/Source/core/css/CSSFontFaceRule.h
index 2b779a2..eade8f3 100644
--- a/Source/core/css/CSSFontFaceRule.h
+++ b/Source/core/css/CSSFontFaceRule.h
@@ -23,6 +23,7 @@
 #define CSSFontFaceRule_h
 
 #include "core/css/CSSRule.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -32,7 +33,10 @@
 
 class CSSFontFaceRule FINAL : public CSSRule {
 public:
-    static PassRefPtr<CSSFontFaceRule> create(StyleRuleFontFace* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSFontFaceRule(rule, sheet)); }
+    static PassRefPtrWillBeRawPtr<CSSFontFaceRule> create(StyleRuleFontFace* rule, CSSStyleSheet* sheet)
+    {
+        return adoptRefWillBeNoop(new CSSFontFaceRule(rule, sheet));
+    }
 
     virtual ~CSSFontFaceRule();
 
@@ -44,10 +48,12 @@
 
     StyleRuleFontFace* styleRule() const { return m_fontFaceRule.get(); }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSFontFaceRule(StyleRuleFontFace*, CSSStyleSheet* parent);
 
-    RefPtr<StyleRuleFontFace> m_fontFaceRule;
+    RefPtrWillBeMember<StyleRuleFontFace> m_fontFaceRule;
     mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
 };
 
diff --git a/Source/core/css/CSSFontFaceSource.cpp b/Source/core/css/CSSFontFaceSource.cpp
index baef101..c6b5150 100644
--- a/Source/core/css/CSSFontFaceSource.cpp
+++ b/Source/core/css/CSSFontFaceSource.cpp
@@ -26,296 +26,40 @@
 #include "config.h"
 #include "core/css/CSSFontFaceSource.h"
 
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/CSSCustomFontData.h"
-#include "core/css/CSSFontFace.h"
-#include "platform/fonts/FontCache.h"
+#include "platform/fonts/FontCacheKey.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/fonts/SimpleFontData.h"
-#include "public/platform/Platform.h"
-#include "wtf/CurrentTime.h"
-
-#if ENABLE(SVG_FONTS)
-#include "SVGNames.h"
-#include "core/svg/SVGFontData.h"
-#include "core/svg/SVGFontElement.h"
-#include "core/svg/SVGFontFaceElement.h"
-#endif
 
 namespace WebCore {
 
-CSSFontFaceSource::CSSFontFaceSource(const String& str, FontResource* font)
-    : m_string(str)
-    , m_font(font)
-    , m_face(0)
-#if ENABLE(SVG_FONTS)
-    , m_hasExternalSVGFont(false)
-#endif
+CSSFontFaceSource::CSSFontFaceSource()
+    : m_face(0)
 {
-    if (m_font)
-        m_font->addClient(this);
 }
 
 CSSFontFaceSource::~CSSFontFaceSource()
 {
-    if (m_font)
-        m_font->removeClient(this);
-    pruneTable();
-}
-
-void CSSFontFaceSource::pruneTable()
-{
-    if (m_fontDataTable.isEmpty())
-        return;
-
-    for (FontDataTable::iterator it = m_fontDataTable.begin(); it != m_fontDataTable.end(); ++it) {
-        SimpleFontData* fontData = it->value.get();
-        if (fontData && fontData->customFontData())
-            fontData->customFontData()->clearCSSFontFaceSource();
-    }
-    m_fontDataTable.clear();
-}
-
-bool CSSFontFaceSource::isLocal() const
-{
-    if (m_font)
-        return false;
-#if ENABLE(SVG_FONTS)
-    if (m_svgFontFaceElement)
-        return false;
-#endif
-    return true;
-}
-
-bool CSSFontFaceSource::isLoading() const
-{
-    if (m_font)
-        return !m_font->stillNeedsLoad() && !m_font->isLoaded();
-    return false;
-}
-
-bool CSSFontFaceSource::isLoaded() const
-{
-    if (m_font)
-        return m_font->isLoaded();
-    return true;
-}
-
-bool CSSFontFaceSource::isValid() const
-{
-    if (m_font)
-        return !m_font->errorOccurred();
-    return true;
-}
-
-void CSSFontFaceSource::didStartFontLoad(FontResource*)
-{
-    // Avoid duplicated reports when multiple CSSFontFaceSource are registered
-    // at this FontResource.
-    if (!m_fontDataTable.isEmpty())
-        m_histograms.loadStarted();
-}
-
-void CSSFontFaceSource::fontLoaded(FontResource*)
-{
-    if (!m_fontDataTable.isEmpty())
-        m_histograms.recordRemoteFont(m_font.get());
-
-    pruneTable();
-    if (m_face)
-        m_face->fontLoaded(this);
 }
 
 PassRefPtr<SimpleFontData> CSSFontFaceSource::getFontData(const FontDescription& fontDescription)
 {
     // If the font hasn't loaded or an error occurred, then we've got nothing.
     if (!isValid())
-        return 0;
+        return nullptr;
 
     if (isLocal()) {
         // We're local. Just return a SimpleFontData from the normal cache.
-        // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter.
-        RefPtr<SimpleFontData> fontData = FontCache::fontCache()->getFontData(fontDescription, m_string, true);
-        m_histograms.recordLocalFont(fontData);
-        return fontData;
+        return createFontData(fontDescription);
     }
 
     // See if we have a mapping in our FontData cache.
     AtomicString emptyFontFamily = "";
     FontCacheKey key = fontDescription.cacheKey(emptyFontFamily);
 
-    RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(key.hash(), 0).storedValue->value;
-    if (fontData)
-        return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable.
-
-    // If we are still loading, then we let the system pick a font.
-    if (isLoaded()) {
-        if (m_font) {
-#if ENABLE(SVG_FONTS)
-            if (m_hasExternalSVGFont) {
-                // For SVG fonts parse the external SVG document, and extract the <font> element.
-                if (!m_font->ensureSVGFontData())
-                    return 0;
-
-                if (!m_externalSVGFontElement) {
-                    String fragmentIdentifier;
-                    size_t start = m_string.find('#');
-                    if (start != kNotFound)
-                        fragmentIdentifier = m_string.string().substring(start + 1);
-                    m_externalSVGFontElement = m_font->getSVGFontById(fragmentIdentifier);
-                }
-
-                if (!m_externalSVGFontElement)
-                    return 0;
-
-                SVGFontFaceElement* fontFaceElement = 0;
-
-                // Select first <font-face> child
-                for (Node* fontChild = m_externalSVGFontElement->firstChild(); fontChild; fontChild = fontChild->nextSibling()) {
-                    if (fontChild->hasTagName(SVGNames::font_faceTag)) {
-                        fontFaceElement = toSVGFontFaceElement(fontChild);
-                        break;
-                    }
-                }
-
-                if (fontFaceElement) {
-                    if (!m_svgFontFaceElement) {
-                        // We're created using a CSS @font-face rule, that means we're not associated with a SVGFontFaceElement.
-                        // Use the imported <font-face> tag as referencing font-face element for these cases.
-                        m_svgFontFaceElement = fontFaceElement;
-                    }
-
-                    fontData = SimpleFontData::create(
-                        SVGFontData::create(fontFaceElement),
-                        fontDescription.effectiveFontSize(),
-                        fontDescription.isSyntheticBold(),
-                        fontDescription.isSyntheticItalic());
-                }
-            } else
-#endif
-            {
-                // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef.
-                if (!m_font->ensureCustomFontData())
-                    return 0;
-
-                fontData = SimpleFontData::create(
-                    m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(),
-                        fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(),
-                        fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create(false));
-            }
-        } else {
-#if ENABLE(SVG_FONTS)
-            // In-Document SVG Fonts
-            if (m_svgFontFaceElement) {
-                fontData = SimpleFontData::create(
-                    SVGFontData::create(m_svgFontFaceElement.get()),
-                    fontDescription.effectiveFontSize(),
-                    fontDescription.isSyntheticBold(),
-                    fontDescription.isSyntheticItalic());
-            }
-#endif
-        }
-    } else {
-        // This temporary font is not retained and should not be returned.
-        FontCachePurgePreventer fontCachePurgePreventer;
-        SimpleFontData* temporaryFont = FontCache::fontCache()->getNonRetainedLastResortFallbackFont(fontDescription);
-        if (!temporaryFont) {
-            ASSERT_NOT_REACHED();
-            return 0;
-        }
-        RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create(true);
-        cssFontData->setCSSFontFaceSource(this);
-        fontData = SimpleFontData::create(temporaryFont->platformData(), cssFontData);
-    }
-
+    RefPtr<SimpleFontData>& fontData = m_fontDataTable.add(key.hash(), nullptr).storedValue->value;
+    if (!fontData)
+        fontData = createFontData(fontDescription);
     return fontData; // No release, because fontData is a reference to a RefPtr that is held in the m_fontDataTable.
 }
 
-#if ENABLE(SVG_FONTS)
-SVGFontFaceElement* CSSFontFaceSource::svgFontFaceElement() const
-{
-    return m_svgFontFaceElement.get();
-}
-
-void CSSFontFaceSource::setSVGFontFaceElement(PassRefPtr<SVGFontFaceElement> element)
-{
-    m_svgFontFaceElement = element;
-}
-
-bool CSSFontFaceSource::isSVGFontFaceSource() const
-{
-    return m_svgFontFaceElement || m_hasExternalSVGFont;
-}
-#endif
-
-bool CSSFontFaceSource::ensureFontData()
-{
-    if (!m_font)
-        return false;
-#if ENABLE(SVG_FONTS)
-    if (m_hasExternalSVGFont)
-        return m_font->ensureSVGFontData();
-#endif
-    return m_font->ensureCustomFontData();
-}
-
-bool CSSFontFaceSource::isLocalFontAvailable(const FontDescription& fontDescription)
-{
-    if (!isLocal())
-        return false;
-    return FontCache::fontCache()->isPlatformFontAvailable(fontDescription, m_string);
-}
-
-void CSSFontFaceSource::beginLoadIfNeeded()
-{
-    if (m_face && m_font)
-        m_face->beginLoadIfNeeded(this);
-}
-
-void CSSFontFaceSource::FontLoadHistograms::loadStarted()
-{
-    if (!m_loadStartTime)
-        m_loadStartTime = currentTimeMS();
-}
-
-void CSSFontFaceSource::FontLoadHistograms::recordLocalFont(bool loadSuccess)
-{
-    if (!m_loadStartTime) {
-        blink::Platform::current()->histogramEnumeration("WebFont.LocalFontUsed", loadSuccess ? 1 : 0, 2);
-        m_loadStartTime = -1; // Do not count this font again.
-    }
-}
-
-void CSSFontFaceSource::FontLoadHistograms::recordRemoteFont(const FontResource* font)
-{
-    if (m_loadStartTime > 0 && font && !font->isLoading()) {
-        int duration = static_cast<int>(currentTimeMS() - m_loadStartTime);
-        blink::Platform::current()->histogramCustomCounts(histogramName(font), duration, 0, 10000, 50);
-        m_loadStartTime = -1;
-
-        enum { Miss, Hit, DataUrl, CacheHitEnumMax };
-        int histogramValue = font->url().protocolIsData() ? DataUrl
-            : font->response().wasCached() ? Hit
-            : Miss;
-        blink::Platform::current()->histogramEnumeration("WebFont.CacheHit", histogramValue, CacheHitEnumMax);
-    }
-}
-
-const char* CSSFontFaceSource::FontLoadHistograms::histogramName(const FontResource* font)
-{
-    if (font->errorOccurred())
-        return "WebFont.DownloadTime.LoadError";
-
-    unsigned size = font->encodedSize();
-    if (size < 10 * 1024)
-        return "WebFont.DownloadTime.0.Under10KB";
-    if (size < 50 * 1024)
-        return "WebFont.DownloadTime.1.10KBTo50KB";
-    if (size < 100 * 1024)
-        return "WebFont.DownloadTime.2.50KBTo100KB";
-    if (size < 1024 * 1024)
-        return "WebFont.DownloadTime.3.100KBTo1MB";
-    return "WebFont.DownloadTime.4.Over1MB";
-}
-
 }
diff --git a/Source/core/css/CSSFontFaceSource.h b/Source/core/css/CSSFontFaceSource.h
index 0d434f7..2b2ac7b 100644
--- a/Source/core/css/CSSFontFaceSource.h
+++ b/Source/core/css/CSSFontFaceSource.h
@@ -26,11 +26,7 @@
 #ifndef CSSFontFaceSource_h
 #define CSSFontFaceSource_h
 
-#include "core/fetch/FontResource.h"
-#include "core/fetch/ResourcePtr.h"
-#include "platform/Timer.h"
 #include "wtf/HashMap.h"
-#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
@@ -38,69 +34,34 @@
 class CSSFontFace;
 class FontDescription;
 class SimpleFontData;
-#if ENABLE(SVG_FONTS)
-class SVGFontElement;
-class SVGFontFaceElement;
-#endif
 
-
-class CSSFontFaceSource FINAL : public FontResourceClient {
+class CSSFontFaceSource {
 public:
-    CSSFontFaceSource(const String&, FontResource* = 0);
     virtual ~CSSFontFaceSource();
 
-    bool isLocal() const;
-    bool isLoading() const;
-    bool isLoaded() const;
-    bool isValid() const;
+    virtual bool isLocal() const { return false; }
+    virtual bool isLoading() const { return false; }
+    virtual bool isLoaded() const { return true; }
+    virtual bool isValid() const { return true; }
 
-    FontResource* resource() { return m_font.get(); }
+    virtual FontResource* resource() { return 0; }
     void setFontFace(CSSFontFace* face) { m_face = face; }
 
-    virtual void didStartFontLoad(FontResource*) OVERRIDE;
-    virtual void fontLoaded(FontResource*) OVERRIDE;
-
     PassRefPtr<SimpleFontData> getFontData(const FontDescription&);
 
-#if ENABLE(SVG_FONTS)
-    SVGFontFaceElement* svgFontFaceElement() const;
-    void setSVGFontFaceElement(PassRefPtr<SVGFontFaceElement>);
-    bool isSVGFontFaceSource() const;
-    void setHasExternalSVGFont(bool value) { m_hasExternalSVGFont = value; }
-#endif
+    virtual bool isLocalFontAvailable(const FontDescription&) { return false; }
 
-    bool ensureFontData();
-    bool isLocalFontAvailable(const FontDescription&);
-    void beginLoadIfNeeded();
+    // For UMA reporting
+    virtual bool hadBlankText() { return false; }
 
-private:
+protected:
+    CSSFontFaceSource();
+    virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) = 0;
+
     typedef HashMap<unsigned, RefPtr<SimpleFontData> > FontDataTable; // The hash key is composed of size synthetic styles.
 
-    class FontLoadHistograms {
-    public:
-        FontLoadHistograms() : m_loadStartTime(0) { }
-        void loadStarted();
-        void recordLocalFont(bool loadSuccess);
-        void recordRemoteFont(const FontResource*);
-    private:
-        const char* histogramName(const FontResource*);
-        double m_loadStartTime;
-    };
-
-    void pruneTable();
-    void startLoadingTimerFired(Timer<CSSFontFaceSource>*);
-
-    AtomicString m_string; // URI for remote, built-in font name for local.
-    ResourcePtr<FontResource> m_font; // For remote fonts, a pointer to our cached resource.
     CSSFontFace* m_face; // Our owning font face.
     FontDataTable m_fontDataTable;
-    FontLoadHistograms m_histograms;
-
-#if ENABLE(SVG_FONTS)
-    RefPtr<SVGFontFaceElement> m_svgFontFaceElement;
-    RefPtr<SVGFontElement> m_externalSVGFontElement;
-    bool m_hasExternalSVGFont;
-#endif
 };
 
 }
diff --git a/Source/core/css/CSSFontFaceSrcValue.h b/Source/core/css/CSSFontFaceSrcValue.h
index c394924..9ebf109 100644
--- a/Source/core/css/CSSFontFaceSrcValue.h
+++ b/Source/core/css/CSSFontFaceSrcValue.h
@@ -41,11 +41,11 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> create(const String& resource)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFontFaceSrcValue(resource, false));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSFontFaceSrcValue(resource, false));
     }
     static PassRefPtrWillBeRawPtr<CSSFontFaceSrcValue> createLocal(const String& resource)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFontFaceSrcValue(resource, true));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSFontFaceSrcValue(resource, true));
     }
 
     const String& resource() const { return m_resource; }
diff --git a/Source/core/css/CSSFontFaceTest.cpp b/Source/core/css/CSSFontFaceTest.cpp
new file mode 100644
index 0000000..87b0bab
--- /dev/null
+++ b/Source/core/css/CSSFontFaceTest.cpp
@@ -0,0 +1,90 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/CSSFontFace.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+static const UChar hiraganaA[2] = { 0x3042, 0 };
+
+TEST(CSSFontFace, UnicodeRangeSetEmpty)
+{
+    Vector<CSSFontFace::UnicodeRange> ranges;
+    CSSFontFace::UnicodeRangeSet set(ranges);
+    EXPECT_TRUE(set.isEntireRange());
+    EXPECT_EQ(0u, set.size());
+    EXPECT_FALSE(set.intersectsWith(String()));
+    EXPECT_TRUE(set.intersectsWith(String("a")));
+    EXPECT_TRUE(set.intersectsWith(String(hiraganaA)));
+}
+
+TEST(CSSFontFace, UnicodeRangeSetSingleCharacter)
+{
+    Vector<CSSFontFace::UnicodeRange> ranges;
+    ranges.append(CSSFontFace::UnicodeRange('b', 'b'));
+    CSSFontFace::UnicodeRangeSet set(ranges);
+    EXPECT_FALSE(set.isEntireRange());
+    EXPECT_FALSE(set.intersectsWith(String()));
+    EXPECT_FALSE(set.intersectsWith(String("a")));
+    EXPECT_TRUE(set.intersectsWith(String("b")));
+    EXPECT_FALSE(set.intersectsWith(String("c")));
+    EXPECT_TRUE(set.intersectsWith(String("abc")));
+    EXPECT_FALSE(set.intersectsWith(String(hiraganaA)));
+    ASSERT_EQ(1u, set.size());
+    EXPECT_EQ('b', set.rangeAt(0).from());
+    EXPECT_EQ('b', set.rangeAt(0).to());
+}
+
+TEST(CSSFontFace, UnicodeRangeSetTwoRanges)
+{
+    Vector<CSSFontFace::UnicodeRange> ranges;
+    ranges.append(CSSFontFace::UnicodeRange('6', '7'));
+    ranges.append(CSSFontFace::UnicodeRange('2', '4'));
+    CSSFontFace::UnicodeRangeSet set(ranges);
+    EXPECT_FALSE(set.isEntireRange());
+    EXPECT_FALSE(set.intersectsWith(String()));
+    EXPECT_FALSE(set.intersectsWith(String("1")));
+    EXPECT_TRUE(set.intersectsWith(String("2")));
+    EXPECT_TRUE(set.intersectsWith(String("3")));
+    EXPECT_TRUE(set.intersectsWith(String("4")));
+    EXPECT_FALSE(set.intersectsWith(String("5")));
+    EXPECT_TRUE(set.intersectsWith(String("6")));
+    EXPECT_TRUE(set.intersectsWith(String("7")));
+    EXPECT_FALSE(set.intersectsWith(String("8")));
+    ASSERT_EQ(2u, set.size());
+    EXPECT_EQ('2', set.rangeAt(0).from());
+    EXPECT_EQ('4', set.rangeAt(0).to());
+    EXPECT_EQ('6', set.rangeAt(1).from());
+    EXPECT_EQ('7', set.rangeAt(1).to());
+}
+
+TEST(CSSFontFace, UnicodeRangeSetOverlap)
+{
+    Vector<CSSFontFace::UnicodeRange> ranges;
+    ranges.append(CSSFontFace::UnicodeRange('0', '2'));
+    ranges.append(CSSFontFace::UnicodeRange('1', '1'));
+    ranges.append(CSSFontFace::UnicodeRange('3', '5'));
+    ranges.append(CSSFontFace::UnicodeRange('4', '6'));
+    CSSFontFace::UnicodeRangeSet set(ranges);
+    ASSERT_EQ(1u, set.size());
+    EXPECT_EQ('0', set.rangeAt(0).from());
+    EXPECT_EQ('6', set.rangeAt(0).to());
+}
+
+TEST(CSSFontFace, UnicodeRangeSetNon8Bit)
+{
+    Vector<CSSFontFace::UnicodeRange> ranges;
+    ranges.append(CSSFontFace::UnicodeRange(0x3042, 0x3042));
+    CSSFontFace::UnicodeRangeSet set(ranges);
+    ASSERT_EQ(1u, set.size());
+    EXPECT_EQ(0x3042, set.rangeAt(0).from());
+    EXPECT_EQ(0x3042, set.rangeAt(0).to());
+    EXPECT_FALSE(set.intersectsWith(String("a")));
+    EXPECT_TRUE(set.intersectsWith(String(hiraganaA)));
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/CSSFontFeatureValue.h b/Source/core/css/CSSFontFeatureValue.h
index b7148c4..458b184 100644
--- a/Source/core/css/CSSFontFeatureValue.h
+++ b/Source/core/css/CSSFontFeatureValue.h
@@ -35,7 +35,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSFontFeatureValue> create(const AtomicString& tag, int value)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFontFeatureValue(tag, value));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSFontFeatureValue(tag, value));
     }
 
     const AtomicString& tag() const { return m_tag; }
diff --git a/Source/core/css/CSSFontSelector.cpp b/Source/core/css/CSSFontSelector.cpp
index be43180..eacd0e9 100644
--- a/Source/core/css/CSSFontSelector.cpp
+++ b/Source/core/css/CSSFontSelector.cpp
@@ -35,9 +35,9 @@
 #include "core/dom/Document.h"
 #include "core/fetch/FontResource.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/loader/FrameLoader.h"
 #include "platform/fonts/FontCache.h"
 #include "platform/fonts/SimpleFontData.h"
 #include "wtf/text/AtomicString.h"
@@ -63,7 +63,7 @@
     // after this font has been requested but before it began loading. Balanced by
     // decrementRequestCount() in beginLoadTimerFired() and in clearDocument().
     m_resourceFetcher->incrementRequestCount(fontResource);
-    m_beginLoadingTimer.startOneShot(0);
+    m_beginLoadingTimer.startOneShot(0, FROM_HERE);
 }
 
 void FontLoader::beginLoadTimerFired(Timer<WebCore::FontLoader>*)
@@ -115,7 +115,7 @@
     ASSERT(m_document);
     ASSERT(m_document->frame());
     FontCache::fontCache()->addClient(this);
-    FontFaceSet::from(document)->addFontFacesToFontFaceCache(&m_fontFaceCache, this);
+    FontFaceSet::from(*document)->addFontFacesToFontFaceCache(&m_fontFaceCache, this);
 }
 
 CSSFontSelector::~CSSFontSelector()
@@ -156,12 +156,15 @@
 {
     UScriptCode script = fontDescription.script();
 
+#if OS(ANDROID)
+    if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
+        return FontCache::getGenericFamilyNameForScript(FontFamilyNames::webkit_standard, script);
+
+    if (genericFamilyName.startsWith("-webkit-"))
+        return FontCache::getGenericFamilyNameForScript(genericFamilyName, script);
+#else
     if (fontDescription.genericFamily() == FontDescription::StandardFamily && !fontDescription.isSpecifiedFont())
         return settings.standard(script);
-
-#if OS(ANDROID)
-    return FontCache::getGenericFamilyNameForScript(genericFamilyName, script);
-#else
     if (genericFamilyName == FontFamilyNames::webkit_serif)
         return settings.serif(script);
     if (genericFamilyName == FontFamilyNames::webkit_sans_serif)
@@ -188,7 +191,7 @@
     // Try to return the correct font based off our settings, in case we were handed the generic font family name.
     AtomicString settingsFamilyName = familyNameFromSettings(m_genericFontFamilySettings, fontDescription, familyName);
     if (settingsFamilyName.isEmpty())
-        return 0;
+        return nullptr;
 
     return FontCache::fontCache()->getFontData(fontDescription, settingsFamilyName);
 }
diff --git a/Source/core/css/CSSFontValue.h b/Source/core/css/CSSFontValue.h
index cf3e97e..f59e2a7 100644
--- a/Source/core/css/CSSFontValue.h
+++ b/Source/core/css/CSSFontValue.h
@@ -34,7 +34,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSFontValue> create()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFontValue);
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSFontValue);
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSFunctionValue.h b/Source/core/css/CSSFunctionValue.h
index b094a5e..40edc33 100644
--- a/Source/core/css/CSSFunctionValue.h
+++ b/Source/core/css/CSSFunctionValue.h
@@ -37,12 +37,12 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSFunctionValue> create(CSSParserFunction* function)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFunctionValue(function));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSFunctionValue(function));
     }
 
     static PassRefPtrWillBeRawPtr<CSSFunctionValue> create(String name, PassRefPtrWillBeRawPtr<CSSValueList> args)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSFunctionValue(name, args));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSFunctionValue(name, args));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSGradientValue.cpp b/Source/core/css/CSSGradientValue.cpp
index a5bbb78..8abfbbe 100644
--- a/Source/core/css/CSSGradientValue.cpp
+++ b/Source/core/css/CSSGradientValue.cpp
@@ -52,12 +52,12 @@
 PassRefPtr<Image> CSSGradientValue::image(RenderObject* renderer, const IntSize& size)
 {
     if (size.isEmpty())
-        return 0;
+        return nullptr;
 
     bool cacheable = isCacheable();
     if (cacheable) {
         if (!clients().contains(renderer))
-            return 0;
+            return nullptr;
 
         // Need to look up our size.  Create a string of width*height to use as a hash key.
         Image* result = getImage(renderer, size);
@@ -131,7 +131,7 @@
         result = toCSSRadialGradientValue(this)->clone();
     else {
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 
     for (unsigned i = 0; i < result->m_stops.size(); i++)
diff --git a/Source/core/css/CSSGradientValue.h b/Source/core/css/CSSGradientValue.h
index 9b29da6..c8ca0d7 100644
--- a/Source/core/css/CSSGradientValue.h
+++ b/Source/core/css/CSSGradientValue.h
@@ -149,7 +149,7 @@
 
     static PassRefPtrWillBeRawPtr<CSSLinearGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSLinearGradient)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSLinearGradientValue(repeat, gradientType));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSLinearGradientValue(repeat, gradientType));
     }
 
     void setAngle(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_angle = val; }
@@ -161,7 +161,7 @@
 
     PassRefPtrWillBeRawPtr<CSSLinearGradientValue> clone() const
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSLinearGradientValue(*this));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSLinearGradientValue(*this));
     }
 
     bool equals(const CSSLinearGradientValue&) const;
@@ -189,12 +189,12 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSRadialGradientValue> create(CSSGradientRepeat repeat, CSSGradientType gradientType = CSSRadialGradient)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSRadialGradientValue(repeat, gradientType));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSRadialGradientValue(repeat, gradientType));
     }
 
     PassRefPtrWillBeRawPtr<CSSRadialGradientValue> clone() const
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSRadialGradientValue(*this));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSRadialGradientValue(*this));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSGrammar.y b/Source/core/css/CSSGrammar.y
index 149ea00..84e7923 100644
--- a/Source/core/css/CSSGrammar.y
+++ b/Source/core/css/CSSGrammar.y
@@ -73,7 +73,10 @@
     CSSParserString string;
 
     StyleRuleBase* rule;
-    Vector<RefPtr<StyleRuleBase> >* ruleList;
+    // The content of the two below HeapVectors are guaranteed to be kept alive by
+    // the corresponding m_parsedRules and m_floatingMediaQueryExpList lists in BisonCSSParser.h.
+    WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >* ruleList;
+    WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* mediaQueryExpList;
     CSSParserSelector* selector;
     Vector<OwnPtr<CSSParserSelector> >* selectorList;
     CSSSelector::MarginBoxType marginBox;
@@ -84,7 +87,6 @@
     MediaQueryExp* mediaQueryExp;
     CSSParserValue value;
     CSSParserValueList* valueList;
-    Vector<OwnPtr<MediaQueryExp> >* mediaQueryExpList;
     StyleKeyframe* keyframe;
     Vector<RefPtr<StyleKeyframe> >* keyframeRuleList;
     float val;
@@ -1044,15 +1046,19 @@
     '+' maybe_space { $$ = CSSSelector::DirectAdjacent; }
     | '~' maybe_space { $$ = CSSSelector::IndirectAdjacent; }
     | '>' maybe_space { $$ = CSSSelector::Child; }
-    | '^' maybe_space {
+    // FIXME: implement named combinator and replace the following /shadow/, /shadow-child/ and
+    // /shadow-deep/ with named combinator's implementation.
+    | '/' IDENT '/' maybe_space {
         if (!RuntimeEnabledFeatures::shadowDOMEnabled())
             YYERROR;
-        $$ = CSSSelector::ChildTree;
-    }
-    | '^' '^' maybe_space {
-        if (!RuntimeEnabledFeatures::shadowDOMEnabled())
+        if ($2.equalIgnoringCase("shadow"))
+            $$ = CSSSelector::Shadow;
+        else if ($2.equalIgnoringCase("shadow-deep"))
+            $$ = CSSSelector::ShadowDeep;
+        else if ($2.equalIgnoringCase("content"))
+            $$ = CSSSelector::ShadowContent;
+        else
             YYERROR;
-        $$ = CSSSelector::DescendantTree;
     }
     ;
 
@@ -1135,8 +1141,6 @@
         while (end->tagHistory())
             end = end->tagHistory();
         end->setRelation(CSSSelector::Descendant);
-        if ($1->isContentPseudoElement())
-            end->setRelationIsAffectedByPseudoContent();
         end->setTagHistory(parser->sinkFloatingSelector($1));
     }
     | selector combinator simple_selector {
@@ -1145,8 +1149,6 @@
         while (end->tagHistory())
             end = end->tagHistory();
         end->setRelation($2);
-        if ($1->isContentPseudoElement())
-            end->setRelationIsAffectedByPseudoContent();
         end->setTagHistory(parser->sinkFloatingSelector($1));
     }
     ;
diff --git a/Source/core/css/CSSGridLineNamesValue.cpp b/Source/core/css/CSSGridLineNamesValue.cpp
index 4e52aac..bbea49e 100644
--- a/Source/core/css/CSSGridLineNamesValue.cpp
+++ b/Source/core/css/CSSGridLineNamesValue.cpp
@@ -45,7 +45,7 @@
 
 PassRefPtrWillBeRawPtr<CSSGridLineNamesValue> CSSGridLineNamesValue::cloneForCSSOM() const
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSGridLineNamesValue(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSGridLineNamesValue(*this));
 }
 
 }
diff --git a/Source/core/css/CSSGridLineNamesValue.h b/Source/core/css/CSSGridLineNamesValue.h
index 3cc8004..7126958 100644
--- a/Source/core/css/CSSGridLineNamesValue.h
+++ b/Source/core/css/CSSGridLineNamesValue.h
@@ -40,7 +40,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSGridLineNamesValue> create()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSGridLineNamesValue());
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSGridLineNamesValue());
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSGridTemplateAreasValue.h b/Source/core/css/CSSGridTemplateAreasValue.h
index da1d130..f50255b 100644
--- a/Source/core/css/CSSGridTemplateAreasValue.h
+++ b/Source/core/css/CSSGridTemplateAreasValue.h
@@ -41,7 +41,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSGridTemplateAreasValue> create(const NamedGridAreaMap& gridAreaMap, size_t rowCount, size_t columnCount)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSGridTemplateAreasValue(gridAreaMap, rowCount, columnCount));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSGridTemplateAreasValue(gridAreaMap, rowCount, columnCount));
     }
     ~CSSGridTemplateAreasValue() { }
 
diff --git a/Source/core/css/CSSGroupingRule.cpp b/Source/core/css/CSSGroupingRule.cpp
index 768f795..ec56762 100644
--- a/Source/core/css/CSSGroupingRule.cpp
+++ b/Source/core/css/CSSGroupingRule.cpp
@@ -35,9 +35,7 @@
 #include "core/css/parser/BisonCSSParser.h"
 #include "core/css/CSSRuleList.h"
 #include "core/css/CSSStyleSheet.h"
-#include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/UseCounter.h"
 #include "wtf/text/StringBuilder.h"
 
@@ -52,35 +50,28 @@
 
 CSSGroupingRule::~CSSGroupingRule()
 {
+#if !ENABLE(OILPAN)
     ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
     for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
         if (m_childRuleCSSOMWrappers[i])
             m_childRuleCSSOMWrappers[i]->setParentRule(0);
     }
+#endif
 }
 
 unsigned CSSGroupingRule::insertRule(const String& ruleString, unsigned index, ExceptionState& exceptionState)
 {
     ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
 
-    CSSStyleSheet* styleSheet = parentStyleSheet();
-    if (styleSheet) {
-        if (Document* document = styleSheet->ownerDocument()) {
-            if (!document->contentSecurityPolicy()->allowStyleEval()) {
-                exceptionState.throwSecurityError(document->contentSecurityPolicy()->styleEvalDisabledErrorMessage());
-                return 0;
-            }
-        }
-    }
-
     if (index > m_groupRule->childRules().size()) {
         exceptionState.throwDOMException(IndexSizeError, "the index " + String::number(index) + " must be less than or equal to the length of the rule list.");
         return 0;
     }
 
+    CSSStyleSheet* styleSheet = parentStyleSheet();
     CSSParserContext context(parserContext(), UseCounter::getFrom(styleSheet));
     BisonCSSParser parser(context);
-    RefPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->contents() : 0, ruleString);
+    RefPtrWillBeRawPtr<StyleRuleBase> newRule = parser.parseRule(styleSheet ? styleSheet->contents() : 0, ruleString);
     if (!newRule) {
         exceptionState.throwDOMException(SyntaxError, "the rule '" + ruleString + "' is invalid and cannot be parsed.");
         return 0;
@@ -97,7 +88,7 @@
 
     m_groupRule->wrapperInsertRule(index, newRule);
 
-    m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
+    m_childRuleCSSOMWrappers.insert(index, RefPtrWillBeMember<CSSRule>(nullptr));
     return index;
 }
 
@@ -139,7 +130,7 @@
     if (index >= length())
         return 0;
     ASSERT(m_childRuleCSSOMWrappers.size() == m_groupRule->childRules().size());
-    RefPtr<CSSRule>& rule = m_childRuleCSSOMWrappers[index];
+    RefPtrWillBeMember<CSSRule>& rule = m_childRuleCSSOMWrappers[index];
     if (!rule)
         rule = m_groupRule->childRules()[index]->createCSSOMWrapper(const_cast<CSSGroupingRule*>(this));
     return rule.get();
@@ -148,7 +139,7 @@
 CSSRuleList* CSSGroupingRule::cssRules() const
 {
     if (!m_ruleListCSSOMWrapper)
-        m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSGroupingRule>(const_cast<CSSGroupingRule*>(this)));
+        m_ruleListCSSOMWrapper = LiveCSSRuleList<CSSGroupingRule>::create(const_cast<CSSGroupingRule*>(this));
     return m_ruleListCSSOMWrapper.get();
 }
 
@@ -162,4 +153,14 @@
     }
 }
 
+void CSSGroupingRule::trace(Visitor* visitor)
+{
+    CSSRule::trace(visitor);
+#if ENABLE(OILPAN)
+    visitor->trace(m_childRuleCSSOMWrappers);
+#endif
+    visitor->trace(m_groupRule);
+    visitor->trace(m_ruleListCSSOMWrapper);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSGroupingRule.h b/Source/core/css/CSSGroupingRule.h
index 9ba6448..cdc98da 100644
--- a/Source/core/css/CSSGroupingRule.h
+++ b/Source/core/css/CSSGroupingRule.h
@@ -47,14 +47,16 @@
     unsigned length() const;
     CSSRule* item(unsigned index) const;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 protected:
     CSSGroupingRule(StyleRuleGroup* groupRule, CSSStyleSheet* parent);
 
     void appendCSSTextForItems(StringBuilder&) const;
 
-    RefPtr<StyleRuleGroup> m_groupRule;
-    mutable Vector<RefPtr<CSSRule> > m_childRuleCSSOMWrappers;
-    mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
+    RefPtrWillBeMember<StyleRuleGroup> m_groupRule;
+    mutable WillBeHeapVector<RefPtrWillBeMember<CSSRule> > m_childRuleCSSOMWrappers;
+    mutable OwnPtrWillBeMember<CSSRuleList> m_ruleListCSSOMWrapper;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSImageGeneratorValue.cpp b/Source/core/css/CSSImageGeneratorValue.cpp
index f492f1e..0872290 100644
--- a/Source/core/css/CSSImageGeneratorValue.cpp
+++ b/Source/core/css/CSSImageGeneratorValue.cpp
@@ -122,7 +122,7 @@
     default:
         ASSERT_NOT_REACHED();
     }
-    return 0;
+    return nullptr;
 }
 
 bool CSSImageGeneratorValue::isFixedSize() const
diff --git a/Source/core/css/CSSImageSetValue.cpp b/Source/core/css/CSSImageSetValue.cpp
index 502004f..bf4ba42 100644
--- a/Source/core/css/CSSImageSetValue.cpp
+++ b/Source/core/css/CSSImageSetValue.cpp
@@ -99,7 +99,7 @@
 
     if (!m_accessedBestFitImage) {
         // FIXME: In the future, we want to take much more than deviceScaleFactor into acount here.
-        // All forms of scale should be included: Page::pageScaleFactor(), Frame::pageZoomFactor(),
+        // All forms of scale should be included: Page::pageScaleFactor(), LocalFrame::pageZoomFactor(),
         // and any CSS transforms. https://bugs.webkit.org/show_bug.cgi?id=81698
         ImageWithScale image = bestImageForScaleFactor();
         if (Document* document = loader->document()) {
@@ -187,7 +187,7 @@
 
 PassRefPtrWillBeRawPtr<CSSImageSetValue> CSSImageSetValue::cloneForCSSOM() const
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSImageSetValue(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSImageSetValue(*this));
 }
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSImageSetValue.h b/Source/core/css/CSSImageSetValue.h
index 3ad6029..2234cc9 100644
--- a/Source/core/css/CSSImageSetValue.h
+++ b/Source/core/css/CSSImageSetValue.h
@@ -40,7 +40,7 @@
 
     static PassRefPtrWillBeRawPtr<CSSImageSetValue> create()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSImageSetValue());
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSImageSetValue());
     }
     ~CSSImageSetValue();
 
diff --git a/Source/core/css/CSSImageValue.cpp b/Source/core/css/CSSImageValue.cpp
index f424da7..8e47d50 100644
--- a/Source/core/css/CSSImageValue.cpp
+++ b/Source/core/css/CSSImageValue.cpp
@@ -33,18 +33,12 @@
 
 namespace WebCore {
 
-CSSImageValue::CSSImageValue(const KURL& url)
+CSSImageValue::CSSImageValue(const String& rawValue, const KURL& url, StyleImage* image)
     : CSSValue(ImageClass)
-    , m_url(url.string())
-    , m_accessedImage(false)
-{
-}
-
-CSSImageValue::CSSImageValue(const KURL& url, StyleImage* image)
-    : CSSValue(ImageClass)
-    , m_url(url.string())
+    , m_relativeURL(rawValue)
+    , m_absoluteURL(url.string())
     , m_image(image)
-    , m_accessedImage(true)
+    , m_accessedImage(image)
 {
 }
 
@@ -67,7 +61,7 @@
     if (!m_accessedImage) {
         m_accessedImage = true;
 
-        FetchRequest request(ResourceRequest(m_url), m_initiatorName.isEmpty() ? FetchInitiatorTypeNames::css : m_initiatorName, options);
+        FetchRequest request(ResourceRequest(m_absoluteURL), m_initiatorName.isEmpty() ? FetchInitiatorTypeNames::css : m_initiatorName, options);
 
         if (options.corsEnabled == IsCORSEnabled)
             request.setCrossOriginAccessControl(fetcher->document()->securityOrigin(), options.allowCredentials);
@@ -90,18 +84,18 @@
 
 bool CSSImageValue::equals(const CSSImageValue& other) const
 {
-    return m_url == other.m_url;
+    return m_absoluteURL == other.m_absoluteURL;
 }
 
 String CSSImageValue::customCSSText() const
 {
-    return "url(" + quoteCSSURLIfNeeded(m_url) + ")";
+    return "url(" + quoteCSSURLIfNeeded(m_absoluteURL) + ")";
 }
 
-PassRefPtr<CSSValue> CSSImageValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSValue> CSSImageValue::cloneForCSSOM() const
 {
     // NOTE: We expose CSSImageValues as URI primitive values in CSSOM to maintain old behavior.
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> uriValue = CSSPrimitiveValue::create(m_url, CSSPrimitiveValue::CSS_URI);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> uriValue = CSSPrimitiveValue::create(m_absoluteURL, CSSPrimitiveValue::CSS_URI);
     uriValue->setCSSOMSafe();
     return uriValue.release();
 }
@@ -116,4 +110,14 @@
     CSSValue::traceAfterDispatch(visitor);
 }
 
+void CSSImageValue::reResolveURL(const Document& document)
+{
+    KURL url = document.completeURL(m_relativeURL);
+    if (url == m_absoluteURL)
+        return;
+    m_absoluteURL = url.string();
+    m_accessedImage = false;
+    m_image.clear();
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSImageValue.h b/Source/core/css/CSSImageValue.h
index 29f2c9d..2d0c1e9 100644
--- a/Source/core/css/CSSImageValue.h
+++ b/Source/core/css/CSSImageValue.h
@@ -27,6 +27,7 @@
 
 namespace WebCore {
 
+class Document;
 class Element;
 class KURL;
 class StyleFetchedImage;
@@ -35,13 +36,13 @@
 
 class CSSImageValue : public CSSValue {
 public:
-    static PassRefPtrWillBeRawPtr<CSSImageValue> create(const KURL& url)
+    static PassRefPtrWillBeRawPtr<CSSImageValue> create(const KURL& url, StyleImage* image = 0)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSImageValue(url));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSImageValue(url, url, image));
     }
-    static PassRefPtrWillBeRawPtr<CSSImageValue> create(const KURL& url, StyleImage* image)
+    static PassRefPtrWillBeRawPtr<CSSImageValue> create(const String& rawValue, const KURL& url, StyleImage* image = 0)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSImageValue(url, image));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSImageValue(rawValue, url, image));
     }
     ~CSSImageValue();
 
@@ -50,11 +51,13 @@
     // Returns a StyleFetchedImage if the image is cached already, otherwise a StylePendingImage.
     StyleImage* cachedOrPendingImage();
 
-    const String& url() { return m_url; }
+    const String& url() { return m_absoluteURL; }
+
+    void reResolveURL(const Document&);
 
     String customCSSText() const;
 
-    PassRefPtr<CSSValue> cloneForCSSOM() const;
+    PassRefPtrWillBeRawPtr<CSSValue> cloneForCSSOM() const;
 
     bool hasFailedOrCanceledSubresources() const;
 
@@ -67,10 +70,10 @@
     void traceAfterDispatch(Visitor*);
 
 private:
-    explicit CSSImageValue(const KURL&);
-    CSSImageValue(const KURL&, StyleImage*);
+    CSSImageValue(const String& rawValue, const KURL&, StyleImage*);
 
-    String m_url;
+    String m_relativeURL;
+    String m_absoluteURL;
     RefPtr<StyleImage> m_image;
     bool m_accessedImage;
     AtomicString m_initiatorName;
diff --git a/Source/core/css/CSSImportRule.cpp b/Source/core/css/CSSImportRule.cpp
index cf733f7..8d5af2f 100644
--- a/Source/core/css/CSSImportRule.cpp
+++ b/Source/core/css/CSSImportRule.cpp
@@ -38,10 +38,15 @@
 
 CSSImportRule::~CSSImportRule()
 {
+#if !ENABLE(OILPAN)
     if (m_styleSheetCSSOMWrapper)
         m_styleSheetCSSOMWrapper->clearOwnerRule();
+    // MediaList and the parent CSSImportRule are both on the oilpan heap and die together.
+    // Therefor clearing is not needed nor allowed since it could be touching already
+    // finalized memory.
     if (m_mediaCSSOMWrapper)
         m_mediaCSSOMWrapper->clearParentRule();
+#endif // ENABLE(OILPAN)
 }
 
 String CSSImportRule::href() const
@@ -91,4 +96,12 @@
     ASSERT_NOT_REACHED();
 }
 
+void CSSImportRule::trace(Visitor* visitor)
+{
+    visitor->trace(m_importRule);
+    visitor->trace(m_mediaCSSOMWrapper);
+    visitor->trace(m_styleSheetCSSOMWrapper);
+    CSSRule::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSImportRule.h b/Source/core/css/CSSImportRule.h
index 95df9c7..8075a18 100644
--- a/Source/core/css/CSSImportRule.h
+++ b/Source/core/css/CSSImportRule.h
@@ -23,6 +23,7 @@
 #define CSSImportRule_h
 
 #include "core/css/CSSRule.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -33,7 +34,10 @@
 
 class CSSImportRule FINAL : public CSSRule {
 public:
-    static PassRefPtr<CSSImportRule> create(StyleRuleImport* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSImportRule(rule, sheet)); }
+    static PassRefPtrWillBeRawPtr<CSSImportRule> create(StyleRuleImport* rule, CSSStyleSheet* sheet)
+    {
+        return adoptRefWillBeNoop(new CSSImportRule(rule, sheet));
+    }
 
     virtual ~CSSImportRule();
 
@@ -45,12 +49,14 @@
     MediaList* media() const;
     CSSStyleSheet* styleSheet() const;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSImportRule(StyleRuleImport*, CSSStyleSheet*);
 
-    RefPtr<StyleRuleImport> m_importRule;
-    mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
-    mutable RefPtr<CSSStyleSheet> m_styleSheetCSSOMWrapper;
+    RefPtrWillBeMember<StyleRuleImport> m_importRule;
+    mutable RefPtrWillBeMember<MediaList> m_mediaCSSOMWrapper;
+    mutable RefPtrWillBeMember<CSSStyleSheet> m_styleSheetCSSOMWrapper;
 };
 
 DEFINE_CSS_RULE_TYPE_CASTS(CSSImportRule, IMPORT_RULE);
diff --git a/Source/core/css/CSSInheritedValue.h b/Source/core/css/CSSInheritedValue.h
index a5fe550..627c465 100644
--- a/Source/core/css/CSSInheritedValue.h
+++ b/Source/core/css/CSSInheritedValue.h
@@ -30,7 +30,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSInheritedValue> create()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSInheritedValue);
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSInheritedValue);
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSInitialValue.h b/Source/core/css/CSSInitialValue.h
index c9a7d4f..a6d4092 100644
--- a/Source/core/css/CSSInitialValue.h
+++ b/Source/core/css/CSSInitialValue.h
@@ -30,11 +30,11 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSInitialValue> createExplicit()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSInitialValue(/* implicit */ false));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSInitialValue(/* implicit */ false));
     }
     static PassRefPtrWillBeRawPtr<CSSInitialValue> createImplicit()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSInitialValue(/* implicit */ true));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSInitialValue(/* implicit */ true));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSKeyframeRule.cpp b/Source/core/css/CSSKeyframeRule.cpp
index a49ef8e..20e1e47 100644
--- a/Source/core/css/CSSKeyframeRule.cpp
+++ b/Source/core/css/CSSKeyframeRule.cpp
@@ -92,15 +92,16 @@
     ASSERT(m_keyText.isNull());
 }
 
-MutableStylePropertySet* StyleKeyframe::mutableProperties()
+MutableStylePropertySet& StyleKeyframe::mutableProperties()
 {
     if (!m_properties->isMutable())
         m_properties = m_properties->mutableCopy();
-    return toMutableStylePropertySet(m_properties);
+    return *toMutableStylePropertySet(m_properties);
 }
 
 void StyleKeyframe::setProperties(PassRefPtr<StylePropertySet> properties)
 {
+    ASSERT(properties);
     m_properties = properties;
 }
 
diff --git a/Source/core/css/CSSKeyframeRule.h b/Source/core/css/CSSKeyframeRule.h
index 5e7fbee..31d78d3 100644
--- a/Source/core/css/CSSKeyframeRule.h
+++ b/Source/core/css/CSSKeyframeRule.h
@@ -55,8 +55,8 @@
     // Used by BisonCSSParser when constructing a new StyleKeyframe.
     void setKeys(PassOwnPtr<Vector<double> >);
 
-    const StylePropertySet* properties() const { return m_properties.get(); }
-    MutableStylePropertySet* mutableProperties();
+    const StylePropertySet& properties() const { return *m_properties; }
+    MutableStylePropertySet& mutableProperties();
     void setProperties(PassRefPtr<StylePropertySet>);
 
     String cssText() const;
@@ -85,6 +85,8 @@
 
     CSSStyleDeclaration* style() const;
 
+    virtual void trace(Visitor* visitor) OVERRIDE { CSSRule::trace(visitor); }
+
 private:
     CSSKeyframeRule(StyleKeyframe*, CSSKeyframesRule* parent);
 
diff --git a/Source/core/css/CSSKeyframesRule.cpp b/Source/core/css/CSSKeyframesRule.cpp
index 6b5576c..9029c65 100644
--- a/Source/core/css/CSSKeyframesRule.cpp
+++ b/Source/core/css/CSSKeyframesRule.cpp
@@ -26,13 +26,10 @@
 #include "config.h"
 #include "core/css/CSSKeyframesRule.h"
 
-#include "bindings/v8/ExceptionState.h"
 #include "core/css/CSSKeyframeRule.h"
 #include "core/css/parser/BisonCSSParser.h"
 #include "core/css/CSSRuleList.h"
 #include "core/css/CSSStyleSheet.h"
-#include "core/dom/Document.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/UseCounter.h"
 #include "wtf/text/StringBuilder.h"
 
@@ -99,12 +96,13 @@
 
 CSSKeyframesRule::~CSSKeyframesRule()
 {
+#if !ENABLE(OILPAN)
     ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
-
     for (unsigned i = 0; i < m_childRuleCSSOMWrappers.size(); ++i) {
         if (m_childRuleCSSOMWrappers[i])
             m_childRuleCSSOMWrappers[i]->setParentRule(0);
     }
+#endif
 }
 
 void CSSKeyframesRule::setName(const String& name)
@@ -114,20 +112,11 @@
     m_keyframesRule->setName(name);
 }
 
-void CSSKeyframesRule::insertRule(const String& ruleText, ExceptionState& exceptionState)
+void CSSKeyframesRule::insertRule(const String& ruleText)
 {
     ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
 
     CSSStyleSheet* styleSheet = parentStyleSheet();
-    if (styleSheet) {
-        if (Document* document = styleSheet->ownerDocument()) {
-            if (!document->contentSecurityPolicy()->allowStyleEval()) {
-                exceptionState.throwSecurityError(document->contentSecurityPolicy()->styleEvalDisabledErrorMessage());
-                return;
-            }
-        }
-    }
-
     CSSParserContext context(parserContext(), UseCounter::getFrom(styleSheet));
     BisonCSSParser parser(context);
     RefPtr<StyleKeyframe> keyframe = parser.parseKeyframeRule(styleSheet ? styleSheet->contents() : 0, ruleText);
@@ -195,9 +184,9 @@
         return 0;
 
     ASSERT(m_childRuleCSSOMWrappers.size() == m_keyframesRule->keyframes().size());
-    RefPtr<CSSKeyframeRule>& rule = m_childRuleCSSOMWrappers[index];
+    RefPtrWillBeMember<CSSKeyframeRule>& rule = m_childRuleCSSOMWrappers[index];
     if (!rule)
-        rule = adoptRef(new CSSKeyframeRule(m_keyframesRule->keyframes()[index].get(), const_cast<CSSKeyframesRule*>(this)));
+        rule = adoptRefWillBeNoop(new CSSKeyframeRule(m_keyframesRule->keyframes()[index].get(), const_cast<CSSKeyframesRule*>(this)));
 
     return rule.get();
 }
@@ -205,7 +194,7 @@
 CSSRuleList* CSSKeyframesRule::cssRules()
 {
     if (!m_ruleListCSSOMWrapper)
-        m_ruleListCSSOMWrapper = adoptPtr(new LiveCSSRuleList<CSSKeyframesRule>(this));
+        m_ruleListCSSOMWrapper = LiveCSSRuleList<CSSKeyframesRule>::create(this);
     return m_ruleListCSSOMWrapper.get();
 }
 
@@ -215,4 +204,14 @@
     m_keyframesRule = toStyleRuleKeyframes(rule);
 }
 
+void CSSKeyframesRule::trace(Visitor* visitor)
+{
+    CSSRule::trace(visitor);
+#if ENABLE(OILPAN)
+    visitor->trace(m_childRuleCSSOMWrappers);
+#endif
+    visitor->trace(m_keyframesRule);
+    visitor->trace(m_ruleListCSSOMWrapper);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSKeyframesRule.h b/Source/core/css/CSSKeyframesRule.h
index 0be3fd1..ab7809d 100644
--- a/Source/core/css/CSSKeyframesRule.h
+++ b/Source/core/css/CSSKeyframesRule.h
@@ -36,11 +36,10 @@
 class CSSRuleList;
 class StyleKeyframe;
 class CSSKeyframeRule;
-class ExceptionState;
 
 class StyleRuleKeyframes FINAL : public StyleRuleBase {
 public:
-    static PassRefPtr<StyleRuleKeyframes> create() { return adoptRef(new StyleRuleKeyframes()); }
+    static PassRefPtrWillBeRawPtr<StyleRuleKeyframes> create() { return adoptRefWillBeNoop(new StyleRuleKeyframes()); }
 
     ~StyleRuleKeyframes();
 
@@ -58,7 +57,9 @@
 
     int findKeyframeIndex(const String& key) const;
 
-    PassRefPtr<StyleRuleKeyframes> copy() const { return adoptRef(new StyleRuleKeyframes(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRuleKeyframes> copy() const { return adoptRefWillBeNoop(new StyleRuleKeyframes(*this)); }
+
+    void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
 
 private:
     StyleRuleKeyframes();
@@ -73,7 +74,10 @@
 
 class CSSKeyframesRule FINAL : public CSSRule {
 public:
-    static PassRefPtr<CSSKeyframesRule> create(StyleRuleKeyframes* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSKeyframesRule(rule, sheet)); }
+    static PassRefPtrWillBeRawPtr<CSSKeyframesRule> create(StyleRuleKeyframes* rule, CSSStyleSheet* sheet)
+    {
+        return adoptRefWillBeNoop(new CSSKeyframesRule(rule, sheet));
+    }
 
     virtual ~CSSKeyframesRule();
 
@@ -86,7 +90,7 @@
 
     CSSRuleList* cssRules();
 
-    void insertRule(const String& rule, ExceptionState&);
+    void insertRule(const String& rule);
     void deleteRule(const String& key);
     CSSKeyframeRule* findRule(const String& key);
 
@@ -97,12 +101,14 @@
     bool isVendorPrefixed() const { return m_isPrefixed; }
     void setVendorPrefixed(bool isPrefixed) { m_isPrefixed = isPrefixed; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSKeyframesRule(StyleRuleKeyframes*, CSSStyleSheet* parent);
 
-    RefPtr<StyleRuleKeyframes> m_keyframesRule;
-    mutable Vector<RefPtr<CSSKeyframeRule> > m_childRuleCSSOMWrappers;
-    mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
+    RefPtrWillBeMember<StyleRuleKeyframes> m_keyframesRule;
+    mutable WillBeHeapVector<RefPtrWillBeMember<CSSKeyframeRule> > m_childRuleCSSOMWrappers;
+    mutable OwnPtrWillBeMember<CSSRuleList> m_ruleListCSSOMWrapper;
     bool m_isPrefixed;
 };
 
diff --git a/Source/core/css/CSSKeyframesRule.idl b/Source/core/css/CSSKeyframesRule.idl
index ee408d9..d85f8d1 100644
--- a/Source/core/css/CSSKeyframesRule.idl
+++ b/Source/core/css/CSSKeyframesRule.idl
@@ -32,7 +32,7 @@
     readonly attribute CSSRuleList cssRules;
 
     [ImplementedAs=item, NotEnumerable] getter CSSKeyframeRule (unsigned long index);
-    [RaisesException] void insertRule([Default=Undefined] optional DOMString rule);
+    void insertRule([Default=Undefined] optional DOMString rule);
     void deleteRule([Default=Undefined] optional DOMString key);
     CSSKeyframeRule findRule([Default=Undefined] optional DOMString key);
 };
diff --git a/Source/core/css/CSSLineBoxContainValue.h b/Source/core/css/CSSLineBoxContainValue.h
index 38185ce..4112add 100644
--- a/Source/core/css/CSSLineBoxContainValue.h
+++ b/Source/core/css/CSSLineBoxContainValue.h
@@ -42,7 +42,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSLineBoxContainValue> create(LineBoxContain value)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSLineBoxContainValue(value));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSLineBoxContainValue(value));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSMatrix.cpp b/Source/core/css/CSSMatrix.cpp
index f1138ba..f37c7f0 100644
--- a/Source/core/css/CSSMatrix.cpp
+++ b/Source/core/css/CSSMatrix.cpp
@@ -61,7 +61,7 @@
     if (BisonCSSParser::parseValue(styleDeclaration.get(), CSSPropertyWebkitTransform, string, true, HTMLStandardMode, 0)) {
         // Convert to TransformOperations. This can fail if a property
         // requires style (i.e., param uses 'ems' or 'exs')
-        RefPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform);
+        RefPtrWillBeRawPtr<CSSValue> value = styleDeclaration->getPropertyCSSValue(CSSPropertyWebkitTransform);
 
         // Check for a "none" or empty transform. In these cases we can use the default identity matrix.
         if (!value || (value->isPrimitiveValue() && (toCSSPrimitiveValue(value.get()))->getValueID() == CSSValueNone))
@@ -89,25 +89,25 @@
 }
 
 // Perform a concatenation of the matrices (this * secondMatrix)
-PassRefPtr<CSSMatrix> CSSMatrix::multiply(CSSMatrix* secondMatrix) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::multiply(CSSMatrix* secondMatrix) const
 {
     if (!secondMatrix)
-        return 0;
+        return nullptr;
 
     return CSSMatrix::create(TransformationMatrix(m_matrix).multiply(secondMatrix->m_matrix));
 }
 
-PassRefPtr<CSSMatrix> CSSMatrix::inverse(ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::inverse(ExceptionState& exceptionState) const
 {
     if (!m_matrix.isInvertible()) {
         exceptionState.throwDOMException(NotSupportedError, "The matrix is not invertable.");
-        return 0;
+        return nullptr;
     }
 
     return CSSMatrix::create(m_matrix.inverse());
 }
 
-PassRefPtr<CSSMatrix> CSSMatrix::translate(double x, double y, double z) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::translate(double x, double y, double z) const
 {
     if (std::isnan(x))
         x = 0;
@@ -118,7 +118,7 @@
     return CSSMatrix::create(TransformationMatrix(m_matrix).translate3d(x, y, z));
 }
 
-PassRefPtr<CSSMatrix> CSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::scale(double scaleX, double scaleY, double scaleZ) const
 {
     if (std::isnan(scaleX))
         scaleX = 1;
@@ -129,7 +129,7 @@
     return CSSMatrix::create(TransformationMatrix(m_matrix).scale3d(scaleX, scaleY, scaleZ));
 }
 
-PassRefPtr<CSSMatrix> CSSMatrix::rotate(double rotX, double rotY, double rotZ) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::rotate(double rotX, double rotY, double rotZ) const
 {
     if (std::isnan(rotX))
         rotX = 0;
@@ -147,7 +147,7 @@
     return CSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(rotX, rotY, rotZ));
 }
 
-PassRefPtr<CSSMatrix> CSSMatrix::rotateAxisAngle(double x, double y, double z, double angle) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::rotateAxisAngle(double x, double y, double z, double angle) const
 {
     if (std::isnan(x))
         x = 0;
@@ -162,14 +162,14 @@
     return CSSMatrix::create(TransformationMatrix(m_matrix).rotate3d(x, y, z, angle));
 }
 
-PassRefPtr<CSSMatrix> CSSMatrix::skewX(double angle) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::skewX(double angle) const
 {
     if (std::isnan(angle))
         angle = 0;
     return CSSMatrix::create(TransformationMatrix(m_matrix).skewX(angle));
 }
 
-PassRefPtr<CSSMatrix> CSSMatrix::skewY(double angle) const
+PassRefPtrWillBeRawPtr<CSSMatrix> CSSMatrix::skewY(double angle) const
 {
     if (std::isnan(angle))
         angle = 0;
diff --git a/Source/core/css/CSSMatrix.h b/Source/core/css/CSSMatrix.h
index 92c6cb1..e620097 100644
--- a/Source/core/css/CSSMatrix.h
+++ b/Source/core/css/CSSMatrix.h
@@ -35,15 +35,15 @@
 
 class ExceptionState;
 
-class CSSMatrix FINAL : public ScriptWrappable, public RefCounted<CSSMatrix> {
+class CSSMatrix FINAL : public RefCountedWillBeGarbageCollectedFinalized<CSSMatrix>, public ScriptWrappable {
 public:
-    static PassRefPtr<CSSMatrix> create(const TransformationMatrix& m)
+    static PassRefPtrWillBeRawPtr<CSSMatrix> create(const TransformationMatrix& m)
     {
-        return adoptRef(new CSSMatrix(m));
+        return adoptRefWillBeNoop(new CSSMatrix(m));
     }
-    static PassRefPtr<CSSMatrix> create(const String& s, ExceptionState& exceptionState)
+    static PassRefPtrWillBeRawPtr<CSSMatrix> create(const String& s, ExceptionState& exceptionState)
     {
-        return adoptRef(new CSSMatrix(s, exceptionState));
+        return adoptRefWillBeNoop(new CSSMatrix(s, exceptionState));
     }
 
     double a() const { return m_matrix.a(); }
@@ -100,53 +100,55 @@
     // specified operation applied. The this value is not modified.
 
     // Multiply this matrix by secondMatrix, on the right (result = this * secondMatrix)
-    PassRefPtr<CSSMatrix> multiply(CSSMatrix* secondMatrix) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> multiply(CSSMatrix* secondMatrix) const;
 
     // Return the inverse of this matrix. Throw an exception if the matrix is not invertible
-    PassRefPtr<CSSMatrix> inverse(ExceptionState&) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> inverse(ExceptionState&) const;
 
     // Return this matrix translated by the passed values.
     // Passing a NaN will use a value of 0. This allows the 3D form to used for 2D operations
     // Operation is performed as though the this matrix is multiplied by a matrix with
     // the translation values on the left (result = translation(x,y,z) * this)
-    PassRefPtr<CSSMatrix> translate(double x, double y, double z) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> translate(double x, double y, double z) const;
 
     // Returns this matrix scaled by the passed values.
     // Passing scaleX or scaleZ as NaN uses a value of 1, but passing scaleY of NaN
     // makes it the same as scaleX. This allows the 3D form to used for 2D operations
     // Operation is performed as though the this matrix is multiplied by a matrix with
     // the scale values on the left (result = scale(x,y,z) * this)
-    PassRefPtr<CSSMatrix> scale(double scaleX, double scaleY, double scaleZ) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> scale(double scaleX, double scaleY, double scaleZ) const;
 
     // Returns this matrix rotated by the passed values.
     // If rotY and rotZ are NaN, rotate about Z (rotX=0, rotateY=0, rotateZ=rotX).
     // Otherwise use a rotation value of 0 for any passed NaN.
     // Operation is performed as though the this matrix is multiplied by a matrix with
     // the rotation values on the left (result = rotation(x,y,z) * this)
-    PassRefPtr<CSSMatrix> rotate(double rotX, double rotY, double rotZ) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> rotate(double rotX, double rotY, double rotZ) const;
 
     // Returns this matrix rotated about the passed axis by the passed angle.
     // Passing a NaN will use a value of 0. If the axis is (0,0,0) use a value
     // Operation is performed as though the this matrix is multiplied by a matrix with
     // the rotation values on the left (result = rotation(x,y,z,angle) * this)
-    PassRefPtr<CSSMatrix> rotateAxisAngle(double x, double y, double z, double angle) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> rotateAxisAngle(double x, double y, double z, double angle) const;
 
     // Return this matrix skewed along the X axis by the passed values.
     // Passing a NaN will use a value of 0.
     // Operation is performed as though the this matrix is multiplied by a matrix with
     // the skew values on the left (result = skewX(angle) * this)
-    PassRefPtr<CSSMatrix> skewX(double angle) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> skewX(double angle) const;
 
     // Return this matrix skewed along the Y axis by the passed values.
     // Passing a NaN will use a value of 0.
     // Operation is performed as though the this matrix is multiplied by a matrix with
     // the skew values on the left (result = skewY(angle) * this)
-    PassRefPtr<CSSMatrix> skewY(double angle) const;
+    PassRefPtrWillBeRawPtr<CSSMatrix> skewY(double angle) const;
 
     const TransformationMatrix& transform() const { return m_matrix; }
 
     String toString() const;
 
+    void trace(Visitor*) { }
+
 protected:
     CSSMatrix(const TransformationMatrix&);
     CSSMatrix(const String&, ExceptionState&);
diff --git a/Source/core/css/CSSMediaRule.cpp b/Source/core/css/CSSMediaRule.cpp
index 7e8c34a..dedea18 100644
--- a/Source/core/css/CSSMediaRule.cpp
+++ b/Source/core/css/CSSMediaRule.cpp
@@ -35,8 +35,10 @@
 
 CSSMediaRule::~CSSMediaRule()
 {
+#if !ENABLE(OILPAN)
     if (m_mediaCSSOMWrapper)
         m_mediaCSSOMWrapper->clearParentRule();
+#endif
 }
 
 MediaQuerySet* CSSMediaRule::mediaQueries() const
@@ -74,4 +76,9 @@
         m_mediaCSSOMWrapper->reattach(mediaQueries());
 }
 
+void CSSMediaRule::trace(Visitor* visitor)
+{
+    visitor->trace(m_mediaCSSOMWrapper);
+    CSSGroupingRule::trace(visitor);
+}
 } // namespace WebCore
diff --git a/Source/core/css/CSSMediaRule.h b/Source/core/css/CSSMediaRule.h
index 3e46410..fb68958 100644
--- a/Source/core/css/CSSMediaRule.h
+++ b/Source/core/css/CSSMediaRule.h
@@ -32,7 +32,10 @@
 
 class CSSMediaRule FINAL : public CSSGroupingRule {
 public:
-    static PassRefPtr<CSSMediaRule> create(StyleRuleMedia* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSMediaRule(rule, sheet)); }
+    static PassRefPtrWillBeRawPtr<CSSMediaRule> create(StyleRuleMedia* rule, CSSStyleSheet* sheet)
+    {
+        return adoptRefWillBeNoop(new CSSMediaRule(rule, sheet));
+    }
 
     virtual ~CSSMediaRule();
 
@@ -42,12 +45,14 @@
 
     MediaList* media() const;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSMediaRule(StyleRuleMedia*, CSSStyleSheet*);
 
     MediaQuerySet* mediaQueries() const;
 
-    mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
+    mutable RefPtrWillBeMember<MediaList> m_mediaCSSOMWrapper;
 };
 
 DEFINE_CSS_RULE_TYPE_CASTS(CSSMediaRule, MEDIA_RULE);
diff --git a/Source/core/css/CSSPageRule.cpp b/Source/core/css/CSSPageRule.cpp
index ff1544b..46ab342 100644
--- a/Source/core/css/CSSPageRule.cpp
+++ b/Source/core/css/CSSPageRule.cpp
@@ -85,7 +85,7 @@
     StringBuilder result;
     result.append(selectorText());
     result.appendLiteral(" { ");
-    String decls = m_pageRule->properties()->asText();
+    String decls = m_pageRule->properties().asText();
     result.append(decls);
     if (!decls.isEmpty())
         result.append(' ');
@@ -101,4 +101,10 @@
         m_propertiesCSSOMWrapper->reattach(m_pageRule->mutableProperties());
 }
 
+void CSSPageRule::trace(Visitor* visitor)
+{
+    visitor->trace(m_pageRule);
+    CSSRule::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSPageRule.h b/Source/core/css/CSSPageRule.h
index 1a49ec6..8585eec 100644
--- a/Source/core/css/CSSPageRule.h
+++ b/Source/core/css/CSSPageRule.h
@@ -23,6 +23,7 @@
 #define CSSPageRule_h
 
 #include "core/css/CSSRule.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -33,7 +34,10 @@
 
 class CSSPageRule FINAL : public CSSRule {
 public:
-    static PassRefPtr<CSSPageRule> create(StyleRulePage* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSPageRule(rule, sheet)); }
+    static PassRefPtrWillBeRawPtr<CSSPageRule> create(StyleRulePage* rule, CSSStyleSheet* sheet)
+    {
+        return adoptRefWillBeNoop(new CSSPageRule(rule, sheet));
+    }
 
     virtual ~CSSPageRule();
 
@@ -46,10 +50,12 @@
     String selectorText() const;
     void setSelectorText(const String&);
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSPageRule(StyleRulePage*, CSSStyleSheet*);
 
-    RefPtr<StyleRulePage> m_pageRule;
+    RefPtrWillBeMember<StyleRulePage> m_pageRule;
     mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
 };
 
diff --git a/Source/core/css/CSSParserValues.cpp b/Source/core/css/CSSParserValues.cpp
index bde7fb7..da1ce80 100644
--- a/Source/core/css/CSSParserValues.cpp
+++ b/Source/core/css/CSSParserValues.cpp
@@ -82,9 +82,9 @@
     valueList.clear();
 }
 
-PassRefPtr<CSSValue> CSSParserValue::createCSSValue()
+PassRefPtrWillBeRawPtr<CSSValue> CSSParserValue::createCSSValue()
 {
-    RefPtr<CSSValue> parsedValue;
+    RefPtrWillBeRawPtr<CSSValue> parsedValue;
     if (id)
         return CSSPrimitiveValue::createIdentifier(id);
 
@@ -158,11 +158,11 @@
     case CSSPrimitiveValue::CSS_CALC:
     case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_NUMBER:
     case CSSPrimitiveValue::CSS_CALC_PERCENTAGE_WITH_LENGTH:
-        return 0;
+        return nullptr;
     }
 
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 CSSParserSelector::CSSParserSelector()
diff --git a/Source/core/css/CSSParserValues.h b/Source/core/css/CSSParserValues.h
index d2879a4..42d069d 100644
--- a/Source/core/css/CSSParserValues.h
+++ b/Source/core/css/CSSParserValues.h
@@ -98,9 +98,11 @@
 
     bool equalIgnoringCase(const char* str) const
     {
-        if (is8Bit())
-            return WTF::equalIgnoringCase(str, characters8(), length());
-        return WTF::equalIgnoringCase(str, characters16(), length());
+        bool match = is8Bit() ? WTF::equalIgnoringCase(str, characters8(), length()) : WTF::equalIgnoringCase(str, characters16(), length());
+        if (!match)
+            return false;
+        ASSERT(strlen(str) >= length());
+        return str[length()] == '\0';
     }
 
     template <size_t strLength>
@@ -161,7 +163,7 @@
     inline void setFromFunction(CSSParserFunction*);
     inline void setFromValueList(PassOwnPtr<CSSParserValueList>);
 
-    PassRefPtr<CSSValue> createCSSValue();
+    PassRefPtrWillBeRawPtr<CSSValue> createCSSValue();
 };
 
 class CSSParserValueList {
@@ -231,7 +233,6 @@
     void setFunctionArgumentSelector(CSSParserSelector* selector) { m_functionArgumentSelector = selector; }
     bool isDistributedPseudoElement() const { return m_selector->isDistributedPseudoElement(); }
     CSSParserSelector* findDistributedPseudoElementSelector() const;
-    bool isContentPseudoElement() const { return m_selector->isContentPseudoElement(); }
 
     CSSSelector::PseudoType pseudoType() const { return m_selector->pseudoType(); }
     bool isCustomPseudoElement() const { return m_selector->isCustomPseudoElement(); }
diff --git a/Source/core/css/CSSParserValuesTest.cpp b/Source/core/css/CSSParserValuesTest.cpp
index 6d1ac8b..41ad43c 100644
--- a/Source/core/css/CSSParserValuesTest.cpp
+++ b/Source/core/css/CSSParserValuesTest.cpp
@@ -56,4 +56,32 @@
     ASSERT_EQ(0u, cssParserString.length());
 }
 
+TEST(CSSParserValuesTest, EqualIgnoringCase8BitsString)
+{
+    CSSParserString cssParserString;
+    String string8bit("sHaDOw");
+    cssParserString.init(string8bit, 0, string8bit.length());
+
+    ASSERT_TRUE(cssParserString.equalIgnoringCase("shadow"));
+    ASSERT_TRUE(cssParserString.equalIgnoringCase("ShaDow"));
+    ASSERT_FALSE(cssParserString.equalIgnoringCase("shadow-all"));
+    ASSERT_FALSE(cssParserString.equalIgnoringCase("sha"));
+    ASSERT_FALSE(cssParserString.equalIgnoringCase("abCD"));
+}
+
+TEST(CSSParserValuesTest, EqualIgnoringCase16BitsString)
+{
+    String string16bit("sHaDOw");
+    string16bit.ensure16Bit();
+
+    CSSParserString cssParserString;
+    cssParserString.init(string16bit, 0, string16bit.length());
+
+    ASSERT_TRUE(cssParserString.equalIgnoringCase("shadow"));
+    ASSERT_TRUE(cssParserString.equalIgnoringCase("ShaDow"));
+    ASSERT_FALSE(cssParserString.equalIgnoringCase("shadow-all"));
+    ASSERT_FALSE(cssParserString.equalIgnoringCase("sha"));
+    ASSERT_FALSE(cssParserString.equalIgnoringCase("abCD"));
+}
+
 } // namespace
diff --git a/Source/core/css/CSSPrimitiveValue.cpp b/Source/core/css/CSSPrimitiveValue.cpp
index d4d8810..f909052 100644
--- a/Source/core/css/CSSPrimitiveValue.cpp
+++ b/Source/core/css/CSSPrimitiveValue.cpp
@@ -112,6 +112,40 @@
     return false;
 }
 
+CSSPrimitiveValue::UnitTable createUnitTable()
+{
+    CSSPrimitiveValue::UnitTable table;
+    table.set(String("em"), CSSPrimitiveValue::CSS_EMS);
+    table.set(String("ex"), CSSPrimitiveValue::CSS_EXS);
+    table.set(String("px"), CSSPrimitiveValue::CSS_PX);
+    table.set(String("cm"), CSSPrimitiveValue::CSS_CM);
+    table.set(String("mm"), CSSPrimitiveValue::CSS_MM);
+    table.set(String("in"), CSSPrimitiveValue::CSS_IN);
+    table.set(String("pt"), CSSPrimitiveValue::CSS_PT);
+    table.set(String("pc"), CSSPrimitiveValue::CSS_PC);
+    table.set(String("deg"), CSSPrimitiveValue::CSS_DEG);
+    table.set(String("rad"), CSSPrimitiveValue::CSS_RAD);
+    table.set(String("grad"), CSSPrimitiveValue::CSS_GRAD);
+    table.set(String("ms"), CSSPrimitiveValue::CSS_MS);
+    table.set(String("s"), CSSPrimitiveValue::CSS_S);
+    table.set(String("hz"), CSSPrimitiveValue::CSS_HZ);
+    table.set(String("khz"), CSSPrimitiveValue::CSS_KHZ);
+    table.set(String("dpi"), CSSPrimitiveValue::CSS_DPI);
+    table.set(String("dpcm"), CSSPrimitiveValue::CSS_DPCM);
+    table.set(String("dppx"), CSSPrimitiveValue::CSS_DPPX);
+    table.set(String("vw"), CSSPrimitiveValue::CSS_VW);
+    table.set(String("vh"), CSSPrimitiveValue::CSS_VH);
+    table.set(String("vmax"), CSSPrimitiveValue::CSS_VMIN);
+    table.set(String("vmin"), CSSPrimitiveValue::CSS_VMAX);
+    return table;
+}
+
+CSSPrimitiveValue::UnitTable& CSSPrimitiveValue::getUnitTable()
+{
+    DEFINE_STATIC_LOCAL(UnitTable, unitTable, (createUnitTable()));
+    return unitTable;
+}
+
 CSSPrimitiveValue::UnitCategory CSSPrimitiveValue::unitCategory(CSSPrimitiveValue::UnitTypes type)
 {
     // Here we violate the spec (http://www.w3.org/TR/DOM-Level-2-Style/css.html#CSS-CSSPrimitiveValue) and allow conversions
@@ -300,42 +334,6 @@
     }
 }
 
-// Remove below specialized constructors once all callers of CSSPrimitiveValue(...)
-// have been converted to PassRefPtrWillBeRawPtr, ie. when
-//    template<typename T> CSSPrimitiveValue(T* val)
-//    template<typename T> CSSPrimitiveValue(PassRefPtr<T> val)
-// both can be converted to use PassRefPtrWillBeRawPtr.
-CSSPrimitiveValue::CSSPrimitiveValue(CSSCalcValue* value)
-    : CSSValue(PrimitiveClass)
-{
-    init(PassRefPtrWillBeRawPtr<CSSCalcValue>(value));
-}
-CSSPrimitiveValue::CSSPrimitiveValue(PassRefPtrWillBeRawPtr<CSSCalcValue> value)
-    : CSSValue(PrimitiveClass)
-{
-    init(value);
-}
-CSSPrimitiveValue::CSSPrimitiveValue(Pair* value)
-    : CSSValue(PrimitiveClass)
-{
-    init(PassRefPtrWillBeRawPtr<Pair>(value));
-}
-CSSPrimitiveValue::CSSPrimitiveValue(PassRefPtrWillBeRawPtr<Pair> value)
-    : CSSValue(PrimitiveClass)
-{
-    init(value);
-}
-CSSPrimitiveValue::CSSPrimitiveValue(Counter* value)
-    : CSSValue(PrimitiveClass)
-{
-    init(PassRefPtrWillBeRawPtr<Counter>(value));
-}
-CSSPrimitiveValue::CSSPrimitiveValue(PassRefPtrWillBeRawPtr<Counter> value)
-    : CSSValue(PrimitiveClass)
-{
-    init(value);
-}
-
 void CSSPrimitiveValue::init(const Length& length)
 {
     switch (length.type()) {
@@ -403,14 +401,14 @@
     m_value.counter = c.leakRef();
 }
 
-void CSSPrimitiveValue::init(PassRefPtr<Rect> r)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Rect> r)
 {
     m_primitiveUnitType = CSS_RECT;
     m_hasCachedCSSText = false;
     m_value.rect = r.leakRef();
 }
 
-void CSSPrimitiveValue::init(PassRefPtr<Quad> quad)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<Quad> quad)
 {
     m_primitiveUnitType = CSS_QUAD;
     m_hasCachedCSSText = false;
@@ -431,7 +429,7 @@
     m_value.calc = c.leakRef();
 }
 
-void CSSPrimitiveValue::init(PassRefPtr<CSSBasicShape> shape)
+void CSSPrimitiveValue::init(PassRefPtrWillBeRawPtr<CSSBasicShape> shape)
 {
     m_primitiveUnitType = CSS_SHAPE;
     m_hasCachedCSSText = false;
@@ -461,10 +459,16 @@
 #endif
         break;
     case CSS_RECT:
+        // We must not call deref() when oilpan is enabled because m_value.rect is traced.
+#if !ENABLE(OILPAN)
         m_value.rect->deref();
+#endif
         break;
     case CSS_QUAD:
+        // We must not call deref() when oilpan is enabled because m_value.quad is traced.
+#if !ENABLE(OILPAN)
         m_value.quad->deref();
+#endif
         break;
     case CSS_PAIR:
         // We must not call deref() when oilpan is enabled because m_value.pair is traced.
@@ -483,7 +487,10 @@
         ASSERT_NOT_REACHED();
         break;
     case CSS_SHAPE:
+        // We must not call deref() when oilpan is enabled because m_value.shape is traced.
+#if !ENABLE(OILPAN)
         m_value.shape->deref();
+#endif
         break;
     case CSS_NUMBER:
     case CSS_PARSER_INTEGER:
@@ -590,7 +597,7 @@
         return m_value.calc->computeLengthPx(conversionData);
 
     const RenderStyle& style = conversionData.style();
-    const RenderStyle& rootStyle = conversionData.rootStyle();
+    const RenderStyle* rootStyle = conversionData.rootStyle();
     bool computingFontSize = conversionData.computingFontSize();
 
     double factor;
@@ -609,7 +616,10 @@
                 factor = (computingFontSize ? style.fontDescription().specifiedSize() : style.fontDescription().computedSize()) / 2.0;
             break;
         case CSS_REMS:
-            factor = computingFontSize ? rootStyle.fontDescription().specifiedSize() : rootStyle.fontDescription().computedSize();
+            if (rootStyle)
+                factor = computingFontSize ? rootStyle->fontDescription().specifiedSize() : rootStyle->fontDescription().computedSize();
+            else
+                factor = 1.0;
             break;
         case CSS_CHS:
             factor = style.fontMetrics().zeroWidth();
@@ -896,11 +906,11 @@
     return m_value.quad;
 }
 
-PassRefPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionState& exceptionState) const
+PassRefPtrWillBeRawPtr<RGBColor> CSSPrimitiveValue::getRGBColorValue(ExceptionState& exceptionState) const
 {
     if (m_primitiveUnitType != CSS_RGBCOLOR) {
         exceptionState.throwDOMException(InvalidAccessError, "This object is not an RGB color value.");
-        return 0;
+        return nullptr;
     }
 
     // FIMXE: This should not return a new object for each invocation.
@@ -1290,12 +1300,21 @@
     case CSS_COUNTER:
         visitor->trace(m_value.counter);
         break;
+    case CSS_RECT:
+        visitor->trace(m_value.rect);
+        break;
+    case CSS_QUAD:
+        visitor->trace(m_value.quad);
+        break;
     case CSS_PAIR:
         visitor->trace(m_value.pair);
         break;
     case CSS_CALC:
         visitor->trace(m_value.calc);
         break;
+    case CSS_SHAPE:
+        visitor->trace(m_value.shape);
+        break;
     default:
         break;
     }
diff --git a/Source/core/css/CSSPrimitiveValue.h b/Source/core/css/CSSPrimitiveValue.h
index 0c53c77..ad00053 100644
--- a/Source/core/css/CSSPrimitiveValue.h
+++ b/Source/core/css/CSSPrimitiveValue.h
@@ -149,6 +149,9 @@
     };
     static UnitCategory unitCategory(CSSPrimitiveValue::UnitTypes);
 
+    typedef HashMap<String, CSSPrimitiveValue::UnitTypes> UnitTable;
+    static UnitTable& getUnitTable();
+
     bool isAngle() const
     {
         return m_primitiveUnitType == CSS_DEG
@@ -198,39 +201,39 @@
 
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifier(CSSValueID valueID)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(valueID));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(valueID));
     }
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createIdentifier(CSSPropertyID propertyID)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(propertyID));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(propertyID));
     }
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createParserOperator(int parserOperator)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(parserOperator));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(parserOperator));
     }
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createColor(unsigned rgbValue)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(rgbValue));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(rgbValue));
     }
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(double value, UnitTypes type)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value, type));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value, type));
     }
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const String& value, UnitTypes type)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value, type));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value, type));
     }
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const Length& value, float zoom)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value, zoom));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value, zoom));
     }
     static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(const LengthSize& value)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value));
     }
     template<typename T> static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> create(T value)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSPrimitiveValue(value));
     }
 
     // This value is used to handle quirky margins in reflow roots (body, td, and th) like WinIE.
@@ -241,7 +244,7 @@
     {
         CSSPrimitiveValue* quirkValue = new CSSPrimitiveValue(value, type);
         quirkValue->m_isQuirkValue = true;
-        return adoptRefCountedWillBeRefCountedGarbageCollected(quirkValue);
+        return adoptRefWillBeRefCountedGarbageCollected(quirkValue);
     }
 
     ~CSSPrimitiveValue();
@@ -314,7 +317,7 @@
     Quad* getQuadValue(ExceptionState&) const;
     Quad* getQuadValue() const { return m_primitiveUnitType != CSS_QUAD ? 0 : m_value.quad; }
 
-    PassRefPtr<RGBColor> getRGBColorValue(ExceptionState&) const;
+    PassRefPtrWillBeRawPtr<RGBColor> getRGBColorValue(ExceptionState&) const;
     RGBA32 getRGBA32Value() const { return m_primitiveUnitType != CSS_RGBCOLOR ? 0 : m_value.rgbcolor; }
 
     Pair* getPairValue(ExceptionState&) const;
@@ -363,24 +366,15 @@
     template<typename T> CSSPrimitiveValue(T* val)
         : CSSValue(PrimitiveClass)
     {
-        init(PassRefPtr<T>(val));
+        init(PassRefPtrWillBeRawPtr<T>(val));
     }
 
-    template<typename T> CSSPrimitiveValue(PassRefPtr<T> val)
+    template<typename T> CSSPrimitiveValue(PassRefPtrWillBeRawPtr<T> val)
         : CSSValue(PrimitiveClass)
     {
         init(val);
     }
 
-    // Remove below overloaded constructors once all callers of CSSPrimitiveValue(...)
-    // have been converted to PassRefPtrWillBeRawPtr.
-    explicit CSSPrimitiveValue(CSSCalcValue*);
-    explicit CSSPrimitiveValue(PassRefPtrWillBeRawPtr<CSSCalcValue>);
-    explicit CSSPrimitiveValue(Pair*);
-    explicit CSSPrimitiveValue(PassRefPtrWillBeRawPtr<Pair>);
-    explicit CSSPrimitiveValue(Counter*);
-    explicit CSSPrimitiveValue(PassRefPtrWillBeRawPtr<Counter>);
-
     static void create(int); // compile-time guard
     static void create(unsigned); // compile-time guard
     template<typename T> operator T*(); // compile-time guard
@@ -388,10 +382,10 @@
     void init(const Length&);
     void init(const LengthSize&);
     void init(PassRefPtrWillBeRawPtr<Counter>);
-    void init(PassRefPtr<Rect>);
+    void init(PassRefPtrWillBeRawPtr<Rect>);
     void init(PassRefPtrWillBeRawPtr<Pair>);
-    void init(PassRefPtr<Quad>);
-    void init(PassRefPtr<CSSBasicShape>);
+    void init(PassRefPtrWillBeRawPtr<Quad>);
+    void init(PassRefPtrWillBeRawPtr<CSSBasicShape>);
     void init(PassRefPtrWillBeRawPtr<CSSCalcValue>);
     bool getDoubleValueInternal(UnitTypes targetUnitType, double* result) const;
 
@@ -403,14 +397,14 @@
         int parserOperator;
         double num;
         StringImpl* string;
-        Rect* rect;
-        Quad* quad;
         unsigned rgbcolor;
-        CSSBasicShape* shape;
         // FIXME: oilpan: Should be members, but no support for members in unions. Just trace the raw ptr for now.
+        CSSBasicShape* shape;
         CSSCalcValue* calc;
         Counter* counter;
         Pair* pair;
+        Rect* rect;
+        Quad* quad;
     } m_value;
 };
 
diff --git a/Source/core/css/CSSPrimitiveValueMappings.h b/Source/core/css/CSSPrimitiveValueMappings.h
index fb459a0..62fb3f5 100644
--- a/Source/core/css/CSSPrimitiveValueMappings.h
+++ b/Source/core/css/CSSPrimitiveValueMappings.h
@@ -3482,15 +3482,15 @@
     return FontWeightNormal;
 }
 
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontItalic italic)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontStyle italic)
     : CSSValue(PrimitiveClass)
 {
     m_primitiveUnitType = CSS_VALUE_ID;
     switch (italic) {
-    case FontItalicOff:
+    case FontStyleNormal:
         m_value.valueID = CSSValueNormal;
         return;
-    case FontItalicOn:
+    case FontStyleItalic:
         m_value.valueID = CSSValueItalic;
         return;
     }
@@ -3499,32 +3499,32 @@
     m_value.valueID = CSSValueNormal;
 }
 
-template<> inline CSSPrimitiveValue::operator FontItalic() const
+template<> inline CSSPrimitiveValue::operator FontStyle() const
 {
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueOblique:
     // FIXME: oblique is the same as italic for the moment...
     case CSSValueItalic:
-        return FontItalicOn;
+        return FontStyleItalic;
     case CSSValueNormal:
-        return FontItalicOff;
+        return FontStyleNormal;
     default:
         break;
     }
     ASSERT_NOT_REACHED();
-    return FontItalicOff;
+    return FontStyleNormal;
 }
 
-template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontSmallCaps smallCaps)
+template<> inline CSSPrimitiveValue::CSSPrimitiveValue(FontVariant smallCaps)
     : CSSValue(PrimitiveClass)
 {
     m_primitiveUnitType = CSS_VALUE_ID;
     switch (smallCaps) {
-    case FontSmallCapsOff:
+    case FontVariantNormal:
         m_value.valueID = CSSValueNormal;
         return;
-    case FontSmallCapsOn:
+    case FontVariantSmallCaps:
         m_value.valueID = CSSValueSmallCaps;
         return;
     }
@@ -3533,19 +3533,19 @@
     m_value.valueID = CSSValueNormal;
 }
 
-template<> inline CSSPrimitiveValue::operator FontSmallCaps() const
+template<> inline CSSPrimitiveValue::operator FontVariant() const
 {
     ASSERT(isValueID());
     switch (m_value.valueID) {
     case CSSValueSmallCaps:
-        return FontSmallCapsOn;
+        return FontVariantSmallCaps;
     case CSSValueNormal:
-        return FontSmallCapsOff;
+        return FontVariantNormal;
     default:
         break;
     }
     ASSERT_NOT_REACHED();
-    return FontSmallCapsOff;
+    return FontVariantNormal;
 }
 
 template<> inline CSSPrimitiveValue::CSSPrimitiveValue(TextRenderingMode e)
@@ -4702,6 +4702,8 @@
         return TouchActionPanX;
     case CSSValuePanY:
         return TouchActionPanY;
+    case CSSValueManipulation:
+        return TouchActionPanX | TouchActionPanY | TouchActionPinchZoom;
     default:
         break;
     }
diff --git a/Source/core/css/CSSProperties.in b/Source/core/css/CSSProperties.in
index b3926cd..0dc65ce 100644
--- a/Source/core/css/CSSProperties.in
+++ b/Source/core/css/CSSProperties.in
@@ -56,10 +56,10 @@
 flex-wrap
 float type_name=EFloat, name_for_methods=Floating
 font-family custom_all
-font-kerning custom_all
+font-kerning font, type_name=FontDescription::Kerning, name_for_methods=Kerning
 font-size custom_all
-font-style custom_all
-font-variant custom_all
+font-style font, type_name=FontStyle, name_for_methods=Style
+font-variant font, type_name=FontVariant, name_for_methods=Variant
 font-variant-ligatures custom_all
 font-weight custom_all
 grid-auto-flow type_name=GridAutoFlow
@@ -125,7 +125,7 @@
 text-indent custom_all
 text-justify type_name=TextJustify
 text-overflow type_name=TextOverflow
-text-rendering custom_all
+text-rendering font, type_name=TextRenderingMode
 text-shadow converter=convertShadow
 text-transform
 top type_name=Length, initial=initialOffset, converter=convertLengthOrAuto
@@ -137,6 +137,7 @@
 white-space
 widows type_name=short, custom_all
 width type_name=Length, initial=initialSize, converter=convertLengthSizing
+will-change custom_all
 word-break
 word-spacing type_name=float, initial=initialLetterWordSpacing, converter=convertSpacing
 // UAs must treat 'word-wrap' as an alternate name for the 'overflow-wrap' property. So using the same handlers.
@@ -187,7 +188,7 @@
 -webkit-column-rule-width type_name=unsigned short, converter=convertLineWidth<unsigned short>
 -webkit-column-span type_name=ColumnSpan
 -webkit-column-width type_name=float, custom_all
--webkit-font-smoothing custom_all
+-webkit-font-smoothing font, type_name=FontSmoothingMode
 -webkit-highlight type_name=AtomicString, converter=convertString<CSSValueNone>
 -webkit-hyphenate-character type_name=AtomicString, name_for_methods=HyphenationString, converter=convertString<CSSValueAuto>
 -webkit-line-break type_name=LineBreak
diff --git a/Source/core/css/CSSProperty.cpp b/Source/core/css/CSSProperty.cpp
index 337d26f..252ede8 100644
--- a/Source/core/css/CSSProperty.cpp
+++ b/Source/core/css/CSSProperty.cpp
@@ -47,7 +47,7 @@
 
 void CSSProperty::wrapValueInCommaSeparatedList()
 {
-    RefPtr<CSSValue> value = m_value.release();
+    RefPtrWillBeRawPtr<CSSValue> value = m_value.release();
     m_value = CSSValueList::createCommaSeparated();
     toCSSValueList(m_value.get())->append(value.release());
 }
@@ -665,6 +665,7 @@
     case CSSPropertyWebkitWrapThrough:
     case CSSPropertyWebkitAppRegion:
     case CSSPropertyWidth:
+    case CSSPropertyWillChange:
     case CSSPropertyMaxZoom:
     case CSSPropertyMinZoom:
     case CSSPropertyOrientation:
diff --git a/Source/core/css/CSSProperty.h b/Source/core/css/CSSProperty.h
index 0f391d8..4f6a40c 100644
--- a/Source/core/css/CSSProperty.h
+++ b/Source/core/css/CSSProperty.h
@@ -53,8 +53,9 @@
 };
 
 class CSSProperty {
+    ALLOW_ONLY_INLINE_ALLOCATION();
 public:
-    CSSProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> value, bool important = false, bool isSetFromShorthand = false, int indexInShorthandsVector = 0, bool implicit = false)
+    CSSProperty(CSSPropertyID propertyID, PassRefPtrWillBeRawPtr<CSSValue> value, bool important = false, bool isSetFromShorthand = false, int indexInShorthandsVector = 0, bool implicit = false)
         : m_metadata(propertyID, isSetFromShorthand, indexInShorthandsVector, important, implicit, isInheritedProperty(propertyID))
         , m_value(value)
     {
@@ -81,9 +82,11 @@
 
     const StylePropertyMetadata& metadata() const { return m_metadata; }
 
+    void trace(Visitor* visitor) { visitor->trace(m_value); }
+
 private:
     StylePropertyMetadata m_metadata;
-    RefPtr<CSSValue> m_value;
+    RefPtrWillBeMember<CSSValue> m_value;
 };
 
 inline CSSPropertyID prefixingVariantForPropertyId(CSSPropertyID propId)
diff --git a/Source/core/css/CSSPropertyNames.in b/Source/core/css/CSSPropertyNames.in
index a172b0a..8b9d78c 100644
--- a/Source/core/css/CSSPropertyNames.in
+++ b/Source/core/css/CSSPropertyNames.in
@@ -226,6 +226,7 @@
 white-space
 widows
 width
+will-change
 word-break
 -epub-word-break alias_for=word-break
 word-spacing
diff --git a/Source/core/css/CSSReflectValue.cpp b/Source/core/css/CSSReflectValue.cpp
index cbb2cdd..5df3254 100644
--- a/Source/core/css/CSSReflectValue.cpp
+++ b/Source/core/css/CSSReflectValue.cpp
@@ -50,6 +50,7 @@
 {
     visitor->trace(m_direction);
     visitor->trace(m_offset);
+    visitor->trace(m_mask);
     CSSValue::traceAfterDispatch(visitor);
 }
 
diff --git a/Source/core/css/CSSReflectValue.h b/Source/core/css/CSSReflectValue.h
index a810242..fa49a49 100644
--- a/Source/core/css/CSSReflectValue.h
+++ b/Source/core/css/CSSReflectValue.h
@@ -37,9 +37,9 @@
 class CSSReflectValue : public CSSValue {
 public:
     static PassRefPtrWillBeRawPtr<CSSReflectValue> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> direction,
-        PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask)
+        PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, PassRefPtrWillBeRawPtr<CSSValue> mask)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSReflectValue(direction, offset, mask));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSReflectValue(direction, offset, mask));
     }
 
     CSSPrimitiveValue* direction() const { return m_direction.get(); }
@@ -53,7 +53,7 @@
     void traceAfterDispatch(Visitor*);
 
 private:
-    CSSReflectValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> direction, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, PassRefPtr<CSSValue> mask)
+    CSSReflectValue(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> direction, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> offset, PassRefPtrWillBeRawPtr<CSSValue> mask)
         : CSSValue(ReflectClass)
         , m_direction(direction)
         , m_offset(offset)
@@ -63,7 +63,7 @@
 
     RefPtrWillBeMember<CSSPrimitiveValue> m_direction;
     RefPtrWillBeMember<CSSPrimitiveValue> m_offset;
-    RefPtr<CSSValue> m_mask;
+    RefPtrWillBeMember<CSSValue> m_mask;
 };
 
 DEFINE_CSS_VALUE_TYPE_CASTS(CSSReflectValue, isReflectValue());
diff --git a/Source/core/css/CSSRule.cpp b/Source/core/css/CSSRule.cpp
index 8819570..60aa695 100644
--- a/Source/core/css/CSSRule.cpp
+++ b/Source/core/css/CSSRule.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-struct SameSizeAsCSSRule : public RefCounted<SameSizeAsCSSRule> {
+struct SameSizeAsCSSRule : public RefCountedWillBeGarbageCollectedFinalized<SameSizeAsCSSRule> {
     virtual ~SameSizeAsCSSRule();
     unsigned char bitfields;
     void* pointerUnion;
@@ -50,4 +50,15 @@
     return styleSheet ? styleSheet->contents()->parserContext() : strictCSSParserContext();
 }
 
+void CSSRule::trace(Visitor* visitor)
+{
+    // This makes the parent link strong, which is different from the
+    // pre-oilpan world, where the parent link is mysteriously zeroed under
+    // some circumstances.
+    if (m_parentIsRule)
+        visitor->trace(m_parentRule);
+    else
+        visitor->trace(m_parentStyleSheet);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSRule.h b/Source/core/css/CSSRule.h
index a66dc50..ec9b39c 100644
--- a/Source/core/css/CSSRule.h
+++ b/Source/core/css/CSSRule.h
@@ -23,6 +23,8 @@
 #ifndef CSSRule_h
 #define CSSRule_h
 
+#include "heap/Handle.h"
+#include "heap/Visitor.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
@@ -32,7 +34,7 @@
 class CSSStyleSheet;
 class StyleRuleBase;
 
-class CSSRule : public RefCounted<CSSRule> {
+class CSSRule : public RefCountedWillBeGarbageCollectedFinalized<CSSRule> {
 public:
     virtual ~CSSRule() { }
 
@@ -72,6 +74,8 @@
         m_parentRule = rule;
     }
 
+    virtual void trace(Visitor*);
+
     CSSStyleSheet* parentStyleSheet() const
     {
         if (m_parentIsRule)
@@ -101,6 +105,7 @@
     mutable unsigned char m_hasCachedSelectorText : 1;
     unsigned char m_parentIsRule : 1;
 
+    // These should be Members, but no Members in unions.
     union {
         CSSRule* m_parentRule;
         CSSStyleSheet* m_parentStyleSheet;
diff --git a/Source/core/css/CSSRule.idl b/Source/core/css/CSSRule.idl
index 494e16a..a70bd3e 100644
--- a/Source/core/css/CSSRule.idl
+++ b/Source/core/css/CSSRule.idl
@@ -22,6 +22,7 @@
 [
     Custom=Wrap,
     DependentLifetime,
+    WillBeGarbageCollected,
 ] interface CSSRule {
 
     // RuleType
diff --git a/Source/core/css/CSSRuleList.cpp b/Source/core/css/CSSRuleList.cpp
index 499518b..21bf906 100644
--- a/Source/core/css/CSSRuleList.cpp
+++ b/Source/core/css/CSSRuleList.cpp
@@ -35,7 +35,9 @@
 }
 
 StaticCSSRuleList::StaticCSSRuleList()
+#if !ENABLE(OILPAN)
     : m_refCount(1)
+#endif
 {
 }
 
@@ -43,11 +45,19 @@
 {
 }
 
+#if !ENABLE(OILPAN)
 void StaticCSSRuleList::deref()
 {
     ASSERT(m_refCount);
     if (!--m_refCount)
         delete this;
 }
+#endif
+
+void StaticCSSRuleList::trace(Visitor* visitor)
+{
+    visitor->trace(m_rules);
+}
+
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSRuleList.h b/Source/core/css/CSSRuleList.h
index ca26dc3..7ba94ef 100644
--- a/Source/core/css/CSSRuleList.h
+++ b/Source/core/css/CSSRuleList.h
@@ -22,6 +22,7 @@
 #ifndef CSSRuleList_h
 #define CSSRuleList_h
 
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
@@ -31,34 +32,46 @@
 class CSSRule;
 class CSSStyleSheet;
 
-class CSSRuleList {
-    WTF_MAKE_NONCOPYABLE(CSSRuleList); WTF_MAKE_FAST_ALLOCATED;
+class CSSRuleList : public NoBaseWillBeGarbageCollectedFinalized<CSSRuleList> {
+    WTF_MAKE_NONCOPYABLE(CSSRuleList);
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
     virtual ~CSSRuleList();
 
+#if !ENABLE(OILPAN)
     virtual void ref() = 0;
     virtual void deref() = 0;
+#endif
 
     virtual unsigned length() const = 0;
     virtual CSSRule* item(unsigned index) const = 0;
 
     virtual CSSStyleSheet* styleSheet() const = 0;
 
+    virtual void trace(Visitor*) = 0;
+
 protected:
     CSSRuleList();
 };
 
 class StaticCSSRuleList FINAL : public CSSRuleList {
 public:
-    static PassRefPtr<StaticCSSRuleList> create() { return adoptRef(new StaticCSSRuleList()); }
+    static PassRefPtrWillBeRawPtr<StaticCSSRuleList> create()
+    {
+        return adoptRefWillBeNoop(new StaticCSSRuleList());
+    }
 
+#if !ENABLE(OILPAN)
     virtual void ref() OVERRIDE { ++m_refCount; }
     virtual void deref() OVERRIDE;
+#endif
 
-    Vector<RefPtr<CSSRule> >& rules() { return m_rules; }
+    WillBeHeapVector<RefPtrWillBeMember<CSSRule> >& rules() { return m_rules; }
 
     virtual CSSStyleSheet* styleSheet() const OVERRIDE { return 0; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     StaticCSSRuleList();
     virtual ~StaticCSSRuleList();
@@ -66,25 +79,38 @@
     virtual unsigned length() const OVERRIDE { return m_rules.size(); }
     virtual CSSRule* item(unsigned index) const OVERRIDE { return index < m_rules.size() ? m_rules[index].get() : 0; }
 
-    Vector<RefPtr<CSSRule> > m_rules;
+    WillBeHeapVector<RefPtrWillBeMember<CSSRule> > m_rules;
+#if !ENABLE(OILPAN)
     unsigned m_refCount;
+#endif
 };
 
-// The rule owns the live list.
 template <class Rule>
 class LiveCSSRuleList FINAL : public CSSRuleList {
 public:
-    LiveCSSRuleList(Rule* rule) : m_rule(rule) { }
+    static PassOwnPtrWillBeRawPtr<LiveCSSRuleList> create(Rule* rule)
+    {
+        return adoptPtrWillBeNoop(new LiveCSSRuleList(rule));
+    }
 
+#if !ENABLE(OILPAN)
     virtual void ref() OVERRIDE { m_rule->ref(); }
     virtual void deref() OVERRIDE { m_rule->deref(); }
+#endif
+
+    virtual void trace(Visitor* visitor) OVERRIDE
+    {
+        visitor->trace(m_rule);
+    }
 
 private:
+    LiveCSSRuleList(Rule* rule) : m_rule(rule) { }
+
     virtual unsigned length() const OVERRIDE { return m_rule->length(); }
     virtual CSSRule* item(unsigned index) const OVERRIDE { return m_rule->item(index); }
     virtual CSSStyleSheet* styleSheet() const OVERRIDE { return m_rule->parentStyleSheet(); }
 
-    Rule* m_rule;
+    RawPtrWillBeMember<Rule> m_rule;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSRuleList.idl b/Source/core/css/CSSRuleList.idl
index dd18910..35fb400 100644
--- a/Source/core/css/CSSRuleList.idl
+++ b/Source/core/css/CSSRuleList.idl
@@ -25,7 +25,8 @@
 
 // Introduced in DOM Level 2:
 [
-    DependentLifetime
+    DependentLifetime,
+    WillBeGarbageCollected,
 ] interface CSSRuleList {
     readonly attribute unsigned long    length;
     getter CSSRule           item(unsigned long index);
diff --git a/Source/core/css/CSSSVGDocumentValue.h b/Source/core/css/CSSSVGDocumentValue.h
index 386d4df..2e23b0d 100644
--- a/Source/core/css/CSSSVGDocumentValue.h
+++ b/Source/core/css/CSSSVGDocumentValue.h
@@ -37,7 +37,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSSVGDocumentValue> create(const String& url)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSSVGDocumentValue(url));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSSVGDocumentValue(url));
     }
     ~CSSSVGDocumentValue();
 
diff --git a/Source/core/css/CSSSegmentedFontFace.cpp b/Source/core/css/CSSSegmentedFontFace.cpp
index f6d2f8a..6f1ad97 100644
--- a/Source/core/css/CSSSegmentedFontFace.cpp
+++ b/Source/core/css/CSSSegmentedFontFace.cpp
@@ -36,9 +36,9 @@
 
 namespace WebCore {
 
-CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector, FontTraitsMask traitsMask)
+CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector, FontTraits traits)
     : m_fontSelector(fontSelector)
-    , m_traitsMask(traitsMask)
+    , m_traits(traits)
     , m_firstNonCssConnectedFace(m_fontFaces.end())
 {
 }
@@ -71,8 +71,6 @@
 
 void CSSSegmentedFontFace::fontLoaded(CSSFontFace*)
 {
-    m_fontSelector->fontLoaded();
-
     pruneTable();
 
     if (RuntimeEnabledFeatures::fontLoadEventsEnabled() && !isLoading()) {
@@ -87,6 +85,12 @@
     }
 }
 
+void CSSSegmentedFontFace::fontLoadWaitLimitExceeded(CSSFontFace*)
+{
+    m_fontSelector->fontLoaded();
+    pruneTable();
+}
+
 void CSSSegmentedFontFace::addFontFace(PassRefPtr<FontFace> prpFontFace, bool cssConnected)
 {
     RefPtr<FontFace> fontFace = prpFontFace;
@@ -133,13 +137,13 @@
 PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription)
 {
     if (!isValid())
-        return 0;
+        return nullptr;
 
-    FontTraitsMask desiredTraitsMask = fontDescription.traitsMask();
+    FontTraits desiredTraits = fontDescription.traits();
     AtomicString emptyFontFamily = "";
-    FontCacheKey key = fontDescription.cacheKey(emptyFontFamily, desiredTraitsMask);
+    FontCacheKey key = fontDescription.cacheKey(emptyFontFamily, desiredTraits);
 
-    RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), 0).storedValue->value;
+    RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), nullptr).storedValue->value;
     if (fontData && fontData->numRanges())
         return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
 
@@ -147,9 +151,9 @@
         fontData = SegmentedFontData::create();
 
     FontDescription requestedFontDescription(fontDescription);
-    requestedFontDescription.setTraitsMask(m_traitsMask);
-    requestedFontDescription.setSyntheticBold(!(m_traitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)) && (desiredTraitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)));
-    requestedFontDescription.setSyntheticItalic(!(m_traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask));
+    requestedFontDescription.setTraits(m_traits);
+    requestedFontDescription.setSyntheticBold(m_traits.weight() < FontWeight600 && desiredTraits.weight() >= FontWeight600);
+    requestedFontDescription.setSyntheticItalic(m_traits.style() == FontStyleNormal && desiredTraits.style() == FontStyleItalic);
 
     for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) {
         if (!(*it)->cssFontFace()->isValid())
@@ -159,7 +163,7 @@
 #if ENABLE(SVG_FONTS)
             // For SVG Fonts that specify that they only support the "normal" variant, we will assume they are incapable
             // of small-caps synthesis and just ignore the font face.
-            if (faceFontData->isSVGFont() && (desiredTraitsMask & FontVariantSmallCapsMask) && !(m_traitsMask & FontVariantSmallCapsMask))
+            if (faceFontData->isSVGFont() && desiredTraits.variant() == FontVariantSmallCaps && m_traits.variant() == FontVariantNormal)
                 continue;
 #endif
             appendFontData(fontData.get(), faceFontData.release(), (*it)->cssFontFace()->ranges());
@@ -168,7 +172,7 @@
     if (fontData->numRanges())
         return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
 
-    return 0;
+    return nullptr;
 }
 
 bool CSSSegmentedFontFace::isLoading() const
diff --git a/Source/core/css/CSSSegmentedFontFace.h b/Source/core/css/CSSSegmentedFontFace.h
index 52b443e..18b49c6 100644
--- a/Source/core/css/CSSSegmentedFontFace.h
+++ b/Source/core/css/CSSSegmentedFontFace.h
@@ -26,7 +26,7 @@
 #ifndef CSSSegmentedFontFace_h
 #define CSSSegmentedFontFace_h
 
-#include "platform/fonts/FontTraitsMask.h"
+#include "platform/fonts/FontTraits.h"
 #include "wtf/HashMap.h"
 #include "wtf/ListHashSet.h"
 #include "wtf/PassRefPtr.h"
@@ -45,13 +45,17 @@
 
 class CSSSegmentedFontFace : public RefCounted<CSSSegmentedFontFace> {
 public:
-    static PassRefPtr<CSSSegmentedFontFace> create(CSSFontSelector* selector, FontTraitsMask traitsMask) { return adoptRef(new CSSSegmentedFontFace(selector, traitsMask)); }
+    static PassRefPtr<CSSSegmentedFontFace> create(CSSFontSelector* selector, FontTraits traits)
+    {
+        return adoptRef(new CSSSegmentedFontFace(selector, traits));
+    }
     ~CSSSegmentedFontFace();
 
     CSSFontSelector* fontSelector() const { return m_fontSelector; }
-    FontTraitsMask traitsMask() const { return m_traitsMask; }
+    FontTraits traits() const { return m_traits; }
 
     void fontLoaded(CSSFontFace*);
+    void fontLoadWaitLimitExceeded(CSSFontFace*);
 
     void addFontFace(PassRefPtr<FontFace>, bool cssConnected);
     void removeFontFace(PassRefPtr<FontFace>);
@@ -71,7 +75,7 @@
     void willUseFontData(const FontDescription&);
 
 private:
-    CSSSegmentedFontFace(CSSFontSelector*, FontTraitsMask);
+    CSSSegmentedFontFace(CSSFontSelector*, FontTraits);
 
     void pruneTable();
     bool isValid() const;
@@ -81,7 +85,7 @@
     typedef ListHashSet<RefPtr<FontFace> > FontFaceList;
 
     CSSFontSelector* m_fontSelector;
-    FontTraitsMask m_traitsMask;
+    FontTraits m_traits;
     HashMap<unsigned, RefPtr<SegmentedFontData> > m_fontDataTable;
     // All non-CSS-connected FontFaces are stored after the CSS-connected ones.
     FontFaceList m_fontFaces;
diff --git a/Source/core/css/CSSSelector.cpp b/Source/core/css/CSSSelector.cpp
index 845ba54..81f8d1c 100644
--- a/Source/core/css/CSSSelector.cpp
+++ b/Source/core/css/CSSSelector.cpp
@@ -252,7 +252,6 @@
     case PseudoPastCue:
     case PseudoDistributed:
     case PseudoUnresolved:
-    case PseudoContent:
     case PseudoHost:
     case PseudoAncestor:
     case PseudoFullScreen:
@@ -268,176 +267,119 @@
     return NOPSEUDO;
 }
 
+// Could be made smaller and faster by replacing pointer with an
+// offset into a string buffer and making the bit fields smaller but
+// that could not be maintained by hand.
+struct NameToPseudoStruct {
+    const char* string;
+    unsigned type:8;
+    unsigned requirement:8;
+};
+
+const static NameToPseudoStruct pseudoTypeMap[] = {
+{"active",                        CSSSelector::PseudoActive,              0},
+{"after",                         CSSSelector::PseudoAfter,               0},
+{"-webkit-any(",                  CSSSelector::PseudoAny,                 0},
+{"-webkit-any-link",              CSSSelector::PseudoAnyLink,             0},
+{"-webkit-autofill",              CSSSelector::PseudoAutofill,            0},
+{"backdrop",                      CSSSelector::PseudoBackdrop,            0},
+{"before",                        CSSSelector::PseudoBefore,              0},
+{"checked",                       CSSSelector::PseudoChecked,             0},
+{"default",                       CSSSelector::PseudoDefault,             0},
+{"disabled",                      CSSSelector::PseudoDisabled,            0},
+{"read-only",                     CSSSelector::PseudoReadOnly,            0},
+{"read-write",                    CSSSelector::PseudoReadWrite,           0},
+{"valid",                         CSSSelector::PseudoValid,               0},
+{"invalid",                       CSSSelector::PseudoInvalid,             0},
+{"-webkit-drag",                  CSSSelector::PseudoDrag,                0},
+{"empty",                         CSSSelector::PseudoEmpty,               0},
+{"enabled",                       CSSSelector::PseudoEnabled,             0},
+{"first-child",                   CSSSelector::PseudoFirstChild,          0},
+{"first-letter",                  CSSSelector::PseudoFirstLetter,         0},
+{"first-line",                    CSSSelector::PseudoFirstLine,           0},
+{"first-of-type",                 CSSSelector::PseudoFirstOfType,         0},
+{"-webkit-full-page-media",       CSSSelector::PseudoFullPageMedia,       0},
+{"nth-child(",                    CSSSelector::PseudoNthChild,            0},
+{"nth-of-type(",                  CSSSelector::PseudoNthOfType,           0},
+{"nth-last-child(",               CSSSelector::PseudoNthLastChild,        0},
+{"nth-last-of-type(",             CSSSelector::PseudoNthLastOfType,       0},
+{"focus",                         CSSSelector::PseudoFocus,               0},
+{"hover",                         CSSSelector::PseudoHover,               0},
+{"indeterminate",                 CSSSelector::PseudoIndeterminate,       0},
+{"last-child",                    CSSSelector::PseudoLastChild,           0},
+{"last-of-type",                  CSSSelector::PseudoLastOfType,          0},
+{"link",                          CSSSelector::PseudoLink,                0},
+{"lang(",                         CSSSelector::PseudoLang,                0},
+{"not(",                          CSSSelector::PseudoNot,                 0},
+{"only-child",                    CSSSelector::PseudoOnlyChild,           0},
+{"only-of-type",                  CSSSelector::PseudoOnlyOfType,          0},
+{"optional",                      CSSSelector::PseudoOptional,            0},
+{"required",                      CSSSelector::PseudoRequired,            0},
+{"-webkit-resizer",               CSSSelector::PseudoResizer,             0},
+{"root",                          CSSSelector::PseudoRoot,                0},
+{"-webkit-scrollbar",             CSSSelector::PseudoScrollbar,           0},
+{"-webkit-scrollbar-button",      CSSSelector::PseudoScrollbarButton,     0},
+{"-webkit-scrollbar-corner",      CSSSelector::PseudoScrollbarCorner,     0},
+{"-webkit-scrollbar-thumb",       CSSSelector::PseudoScrollbarThumb,      0},
+{"-webkit-scrollbar-track",       CSSSelector::PseudoScrollbarTrack,      0},
+{"-webkit-scrollbar-track-piece", CSSSelector::PseudoScrollbarTrackPiece, 0},
+{"selection",                     CSSSelector::PseudoSelection,           0},
+{"target",                        CSSSelector::PseudoTarget,              0},
+{"visited",                       CSSSelector::PseudoVisited,             0},
+{"window-inactive",               CSSSelector::PseudoWindowInactive,      0},
+{"decrement",                     CSSSelector::PseudoDecrement,           0},
+{"increment",                     CSSSelector::PseudoIncrement,           0},
+{"start",                         CSSSelector::PseudoStart,               0},
+{"end",                           CSSSelector::PseudoEnd,                 0},
+{"horizontal",                    CSSSelector::PseudoHorizontal,          0},
+{"vertical",                      CSSSelector::PseudoVertical,            0},
+{"double-button",                 CSSSelector::PseudoDoubleButton,        0},
+{"single-button",                 CSSSelector::PseudoSingleButton,        0},
+{"no-button",                     CSSSelector::PseudoNoButton,            0},
+{"corner-present",                CSSSelector::PseudoCornerPresent,       0},
+{"first",                         CSSSelector::PseudoFirstPage,           0},
+{"left",                          CSSSelector::PseudoLeftPage,            0},
+{"right",                         CSSSelector::PseudoRightPage,           0},
+{"-webkit-full-screen",           CSSSelector::PseudoFullScreen,          0},
+{"-webkit-full-screen-document",  CSSSelector::PseudoFullScreenDocument,  0},
+{"-webkit-full-screen-ancestor",  CSSSelector::PseudoFullScreenAncestor,  0},
+{"cue(",                          CSSSelector::PseudoCue,                 0},
+{"cue",                           CSSSelector::PseudoWebKitCustomElement, 0},
+{"future",                        CSSSelector::PseudoFutureCue,           0},
+{"past",                          CSSSelector::PseudoPastCue,             0},
+{"-webkit-distributed(",          CSSSelector::PseudoDistributed,         0},
+{"in-range",                      CSSSelector::PseudoInRange,             0},
+{"out-of-range",                  CSSSelector::PseudoOutOfRange,          0},
+{"scope",                         CSSSelector::PseudoScope,               0},
+{"unresolved",                    CSSSelector::PseudoUnresolved,          0},
+{"host",                          CSSSelector::PseudoHost,                CSSSelector::RequiresShadowDOM},
+{"host(",                         CSSSelector::PseudoHost,                CSSSelector::RequiresShadowDOM},
+{"ancestor",                      CSSSelector::PseudoAncestor,            CSSSelector::RequiresShadowDOM},
+{"ancestor(",                     CSSSelector::PseudoAncestor,            CSSSelector::RequiresShadowDOM},
+};
+
 static HashMap<StringImpl*, CSSSelector::PseudoType>* nameToPseudoTypeMap()
 {
-    DEFINE_STATIC_LOCAL(AtomicString, active, ("active", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, after, ("after", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, any, ("-webkit-any(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, anyLink, ("-webkit-any-link", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, autofill, ("-webkit-autofill", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, backdrop, ("backdrop", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, before, ("before", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, checked, ("checked", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, defaultString, ("default", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, disabled, ("disabled", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, readOnly, ("read-only", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, readWrite, ("read-write", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, valid, ("valid", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, invalid, ("invalid", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, drag, ("-webkit-drag", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, empty, ("empty", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, enabled, ("enabled", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, firstChild, ("first-child", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, firstLetter, ("first-letter", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, firstLine, ("first-line", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, firstOfType, ("first-of-type", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, fullPageMedia, ("-webkit-full-page-media", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, nthChild, ("nth-child(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, nthOfType, ("nth-of-type(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, nthLastChild, ("nth-last-child(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, nthLastOfType, ("nth-last-of-type(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, focus, ("focus", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, hover, ("hover", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, indeterminate, ("indeterminate", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, lastChild, ("last-child", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, lastOfType, ("last-of-type", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, link, ("link", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, lang, ("lang(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, notStr, ("not(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, onlyChild, ("only-child", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, onlyOfType, ("only-of-type", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, optional, ("optional", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, required, ("required", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, resizer, ("-webkit-resizer", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, root, ("root", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, scrollbar, ("-webkit-scrollbar", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, scrollbarButton, ("-webkit-scrollbar-button", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, scrollbarCorner, ("-webkit-scrollbar-corner", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, scrollbarThumb, ("-webkit-scrollbar-thumb", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrack, ("-webkit-scrollbar-track", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, scrollbarTrackPiece, ("-webkit-scrollbar-track-piece", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, selection, ("selection", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, target, ("target", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, visited, ("visited", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, windowInactive, ("window-inactive", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, decrement, ("decrement", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, increment, ("increment", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, start, ("start", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, end, ("end", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, horizontal, ("horizontal", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, vertical, ("vertical", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, doubleButton, ("double-button", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, singleButton, ("single-button", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, noButton, ("no-button", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, cornerPresent, ("corner-present", AtomicString::ConstructFromLiteral));
-    // Paged Media pseudo-classes
-    DEFINE_STATIC_LOCAL(AtomicString, firstPage, ("first", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, leftPage, ("left", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, rightPage, ("right", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, fullScreen, ("-webkit-full-screen", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, fullScreenDocument, ("-webkit-full-screen-document", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, fullScreenAncestor, ("-webkit-full-screen-ancestor", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, cue, ("cue(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, cueWithoutParen, ("cue", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, futureCue, ("future", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, pastCue, ("past", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, distributed, ("-webkit-distributed(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, inRange, ("in-range", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, outOfRange, ("out-of-range", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, scope, ("scope", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, unresolved, ("unresolved", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, content, ("content", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, host, ("host", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, hostWithParams, ("host(", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, ancestor, ("ancestor", AtomicString::ConstructFromLiteral));
-    DEFINE_STATIC_LOCAL(AtomicString, ancestorWithParams, ("ancestor(", AtomicString::ConstructFromLiteral));
-
     static HashMap<StringImpl*, CSSSelector::PseudoType>* nameToPseudoType = 0;
     if (!nameToPseudoType) {
         nameToPseudoType = new HashMap<StringImpl*, CSSSelector::PseudoType>;
-        nameToPseudoType->set(active.impl(), CSSSelector::PseudoActive);
-        nameToPseudoType->set(after.impl(), CSSSelector::PseudoAfter);
-        nameToPseudoType->set(anyLink.impl(), CSSSelector::PseudoAnyLink);
-        nameToPseudoType->set(any.impl(), CSSSelector::PseudoAny);
-        nameToPseudoType->set(autofill.impl(), CSSSelector::PseudoAutofill);
-        nameToPseudoType->set(backdrop.impl(), CSSSelector::PseudoBackdrop);
-        nameToPseudoType->set(before.impl(), CSSSelector::PseudoBefore);
-        nameToPseudoType->set(checked.impl(), CSSSelector::PseudoChecked);
-        nameToPseudoType->set(defaultString.impl(), CSSSelector::PseudoDefault);
-        nameToPseudoType->set(disabled.impl(), CSSSelector::PseudoDisabled);
-        nameToPseudoType->set(readOnly.impl(), CSSSelector::PseudoReadOnly);
-        nameToPseudoType->set(readWrite.impl(), CSSSelector::PseudoReadWrite);
-        nameToPseudoType->set(valid.impl(), CSSSelector::PseudoValid);
-        nameToPseudoType->set(invalid.impl(), CSSSelector::PseudoInvalid);
-        nameToPseudoType->set(drag.impl(), CSSSelector::PseudoDrag);
-        nameToPseudoType->set(enabled.impl(), CSSSelector::PseudoEnabled);
-        nameToPseudoType->set(empty.impl(), CSSSelector::PseudoEmpty);
-        nameToPseudoType->set(firstChild.impl(), CSSSelector::PseudoFirstChild);
-        nameToPseudoType->set(fullPageMedia.impl(), CSSSelector::PseudoFullPageMedia);
-        nameToPseudoType->set(lastChild.impl(), CSSSelector::PseudoLastChild);
-        nameToPseudoType->set(lastOfType.impl(), CSSSelector::PseudoLastOfType);
-        nameToPseudoType->set(onlyChild.impl(), CSSSelector::PseudoOnlyChild);
-        nameToPseudoType->set(onlyOfType.impl(), CSSSelector::PseudoOnlyOfType);
-        nameToPseudoType->set(firstLetter.impl(), CSSSelector::PseudoFirstLetter);
-        nameToPseudoType->set(firstLine.impl(), CSSSelector::PseudoFirstLine);
-        nameToPseudoType->set(firstOfType.impl(), CSSSelector::PseudoFirstOfType);
-        nameToPseudoType->set(focus.impl(), CSSSelector::PseudoFocus);
-        nameToPseudoType->set(hover.impl(), CSSSelector::PseudoHover);
-        nameToPseudoType->set(indeterminate.impl(), CSSSelector::PseudoIndeterminate);
-        nameToPseudoType->set(link.impl(), CSSSelector::PseudoLink);
-        nameToPseudoType->set(lang.impl(), CSSSelector::PseudoLang);
-        nameToPseudoType->set(notStr.impl(), CSSSelector::PseudoNot);
-        nameToPseudoType->set(nthChild.impl(), CSSSelector::PseudoNthChild);
-        nameToPseudoType->set(nthOfType.impl(), CSSSelector::PseudoNthOfType);
-        nameToPseudoType->set(nthLastChild.impl(), CSSSelector::PseudoNthLastChild);
-        nameToPseudoType->set(nthLastOfType.impl(), CSSSelector::PseudoNthLastOfType);
-        nameToPseudoType->set(root.impl(), CSSSelector::PseudoRoot);
-        nameToPseudoType->set(windowInactive.impl(), CSSSelector::PseudoWindowInactive);
-        nameToPseudoType->set(decrement.impl(), CSSSelector::PseudoDecrement);
-        nameToPseudoType->set(increment.impl(), CSSSelector::PseudoIncrement);
-        nameToPseudoType->set(start.impl(), CSSSelector::PseudoStart);
-        nameToPseudoType->set(end.impl(), CSSSelector::PseudoEnd);
-        nameToPseudoType->set(horizontal.impl(), CSSSelector::PseudoHorizontal);
-        nameToPseudoType->set(vertical.impl(), CSSSelector::PseudoVertical);
-        nameToPseudoType->set(doubleButton.impl(), CSSSelector::PseudoDoubleButton);
-        nameToPseudoType->set(singleButton.impl(), CSSSelector::PseudoSingleButton);
-        nameToPseudoType->set(noButton.impl(), CSSSelector::PseudoNoButton);
-        nameToPseudoType->set(optional.impl(), CSSSelector::PseudoOptional);
-        nameToPseudoType->set(required.impl(), CSSSelector::PseudoRequired);
-        nameToPseudoType->set(resizer.impl(), CSSSelector::PseudoResizer);
-        nameToPseudoType->set(scope.impl(), CSSSelector::PseudoScope);
-        nameToPseudoType->set(scrollbar.impl(), CSSSelector::PseudoScrollbar);
-        nameToPseudoType->set(scrollbarButton.impl(), CSSSelector::PseudoScrollbarButton);
-        nameToPseudoType->set(scrollbarCorner.impl(), CSSSelector::PseudoScrollbarCorner);
-        nameToPseudoType->set(scrollbarThumb.impl(), CSSSelector::PseudoScrollbarThumb);
-        nameToPseudoType->set(scrollbarTrack.impl(), CSSSelector::PseudoScrollbarTrack);
-        nameToPseudoType->set(scrollbarTrackPiece.impl(), CSSSelector::PseudoScrollbarTrackPiece);
-        nameToPseudoType->set(cornerPresent.impl(), CSSSelector::PseudoCornerPresent);
-        nameToPseudoType->set(selection.impl(), CSSSelector::PseudoSelection);
-        nameToPseudoType->set(target.impl(), CSSSelector::PseudoTarget);
-        nameToPseudoType->set(visited.impl(), CSSSelector::PseudoVisited);
-        nameToPseudoType->set(firstPage.impl(), CSSSelector::PseudoFirstPage);
-        nameToPseudoType->set(leftPage.impl(), CSSSelector::PseudoLeftPage);
-        nameToPseudoType->set(rightPage.impl(), CSSSelector::PseudoRightPage);
-        nameToPseudoType->set(fullScreen.impl(), CSSSelector::PseudoFullScreen);
-        nameToPseudoType->set(fullScreenDocument.impl(), CSSSelector::PseudoFullScreenDocument);
-        nameToPseudoType->set(fullScreenAncestor.impl(), CSSSelector::PseudoFullScreenAncestor);
-        nameToPseudoType->set(cue.impl(), CSSSelector::PseudoCue);
-        nameToPseudoType->set(cueWithoutParen.impl(), CSSSelector::PseudoWebKitCustomElement);
-        nameToPseudoType->set(futureCue.impl(), CSSSelector::PseudoFutureCue);
-        nameToPseudoType->set(pastCue.impl(), CSSSelector::PseudoPastCue);
-        nameToPseudoType->set(distributed.impl(), CSSSelector::PseudoDistributed);
-        nameToPseudoType->set(inRange.impl(), CSSSelector::PseudoInRange);
-        nameToPseudoType->set(outOfRange.impl(), CSSSelector::PseudoOutOfRange);
-        nameToPseudoType->set(unresolved.impl(), CSSSelector::PseudoUnresolved);
-        if (RuntimeEnabledFeatures::shadowDOMEnabled()) {
-            nameToPseudoType->set(host.impl(), CSSSelector::PseudoHost);
-            nameToPseudoType->set(hostWithParams.impl(), CSSSelector::PseudoHost);
-            nameToPseudoType->set(ancestor.impl(), CSSSelector::PseudoAncestor);
-            nameToPseudoType->set(ancestorWithParams.impl(), CSSSelector::PseudoAncestor);
-            nameToPseudoType->set(content.impl(), CSSSelector::PseudoContent);
+
+        size_t pseudoCount = WTF_ARRAY_LENGTH(pseudoTypeMap);
+        for (size_t i = 0; i < pseudoCount; i++) {
+            if (pseudoTypeMap[i].requirement == CSSSelector::RequiresShadowDOM) {
+                if (!RuntimeEnabledFeatures::shadowDOMEnabled())
+                    continue;
+            }
+
+            const char* str = pseudoTypeMap[i].string;
+            CSSSelector::PseudoType type;
+            type = static_cast<CSSSelector::PseudoType>(pseudoTypeMap[i].type);
+            // This is a one-time leak.
+            AtomicString* name = new AtomicString(str, strlen(str), AtomicString::ConstructFromLiteral);
+            nameToPseudoType->set(name->impl(), type);
         }
     }
+
     return nameToPseudoType;
 }
 
@@ -483,7 +425,7 @@
 
     if (name.startsWith("-webkit-"))
         return PseudoWebKitCustomElement;
-    if (name.startsWith("cue"))
+    if (name.startsWith("x-") || name.startsWith("cue"))
         return PseudoUserAgentCustomElement;
 
     return PseudoUnknown;
@@ -519,7 +461,6 @@
     case PseudoSelection:
     case PseudoUserAgentCustomElement:
     case PseudoWebKitCustomElement:
-    case PseudoContent:
         element = true;
         break;
     case PseudoUnknown:
@@ -701,11 +642,6 @@
         } else if (cs->m_match == CSSSelector::PseudoElement) {
             str.appendLiteral("::");
             str.append(cs->value());
-
-            if (cs->pseudoType() == PseudoContent) {
-                if (cs->relation() == CSSSelector::SubSelector && cs->tagHistory())
-                    return cs->tagHistory()->selectorText() + str.toString() + rightSide;
-            }
         } else if (cs->isAttributeSelector()) {
             str.append('[');
             const AtomicString& prefix = cs->attribute().prefix();
@@ -753,17 +689,17 @@
     if (const CSSSelector* tagHistory = cs->tagHistory()) {
         switch (cs->relation()) {
         case CSSSelector::Descendant:
-            if (cs->relationIsAffectedByPseudoContent() && tagHistory->pseudoType() != CSSSelector::PseudoContent)
+            if (cs->relationIsAffectedByPseudoContent())
                 return tagHistory->selectorText("::-webkit-distributed(" + str.toString() + rightSide + ")");
             return tagHistory->selectorText(" " + str.toString() + rightSide);
         case CSSSelector::Child:
-            if (cs->relationIsAffectedByPseudoContent() && tagHistory->pseudoType() != CSSSelector::PseudoContent)
+            if (cs->relationIsAffectedByPseudoContent())
                 return tagHistory->selectorText("::-webkit-distributed(> " + str.toString() + rightSide + ")");
             return tagHistory->selectorText(" > " + str.toString() + rightSide);
-        case CSSSelector::ChildTree:
-            return tagHistory->selectorText(" ^ " + str.toString() + rightSide);
-        case CSSSelector::DescendantTree:
-            return tagHistory->selectorText(" ^^ " + str.toString() + rightSide);
+        case CSSSelector::Shadow:
+            return tagHistory->selectorText(" /shadow/ " + str.toString() + rightSide);
+        case CSSSelector::ShadowDeep:
+            return tagHistory->selectorText(" /shadow-deep/ " + str.toString() + rightSide);
         case CSSSelector::DirectAdjacent:
             return tagHistory->selectorText(" + " + str.toString() + rightSide);
         case CSSSelector::IndirectAdjacent:
@@ -772,6 +708,8 @@
             ASSERT_NOT_REACHED();
         case CSSSelector::ShadowPseudo:
             return tagHistory->selectorText(str.toString() + rightSide);
+        case CSSSelector::ShadowContent:
+            return tagHistory->selectorText(" /content/ " + str.toString() + rightSide);
         }
     }
     return str.toString() + rightSide;
diff --git a/Source/core/css/CSSSelector.h b/Source/core/css/CSSSelector.h
index b7a1ab1..3cf279c 100644
--- a/Source/core/css/CSSSelector.h
+++ b/Source/core/css/CSSSelector.h
@@ -129,9 +129,11 @@
             IndirectAdjacent, // ~ combinator
             SubSelector, // "No space" combinator
             ShadowPseudo, // Special case of shadow DOM pseudo elements
-            // FIXME: rename ChildTree and DescendantTree when the spec for this is written down.
-            ChildTree, // ^ operator for shadow DOM
-            DescendantTree // ^^ operator for shadow DOM
+            // FIXME: implement named combinator (i.e. named relation) and
+            // replace the following /shadow/ and /shadow-deep/ with the implementation.
+            Shadow, // /shadow/ combinator
+            ShadowDeep, // /shadow-deep/ combinator
+            ShadowContent // /content/ for shadow styling
         };
 
         enum PseudoType {
@@ -215,11 +217,15 @@
             PseudoPastCue,
             PseudoDistributed,
             PseudoUnresolved,
-            PseudoContent,
             PseudoHost,
             PseudoAncestor
         };
 
+        enum OptionalPseudoTypeRequirements {
+            // 0 is used to mean "no requirements".
+            RequiresShadowDOM = 1
+        };
+
         enum MarginBoxType {
             TopLeftCornerMarginBox,
             TopLeftMarginBox,
@@ -287,7 +293,6 @@
         bool isSiblingSelector() const;
         bool isAttributeSelector() const;
         bool isDistributedPseudoElement() const;
-        bool isContentPseudoElement() const;
         bool isHostPseudoClass() const;
 
         // FIXME: selectors with no tagHistory() get a relation() of Descendant. It should instead be
@@ -308,7 +313,7 @@
         bool relationIsAffectedByPseudoContent() const { return m_relationIsAffectedByPseudoContent; }
         void setRelationIsAffectedByPseudoContent() { m_relationIsAffectedByPseudoContent = true; }
 
-        unsigned m_relation           : 3; // enum Relation
+        unsigned m_relation           : 4; // enum Relation
         mutable unsigned m_match      : 4; // enum Match
         mutable unsigned m_pseudoType : 8; // PseudoType
 
@@ -418,11 +423,6 @@
     return m_match == PseudoElement && pseudoType() == PseudoDistributed;
 }
 
-inline bool CSSSelector::isContentPseudoElement() const
-{
-    return m_match == PseudoElement && pseudoType() == PseudoContent;
-}
-
 inline void CSSSelector::setValue(const AtomicString& value)
 {
     ASSERT(m_match != Tag);
diff --git a/Source/core/css/CSSSelectorList.cpp b/Source/core/css/CSSSelectorList.cpp
index 26892fd..fe4a296 100644
--- a/Source/core/css/CSSSelectorList.cpp
+++ b/Source/core/css/CSSSelectorList.cpp
@@ -186,7 +186,7 @@
 public:
     bool operator()(const CSSSelector& selector)
     {
-        return selector.relation() == CSSSelector::ChildTree || selector.relation() == CSSSelector::DescendantTree;
+        return selector.relation() == CSSSelector::Shadow || selector.relation() == CSSSelector::ShadowDeep || selector.relation() == CSSSelector::ShadowContent;
     }
 };
 
diff --git a/Source/core/css/CSSSelectorTest.cpp b/Source/core/css/CSSSelectorTest.cpp
index baf0465..6f4e895 100644
--- a/Source/core/css/CSSSelectorTest.cpp
+++ b/Source/core/css/CSSSelectorTest.cpp
@@ -27,7 +27,7 @@
     "#id.class { }"
     "[attr]#id { }"
     "div[attr]#id { }"
-    "div::content { }"
+    "video::cue { }"
     "div::first-line { }"
     ".a.b.c { }"
     "div:not(.a) { }" // without class a
diff --git a/Source/core/css/CSSShadowValue.h b/Source/core/css/CSSShadowValue.h
index 9a76368..f29dd2b 100644
--- a/Source/core/css/CSSShadowValue.h
+++ b/Source/core/css/CSSShadowValue.h
@@ -39,7 +39,7 @@
         PassRefPtrWillBeRawPtr<CSSPrimitiveValue> style,
         PassRefPtrWillBeRawPtr<CSSPrimitiveValue> color)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSShadowValue(x, y, blur, spread, style, color));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSShadowValue(x, y, blur, spread, style, color));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSStyleDeclaration.h b/Source/core/css/CSSStyleDeclaration.h
index 9d1de6f..9f570e4 100644
--- a/Source/core/css/CSSStyleDeclaration.h
+++ b/Source/core/css/CSSStyleDeclaration.h
@@ -48,7 +48,7 @@
     virtual void setCSSText(const String&, ExceptionState&) = 0;
     virtual unsigned length() const = 0;
     virtual String item(unsigned index) const = 0;
-    virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName) = 0;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(const String& propertyName) = 0;
     virtual String getPropertyValue(const String& propertyName) = 0;
     virtual String getPropertyPriority(const String& propertyName) = 0;
     virtual String getPropertyShorthand(const String& propertyName) = 0;
@@ -59,7 +59,7 @@
     // CSSPropertyID versions of the CSSOM functions to support bindings and editing.
     // Use the non-virtual methods in the concrete subclasses when possible.
     // The CSSValue returned by this function should not be exposed to the web as it may be used by multiple documents at the same time.
-    virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) = 0;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) = 0;
     virtual String getPropertyValueInternal(CSSPropertyID) = 0;
     virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&) = 0;
 
diff --git a/Source/core/css/CSSStyleDeclaration.idl b/Source/core/css/CSSStyleDeclaration.idl
index 63bd8ff..ccc3be7 100644
--- a/Source/core/css/CSSStyleDeclaration.idl
+++ b/Source/core/css/CSSStyleDeclaration.idl
@@ -29,7 +29,7 @@
     [TreatReturnedNullStringAs=Null] DOMString          getPropertyPriority([Default=Undefined] optional DOMString propertyName);
      [RaisesException] void setProperty([Default=Undefined] optional DOMString propertyName,
                                     [TreatNullAs=NullString,Default=Undefined] optional DOMString value,
-                                    [Default=Undefined] optional DOMString priority);
+                                    [TreatNullAs=NullString,Default=NullString] optional DOMString priority);
 
     readonly attribute unsigned long    length;
     getter DOMString          item([Default=Undefined] optional unsigned long index);
diff --git a/Source/core/css/CSSStyleRule.cpp b/Source/core/css/CSSStyleRule.cpp
index a3fe6aa..8317440 100644
--- a/Source/core/css/CSSStyleRule.cpp
+++ b/Source/core/css/CSSStyleRule.cpp
@@ -113,7 +113,7 @@
     StringBuilder result;
     result.append(selectorText());
     result.appendLiteral(" { ");
-    String decls = m_styleRule->properties()->asText();
+    String decls = m_styleRule->properties().asText();
     result.append(decls);
     if (!decls.isEmpty())
         result.append(' ');
@@ -129,4 +129,10 @@
         m_propertiesCSSOMWrapper->reattach(m_styleRule->mutableProperties());
 }
 
+void CSSStyleRule::trace(Visitor* visitor)
+{
+    visitor->trace(m_styleRule);
+    CSSRule::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSStyleRule.h b/Source/core/css/CSSStyleRule.h
index 6059179..e9a9eed 100644
--- a/Source/core/css/CSSStyleRule.h
+++ b/Source/core/css/CSSStyleRule.h
@@ -23,6 +23,7 @@
 #define CSSStyleRule_h
 
 #include "core/css/CSSRule.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -32,7 +33,10 @@
 
 class CSSStyleRule FINAL : public CSSRule {
 public:
-    static PassRefPtr<CSSStyleRule> create(StyleRule* rule, CSSStyleSheet* sheet) { return adoptRef(new CSSStyleRule(rule, sheet)); }
+    static PassRefPtrWillBeRawPtr<CSSStyleRule> create(StyleRule* rule, CSSStyleSheet* sheet)
+    {
+        return adoptRefWillBeNoop(new CSSStyleRule(rule, sheet));
+    }
 
     virtual ~CSSStyleRule();
 
@@ -48,12 +52,14 @@
     // FIXME: Not CSSOM. Remove.
     StyleRule* styleRule() const { return m_styleRule.get(); }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSStyleRule(StyleRule*, CSSStyleSheet*);
 
     String generateSelectorText() const;
 
-    RefPtr<StyleRule> m_styleRule;
+    RefPtrWillBeMember<StyleRule> m_styleRule;
     mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
 };
 
diff --git a/Source/core/css/CSSStyleSheet.cpp b/Source/core/css/CSSStyleSheet.cpp
index 13adbc4..d9f73c8 100644
--- a/Source/core/css/CSSStyleSheet.cpp
+++ b/Source/core/css/CSSStyleSheet.cpp
@@ -35,9 +35,10 @@
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/Node.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/UseCounter.h"
+#include "core/html/HTMLStyleElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
+#include "core/svg/SVGStyleElement.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "wtf/text/StringBuilder.h"
 
@@ -45,18 +46,30 @@
 
 class StyleSheetCSSRuleList FINAL : public CSSRuleList {
 public:
-    StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { }
+    static PassOwnPtrWillBeRawPtr<StyleSheetCSSRuleList> create(CSSStyleSheet* sheet)
+    {
+        return adoptPtrWillBeNoop(new StyleSheetCSSRuleList(sheet));
+    }
+
+    virtual void trace(Visitor* visitor) OVERRIDE
+    {
+        visitor->trace(m_styleSheet);
+    }
 
 private:
+    StyleSheetCSSRuleList(CSSStyleSheet* sheet) : m_styleSheet(sheet) { }
+
+#if !ENABLE(OILPAN)
     virtual void ref() OVERRIDE { m_styleSheet->ref(); }
     virtual void deref() OVERRIDE { m_styleSheet->deref(); }
+#endif
 
     virtual unsigned length() const OVERRIDE { return m_styleSheet->length(); }
     virtual CSSRule* item(unsigned index) const OVERRIDE { return m_styleSheet->item(index); }
 
     virtual CSSStyleSheet* styleSheet() const OVERRIDE { return m_styleSheet; }
 
-    CSSStyleSheet* m_styleSheet;
+    RawPtrWillBeMember<CSSStyleSheet> m_styleSheet;
 };
 
 #if !ASSERT_DISABLED
@@ -65,37 +78,37 @@
     // Only these nodes can be parents of StyleSheets, and they need to call clearOwnerNode() when moved out of document.
     return !parentNode
         || parentNode->isDocumentNode()
-        || parentNode->hasTagName(HTMLNames::linkTag)
-        || parentNode->hasTagName(HTMLNames::styleTag)
-        || parentNode->hasTagName(SVGNames::styleTag)
+        || isHTMLLinkElement(*parentNode)
+        || isHTMLStyleElement(*parentNode)
+        || isSVGStyleElement(*parentNode)
         || parentNode->nodeType() == Node::PROCESSING_INSTRUCTION_NODE;
 }
 #endif
 
-PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, CSSImportRule* ownerRule)
 {
-    return adoptRef(new CSSStyleSheet(sheet, ownerRule));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet, ownerRule));
 }
 
-PassRefPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtr<StyleSheetContents> sheet, Node* ownerNode)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::create(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode)
 {
-    return adoptRef(new CSSStyleSheet(sheet, ownerNode, false, TextPosition::minimumPosition()));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet, ownerNode, false, TextPosition::minimumPosition()));
 }
 
-PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(PassRefPtr<StyleSheetContents> sheet, Node* ownerNode, const TextPosition& startPosition)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::createInline(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet, Node* ownerNode, const TextPosition& startPosition)
 {
     ASSERT(sheet);
-    return adoptRef(new CSSStyleSheet(sheet, ownerNode, true, startPosition));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet, ownerNode, true, startPosition));
 }
 
-PassRefPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const TextPosition& startPosition, const String& encoding)
+PassRefPtrWillBeRawPtr<CSSStyleSheet> CSSStyleSheet::createInline(Node* ownerNode, const KURL& baseURL, const TextPosition& startPosition, const String& encoding)
 {
     CSSParserContext parserContext(ownerNode->document(), 0, baseURL, encoding);
-    RefPtr<StyleSheetContents> sheet = StyleSheetContents::create(baseURL.string(), parserContext);
-    return adoptRef(new CSSStyleSheet(sheet.release(), ownerNode, true, startPosition));
+    RefPtrWillBeRawPtr<StyleSheetContents> sheet = StyleSheetContents::create(baseURL.string(), parserContext);
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSStyleSheet(sheet.release(), ownerNode, true, startPosition));
 }
 
-CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetContents> contents, CSSImportRule* ownerRule)
+CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents, CSSImportRule* ownerRule)
     : m_contents(contents)
     , m_isInlineStylesheet(false)
     , m_isDisabled(false)
@@ -107,12 +120,12 @@
     m_contents->registerClient(this);
 }
 
-CSSStyleSheet::CSSStyleSheet(PassRefPtr<StyleSheetContents> contents, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition)
+CSSStyleSheet::CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> contents, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition)
     : m_contents(contents)
     , m_isInlineStylesheet(isInlineStylesheet)
     , m_isDisabled(false)
     , m_ownerNode(ownerNode)
-    , m_ownerRule(0)
+    , m_ownerRule(nullptr)
     , m_startPosition(startPosition)
     , m_loadCompleted(false)
 {
@@ -122,6 +135,11 @@
 
 CSSStyleSheet::~CSSStyleSheet()
 {
+    // With oilpan the parent style sheet pointer is strong and the sheet and
+    // its RuleCSSOMWrappers die together and we don't need to clear them here.
+    // Also with oilpan the StyleSheetContents client pointers are weak and
+    // therefore do not need to be cleared here.
+#if !ENABLE(OILPAN)
     // For style rules outside the document, .parentStyleSheet can become null even if the style rule
     // is still observable from JavaScript. This matches the behavior of .parentNode for nodes, but
     // it's not ideal because it makes the CSSOM's behavior depend on the timing of garbage collection.
@@ -134,6 +152,7 @@
         m_mediaCSSOMWrapper->clearParentStyleSheet();
 
     m_contents->unregisterClient(this);
+#endif
 }
 
 void CSSStyleSheet::willMutateRules()
@@ -200,7 +219,7 @@
     didMutate();
 }
 
-void CSSStyleSheet::setMediaQueries(PassRefPtr<MediaQuerySet> mediaQueries)
+void CSSStyleSheet::setMediaQueries(PassRefPtrWillBeRawPtr<MediaQuerySet> mediaQueries)
 {
     m_mediaQueries = mediaQueries;
     if (m_mediaCSSOMWrapper && m_mediaQueries)
@@ -225,7 +244,7 @@
         m_childRuleCSSOMWrappers.grow(ruleCount);
     ASSERT(m_childRuleCSSOMWrappers.size() == ruleCount);
 
-    RefPtr<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index];
+    RefPtrWillBeMember<CSSRule>& cssRule = m_childRuleCSSOMWrappers[index];
     if (!cssRule) {
         if (index == 0 && m_contents->hasCharsetRule()) {
             ASSERT(!m_contents->ruleAt(0));
@@ -251,12 +270,12 @@
     return false;
 }
 
-PassRefPtr<CSSRuleList> CSSStyleSheet::rules()
+PassRefPtrWillBeRawPtr<CSSRuleList> CSSStyleSheet::rules()
 {
     if (!canAccessRules())
-        return 0;
+        return nullptr;
     // IE behavior.
-    RefPtr<StaticCSSRuleList> nonCharsetRules = StaticCSSRuleList::create();
+    RefPtrWillBeRawPtr<StaticCSSRuleList> nonCharsetRules(StaticCSSRuleList::create());
     unsigned ruleCount = length();
     for (unsigned i = 0; i < ruleCount; ++i) {
         CSSRule* rule = item(i);
@@ -271,20 +290,13 @@
 {
     ASSERT(m_childRuleCSSOMWrappers.isEmpty() || m_childRuleCSSOMWrappers.size() == m_contents->ruleCount());
 
-    if (Document* document = ownerDocument()) {
-        if (!document->contentSecurityPolicy()->allowStyleEval()) {
-            exceptionState.throwSecurityError(document->contentSecurityPolicy()->styleEvalDisabledErrorMessage());
-            return 0;
-        }
-    }
-
     if (index > length()) {
         exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is larger than the maximum index (" + String::number(length()) + ").");
         return 0;
     }
     CSSParserContext context(m_contents->parserContext(), UseCounter::getFrom(this));
     BisonCSSParser p(context);
-    RefPtr<StyleRuleBase> rule = p.parseRule(m_contents.get(), ruleString);
+    RefPtrWillBeRawPtr<StyleRuleBase> rule = p.parseRule(m_contents.get(), ruleString);
 
     if (!rule) {
         exceptionState.throwDOMException(SyntaxError, "Failed to parse the rule '" + ruleString + "'.");
@@ -298,14 +310,14 @@
         return 0;
     }
     if (!m_childRuleCSSOMWrappers.isEmpty())
-        m_childRuleCSSOMWrappers.insert(index, RefPtr<CSSRule>());
+        m_childRuleCSSOMWrappers.insert(index, RefPtrWillBeMember<CSSRule>(nullptr));
 
     return index;
 }
 
 unsigned CSSStyleSheet::insertRule(const String& rule, ExceptionState& exceptionState)
 {
-    UseCounter::countDeprecation(activeExecutionContext(V8PerIsolateData::mainThreadIsolate()), UseCounter::CSSStyleSheetInsertRuleOptionalArg);
+    UseCounter::countDeprecation(callingExecutionContext(V8PerIsolateData::mainThreadIsolate()), UseCounter::CSSStyleSheetInsertRuleOptionalArg);
     return insertRule(rule, 0, exceptionState);
 }
 
@@ -349,12 +361,12 @@
 }
 
 
-PassRefPtr<CSSRuleList> CSSStyleSheet::cssRules()
+PassRefPtrWillBeRawPtr<CSSRuleList> CSSStyleSheet::cssRules()
 {
     if (!canAccessRules())
-        return 0;
+        return nullptr;
     if (!m_ruleListCSSOMWrapper)
-        m_ruleListCSSOMWrapper = adoptPtr(new StyleSheetCSSRuleList(this));
+        m_ruleListCSSOMWrapper = StyleSheetCSSRuleList::create(this);
     return m_ruleListCSSOMWrapper.get();
 }
 
@@ -403,14 +415,38 @@
 
 bool CSSStyleSheet::sheetLoaded()
 {
-    m_loadCompleted = m_ownerNode->sheetLoaded();
+    ASSERT(m_ownerNode);
+    setLoadCompleted(m_ownerNode->sheetLoaded());
     return m_loadCompleted;
 }
 
 void CSSStyleSheet::startLoadingDynamicSheet()
 {
-    m_loadCompleted = false;
+    setLoadCompleted(false);
     m_ownerNode->startLoadingDynamicSheet();
 }
 
+void CSSStyleSheet::setLoadCompleted(bool completed)
+{
+    if (completed == m_loadCompleted)
+        return;
+
+    m_loadCompleted = completed;
+
+    if (completed)
+        m_contents->clientLoadCompleted(this);
+    else
+        m_contents->clientLoadStarted(this);
+}
+
+void CSSStyleSheet::trace(Visitor* visitor)
+{
+    visitor->trace(m_contents);
+    visitor->trace(m_mediaQueries);
+    visitor->trace(m_ownerRule);
+    visitor->trace(m_mediaCSSOMWrapper);
+    visitor->trace(m_childRuleCSSOMWrappers);
+    visitor->trace(m_ruleListCSSOMWrapper);
+}
+
 }
diff --git a/Source/core/css/CSSStyleSheet.h b/Source/core/css/CSSStyleSheet.h
index 13ab90f..ab7106e 100644
--- a/Source/core/css/CSSStyleSheet.h
+++ b/Source/core/css/CSSStyleSheet.h
@@ -23,6 +23,7 @@
 
 #include "core/css/CSSRule.h"
 #include "core/css/StyleSheet.h"
+#include "heap/Handle.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/text/TextPosition.h"
 
@@ -48,10 +49,10 @@
 
 class CSSStyleSheet FINAL : public StyleSheet {
 public:
-    static PassRefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents>, CSSImportRule* ownerRule = 0);
-    static PassRefPtr<CSSStyleSheet> create(PassRefPtr<StyleSheetContents>, Node* ownerNode);
-    static PassRefPtr<CSSStyleSheet> createInline(Node*, const KURL&, const TextPosition& startPosition = TextPosition::minimumPosition(), const String& encoding = String());
-    static PassRefPtr<CSSStyleSheet> createInline(PassRefPtr<StyleSheetContents>, Node* ownerNode, const TextPosition& startPosition = TextPosition::minimumPosition());
+    static PassRefPtrWillBeRawPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule = 0);
+    static PassRefPtrWillBeRawPtr<CSSStyleSheet> create(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode);
+    static PassRefPtrWillBeRawPtr<CSSStyleSheet> createInline(Node*, const KURL&, const TextPosition& startPosition = TextPosition::minimumPosition(), const String& encoding = String());
+    static PassRefPtrWillBeRawPtr<CSSStyleSheet> createInline(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, const TextPosition& startPosition = TextPosition::minimumPosition());
 
     virtual ~CSSStyleSheet();
 
@@ -63,13 +64,13 @@
     virtual bool disabled() const OVERRIDE { return m_isDisabled; }
     virtual void setDisabled(bool) OVERRIDE;
 
-    PassRefPtr<CSSRuleList> cssRules();
+    PassRefPtrWillBeRawPtr<CSSRuleList> cssRules();
     unsigned insertRule(const String& rule, unsigned index, ExceptionState&);
     unsigned insertRule(const String& rule, ExceptionState&); // Deprecated.
     void deleteRule(unsigned index, ExceptionState&);
 
     // IE Extensions
-    PassRefPtr<CSSRuleList> rules();
+    PassRefPtrWillBeRawPtr<CSSRuleList> rules();
     int addRule(const String& selector, const String& style, int index, ExceptionState&);
     int addRule(const String& selector, const String& style, ExceptionState&);
     void removeRule(unsigned index, ExceptionState& exceptionState) { deleteRule(index, exceptionState); }
@@ -83,10 +84,10 @@
     virtual KURL baseURL() const OVERRIDE;
     virtual bool isLoading() const OVERRIDE;
 
-    void clearOwnerRule() { m_ownerRule = 0; }
+    void clearOwnerRule() { m_ownerRule = nullptr; }
     Document* ownerDocument() const;
     MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
-    void setMediaQueries(PassRefPtr<MediaQuerySet>);
+    void setMediaQueries(PassRefPtrWillBeRawPtr<MediaQuerySet>);
     void setTitle(const String& title) { m_title = title; }
 
     class RuleMutationScope {
@@ -115,9 +116,11 @@
     bool loadCompleted() const { return m_loadCompleted; }
     void startLoadingDynamicSheet();
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
-    CSSStyleSheet(PassRefPtr<StyleSheetContents>, CSSImportRule* ownerRule);
-    CSSStyleSheet(PassRefPtr<StyleSheetContents>, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition);
+    CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, CSSImportRule* ownerRule);
+    CSSStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>, Node* ownerNode, bool isInlineStylesheet, const TextPosition& startPosition);
 
     virtual bool isCSSStyleSheet() const OVERRIDE { return true; }
     virtual String type() const OVERRIDE { return "text/css"; }
@@ -126,21 +129,22 @@
 
     bool canAccessRules() const;
 
-    RefPtr<StyleSheetContents> m_contents;
+    void setLoadCompleted(bool);
+
+    RefPtrWillBeMember<StyleSheetContents> m_contents;
     bool m_isInlineStylesheet;
     bool m_isDisabled;
     String m_title;
-    RefPtr<MediaQuerySet> m_mediaQueries;
+    RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
 
     Node* m_ownerNode;
-    CSSRule* m_ownerRule;
+    RawPtrWillBeMember<CSSRule> m_ownerRule;
 
     TextPosition m_startPosition;
     bool m_loadCompleted;
-
-    mutable RefPtr<MediaList> m_mediaCSSOMWrapper;
-    mutable Vector<RefPtr<CSSRule> > m_childRuleCSSOMWrappers;
-    mutable OwnPtr<CSSRuleList> m_ruleListCSSOMWrapper;
+    mutable RefPtrWillBeMember<MediaList> m_mediaCSSOMWrapper;
+    mutable WillBeHeapVector<RefPtrWillBeMember<CSSRule> > m_childRuleCSSOMWrappers;
+    mutable OwnPtrWillBeMember<CSSRuleList> m_ruleListCSSOMWrapper;
 };
 
 inline CSSStyleSheet::RuleMutationScope::RuleMutationScope(CSSStyleSheet* sheet)
diff --git a/Source/core/css/CSSSupportsRule.h b/Source/core/css/CSSSupportsRule.h
index 1e461f8..75f4675 100644
--- a/Source/core/css/CSSSupportsRule.h
+++ b/Source/core/css/CSSSupportsRule.h
@@ -38,9 +38,9 @@
 
 class CSSSupportsRule FINAL : public CSSGroupingRule {
 public:
-    static PassRefPtr<CSSSupportsRule> create(StyleRuleSupports* rule, CSSStyleSheet* sheet)
+    static PassRefPtrWillBeRawPtr<CSSSupportsRule> create(StyleRuleSupports* rule, CSSStyleSheet* sheet)
     {
-        return adoptRef(new CSSSupportsRule(rule, sheet));
+        return adoptRefWillBeNoop(new CSSSupportsRule(rule, sheet));
     }
 
     virtual ~CSSSupportsRule() { }
@@ -50,6 +50,8 @@
 
     String conditionText() const;
 
+    virtual void trace(Visitor* visitor) OVERRIDE { CSSGroupingRule::trace(visitor); }
+
 private:
     CSSSupportsRule(StyleRuleSupports*, CSSStyleSheet*);
 };
diff --git a/Source/core/css/CSSTestHelper.cpp b/Source/core/css/CSSTestHelper.cpp
index d0fac9f..3b24d9c 100644
--- a/Source/core/css/CSSTestHelper.cpp
+++ b/Source/core/css/CSSTestHelper.cpp
@@ -67,26 +67,4 @@
     ASSERT_TRUE(m_styleSheet->length() > sheetLength);
 }
 
-int CSSTestHelper::numRules(const RuleData* ruleData)
-{
-    if (!ruleData)
-        return 0;
-    int count = 1;
-    while (!ruleData->isLastInArray()) {
-        ruleData++;
-        count++;
-    }
-    return count;
-}
-
-const RuleData& CSSTestHelper::getRule(const RuleData* ruleData, int index)
-{
-    int count = 0;
-    while (!ruleData->isLastInArray() && count < index) {
-        ruleData++;
-        count++;
-    }
-    return *ruleData;
-}
-
 } // namespace WebCore
diff --git a/Source/core/css/CSSTestHelper.h b/Source/core/css/CSSTestHelper.h
index ea87f1e..58aa933 100644
--- a/Source/core/css/CSSTestHelper.h
+++ b/Source/core/css/CSSTestHelper.h
@@ -53,10 +53,6 @@
     void addCSSRules(const char* ruleText);
     RuleSet& ruleSet();
 
-    // Returns the number of rules in the given RuleData array.
-    static int numRules(const RuleData*);
-    // Returns the data at index i (must be less than numNules())
-    static const RuleData& getRule(const RuleData*, int index);
 private:
     RefPtr<Document> m_document;
     RefPtr<CSSStyleSheet> m_styleSheet;
diff --git a/Source/core/css/CSSTimingFunctionValue.cpp b/Source/core/css/CSSTimingFunctionValue.cpp
index 49420cb..b8eee45 100644
--- a/Source/core/css/CSSTimingFunctionValue.cpp
+++ b/Source/core/css/CSSTimingFunctionValue.cpp
@@ -46,12 +46,28 @@
 
 String CSSStepsTimingFunctionValue::customCSSText() const
 {
-    return "steps(" + String::number(m_steps) + ", " + (m_stepAtStart ? "start" : "end") + ')';
+    String stepAtPositionString;
+    switch (m_stepAtPosition) {
+    case StepsTimingFunction::StepAtStart:
+        stepAtPositionString = "start";
+        break;
+    case StepsTimingFunction::StepAtMiddle:
+        stepAtPositionString = "middle";
+        break;
+    case StepsTimingFunction::StepAtEnd:
+        stepAtPositionString = "end";
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        stepAtPositionString = "end";
+        break;
+    }
+    return "steps(" + String::number(m_steps) + ", " + stepAtPositionString + ')';
 }
 
 bool CSSStepsTimingFunctionValue::equals(const CSSStepsTimingFunctionValue& other) const
 {
-    return m_steps == other.m_steps && m_stepAtStart == other.m_stepAtStart;
+    return m_steps == other.m_steps && m_stepAtPosition == other.m_stepAtPosition;
 }
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSTimingFunctionValue.h b/Source/core/css/CSSTimingFunctionValue.h
index 10778e8..fa77517 100644
--- a/Source/core/css/CSSTimingFunctionValue.h
+++ b/Source/core/css/CSSTimingFunctionValue.h
@@ -27,6 +27,7 @@
 #define CSSTimingFunctionValue_h
 
 #include "core/css/CSSValue.h"
+#include "platform/animation/TimingFunction.h"
 #include "wtf/PassRefPtr.h"
 
 namespace WebCore {
@@ -35,7 +36,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSCubicBezierTimingFunctionValue> create(double x1, double y1, double x2, double y2)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSCubicBezierTimingFunctionValue(x1, y1, x2, y2));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSCubicBezierTimingFunctionValue(x1, y1, x2, y2));
     }
 
     String customCSSText() const;
@@ -69,13 +70,13 @@
 
 class CSSStepsTimingFunctionValue : public CSSValue {
 public:
-    static PassRefPtrWillBeRawPtr<CSSStepsTimingFunctionValue> create(int steps, bool stepAtStart)
+    static PassRefPtrWillBeRawPtr<CSSStepsTimingFunctionValue> create(int steps, StepsTimingFunction::StepAtPosition stepAtPosition)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSStepsTimingFunctionValue(steps, stepAtStart));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSStepsTimingFunctionValue(steps, stepAtPosition));
     }
 
     int numberOfSteps() const { return m_steps; }
-    bool stepAtStart() const { return m_stepAtStart; }
+    StepsTimingFunction::StepAtPosition stepAtPosition() const { return m_stepAtPosition; }
 
     String customCSSText() const;
 
@@ -84,15 +85,15 @@
     void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
 
 private:
-    CSSStepsTimingFunctionValue(int steps, bool stepAtStart)
+    CSSStepsTimingFunctionValue(int steps, StepsTimingFunction::StepAtPosition stepAtPosition)
         : CSSValue(StepsTimingFunctionClass)
         , m_steps(steps)
-        , m_stepAtStart(stepAtStart)
+        , m_stepAtPosition(stepAtPosition)
     {
     }
 
     int m_steps;
-    bool m_stepAtStart;
+    StepsTimingFunction::StepAtPosition m_stepAtPosition;
 };
 
 DEFINE_CSS_VALUE_TYPE_CASTS(CSSStepsTimingFunctionValue, isStepsTimingFunctionValue());
diff --git a/Source/core/css/CSSToLengthConversionData.h b/Source/core/css/CSSToLengthConversionData.h
index f110b23..6b81ce9 100644
--- a/Source/core/css/CSSToLengthConversionData.h
+++ b/Source/core/css/CSSToLengthConversionData.h
@@ -46,7 +46,7 @@
     CSSToLengthConversionData(const RenderStyle* currStyle, const RenderStyle* rootStyle, float viewportWidth, float viewportHeight, float zoom, bool computingFontSize = false);
 
     const RenderStyle& style() const { return *m_style; }
-    const RenderStyle& rootStyle() const { return *m_rootStyle; }
+    const RenderStyle* rootStyle() const { return m_rootStyle; }
     float zoom() const;
     bool computingFontSize() const { return m_computingFontSize; }
 
diff --git a/Source/core/css/CSSTransformValue.cpp b/Source/core/css/CSSTransformValue.cpp
index 06021d8..92af4b9 100644
--- a/Source/core/css/CSSTransformValue.cpp
+++ b/Source/core/css/CSSTransformValue.cpp
@@ -84,7 +84,7 @@
 
 PassRefPtrWillBeRawPtr<CSSTransformValue> CSSTransformValue::cloneForCSSOM() const
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSTransformValue(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSTransformValue(*this));
 }
 
 }
diff --git a/Source/core/css/CSSTransformValue.h b/Source/core/css/CSSTransformValue.h
index bd8f69a..b3e4e11 100644
--- a/Source/core/css/CSSTransformValue.h
+++ b/Source/core/css/CSSTransformValue.h
@@ -61,7 +61,7 @@
 
     static PassRefPtrWillBeRawPtr<CSSTransformValue> create(TransformOperationType type)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSTransformValue(type));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSTransformValue(type));
     }
 
     String customCSSText() const;
diff --git a/Source/core/css/CSSUnicodeRangeValue.h b/Source/core/css/CSSUnicodeRangeValue.h
index acfc0a6..74e8d83 100644
--- a/Source/core/css/CSSUnicodeRangeValue.h
+++ b/Source/core/css/CSSUnicodeRangeValue.h
@@ -35,7 +35,7 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSUnicodeRangeValue> create(UChar32 from, UChar32 to)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSUnicodeRangeValue(from, to));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSUnicodeRangeValue(from, to));
     }
 
     UChar32 from() const { return m_from; }
diff --git a/Source/core/css/CSSUnknownRule.h b/Source/core/css/CSSUnknownRule.h
index ada0b6e..06d1be4 100644
--- a/Source/core/css/CSSUnknownRule.h
+++ b/Source/core/css/CSSUnknownRule.h
@@ -34,6 +34,7 @@
     virtual CSSRule::Type type() const OVERRIDE { return UNKNOWN_RULE; }
     virtual String cssText() const OVERRIDE { return String(); }
     virtual void reattach(StyleRuleBase*) OVERRIDE { }
+    virtual void trace(Visitor* visitor) OVERRIDE { CSSRule::trace(visitor); }
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/CSSValue.cpp b/Source/core/css/CSSValue.cpp
index a02a034..8db94f4 100644
--- a/Source/core/css/CSSValue.cpp
+++ b/Source/core/css/CSSValue.cpp
@@ -55,13 +55,10 @@
 #include "core/css/CSSTransformValue.h"
 #include "core/css/CSSUnicodeRangeValue.h"
 #include "core/css/CSSValueList.h"
-#include "core/svg/SVGColor.h"
 #include "core/svg/SVGPaint.h"
 
 namespace WebCore {
 
-DEFINE_GC_INFO(CSSValue);
-
 struct SameSizeAsCSSValue : public RefCountedWillBeRefCountedGarbageCollected<SameSizeAsCSSValue> {
     uint32_t bitfields;
 };
@@ -70,7 +67,10 @@
 
 class TextCloneCSSValue : public CSSValue {
 public:
-    static PassRefPtr<TextCloneCSSValue> create(ClassType classType, const String& text) { return adoptRef(new TextCloneCSSValue(classType, text)); }
+    static PassRefPtrWillBeRawPtr<TextCloneCSSValue> create(ClassType classType, const String& text)
+    {
+        return adoptRefWillBeRefCountedGarbageCollected(new TextCloneCSSValue(classType, text));
+    }
 
     String cssText() const { return m_cssText; }
 
@@ -199,8 +199,6 @@
             return compareCSSValues<CSSFilterValue>(*this, other);
         case CSSArrayFunctionValueClass:
             return compareCSSValues<CSSArrayFunctionValue>(*this, other);
-        case SVGColorClass:
-            return compareCSSValues<SVGColor>(*this, other);
         case SVGPaintClass:
             return compareCSSValues<SVGPaint>(*this, other);
         case CSSSVGDocumentClass:
@@ -283,8 +281,6 @@
         return toCSSFilterValue(this)->customCSSText();
     case CSSArrayFunctionValueClass:
         return toCSSArrayFunctionValue(this)->customCSSText();
-    case SVGColorClass:
-        return toSVGColor(this)->customCSSText();
     case SVGPaintClass:
         return toSVGPaint(this)->customCSSText();
     case CSSSVGDocumentClass:
@@ -391,9 +387,6 @@
     case CSSArrayFunctionValueClass:
         delete toCSSArrayFunctionValue(this);
         return;
-    case SVGColorClass:
-        delete toSVGColor(this);
-        return;
     case SVGPaintClass:
         delete toSVGPaint(this);
         return;
@@ -415,100 +408,97 @@
 
     switch (classType()) {
     case AspectRatioClass:
-        static_cast<CSSAspectRatioValue*>(this)->~CSSAspectRatioValue();
+        toCSSAspectRatioValue(this)->~CSSAspectRatioValue();
         return;
     case BorderImageSliceClass:
-        static_cast<CSSBorderImageSliceValue*>(this)->~CSSBorderImageSliceValue();
+        toCSSBorderImageSliceValue(this)->~CSSBorderImageSliceValue();
         return;
     case CanvasClass:
-        static_cast<CSSCanvasValue*>(this)->~CSSCanvasValue();
+        toCSSCanvasValue(this)->~CSSCanvasValue();
         return;
     case CursorImageClass:
-        static_cast<CSSCursorImageValue*>(this)->~CSSCursorImageValue();
+        toCSSCursorImageValue(this)->~CSSCursorImageValue();
         return;
     case FontClass:
-        static_cast<CSSFontValue*>(this)->~CSSFontValue();
+        toCSSFontValue(this)->~CSSFontValue();
         return;
     case FontFaceSrcClass:
-        static_cast<CSSFontFaceSrcValue*>(this)->~CSSFontFaceSrcValue();
+        toCSSFontFaceSrcValue(this)->~CSSFontFaceSrcValue();
         return;
     case FontFeatureClass:
-        static_cast<CSSFontFeatureValue*>(this)->~CSSFontFeatureValue();
+        toCSSFontFeatureValue(this)->~CSSFontFeatureValue();
         return;
     case FunctionClass:
-        static_cast<CSSFunctionValue*>(this)->~CSSFunctionValue();
+        toCSSFunctionValue(this)->~CSSFunctionValue();
         return;
     case LinearGradientClass:
-        static_cast<CSSLinearGradientValue*>(this)->~CSSLinearGradientValue();
+        toCSSLinearGradientValue(this)->~CSSLinearGradientValue();
         return;
     case RadialGradientClass:
-        static_cast<CSSRadialGradientValue*>(this)->~CSSRadialGradientValue();
+        toCSSRadialGradientValue(this)->~CSSRadialGradientValue();
         return;
     case CrossfadeClass:
-        static_cast<CSSCrossfadeValue*>(this)->~CSSCrossfadeValue();
+        toCSSCrossfadeValue(this)->~CSSCrossfadeValue();
         return;
     case ImageClass:
-        static_cast<CSSImageValue*>(this)->~CSSImageValue();
+        toCSSImageValue(this)->~CSSImageValue();
         return;
     case InheritedClass:
-        static_cast<CSSInheritedValue*>(this)->~CSSInheritedValue();
+        toCSSInheritedValue(this)->~CSSInheritedValue();
         return;
     case InitialClass:
-        static_cast<CSSInitialValue*>(this)->~CSSInitialValue();
+        toCSSInitialValue(this)->~CSSInitialValue();
         return;
     case GridLineNamesClass:
-        static_cast<CSSGridLineNamesValue*>(this)->~CSSGridLineNamesValue();
+        toCSSGridLineNamesValue(this)->~CSSGridLineNamesValue();
         return;
     case GridTemplateAreasClass:
-        static_cast<CSSGridTemplateAreasValue*>(this)->~CSSGridTemplateAreasValue();
+        toCSSGridTemplateAreasValue(this)->~CSSGridTemplateAreasValue();
         return;
     case PrimitiveClass:
-        static_cast<CSSPrimitiveValue*>(this)->~CSSPrimitiveValue();
+        toCSSPrimitiveValue(this)->~CSSPrimitiveValue();
         return;
     case ReflectClass:
-        static_cast<CSSReflectValue*>(this)->~CSSReflectValue();
+        toCSSReflectValue(this)->~CSSReflectValue();
         return;
     case ShadowClass:
-        static_cast<CSSShadowValue*>(this)->~CSSShadowValue();
+        toCSSShadowValue(this)->~CSSShadowValue();
         return;
     case CubicBezierTimingFunctionClass:
-        static_cast<CSSCubicBezierTimingFunctionValue*>(this)->~CSSCubicBezierTimingFunctionValue();
+        toCSSCubicBezierTimingFunctionValue(this)->~CSSCubicBezierTimingFunctionValue();
         return;
     case StepsTimingFunctionClass:
-        static_cast<CSSStepsTimingFunctionValue*>(this)->~CSSStepsTimingFunctionValue();
+        toCSSStepsTimingFunctionValue(this)->~CSSStepsTimingFunctionValue();
         return;
     case UnicodeRangeClass:
-        static_cast<CSSUnicodeRangeValue*>(this)->~CSSUnicodeRangeValue();
+        toCSSUnicodeRangeValue(this)->~CSSUnicodeRangeValue();
         return;
     case ValueListClass:
-        static_cast<CSSValueList*>(this)->~CSSValueList();
+        toCSSValueList(this)->~CSSValueList();
         return;
     case CSSTransformClass:
-        static_cast<CSSTransformValue*>(this)->~CSSTransformValue();
+        toCSSTransformValue(this)->~CSSTransformValue();
         return;
     case LineBoxContainClass:
-        static_cast<CSSLineBoxContainValue*>(this)->~CSSLineBoxContainValue();
+        toCSSLineBoxContainValue(this)->~CSSLineBoxContainValue();
         return;
     case CalculationClass:
-        static_cast<CSSCalcValue*>(this)->~CSSCalcValue();
+        toCSSCalcValue(this)->~CSSCalcValue();
         return;
     case ImageSetClass:
-        static_cast<CSSImageSetValue*>(this)->~CSSImageSetValue();
+        toCSSImageSetValue(this)->~CSSImageSetValue();
         return;
     case CSSFilterClass:
-        static_cast<CSSFilterValue*>(this)->~CSSFilterValue();
+        toCSSFilterValue(this)->~CSSFilterValue();
         return;
     case CSSArrayFunctionValueClass:
-        static_cast<CSSArrayFunctionValue*>(this)->~CSSArrayFunctionValue();
-        return;
-    case SVGColorClass:
-        static_cast<SVGColor*>(this)->~SVGColor();
+        toCSSArrayFunctionValue(this)->~CSSArrayFunctionValue();
         return;
     case SVGPaintClass:
-        static_cast<SVGPaint*>(this)->~SVGPaint();
+        toSVGPaint(this)->~SVGPaint();
         return;
     case CSSSVGDocumentClass:
-        static_cast<CSSSVGDocumentValue*>(this)->~CSSSVGDocumentValue();
+        toCSSSVGDocumentValue(this)->~CSSSVGDocumentValue();
         return;
     }
     ASSERT_NOT_REACHED();
@@ -611,9 +601,6 @@
     case CSSArrayFunctionValueClass:
         static_cast<CSSArrayFunctionValue*>(this)->traceAfterDispatch(visitor);
         return;
-    case SVGColorClass:
-        static_cast<SVGColor*>(this)->traceAfterDispatch(visitor);
-        return;
     case SVGPaintClass:
         static_cast<SVGPaint*>(this)->traceAfterDispatch(visitor);
         return;
@@ -624,7 +611,7 @@
     ASSERT_NOT_REACHED();
 }
 
-PassRefPtr<CSSValue> CSSValue::cloneForCSSOM() const
+PassRefPtrWillBeRawPtr<CSSValue> CSSValue::cloneForCSSOM() const
 {
     switch (classType()) {
     case PrimitiveClass:
@@ -642,8 +629,6 @@
         return toCSSTransformValue(this)->cloneForCSSOM();
     case ImageSetClass:
         return toCSSImageSetValue(this)->cloneForCSSOM();
-    case SVGColorClass:
-        return toSVGColor(this)->cloneForCSSOM();
     case SVGPaintClass:
         return toSVGPaint(this)->cloneForCSSOM();
     default:
diff --git a/Source/core/css/CSSValue.h b/Source/core/css/CSSValue.h
index 2d6cdff..3fd465e 100644
--- a/Source/core/css/CSSValue.h
+++ b/Source/core/css/CSSValue.h
@@ -42,7 +42,6 @@
 
 // Please don't expose more CSSValue types to the web.
 class CSSValue : public RefCountedWillBeRefCountedGarbageCollected<CSSValue> {
-    DECLARE_GC_INFO;
 public:
     enum Type {
         CSS_INHERIT = 0,
@@ -104,7 +103,6 @@
     bool isFilterValue() const { return m_classType == CSSFilterClass; }
     bool isArrayFunctionValue() const { return m_classType == CSSArrayFunctionValueClass; }
     bool isGridTemplateAreasValue() const { return m_classType == GridTemplateAreasClass; }
-    bool isSVGColor() const { return m_classType == SVGColorClass || m_classType == SVGPaintClass; }
     bool isSVGPaint() const { return m_classType == SVGPaintClass; }
     bool isSVGDocumentValue() const { return m_classType == CSSSVGDocumentClass; }
     bool isUnicodeRangeValue() const { return m_classType == UnicodeRangeClass; }
@@ -113,10 +111,10 @@
     bool isCSSOMSafe() const { return m_isCSSOMSafe; }
     bool isSubtypeExposedToCSSOM() const
     {
-        return isPrimitiveValue() || isSVGColor() || isValueList();
+        return isPrimitiveValue() || isSVGPaint() || isValueList();
     }
 
-    PassRefPtr<CSSValue> cloneForCSSOM() const;
+    PassRefPtrWillBeRawPtr<CSSValue> cloneForCSSOM() const;
 
     bool hasFailedOrCanceledSubresources() const;
 
@@ -165,7 +163,6 @@
         GridTemplateAreasClass,
 
         // SVG classes.
-        SVGColorClass,
         SVGPaintClass,
         CSSSVGDocumentClass,
 
@@ -224,16 +221,16 @@
     unsigned m_classType : ClassTypeBits; // ClassType
 };
 
-template<typename CSSValueType>
-inline bool compareCSSValueVector(const Vector<RefPtr<CSSValueType> >& firstVector, const Vector<RefPtr<CSSValueType> >& secondVector)
+template<typename CSSValueType, size_t inlineCapacity>
+inline bool compareCSSValueVector(const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& firstVector, const WillBeHeapVector<RefPtrWillBeMember<CSSValueType>, inlineCapacity>& secondVector)
 {
     size_t size = firstVector.size();
     if (size != secondVector.size())
         return false;
 
     for (size_t i = 0; i < size; i++) {
-        const RefPtr<CSSValueType>& firstPtr = firstVector[i];
-        const RefPtr<CSSValueType>& secondPtr = secondVector[i];
+        const RefPtrWillBeMember<CSSValueType>& firstPtr = firstVector[i];
+        const RefPtrWillBeMember<CSSValueType>& secondPtr = secondVector[i];
         if (firstPtr == secondPtr || (firstPtr && secondPtr && firstPtr->equals(*secondPtr)))
             continue;
         return false;
diff --git a/Source/core/css/CSSValue.idl b/Source/core/css/CSSValue.idl
index dfdacd3..145010b 100644
--- a/Source/core/css/CSSValue.idl
+++ b/Source/core/css/CSSValue.idl
@@ -21,6 +21,7 @@
 [
     Custom=Wrap,
     DependentLifetime,
+    WillBeGarbageCollected,
 ] interface CSSValue {
 
     // UnitTypes
diff --git a/Source/core/css/CSSValueKeywords.in b/Source/core/css/CSSValueKeywords.in
index eb6235f..9c50dbb 100644
--- a/Source/core/css/CSSValueKeywords.in
+++ b/Source/core/css/CSSValueKeywords.in
@@ -61,6 +61,8 @@
 no-discretionary-ligatures
 historical-ligatures
 no-historical-ligatures
+contextual
+no-contextual
 
 //
 // CSS_PROP_FONT_WEIGHT:
@@ -779,6 +781,7 @@
 ease-out
 ease-in-out
 step-start
+step-middle
 step-end
 
 //
@@ -1008,6 +1011,7 @@
 // touch-action
 pan-x
 pan-y
+manipulation
 
 // justify-self
 // auto
@@ -1028,3 +1032,8 @@
 // scroll-behavior
 instant
 smooth
+
+// will-change
+// auto
+contents
+scroll-position
diff --git a/Source/core/css/CSSValueList.cpp b/Source/core/css/CSSValueList.cpp
index 9c0a989..b41d465 100644
--- a/Source/core/css/CSSValueList.cpp
+++ b/Source/core/css/CSSValueList.cpp
@@ -53,7 +53,7 @@
 {
     bool found = false;
     for (size_t index = 0; index < m_values.size(); index++) {
-        RefPtr<CSSValue>& value = m_values.at(index);
+        RefPtrWillBeMember<CSSValue>& value = m_values.at(index);
         if (value && val && value->equals(*val)) {
             m_values.remove(index);
             found = true;
@@ -66,7 +66,7 @@
 bool CSSValueList::hasValue(CSSValue* val) const
 {
     for (size_t index = 0; index < m_values.size(); index++) {
-        const RefPtr<CSSValue>& value = m_values.at(index);
+        const RefPtrWillBeMember<CSSValue>& value = m_values.at(index);
         if (value && val && value->equals(*val))
             return true;
     }
@@ -127,16 +127,15 @@
 
 bool CSSValueList::equals(const CSSValueList& other) const
 {
-    // FIXME: the explicit Vector conversion copies into a temporary and is
-    // wasteful.
-    return m_valueListSeparator == other.m_valueListSeparator && compareCSSValueVector<CSSValue>(Vector<RefPtr<CSSValue> >(m_values), Vector<RefPtr<CSSValue> >(other.m_values));}
+    return m_valueListSeparator == other.m_valueListSeparator && compareCSSValueVector(m_values, other.m_values);
+}
 
 bool CSSValueList::equals(const CSSValue& other) const
 {
     if (m_values.size() != 1)
         return false;
 
-    const RefPtr<CSSValue>& value = m_values[0];
+    const RefPtrWillBeMember<CSSValue>& value = m_values[0];
     return value && value->equals(other);
 }
 
@@ -160,11 +159,12 @@
 
 PassRefPtrWillBeRawPtr<CSSValueList> CSSValueList::cloneForCSSOM() const
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSValueList(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new CSSValueList(*this));
 }
 
 void CSSValueList::traceAfterDispatch(Visitor* visitor)
 {
+    visitor->trace(m_values);
     CSSValue::traceAfterDispatch(visitor);
 }
 
diff --git a/Source/core/css/CSSValueList.h b/Source/core/css/CSSValueList.h
index 9ce1e53..7e4d9ff 100644
--- a/Source/core/css/CSSValueList.h
+++ b/Source/core/css/CSSValueList.h
@@ -33,19 +33,19 @@
 public:
     static PassRefPtrWillBeRawPtr<CSSValueList> createCommaSeparated()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSValueList(CommaSeparator));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSValueList(CommaSeparator));
     }
     static PassRefPtrWillBeRawPtr<CSSValueList> createSpaceSeparated()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSValueList(SpaceSeparator));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSValueList(SpaceSeparator));
     }
     static PassRefPtrWillBeRawPtr<CSSValueList> createSlashSeparated()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSValueList(SlashSeparator));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSValueList(SlashSeparator));
     }
     static PassRefPtrWillBeRawPtr<CSSValueList> createFromParserValueList(CSSParserValueList* list)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new CSSValueList(list));
+        return adoptRefWillBeRefCountedGarbageCollected(new CSSValueList(list));
     }
 
     size_t length() const { return m_values.size(); }
@@ -53,8 +53,8 @@
     const CSSValue* item(size_t index) const { return index < m_values.size() ? m_values[index].get() : 0; }
     CSSValue* itemWithoutBoundsCheck(size_t index) { return m_values[index].get(); }
 
-    void append(PassRefPtr<CSSValue> value) { m_values.append(value); }
-    void prepend(PassRefPtr<CSSValue> value) { m_values.prepend(value); }
+    void append(PassRefPtrWillBeRawPtr<CSSValue> value) { m_values.append(value); }
+    void prepend(PassRefPtrWillBeRawPtr<CSSValue> value) { m_values.prepend(value); }
     bool removeAll(CSSValue*);
     bool hasValue(CSSValue*) const;
     PassRefPtrWillBeRawPtr<CSSValueList> copy();
@@ -77,7 +77,7 @@
     explicit CSSValueList(ValueListSeparator);
     explicit CSSValueList(CSSParserValueList*);
 
-    Vector<RefPtr<CSSValue>, 4> m_values;
+    WillBeHeapVector<RefPtrWillBeMember<CSSValue>, 4> m_values;
 };
 
 DEFINE_CSS_VALUE_TYPE_CASTS(CSSValueList, isValueList());
@@ -85,6 +85,7 @@
 // Objects of this class are intended to be stack-allocated and scoped to a single function.
 // Please take care not to pass these around as they do hold onto a raw pointer.
 class CSSValueListInspector {
+    STACK_ALLOCATED();
 public:
     CSSValueListInspector(CSSValue* value) : m_list((value && value->isValueList()) ? toCSSValueList(value) : 0) { }
     CSSValue* item(size_t index) const { ASSERT_WITH_SECURITY_IMPLICATION(index < length()); return m_list->itemWithoutBoundsCheck(index); }
@@ -99,6 +100,7 @@
 // Objects of this class are intended to be stack-allocated and scoped to a single function.
 // Please take care not to pass these around as they do hold onto a raw pointer.
 class CSSValueListIterator {
+    STACK_ALLOCATED();
 public:
     CSSValueListIterator(CSSValue* value) : m_inspector(value), m_position(0) { }
     bool hasMore() const { return m_position < m_inspector.length(); }
diff --git a/Source/core/css/CSSValuePool.cpp b/Source/core/css/CSSValuePool.cpp
index 4e6e9f2..cfada98 100644
--- a/Source/core/css/CSSValuePool.cpp
+++ b/Source/core/css/CSSValuePool.cpp
@@ -32,8 +32,6 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(CSSValuePool);
-
 CSSValuePool& cssValuePool()
 {
 #if ENABLE(OILPAN)
@@ -131,7 +129,7 @@
 
 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSValuePool::createFontFamilyValue(const String& familyName)
 {
-    RefPtrWillBeMember<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, 0).storedValue->value;
+    RefPtrWillBeMember<CSSPrimitiveValue>& value = m_fontFamilyValueCache.add(familyName, nullptr).storedValue->value;
     if (!value)
         value = CSSPrimitiveValue::create(familyName, CSSPrimitiveValue::CSS_STRING);
     return value;
@@ -144,7 +142,7 @@
     if (m_fontFaceValueCache.size() > maximumFontFaceCacheSize)
         m_fontFaceValueCache.clear();
 
-    RefPtrWillBeMember<CSSValueList>& value = m_fontFaceValueCache.add(string, 0).storedValue->value;
+    RefPtrWillBeMember<CSSValueList>& value = m_fontFaceValueCache.add(string, nullptr).storedValue->value;
     if (!value)
         value = BisonCSSParser::parseFontFaceValue(string);
     return value;
diff --git a/Source/core/css/CSSValuePool.h b/Source/core/css/CSSValuePool.h
index 9ed7f39..be55928 100644
--- a/Source/core/css/CSSValuePool.h
+++ b/Source/core/css/CSSValuePool.h
@@ -40,7 +40,6 @@
 class CSSValueList;
 
 class CSSValuePool :  public NoBaseWillBeGarbageCollected<CSSValuePool> {
-    DECLARE_GC_INFO;
     WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
     PassRefPtrWillBeRawPtr<CSSValueList> createFontFaceValue(const AtomicString&);
diff --git a/Source/core/css/CSSViewportRule.cpp b/Source/core/css/CSSViewportRule.cpp
index a5d1f0e..2565022 100644
--- a/Source/core/css/CSSViewportRule.cpp
+++ b/Source/core/css/CSSViewportRule.cpp
@@ -63,7 +63,7 @@
     StringBuilder result;
     result.appendLiteral("@viewport { ");
 
-    String decls = m_viewportRule->properties()->asText();
+    String decls = m_viewportRule->properties().asText();
     result.append(decls);
     if (!decls.isEmpty())
         result.append(' ');
@@ -81,4 +81,10 @@
         m_propertiesCSSOMWrapper->reattach(m_viewportRule->mutableProperties());
 }
 
+void CSSViewportRule::trace(Visitor* visitor)
+{
+    visitor->trace(m_viewportRule);
+    CSSRule::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/CSSViewportRule.h b/Source/core/css/CSSViewportRule.h
index 50cd88a..2ac4cbe 100644
--- a/Source/core/css/CSSViewportRule.h
+++ b/Source/core/css/CSSViewportRule.h
@@ -32,6 +32,7 @@
 #define CSSViewportRule_h
 
 #include "core/css/CSSRule.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -41,9 +42,9 @@
 
 class CSSViewportRule FINAL: public CSSRule {
 public:
-    static PassRefPtr<CSSViewportRule> create(StyleRuleViewport* viewportRule, CSSStyleSheet* sheet)
+    static PassRefPtrWillBeRawPtr<CSSViewportRule> create(StyleRuleViewport* viewportRule, CSSStyleSheet* sheet)
     {
-        return adoptRef(new CSSViewportRule(viewportRule, sheet));
+        return adoptRefWillBeNoop(new CSSViewportRule(viewportRule, sheet));
     }
     virtual ~CSSViewportRule();
 
@@ -53,10 +54,12 @@
 
     CSSStyleDeclaration* style() const;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CSSViewportRule(StyleRuleViewport*, CSSStyleSheet*);
 
-    RefPtr<StyleRuleViewport> m_viewportRule;
+    RefPtrWillBeMember<StyleRuleViewport> m_viewportRule;
     mutable RefPtr<StyleRuleCSSStyleDeclaration> m_propertiesCSSOMWrapper;
 };
 
diff --git a/Source/core/css/Counter.cpp b/Source/core/css/Counter.cpp
index 4e27e48..d012b1a 100644
--- a/Source/core/css/Counter.cpp
+++ b/Source/core/css/Counter.cpp
@@ -7,8 +7,6 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(Counter);
-
 void Counter::trace(Visitor* visitor)
 {
     visitor->trace(m_identifier);
diff --git a/Source/core/css/Counter.h b/Source/core/css/Counter.h
index d27ff18..68b3a73 100644
--- a/Source/core/css/Counter.h
+++ b/Source/core/css/Counter.h
@@ -27,7 +27,6 @@
 namespace WebCore {
 
 class Counter : public RefCountedWillBeGarbageCollected<Counter> {
-    DECLARE_GC_INFO;
 public:
     static PassRefPtrWillBeRawPtr<Counter> create(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> identifier, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> separator)
     {
@@ -53,9 +52,9 @@
 
     PassRefPtrWillBeRawPtr<Counter> cloneForCSSOM() const
     {
-        return create(m_identifier ? m_identifier->cloneForCSSOM() : 0
-            , m_listStyle ? m_listStyle->cloneForCSSOM() : 0
-            , m_separator ? m_separator->cloneForCSSOM() : 0);
+        return create(m_identifier ? m_identifier->cloneForCSSOM() : nullptr
+            , m_listStyle ? m_listStyle->cloneForCSSOM() : nullptr
+            , m_separator ? m_separator->cloneForCSSOM() : nullptr);
     }
 
     void trace(Visitor*);
diff --git a/Source/core/css/DocumentFontFaceSet.cpp b/Source/core/css/DocumentFontFaceSet.cpp
index 408668f..a5952c6 100644
--- a/Source/core/css/DocumentFontFaceSet.cpp
+++ b/Source/core/css/DocumentFontFaceSet.cpp
@@ -30,7 +30,7 @@
 
 namespace WebCore {
 
-PassRefPtr<FontFaceSet> DocumentFontFaceSet::fonts(Document* document)
+PassRefPtr<FontFaceSet> DocumentFontFaceSet::fonts(Document& document)
 {
     return FontFaceSet::from(document);
 }
diff --git a/Source/core/css/DocumentFontFaceSet.h b/Source/core/css/DocumentFontFaceSet.h
index 910d878..2aa2d22 100644
--- a/Source/core/css/DocumentFontFaceSet.h
+++ b/Source/core/css/DocumentFontFaceSet.h
@@ -35,7 +35,7 @@
 
 class DocumentFontFaceSet {
 public:
-    static PassRefPtr<FontFaceSet> fonts(Document*);
+    static PassRefPtr<FontFaceSet> fonts(Document&);
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/ElementRuleCollector.cpp b/Source/core/css/ElementRuleCollector.cpp
index 53bd4fb..cfc7ce3 100644
--- a/Source/core/css/ElementRuleCollector.cpp
+++ b/Source/core/css/ElementRuleCollector.cpp
@@ -72,7 +72,7 @@
     return m_styleRuleList.release();
 }
 
-PassRefPtr<CSSRuleList> ElementRuleCollector::matchedCSSRuleList()
+PassRefPtrWillBeRawPtr<CSSRuleList> ElementRuleCollector::matchedCSSRuleList()
 {
     ASSERT(m_mode == SelectorChecker::CollectingCSSRules);
     return m_cssRuleList.release();
@@ -218,7 +218,11 @@
     // |parentStyleSheet| is 0 if and only if the |rule| is coming from User Agent. In this case,
     // it is safe to create CSSOM wrappers without parentStyleSheets as they will be used only
     // by inspector which will not try to edit them.
-    RefPtr<CSSRule> cssRule = parentStyleSheet ? findStyleRule(parentStyleSheet, rule) : rule->createCSSOMWrapper();
+    RefPtrWillBeRawPtr<CSSRule> cssRule;
+    if (parentStyleSheet)
+        cssRule = findStyleRule(parentStyleSheet, rule);
+    else
+        cssRule = rule->createCSSOMWrapper();
     ASSERT(!parentStyleSheet || cssRule);
     ensureRuleList()->rules().append(cssRule);
 }
@@ -249,7 +253,7 @@
         const RuleData* ruleData = matchedRules[i].ruleData();
         if (m_style && ruleData->containsUncommonAttributeSelector())
             m_style->setUnique();
-        m_result.addMatchedProperties(ruleData->rule()->properties(), ruleData->rule(), ruleData->linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules));
+        m_result.addMatchedProperties(&ruleData->rule()->properties(), ruleData->rule(), ruleData->linkMatchType(), ruleData->propertyWhitelistType(m_matchingUARules));
     }
 }
 
@@ -303,8 +307,8 @@
     SelectorChecker::MatchResult result;
     if (ruleMatches(ruleData, matchRequest.scope, behaviorAtBoundary, &result)) {
         // If the rule has no properties to apply, then ignore it in the non-debug mode.
-        const StylePropertySet* properties = rule->properties();
-        if (!properties || (properties->isEmpty() && !matchRequest.includeEmptyRules))
+        const StylePropertySet& properties = rule->properties();
+        if (properties.isEmpty() && !matchRequest.includeEmptyRules)
             return;
         // FIXME: Exposing the non-standard getMatchedCSSRules API to web is the only reason this is needed.
         if (m_sameOriginOnly && !ruleData.hasDocumentSecurityOrigin())
@@ -332,24 +336,6 @@
     }
 }
 
-void ElementRuleCollector::collectMatchingRulesForList(const RuleData* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
-{
-    if (!rules)
-        return;
-    while (!rules->isLastInArray())
-        collectRuleIfMatches(*rules++, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
-    collectRuleIfMatches(*rules, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
-}
-
-void ElementRuleCollector::collectMatchingRulesForList(const Vector<RuleData>* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
-{
-    if (!rules)
-        return;
-    unsigned size = rules->size();
-    for (unsigned i = 0; i < size; ++i)
-        collectRuleIfMatches(rules->at(i), behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
-}
-
 static inline bool compareRules(const MatchedRule& matchedRule1, const MatchedRule& matchedRule2)
 {
     if (matchedRule1.cascadeScope() != matchedRule2.cascadeScope())
diff --git a/Source/core/css/ElementRuleCollector.h b/Source/core/css/ElementRuleCollector.h
index dbab0fe..5c169b6 100644
--- a/Source/core/css/ElementRuleCollector.h
+++ b/Source/core/css/ElementRuleCollector.h
@@ -75,10 +75,11 @@
     const CSSStyleSheet* m_parentStyleSheet;
 };
 
+// FIXME: oilpan: when transition types are gone this class can be replaced with HeapVector.
 class StyleRuleList : public RefCounted<StyleRuleList> {
 public:
     static PassRefPtr<StyleRuleList> create() { return adoptRef(new StyleRuleList()); }
-    Vector<StyleRule*> m_list;
+    WillBePersistentHeapVector<RawPtrWillBeMember<StyleRule> > m_list;
 };
 
 // ElementRuleCollector is designed to be used as a stack object.
@@ -86,6 +87,7 @@
 // and then let it go out of scope.
 // FIXME: Currently it modifies the RenderStyle but should not!
 class ElementRuleCollector {
+    STACK_ALLOCATED();
     WTF_MAKE_NONCOPYABLE(ElementRuleCollector);
 public:
     ElementRuleCollector(const ElementResolveContext&, const SelectorFilter&, RenderStyle* = 0);
@@ -100,7 +102,7 @@
 
     MatchResult& matchedResult();
     PassRefPtr<StyleRuleList> matchedStyleRuleList();
-    PassRefPtr<CSSRuleList> matchedCSSRuleList();
+    PassRefPtrWillBeRawPtr<CSSRuleList> matchedCSSRuleList();
 
     void collectMatchingRules(const MatchRequest&, RuleRange&, SelectorChecker::BehaviorAtBoundary = SelectorChecker::DoesNotCrossBoundary, CascadeScope = ignoreCascadeScope, CascadeOrder = ignoreCascadeOrder);
     void sortAndTransferMatchedRules();
@@ -113,8 +115,17 @@
 
 private:
     void collectRuleIfMatches(const RuleData&, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
-    void collectMatchingRulesForList(const Vector<RuleData>*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
-    void collectMatchingRulesForList(const RuleData*, SelectorChecker::BehaviorAtBoundary, CascadeScope, CascadeOrder, const MatchRequest&, RuleRange&);
+
+    template<typename RuleDataListType>
+    void collectMatchingRulesForList(const RuleDataListType* rules, SelectorChecker::BehaviorAtBoundary behaviorAtBoundary, CascadeScope cascadeScope, CascadeOrder cascadeOrder, const MatchRequest& matchRequest, RuleRange& ruleRange)
+    {
+        if (!rules)
+            return;
+
+        for (typename RuleDataListType::const_iterator it = rules->begin(), end = rules->end(); it != end; ++it)
+            collectRuleIfMatches(*it, behaviorAtBoundary, cascadeScope, cascadeOrder, matchRequest, ruleRange);
+    }
+
     bool ruleMatches(const RuleData&, const ContainerNode* scope, SelectorChecker::BehaviorAtBoundary, SelectorChecker::MatchResult*);
 
     CSSRuleList* nestedRuleList(CSSRule*);
@@ -142,7 +153,7 @@
     OwnPtr<Vector<MatchedRule, 32> > m_matchedRules;
 
     // Output.
-    RefPtr<StaticCSSRuleList> m_cssRuleList;
+    RefPtrWillBeMember<StaticCSSRuleList> m_cssRuleList;
     RefPtr<StyleRuleList> m_styleRuleList;
     MatchResult m_result;
 };
diff --git a/Source/core/css/FontFace.cpp b/Source/core/css/FontFace.cpp
index 6169ab4..34d2095 100644
--- a/Source/core/css/FontFace.cpp
+++ b/Source/core/css/FontFace.cpp
@@ -38,12 +38,15 @@
 #include "bindings/v8/ScriptPromiseResolver.h"
 #include "bindings/v8/ScriptScope.h"
 #include "bindings/v8/ScriptState.h"
+#include "core/css/BinaryDataFontFaceSource.h"
 #include "core/css/CSSFontFace.h"
 #include "core/css/CSSFontFaceSrcValue.h"
 #include "core/css/CSSFontSelector.h"
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSUnicodeRangeValue.h"
 #include "core/css/CSSValueList.h"
+#include "core/css/LocalFontFaceSource.h"
+#include "core/css/RemoteFontFaceSource.h"
 #include "core/css/StylePropertySet.h"
 #include "core/css/StyleRule.h"
 #include "core/css/parser/BisonCSSParser.h"
@@ -51,19 +54,21 @@
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/StyleEngine.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/svg/SVGFontFaceElement.h"
+#include "core/svg/SVGFontFaceSource.h"
+#include "core/svg/SVGRemoteFontFaceSource.h"
+#include "platform/SharedBuffer.h"
 #include "platform/fonts/FontDescription.h"
-#include "platform/fonts/FontTraitsMask.h"
 
 namespace WebCore {
 
 class FontFaceReadyPromiseResolver {
 public:
-    static PassOwnPtr<FontFaceReadyPromiseResolver> create(ScriptPromise promise, ExecutionContext* context)
+    static PassOwnPtr<FontFaceReadyPromiseResolver> create(ExecutionContext* context)
     {
-        return adoptPtr(new FontFaceReadyPromiseResolver(promise, context));
+        return adoptPtr(new FontFaceReadyPromiseResolver(context));
     }
 
     void resolve(PassRefPtr<FontFace> fontFace)
@@ -74,93 +79,116 @@
             m_resolver->resolve(fontFace);
             break;
         case FontFace::Error:
-            m_resolver->reject(DOMError::create(NetworkError));
+            m_resolver->reject(fontFace->error());
             break;
         default:
             ASSERT_NOT_REACHED();
         }
     }
 
+    ScriptPromise promise() { return m_resolver->promise(); }
+
 private:
-    FontFaceReadyPromiseResolver(ScriptPromise promise, ExecutionContext* context)
+    FontFaceReadyPromiseResolver(ExecutionContext* context)
         : m_scriptState(ScriptState::current())
-        , m_resolver(ScriptPromiseResolver::create(promise, context))
+        , m_resolver(ScriptPromiseResolver::create(context))
     { }
     ScriptState* m_scriptState;
     RefPtr<ScriptPromiseResolver> m_resolver;
 };
 
-static PassRefPtr<CSSValue> parseCSSValue(const Document* document, const String& s, CSSPropertyID propertyID)
+static PassRefPtrWillBeRawPtr<CSSValue> parseCSSValue(const Document* document, const String& s, CSSPropertyID propertyID)
 {
     if (s.isEmpty())
-        return 0;
+        return nullptr;
     RefPtr<MutableStylePropertySet> parsedStyle = MutableStylePropertySet::create();
     BisonCSSParser::parseValue(parsedStyle.get(), propertyID, s, true, *document);
     return parsedStyle->getPropertyCSSValue(propertyID);
 }
 
-PassRefPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, const String& source, const Dictionary& descriptors, ExceptionState& exceptionState)
+static bool initFontFace(FontFace* fontFace, ExecutionContext* context, const AtomicString& family, const Dictionary& descriptors, ExceptionState& exceptionState)
 {
-    RefPtr<CSSValue> src = parseCSSValue(toDocument(context), source, CSSPropertySrc);
-    if (!src || !src->isValueList()) {
-        exceptionState.throwDOMException(SyntaxError, "The source provided ('" + source + "') could not be parsed as a value list.");
-        return 0;
-    }
-
-    RefPtr<FontFace> fontFace = adoptRef<FontFace>(new FontFace(src));
     fontFace->setFamily(context, family, exceptionState);
     if (exceptionState.hadException())
-        return 0;
+        return false;
 
     String value;
     if (descriptors.get("style", value)) {
         fontFace->setStyle(context, value, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return false;
     }
     if (descriptors.get("weight", value)) {
         fontFace->setWeight(context, value, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return false;
     }
     if (descriptors.get("stretch", value)) {
         fontFace->setStretch(context, value, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return false;
     }
     if (descriptors.get("unicodeRange", value)) {
         fontFace->setUnicodeRange(context, value, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return false;
     }
     if (descriptors.get("variant", value)) {
         fontFace->setVariant(context, value, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return false;
     }
     if (descriptors.get("featureSettings", value)) {
         fontFace->setFeatureSettings(context, value, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return false;
+    }
+    return true;
+}
+
+PassRefPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, const String& source, const Dictionary& descriptors, ExceptionState& exceptionState)
+{
+    RefPtrWillBeRawPtr<CSSValue> src = parseCSSValue(toDocument(context), source, CSSPropertySrc);
+    if (!src || !src->isValueList()) {
+        exceptionState.throwDOMException(SyntaxError, "The source provided ('" + source + "') could not be parsed as a value list.");
+        return nullptr;
     }
 
-    fontFace->initCSSFontFace(toDocument(context));
-    return fontFace;
+    RefPtr<FontFace> fontFace = adoptRefWillBeRefCountedGarbageCollected<FontFace>(new FontFace());
+    if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState))
+        fontFace->initCSSFontFace(toDocument(context), src);
+    return fontFace.release();
+}
+
+PassRefPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, PassRefPtr<ArrayBuffer> source, const Dictionary& descriptors, ExceptionState& exceptionState)
+{
+    RefPtr<FontFace> fontFace = adoptRefWillBeRefCountedGarbageCollected<FontFace>(new FontFace());
+    if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState))
+        fontFace->initCSSFontFace(static_cast<const unsigned char*>(source->data()), source->byteLength());
+    return fontFace.release();
+}
+
+PassRefPtr<FontFace> FontFace::create(ExecutionContext* context, const AtomicString& family, PassRefPtr<ArrayBufferView> source, const Dictionary& descriptors, ExceptionState& exceptionState)
+{
+    RefPtr<FontFace> fontFace = adoptRefWillBeRefCountedGarbageCollected<FontFace>(new FontFace());
+    if (initFontFace(fontFace.get(), context, family, descriptors, exceptionState))
+        fontFace->initCSSFontFace(static_cast<const unsigned char*>(source->baseAddress()), source->byteLength());
+    return fontFace.release();
 }
 
 PassRefPtr<FontFace> FontFace::create(Document* document, const StyleRuleFontFace* fontFaceRule)
 {
-    const StylePropertySet* properties = fontFaceRule->properties();
+    const StylePropertySet& properties = fontFaceRule->properties();
 
     // Obtain the font-family property and the src property. Both must be defined.
-    RefPtr<CSSValue> family = properties->getPropertyCSSValue(CSSPropertyFontFamily);
+    RefPtrWillBeRawPtr<CSSValue> family = properties.getPropertyCSSValue(CSSPropertyFontFamily);
     if (!family || !family->isValueList())
-        return 0;
-    RefPtr<CSSValue> src = properties->getPropertyCSSValue(CSSPropertySrc);
+        return nullptr;
+    RefPtrWillBeRawPtr<CSSValue> src = properties.getPropertyCSSValue(CSSPropertySrc);
     if (!src || !src->isValueList())
-        return 0;
+        return nullptr;
 
-    RefPtr<FontFace> fontFace = adoptRef<FontFace>(new FontFace(src));
+    RefPtr<FontFace> fontFace = adoptRefWillBeRefCountedGarbageCollected<FontFace>(new FontFace());
 
     if (fontFace->setFamilyValue(toCSSValueList(family.get()))
         && fontFace->setPropertyFromStyle(properties, CSSPropertyFontStyle)
@@ -170,16 +198,15 @@
         && fontFace->setPropertyFromStyle(properties, CSSPropertyFontVariant)
         && fontFace->setPropertyFromStyle(properties, CSSPropertyWebkitFontFeatureSettings)
         && !fontFace->family().isEmpty()
-        && fontFace->traitsMask()) {
-        fontFace->initCSSFontFace(document);
-        return fontFace;
+        && fontFace->traits().mask()) {
+        fontFace->initCSSFontFace(document, src);
+        return fontFace.release();
     }
-    return 0;
+    return nullptr;
 }
 
-FontFace::FontFace(PassRefPtr<CSSValue> src)
-    : m_src(src)
-    , m_status(Unloaded)
+FontFace::FontFace()
+    : m_status(Unloaded)
 {
 }
 
@@ -249,17 +276,17 @@
 
 void FontFace::setPropertyFromString(const Document* document, const String& s, CSSPropertyID propertyID, ExceptionState& exceptionState)
 {
-    RefPtr<CSSValue> value = parseCSSValue(document, s, propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = parseCSSValue(document, s, propertyID);
     if (!value || !setPropertyValue(value, propertyID))
         exceptionState.throwDOMException(SyntaxError, "Failed to set '" + s + "' as a property value.");
 }
 
-bool FontFace::setPropertyFromStyle(const StylePropertySet* properties, CSSPropertyID propertyID)
+bool FontFace::setPropertyFromStyle(const StylePropertySet& properties, CSSPropertyID propertyID)
 {
-    return setPropertyValue(properties->getPropertyCSSValue(propertyID), propertyID);
+    return setPropertyValue(properties.getPropertyCSSValue(propertyID), propertyID);
 }
 
-bool FontFace::setPropertyValue(PassRefPtr<CSSValue> value, CSSPropertyID propertyID)
+bool FontFace::setPropertyValue(PassRefPtrWillBeRawPtr<CSSValue> value, CSSPropertyID propertyID)
 {
     switch (propertyID) {
     case CSSPropertyFontStyle:
@@ -349,6 +376,8 @@
 void FontFace::setLoadStatus(LoadStatus status)
 {
     m_status = status;
+    if (m_status == Error)
+        m_error = DOMError::create(NetworkError);
     if (m_status == Loaded || m_status == Error)
         resolveReadyPromises();
 }
@@ -362,7 +391,7 @@
     FontFamily fontFamily;
     fontFamily.setFamily(m_family);
     fontDescription.setFamily(fontFamily);
-    fontDescription.setTraitsMask(static_cast<FontTraitsMask>(traitsMask()));
+    fontDescription.setTraits(traits());
 
     CSSFontSelector* fontSelector = toDocument(context)->styleEngine()->fontSelector();
     m_cssFontFace->load(fontDescription, fontSelector);
@@ -371,8 +400,8 @@
 
 ScriptPromise FontFace::ready(ExecutionContext* context)
 {
-    ScriptPromise promise = ScriptPromise::createPending(context);
-    OwnPtr<FontFaceReadyPromiseResolver> resolver = FontFaceReadyPromiseResolver::create(promise, context);
+    OwnPtr<FontFaceReadyPromiseResolver> resolver = FontFaceReadyPromiseResolver::create(context);
+    ScriptPromise promise = resolver->promise();
     if (m_status == Loaded || m_status == Error)
         resolver->resolve(this);
     else
@@ -387,29 +416,27 @@
     m_readyResolvers.clear();
 }
 
-unsigned FontFace::traitsMask() const
+FontTraits FontFace::traits() const
 {
-    unsigned traitsMask = 0;
-
+    FontStyle style = FontStyleNormal;
     if (m_style) {
         if (!m_style->isPrimitiveValue())
             return 0;
 
         switch (toCSSPrimitiveValue(m_style.get())->getValueID()) {
         case CSSValueNormal:
-            traitsMask |= FontStyleNormalMask;
+            style = FontStyleNormal;
             break;
         case CSSValueItalic:
         case CSSValueOblique:
-            traitsMask |= FontStyleItalicMask;
+            style = FontStyleItalic;
             break;
         default:
             break;
         }
-    } else {
-        traitsMask |= FontStyleNormalMask;
     }
 
+    FontWeight weight = FontWeight400;
     if (m_weight) {
         if (!m_weight->isPrimitiveValue())
             return 0;
@@ -417,43 +444,42 @@
         switch (toCSSPrimitiveValue(m_weight.get())->getValueID()) {
         case CSSValueBold:
         case CSSValue700:
-            traitsMask |= FontWeight700Mask;
+            weight = FontWeight700;
             break;
         case CSSValueNormal:
         case CSSValue400:
-            traitsMask |= FontWeight400Mask;
+            weight = FontWeight400;
             break;
         case CSSValue900:
-            traitsMask |= FontWeight900Mask;
+            weight = FontWeight900;
             break;
         case CSSValue800:
-            traitsMask |= FontWeight800Mask;
+            weight = FontWeight800;
             break;
         case CSSValue600:
-            traitsMask |= FontWeight600Mask;
+            weight = FontWeight600;
             break;
         case CSSValue500:
-            traitsMask |= FontWeight500Mask;
+            weight = FontWeight500;
             break;
         case CSSValue300:
-            traitsMask |= FontWeight300Mask;
+            weight = FontWeight300;
             break;
         case CSSValue200:
-            traitsMask |= FontWeight200Mask;
+            weight = FontWeight200;
             break;
         case CSSValueLighter:
         case CSSValue100:
-            traitsMask |= FontWeight100Mask;
+            weight = FontWeight100;
             break;
         default:
             ASSERT_NOT_REACHED();
             break;
         }
-    } else {
-        traitsMask |= FontWeight400Mask;
     }
 
-    if (RefPtr<CSSValue> fontVariant = m_variant) {
+    FontVariant variant = FontVariantNormal;
+    if (RefPtrWillBeRawPtr<CSSValue> fontVariant = m_variant) {
         // font-variant descriptor can be a value list.
         if (fontVariant->isPrimitiveValue()) {
             RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
@@ -471,28 +497,40 @@
         for (unsigned i = 0; i < numVariants; ++i) {
             switch (toCSSPrimitiveValue(variantList->itemWithoutBoundsCheck(i))->getValueID()) {
             case CSSValueNormal:
-                traitsMask |= FontVariantNormalMask;
+                variant = FontVariantNormal;
                 break;
             case CSSValueSmallCaps:
-                traitsMask |= FontVariantSmallCapsMask;
+                variant = FontVariantSmallCaps;
                 break;
             default:
                 break;
             }
         }
-    } else {
-        traitsMask |= FontVariantNormalMask;
     }
-    return traitsMask;
+
+    return FontTraits(style, variant, weight, FontStretchNormal);
 }
 
-void FontFace::initCSSFontFace(Document* document)
+static PassOwnPtr<CSSFontFace> createCSSFontFace(FontFace* fontFace, CSSValue* unicodeRange)
 {
-    ASSERT(!m_cssFontFace);
-    m_cssFontFace = adoptPtr(new CSSFontFace(this));
+    Vector<CSSFontFace::UnicodeRange> ranges;
+    if (CSSValueList* rangeList = toCSSValueList(unicodeRange)) {
+        unsigned numRanges = rangeList->length();
+        for (unsigned i = 0; i < numRanges; i++) {
+            CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i));
+            ranges.append(CSSFontFace::UnicodeRange(range->from(), range->to()));
+        }
+    }
+
+    return adoptPtr(new CSSFontFace(fontFace, ranges));
+}
+
+void FontFace::initCSSFontFace(Document* document, PassRefPtrWillBeRawPtr<CSSValue> src)
+{
+    m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get());
 
     // Each item in the src property's list is a single CSSFontFaceSource. Put them all into a CSSFontFace.
-    CSSValueList* srcList = toCSSValueList(m_src.get());
+    CSSValueList* srcList = toCSSValueList(src.get());
     int srcLength = srcList->length();
 
     bool foundSVGFont = false;
@@ -511,32 +549,62 @@
             if (allowDownloading && item->isSupportedFormat() && document) {
                 FontResource* fetched = item->fetch(document);
                 if (fetched) {
-                    source = adoptPtr(new CSSFontFaceSource(item->resource(), fetched));
 #if ENABLE(SVG_FONTS)
-                    if (foundSVGFont)
-                        source->setHasExternalSVGFont(true);
+                    if (foundSVGFont) {
+                        source = adoptPtr(new SVGRemoteFontFaceSource(item->resource(), fetched));
+                    } else
 #endif
+                    {
+                        source = adoptPtr(new RemoteFontFaceSource(fetched));
+                    }
                 }
             }
         } else {
-            source = adoptPtr(new CSSFontFaceSource(item->resource()));
-        }
-
-        if (source) {
 #if ENABLE(SVG_FONTS)
-            source->setSVGFontFaceElement(item->svgFontFaceElement());
+            if (item->svgFontFaceElement()) {
+                source = adoptPtr(new SVGFontFaceSource(item->svgFontFaceElement()));
+            } else
 #endif
-            m_cssFontFace->addSource(source.release());
+            {
+                source = adoptPtr(new LocalFontFaceSource(item->resource()));
+            }
         }
-    }
 
-    if (CSSValueList* rangeList = toCSSValueList(m_unicodeRange.get())) {
-        unsigned numRanges = rangeList->length();
-        for (unsigned i = 0; i < numRanges; i++) {
-            CSSUnicodeRangeValue* range = toCSSUnicodeRangeValue(rangeList->itemWithoutBoundsCheck(i));
-            m_cssFontFace->ranges().add(range->from(), range->to());
-        }
+        if (source)
+            m_cssFontFace->addSource(source.release());
     }
 }
 
+void FontFace::initCSSFontFace(const unsigned char* data, unsigned size)
+{
+    m_cssFontFace = createCSSFontFace(this, m_unicodeRange.get());
+
+    RefPtr<SharedBuffer> buffer = SharedBuffer::create(data, size);
+    OwnPtr<BinaryDataFontFaceSource> source = adoptPtr(new BinaryDataFontFaceSource(buffer.get()));
+    if (source->isValid()) {
+        m_status = Loaded;
+    } else {
+        m_status = Error;
+        m_error = DOMError::create(SyntaxError, "Invalid font data in ArrayBuffer.");
+    }
+    m_cssFontFace->addSource(source.release());
+}
+
+void FontFace::trace(Visitor* visitor)
+{
+    visitor->trace(m_src);
+    visitor->trace(m_style);
+    visitor->trace(m_weight);
+    visitor->trace(m_stretch);
+    visitor->trace(m_unicodeRange);
+    visitor->trace(m_variant);
+    visitor->trace(m_featureSettings);
+    visitor->trace(m_error);
+}
+
+bool FontFace::hadBlankText() const
+{
+    return m_cssFontFace->hadBlankText();
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/FontFace.h b/Source/core/css/FontFace.h
index 4acea31..5379cff 100644
--- a/Source/core/css/FontFace.h
+++ b/Source/core/css/FontFace.h
@@ -34,6 +34,8 @@
 #include "CSSPropertyNames.h"
 #include "bindings/v8/ScriptPromise.h"
 #include "core/css/CSSValue.h"
+#include "core/dom/DOMError.h"
+#include "platform/fonts/FontTraits.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
@@ -49,10 +51,12 @@
 class StylePropertySet;
 class StyleRuleFontFace;
 
-class FontFace : public RefCounted<FontFace> {
+class FontFace : public RefCountedWillBeRefCountedGarbageCollected<FontFace> {
 public:
     enum LoadStatus { Unloaded, Loading, Loaded, Error };
 
+    static PassRefPtr<FontFace> create(ExecutionContext*, const AtomicString& family, PassRefPtr<ArrayBuffer> source, const Dictionary&, ExceptionState&);
+    static PassRefPtr<FontFace> create(ExecutionContext*, const AtomicString& family, PassRefPtr<ArrayBufferView>, const Dictionary&, ExceptionState&);
     static PassRefPtr<FontFace> create(ExecutionContext*, const AtomicString& family, const String& source, const Dictionary&, ExceptionState&);
     static PassRefPtr<FontFace> create(Document*, const StyleRuleFontFace*);
 
@@ -82,28 +86,35 @@
 
     LoadStatus loadStatus() const { return m_status; }
     void setLoadStatus(LoadStatus);
-    unsigned traitsMask() const;
+    DOMError* error() const { return m_error.get(); }
+    FontTraits traits() const;
     CSSFontFace* cssFontFace() { return m_cssFontFace.get(); }
 
-private:
-    FontFace(PassRefPtr<CSSValue> source);
+    void trace(Visitor*);
 
-    void initCSSFontFace(Document*);
+    bool hadBlankText() const;
+
+private:
+    FontFace();
+
+    void initCSSFontFace(Document*, PassRefPtrWillBeRawPtr<CSSValue> src);
+    void initCSSFontFace(const unsigned char* data, unsigned size);
     void setPropertyFromString(const Document*, const String&, CSSPropertyID, ExceptionState&);
-    bool setPropertyFromStyle(const StylePropertySet*, CSSPropertyID);
-    bool setPropertyValue(PassRefPtr<CSSValue>, CSSPropertyID);
+    bool setPropertyFromStyle(const StylePropertySet&, CSSPropertyID);
+    bool setPropertyValue(PassRefPtrWillBeRawPtr<CSSValue>, CSSPropertyID);
     bool setFamilyValue(CSSValueList*);
     void resolveReadyPromises();
 
     AtomicString m_family;
-    RefPtr<CSSValue> m_src;
-    RefPtr<CSSValue> m_style;
-    RefPtr<CSSValue> m_weight;
-    RefPtr<CSSValue> m_stretch;
-    RefPtr<CSSValue> m_unicodeRange;
-    RefPtr<CSSValue> m_variant;
-    RefPtr<CSSValue> m_featureSettings;
+    RefPtrWillBeMember<CSSValue> m_src;
+    RefPtrWillBeMember<CSSValue> m_style;
+    RefPtrWillBeMember<CSSValue> m_weight;
+    RefPtrWillBeMember<CSSValue> m_stretch;
+    RefPtrWillBeMember<CSSValue> m_unicodeRange;
+    RefPtrWillBeMember<CSSValue> m_variant;
+    RefPtrWillBeMember<CSSValue> m_featureSettings;
     LoadStatus m_status;
+    RefPtrWillBeMember<DOMError> m_error;
 
     Vector<OwnPtr<FontFaceReadyPromiseResolver> > m_readyResolvers;
     OwnPtr<CSSFontFace> m_cssFontFace;
diff --git a/Source/core/css/FontFace.idl b/Source/core/css/FontFace.idl
index 922be52..a3a0809 100644
--- a/Source/core/css/FontFace.idl
+++ b/Source/core/css/FontFace.idl
@@ -37,6 +37,8 @@
 
 [
     RuntimeEnabled=FontLoadEvents,
+    Constructor(DOMString family, ArrayBuffer source, Dictionary descriptors),
+    Constructor(DOMString family, ArrayBufferView source, Dictionary descriptors),
     Constructor(DOMString family, DOMString source, Dictionary descriptors),
     ConstructorCallWith=ExecutionContext,
     RaisesException=Constructor
diff --git a/Source/core/css/FontFaceCache.cpp b/Source/core/css/FontFaceCache.cpp
index 6c4c9b5..a85e9fa 100644
--- a/Source/core/css/FontFaceCache.cpp
+++ b/Source/core/css/FontFaceCache.cpp
@@ -62,9 +62,9 @@
     if (!familyFontFaces)
         familyFontFaces = adoptPtr(new TraitsMap);
 
-    RefPtr<CSSSegmentedFontFace>& segmentedFontFace = familyFontFaces->add(fontFace->traitsMask(), 0).storedValue->value;
+    RefPtr<CSSSegmentedFontFace>& segmentedFontFace = familyFontFaces->add(fontFace->traits().mask(), nullptr).storedValue->value;
     if (!segmentedFontFace)
-        segmentedFontFace = CSSSegmentedFontFace::create(cssFontSelector, static_cast<FontTraitsMask>(fontFace->traitsMask()));
+        segmentedFontFace = CSSSegmentedFontFace::create(cssFontSelector, fontFace->traits());
 
     segmentedFontFace->addFontFace(fontFace, cssConnected);
     if (cssConnected)
@@ -89,7 +89,7 @@
         return;
     TraitsMap* familyFontFaces = fontFacesIter->value.get();
 
-    TraitsMap::iterator familyFontFacesIter = familyFontFaces->find(fontFace->traitsMask());
+    TraitsMap::iterator familyFontFacesIter = familyFontFaces->find(fontFace->traits().mask());
     if (familyFontFacesIter == familyFontFaces->end())
         return;
     RefPtr<CSSSegmentedFontFace> segmentedFontFace = familyFontFacesIter->value;
@@ -114,45 +114,45 @@
     m_styleRuleToFontFace.clear();
 }
 
-static inline bool compareFontFaces(CSSSegmentedFontFace* first, CSSSegmentedFontFace* second, FontTraitsMask desiredTraitsMask)
+static inline bool compareFontFaces(CSSSegmentedFontFace* first, CSSSegmentedFontFace* second, FontTraits desiredTraits)
 {
-    FontTraitsMask firstTraitsMask = first->traitsMask();
-    FontTraitsMask secondTraitsMask = second->traitsMask();
+    const FontTraits& firstTraits = first->traits();
+    const FontTraits& secondTraits = second->traits();
 
-    bool firstHasDesiredVariant = firstTraitsMask & desiredTraitsMask & FontVariantMask;
-    bool secondHasDesiredVariant = secondTraitsMask & desiredTraitsMask & FontVariantMask;
+    bool firstHasDesiredVariant = firstTraits.variant() == desiredTraits.variant();
+    bool secondHasDesiredVariant = secondTraits.variant() == desiredTraits.variant();
 
     if (firstHasDesiredVariant != secondHasDesiredVariant)
         return firstHasDesiredVariant;
 
     // We need to check font-variant css property for CSS2.1 compatibility.
-    if (desiredTraitsMask & FontVariantSmallCapsMask) {
+    if (desiredTraits.variant() == FontVariantSmallCaps) {
         // Prefer a font that has indicated that it can only support small-caps to a font that claims to support
         // all variants. The specialized font is more likely to be true small-caps and not require synthesis.
-        bool firstRequiresSmallCaps = (firstTraitsMask & FontVariantSmallCapsMask) && !(firstTraitsMask & FontVariantNormalMask);
-        bool secondRequiresSmallCaps = (secondTraitsMask & FontVariantSmallCapsMask) && !(secondTraitsMask & FontVariantNormalMask);
+        bool firstRequiresSmallCaps = firstTraits.variant() == FontVariantSmallCaps;
+        bool secondRequiresSmallCaps = secondTraits.variant() == FontVariantSmallCaps;
         if (firstRequiresSmallCaps != secondRequiresSmallCaps)
             return firstRequiresSmallCaps;
     }
 
-    bool firstHasDesiredStyle = firstTraitsMask & desiredTraitsMask & FontStyleMask;
-    bool secondHasDesiredStyle = secondTraitsMask & desiredTraitsMask & FontStyleMask;
+    bool firstHasDesiredStyle = firstTraits.style() == desiredTraits.style();
+    bool secondHasDesiredStyle = secondTraits.style() == desiredTraits.style();
 
     if (firstHasDesiredStyle != secondHasDesiredStyle)
         return firstHasDesiredStyle;
 
-    if (desiredTraitsMask & FontStyleItalicMask) {
+    if (desiredTraits.style() == FontStyleItalic) {
         // Prefer a font that has indicated that it can only support italics to a font that claims to support
         // all styles. The specialized font is more likely to be the one the author wants used.
-        bool firstRequiresItalics = (firstTraitsMask & FontStyleItalicMask) && !(firstTraitsMask & FontStyleNormalMask);
-        bool secondRequiresItalics = (secondTraitsMask & FontStyleItalicMask) && !(secondTraitsMask & FontStyleNormalMask);
+        bool firstRequiresItalics = firstTraits.style() == FontStyleItalic;
+        bool secondRequiresItalics = secondTraits.style() == FontStyleItalic;
         if (firstRequiresItalics != secondRequiresItalics)
             return firstRequiresItalics;
     }
-
-    if (secondTraitsMask & desiredTraitsMask & FontWeightMask)
+    if (secondTraits.weight() == desiredTraits.weight())
         return false;
-    if (firstTraitsMask & desiredTraitsMask & FontWeightMask)
+
+    if (firstTraits.weight() == desiredTraits.weight())
         return true;
 
     // http://www.w3.org/TR/2011/WD-css3-fonts-20111004/#font-matching-algorithm says :
@@ -160,34 +160,27 @@
     //   - If the desired weight is greater than 500, weights above the desired weight are checked in ascending order followed by weights below the desired weight in descending order until a match is found.
     //   - If the desired weight is 400, 500 is checked first and then the rule for desired weights less than 400 is used.
     //   - If the desired weight is 500, 400 is checked first and then the rule for desired weights less than 400 is used.
-
     static const unsigned fallbackRuleSets = 9;
     static const unsigned rulesPerSet = 8;
-    static const FontTraitsMask weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = {
-        { FontWeight200Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight100Mask, FontWeight300Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight200Mask, FontWeight100Mask, FontWeight400Mask, FontWeight500Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight500Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask, FontWeight600Mask, FontWeight700Mask, FontWeight800Mask, FontWeight900Mask },
-        { FontWeight700Mask, FontWeight800Mask, FontWeight900Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
-        { FontWeight800Mask, FontWeight900Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
-        { FontWeight900Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask },
-        { FontWeight800Mask, FontWeight700Mask, FontWeight600Mask, FontWeight500Mask, FontWeight400Mask, FontWeight300Mask, FontWeight200Mask, FontWeight100Mask }
+    static const FontWeight weightFallbackRuleSets[fallbackRuleSets][rulesPerSet] = {
+        { FontWeight200, FontWeight300, FontWeight400, FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+        { FontWeight100, FontWeight300, FontWeight400, FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+        { FontWeight200, FontWeight100, FontWeight400, FontWeight500, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+        { FontWeight500, FontWeight300, FontWeight200, FontWeight100, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+        { FontWeight400, FontWeight300, FontWeight200, FontWeight100, FontWeight600, FontWeight700, FontWeight800, FontWeight900 },
+        { FontWeight700, FontWeight800, FontWeight900, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 },
+        { FontWeight800, FontWeight900, FontWeight600, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 },
+        { FontWeight900, FontWeight700, FontWeight600, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 },
+        { FontWeight800, FontWeight700, FontWeight600, FontWeight500, FontWeight400, FontWeight300, FontWeight200, FontWeight100 }
     };
 
-    unsigned ruleSetIndex = 0;
-    unsigned w = FontWeight100Bit;
-    while (!(desiredTraitsMask & (1 << w))) {
-        w++;
-        ruleSetIndex++;
-    }
-
+    unsigned ruleSetIndex = static_cast<unsigned>(desiredTraits.weight());
     ASSERT(ruleSetIndex < fallbackRuleSets);
-    const FontTraitsMask* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex];
+    const FontWeight* weightFallbackRule = weightFallbackRuleSets[ruleSetIndex];
     for (unsigned i = 0; i < rulesPerSet; ++i) {
-        if (secondTraitsMask & weightFallbackRule[i])
+        if (secondTraits.weight() == weightFallbackRule[i])
             return false;
-        if (firstTraitsMask & weightFallbackRule[i])
+        if (firstTraits.weight() == weightFallbackRule[i])
             return true;
     }
 
@@ -204,18 +197,17 @@
     if (!segmentedFontFaceCache)
         segmentedFontFaceCache = adoptPtr(new TraitsMap);
 
-    FontTraitsMask traitsMask = fontDescription.traitsMask();
-
-    RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traitsMask, 0).storedValue->value;
+    FontTraits traits = fontDescription.traits();
+    RefPtr<CSSSegmentedFontFace>& face = segmentedFontFaceCache->add(traits.mask(), nullptr).storedValue->value;
     if (!face) {
         for (TraitsMap::const_iterator i = familyFontFaces->begin(); i != familyFontFaces->end(); ++i) {
             CSSSegmentedFontFace* candidate = i->value.get();
-            unsigned candidateTraitsMask = candidate->traitsMask();
-            if ((traitsMask & FontStyleNormalMask) && !(candidateTraitsMask & FontStyleNormalMask))
+            FontTraits candidateTraits = candidate->traits();
+            if (traits.style() == FontStyleNormal && candidateTraits.style() != FontStyleNormal)
                 continue;
-            if ((traitsMask & FontVariantNormalMask) && !(candidateTraitsMask & FontVariantNormalMask))
+            if (traits.variant() == FontVariantNormal && candidateTraits.variant() != FontVariantNormal)
                 continue;
-            if (!face || compareFontFaces(candidate, face.get(), traitsMask))
+            if (!face || compareFontFaces(candidate, face.get(), traits))
                 face = candidate;
         }
     }
diff --git a/Source/core/css/FontFaceSet.cpp b/Source/core/css/FontFaceSet.cpp
index af5f8d5..54e200d 100644
--- a/Source/core/css/FontFaceSet.cpp
+++ b/Source/core/css/FontFaceSet.cpp
@@ -39,8 +39,9 @@
 #include "core/css/StylePropertySet.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/dom/StyleEngine.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "public/platform/Platform.h"
 
 namespace WebCore {
@@ -50,25 +51,27 @@
 
 class LoadFontPromiseResolver : public CSSSegmentedFontFace::LoadFontCallback {
 public:
-    static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ScriptPromise promise, ExecutionContext* context)
+    static PassRefPtr<LoadFontPromiseResolver> create(const FontFamily& family, ExecutionContext* context)
     {
         int numFamilies = 0;
         for (const FontFamily* f = &family; f; f = f->next())
             numFamilies++;
-        return adoptRef<LoadFontPromiseResolver>(new LoadFontPromiseResolver(numFamilies, promise, context));
+        return adoptRef<LoadFontPromiseResolver>(new LoadFontPromiseResolver(numFamilies, context));
     }
 
+    ScriptPromise promise() { return m_resolver->promise(); }
+
     virtual void notifyLoaded(CSSSegmentedFontFace*) OVERRIDE { loaded(); }
     virtual void notifyError(CSSSegmentedFontFace*) OVERRIDE { error(); }
     void loaded();
     void error();
 
 private:
-    LoadFontPromiseResolver(int numLoading, ScriptPromise promise, ExecutionContext* context)
+    LoadFontPromiseResolver(int numLoading, ExecutionContext* context)
         : m_numLoading(numLoading)
         , m_errorOccured(false)
         , m_scriptState(ScriptState::current())
-        , m_resolver(ScriptPromiseResolver::create(promise, context))
+        , m_resolver(ScriptPromiseResolver::create(context))
     { }
 
     int m_numLoading;
@@ -98,9 +101,9 @@
 
 class FontsReadyPromiseResolver {
 public:
-    static PassOwnPtr<FontsReadyPromiseResolver> create(ScriptPromise promise, ExecutionContext* context)
+    static PassOwnPtr<FontsReadyPromiseResolver> create(ExecutionContext* context)
     {
-        return adoptPtr(new FontsReadyPromiseResolver(promise, context));
+        return adoptPtr(new FontsReadyPromiseResolver(context));
     }
 
     void resolve(PassRefPtr<FontFaceSet> fontFaceSet)
@@ -109,18 +112,19 @@
         m_resolver->resolve(fontFaceSet);
     }
 
+    ScriptPromise promise() { return m_resolver->promise(); }
+
 private:
-    FontsReadyPromiseResolver(ScriptPromise promise, ExecutionContext* context)
+    FontsReadyPromiseResolver(ExecutionContext* context)
         : m_scriptState(ScriptState::current())
-        , m_resolver(ScriptPromiseResolver::create(promise, context))
+        , m_resolver(ScriptPromiseResolver::create(context))
     { }
     ScriptState* m_scriptState;
     RefPtr<ScriptPromiseResolver> m_resolver;
 };
 
-FontFaceSet::FontFaceSet(Document* document)
-    : ActiveDOMObject(document)
-    , m_loadingCount(0)
+FontFaceSet::FontFaceSet(Document& document)
+    : ActiveDOMObject(&document)
     , m_shouldFireLoadingEvent(false)
     , m_asyncRunner(this, &FontFaceSet::handlePendingEventsAndPromises)
 {
@@ -162,7 +166,7 @@
 {
     DEFINE_STATIC_LOCAL(AtomicString, loading, ("loading", AtomicString::ConstructFromLiteral));
     DEFINE_STATIC_LOCAL(AtomicString, loaded, ("loaded", AtomicString::ConstructFromLiteral));
-    return (m_loadingCount > 0 || hasLoadedFonts()) ? loading : loaded;
+    return (!m_loadingFonts.isEmpty() || hasLoadedFonts()) ? loading : loaded;
 }
 
 void FontFaceSet::handlePendingEventsAndPromisesSoon()
@@ -174,11 +178,11 @@
 
 void FontFaceSet::didLayout()
 {
-    if (document()->frame()->isMainFrame())
+    if (document()->frame()->isMainFrame() && m_loadingFonts.isEmpty())
         m_histogram.record();
     if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
         return;
-    if (m_loadingCount || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
+    if (!m_loadingFonts.isEmpty() || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
         return;
     handlePendingEventsAndPromisesSoon();
 }
@@ -215,41 +219,38 @@
 void FontFaceSet::beginFontLoading(FontFace* fontFace)
 {
     m_histogram.incrementCount();
-    if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
-        return;
-    incrementLoadingCount();
+    addToLoadingFonts(fontFace);
 }
 
 void FontFaceSet::fontLoaded(FontFace* fontFace)
 {
-    if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
-        return;
-    m_loadedFonts.append(fontFace);
-    decrementLoadingCount();
+    m_histogram.updateStatus(fontFace);
+    if (RuntimeEnabledFeatures::fontLoadEventsEnabled())
+        m_loadedFonts.append(fontFace);
+    removeFromLoadingFonts(fontFace);
 }
 
 void FontFaceSet::loadError(FontFace* fontFace)
 {
-    if (!RuntimeEnabledFeatures::fontLoadEventsEnabled())
-        return;
-    m_failedFonts.append(fontFace);
-    decrementLoadingCount();
+    m_histogram.updateStatus(fontFace);
+    if (RuntimeEnabledFeatures::fontLoadEventsEnabled())
+        m_failedFonts.append(fontFace);
+    removeFromLoadingFonts(fontFace);
 }
 
-void FontFaceSet::incrementLoadingCount()
+void FontFaceSet::addToLoadingFonts(PassRefPtr<FontFace> fontFace)
 {
-    if (!m_loadingCount && !hasLoadedFonts()) {
+    if (RuntimeEnabledFeatures::fontLoadEventsEnabled() && m_loadingFonts.isEmpty() && !hasLoadedFonts()) {
         m_shouldFireLoadingEvent = true;
         handlePendingEventsAndPromisesSoon();
     }
-    ++m_loadingCount;
+    m_loadingFonts.add(fontFace);
 }
 
-void FontFaceSet::decrementLoadingCount()
+void FontFaceSet::removeFromLoadingFonts(PassRefPtr<FontFace> fontFace)
 {
-    ASSERT(m_loadingCount > 0);
-    --m_loadingCount;
-    if (!m_loadingCount)
+    m_loadingFonts.remove(fontFace);
+    if (RuntimeEnabledFeatures::fontLoadEventsEnabled() && m_loadingFonts.isEmpty())
         handlePendingEventsAndPromisesSoon();
 }
 
@@ -257,8 +258,8 @@
 {
     if (!inActiveDocumentContext())
         return ScriptPromise();
-    ScriptPromise promise = ScriptPromise::createPending(executionContext());
-    OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::create(promise, executionContext());
+    OwnPtr<FontsReadyPromiseResolver> resolver = FontsReadyPromiseResolver::create(executionContext());
+    ScriptPromise promise = resolver->promise();
     m_readyResolvers.append(resolver.release());
     handlePendingEventsAndPromisesSoon();
     return promise;
@@ -282,7 +283,7 @@
     m_nonCSSConnectedFaces.add(fontFace);
     fontSelector->fontFaceCache()->addFontFace(fontSelector, fontFace, false);
     if (fontFace->loadStatus() == FontFace::Loading)
-        incrementLoadingCount();
+        addToLoadingFonts(fontFace);
 }
 
 void FontFaceSet::clear()
@@ -293,7 +294,7 @@
     for (ListHashSet<RefPtr<FontFace> >::iterator it = m_nonCSSConnectedFaces.begin(); it != m_nonCSSConnectedFaces.end(); ++it) {
         fontFaceCache->removeFontFace(it->get(), false);
         if ((*it)->loadStatus() == FontFace::Loading)
-            decrementLoadingCount();
+            removeFromLoadingFonts(*it);
     }
     m_nonCSSConnectedFaces.clear();
 }
@@ -311,7 +312,7 @@
         m_nonCSSConnectedFaces.remove(it);
         document()->styleEngine()->fontSelector()->fontFaceCache()->removeFontFace(fontFace, false);
         if (fontFace->loadStatus() == FontFace::Loading)
-            decrementLoadingCount();
+            removeFromLoadingFonts(fontFace);
         return true;
     }
     if (isCSSConnectedFontFace(fontFace))
@@ -384,7 +385,7 @@
 {
     if (m_shouldFireLoadingEvent)
         return;
-    if (m_loadingCount || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
+    if (!m_loadingFonts.isEmpty() || (!hasLoadedFonts() && m_readyResolvers.isEmpty()))
         return;
 
     // If the layout was invalidated in between when we thought layout
@@ -435,8 +436,8 @@
 
     CSSFontSelector* fontSelector = document()->styleEngine()->fontSelector();
     FontFaceCache* fontFaceCache = fontSelector->fontFaceCache();
-    ScriptPromise promise = ScriptPromise::createPending(executionContext());
-    RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(font.fontDescription().family(), promise, executionContext());
+    RefPtr<LoadFontPromiseResolver> resolver = LoadFontPromiseResolver::create(font.fontDescription().family(), executionContext());
+    ScriptPromise promise = resolver->promise();
     for (const FontFamily* f = &font.fontDescription().family(); f; f = f->next()) {
         CSSSegmentedFontFace* face = fontFaceCache->get(font.fontDescription(), f->family());
         if (!face) {
@@ -515,12 +516,26 @@
     return true;
 }
 
+void FontFaceSet::FontLoadHistogram::updateStatus(FontFace* fontFace)
+{
+    if (m_status == Reported)
+        return;
+    if (fontFace->hadBlankText())
+        m_status = HadBlankText;
+    else if (m_status == NoWebFonts)
+        m_status = DidNotHaveBlankText;
+}
+
 void FontFaceSet::FontLoadHistogram::record()
 {
-    if (m_recorded)
-        return;
-    m_recorded = true;
-    blink::Platform::current()->histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1, 100, 50);
+    if (!m_recorded) {
+        m_recorded = true;
+        blink::Platform::current()->histogramCustomCounts("WebFont.WebFontsInPage", m_count, 1, 100, 50);
+    }
+    if (m_status == HadBlankText || m_status == DidNotHaveBlankText) {
+        blink::Platform::current()->histogramEnumeration("WebFont.HadBlankText", m_status == HadBlankText ? 1 : 0, 2);
+        m_status = Reported;
+    }
 }
 
 static const char* supplementName()
@@ -528,7 +543,7 @@
     return "FontFaceSet";
 }
 
-PassRefPtr<FontFaceSet> FontFaceSet::from(Document* document)
+PassRefPtr<FontFaceSet> FontFaceSet::from(Document& document)
 {
     RefPtr<FontFaceSet> fonts = static_cast<FontFaceSet*>(SupplementType::from(document, supplementName()));
     if (!fonts) {
@@ -539,7 +554,7 @@
     return fonts.release();
 }
 
-void FontFaceSet::didLayout(Document* document)
+void FontFaceSet::didLayout(Document& document)
 {
     if (FontFaceSet* fonts = static_cast<FontFaceSet*>(SupplementType::from(document, supplementName())))
         fonts->didLayout();
diff --git a/Source/core/css/FontFaceSet.h b/Source/core/css/FontFaceSet.h
index 9b50984..3303a26 100644
--- a/Source/core/css/FontFaceSet.h
+++ b/Source/core/css/FontFaceSet.h
@@ -96,38 +96,41 @@
     virtual void resume() OVERRIDE;
     virtual void stop() OVERRIDE;
 
-    static PassRefPtr<FontFaceSet> from(Document*);
-    static void didLayout(Document*);
+    static PassRefPtr<FontFaceSet> from(Document&);
+    static void didLayout(Document&);
 
     void addFontFacesToFontFaceCache(FontFaceCache*, CSSFontSelector*);
 
 private:
     typedef RefCountedSupplement<Document, FontFaceSet> SupplementType;
 
-    static PassRefPtr<FontFaceSet> create(Document* document)
+    static PassRefPtr<FontFaceSet> create(Document& document)
     {
         return adoptRef<FontFaceSet>(new FontFaceSet(document));
     }
 
     class FontLoadHistogram {
     public:
-        FontLoadHistogram() : m_count(0), m_recorded(false) { }
+        enum Status { NoWebFonts, HadBlankText, DidNotHaveBlankText, Reported };
+        FontLoadHistogram() : m_status(NoWebFonts), m_count(0), m_recorded(false) { }
         void incrementCount() { m_count++; }
+        void updateStatus(FontFace*);
         void record();
 
     private:
+        Status m_status;
         int m_count;
         bool m_recorded;
     };
 
-    FontFaceSet(Document*);
+    FontFaceSet(Document&);
 
     bool hasLoadedFonts() const { return !m_loadedFonts.isEmpty() || !m_failedFonts.isEmpty(); }
 
     bool inActiveDocumentContext() const;
     void forEachInternal(PassOwnPtr<FontFaceSetForEachCallback>, ScriptValue* thisArg) const;
-    void incrementLoadingCount();
-    void decrementLoadingCount();
+    void addToLoadingFonts(PassRefPtr<FontFace>);
+    void removeFromLoadingFonts(PassRefPtr<FontFace>);
     void fireLoadingEvent();
     void fireDoneEventIfPossible();
     bool resolveFontStyle(const String&, Font&);
@@ -136,7 +139,7 @@
     const ListHashSet<RefPtr<FontFace> >& cssConnectedFontFaceList() const;
     bool isCSSConnectedFontFace(FontFace*) const;
 
-    unsigned m_loadingCount;
+    HashSet<RefPtr<FontFace> > m_loadingFonts;
     bool m_shouldFireLoadingEvent;
     Vector<OwnPtr<FontsReadyPromiseResolver> > m_readyResolvers;
     FontFaceArray m_loadedFonts;
diff --git a/Source/core/css/HoverUpdateTest.cpp b/Source/core/css/HoverUpdateTest.cpp
index 23845c6..ac60a2e 100644
--- a/Source/core/css/HoverUpdateTest.cpp
+++ b/Source/core/css/HoverUpdateTest.cpp
@@ -6,8 +6,8 @@
 #include "HTMLNames.h"
 #include "core/dom/Element.h"
 #include "core/dom/ElementTraversal.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLDocument.h"
 #include "core/html/HTMLElement.h"
 #include "core/page/EventHandler.h"
diff --git a/Source/core/css/LocalFontFaceSource.cpp b/Source/core/css/LocalFontFaceSource.cpp
new file mode 100644
index 0000000..a920bdf
--- /dev/null
+++ b/Source/core/css/LocalFontFaceSource.cpp
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/LocalFontFaceSource.h"
+
+#include "platform/fonts/FontCache.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+#include "public/platform/Platform.h"
+
+namespace WebCore {
+
+bool LocalFontFaceSource::isLocalFontAvailable(const FontDescription& fontDescription)
+{
+    return FontCache::fontCache()->isPlatformFontAvailable(fontDescription, m_fontName);
+}
+
+PassRefPtr<SimpleFontData> LocalFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+    // We don't want to check alternate font family names here, so pass true as the checkingAlternateName parameter.
+    RefPtr<SimpleFontData> fontData = FontCache::fontCache()->getFontData(fontDescription, m_fontName, true);
+    m_histograms.record(fontData);
+    return fontData.release();
+}
+
+void LocalFontFaceSource::LocalFontHistograms::record(bool loadSuccess)
+{
+    if (m_reported)
+        return;
+    m_reported = true;
+    blink::Platform::current()->histogramEnumeration("WebFont.LocalFontUsed", loadSuccess ? 1 : 0, 2);
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/LocalFontFaceSource.h b/Source/core/css/LocalFontFaceSource.h
new file mode 100644
index 0000000..3036e4f
--- /dev/null
+++ b/Source/core/css/LocalFontFaceSource.h
@@ -0,0 +1,36 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef LocalFontFaceSource_h
+#define LocalFontFaceSource_h
+
+#include "core/css/CSSFontFaceSource.h"
+#include "wtf/text/AtomicString.h"
+
+namespace WebCore {
+
+class LocalFontFaceSource : public CSSFontFaceSource {
+public:
+    LocalFontFaceSource(const String& fontName) : m_fontName(fontName) { }
+    virtual bool isLocal() const { return true; }
+    virtual bool isLocalFontAvailable(const FontDescription&) OVERRIDE;
+
+private:
+    virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+    class LocalFontHistograms {
+    public:
+        LocalFontHistograms() : m_reported(false) { }
+        void record(bool loadSuccess);
+    private:
+        bool m_reported;
+    };
+
+    AtomicString m_fontName;
+    LocalFontHistograms m_histograms;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/css/MediaFeatureNames.cpp b/Source/core/css/MediaFeatureNames.cpp
deleted file mode 100644
index 2db2bd9..0000000
--- a/Source/core/css/MediaFeatureNames.cpp
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2005 Apple Computer, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#include "config.h"
-
-#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC
-#define CSS_MEDIAQUERY_NAMES_HIDE_GLOBALS 1
-#endif
-
-#include "core/css/MediaFeatureNames.h"
-
-#include "wtf/StaticConstructors.h"
-
-namespace WebCore {
-namespace MediaFeatureNames {
-
-#define DEFINE_MEDIAFEATURE_GLOBAL(name, str) \
-    DEFINE_GLOBAL(AtomicString, name##MediaFeature, str)
-CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(DEFINE_MEDIAFEATURE_GLOBAL)
-#undef DEFINE_MEDIAFEATURE_GLOBAL
-
-void init()
-{
-#define INITIALIZE_GLOBAL(name, str) new (NotNull, (void*)&name##MediaFeature) AtomicString(str, AtomicString::ConstructFromLiteral);
-    CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(INITIALIZE_GLOBAL)
-#undef INITIALIZE_GLOBAL
-}
-
-} // namespace MediaFeatureNames
-} // namespace WebCore
diff --git a/Source/core/css/MediaFeatureNames.h b/Source/core/css/MediaFeatureNames.h
deleted file mode 100644
index 7624372..0000000
--- a/Source/core/css/MediaFeatureNames.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2005, 2013 Apple Inc. All rights reserved.
- * Copyright (C) 2013 Intel Corporation. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-#ifndef MediaFeatureNames_h
-#define MediaFeatureNames_h
-
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-namespace MediaFeatureNames {
-
-#define CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(macro) \
-    macro(color, "color") \
-    macro(colorIndex, "color-index") \
-    macro(grid, "grid") \
-    macro(monochrome, "monochrome") \
-    macro(height, "height") \
-    macro(hover, "hover") \
-    macro(width, "width") \
-    macro(orientation, "orientation") \
-    macro(aspectRatio, "aspect-ratio") \
-    macro(deviceAspectRatio, "device-aspect-ratio") \
-    macro(devicePixelRatio, "-webkit-device-pixel-ratio") \
-    macro(deviceHeight, "device-height") \
-    macro(deviceWidth, "device-width") \
-    macro(maxColor, "max-color") \
-    macro(maxColorIndex, "max-color-index") \
-    macro(maxAspectRatio, "max-aspect-ratio") \
-    macro(maxDeviceAspectRatio, "max-device-aspect-ratio") \
-    macro(maxDevicePixelRatio, "-webkit-max-device-pixel-ratio") \
-    macro(maxDeviceHeight, "max-device-height") \
-    macro(maxDeviceWidth, "max-device-width") \
-    macro(maxHeight, "max-height") \
-    macro(maxMonochrome, "max-monochrome") \
-    macro(maxWidth, "max-width") \
-    macro(maxResolution, "max-resolution") \
-    macro(minColor, "min-color") \
-    macro(minColorIndex, "min-color-index") \
-    macro(minAspectRatio, "min-aspect-ratio") \
-    macro(minDeviceAspectRatio, "min-device-aspect-ratio") \
-    macro(minDevicePixelRatio, "-webkit-min-device-pixel-ratio") \
-    macro(minDeviceHeight, "min-device-height") \
-    macro(minDeviceWidth, "min-device-width") \
-    macro(minHeight, "min-height") \
-    macro(minMonochrome, "min-monochrome") \
-    macro(minWidth, "min-width") \
-    macro(minResolution, "min-resolution") \
-    macro(pointer, "pointer") \
-    macro(resolution, "resolution") \
-    macro(transform2d, "-webkit-transform-2d") \
-    macro(transform3d, "-webkit-transform-3d") \
-    macro(scan, "scan") \
-    macro(animation, "-webkit-animation") \
-    macro(viewMode, "-webkit-view-mode")
-
-// end of macro
-
-#ifndef CSS_MEDIAQUERY_NAMES_HIDE_GLOBALS
-#define CSS_MEDIAQUERY_NAMES_DECLARE(name, str) extern const AtomicString name##MediaFeature;
-CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(CSS_MEDIAQUERY_NAMES_DECLARE)
-#undef CSS_MEDIAQUERY_NAMES_DECLARE
-#endif
-
-    void init();
-
-} // namespace MediaFeatureNames
-} // namespace WebCore
-
-#endif // MediaFeatureNames_h
diff --git a/Source/core/css/MediaFeatureNames.in b/Source/core/css/MediaFeatureNames.in
new file mode 100644
index 0000000..4b10342
--- /dev/null
+++ b/Source/core/css/MediaFeatureNames.in
@@ -0,0 +1,45 @@
+namespace="MediaFeature"
+export=""
+
+color
+color-index
+grid
+monochrome
+height
+hover
+width
+orientation
+aspect-ratio
+device-aspect-ratio
+-webkit-device-pixel-ratio
+device-height
+device-width
+max-color
+max-color-index
+max-aspect-ratio
+max-device-aspect-ratio
+-webkit-max-device-pixel-ratio
+max-device-height
+max-device-width
+max-height
+max-monochrome
+max-width
+max-resolution
+min-color
+min-color-index
+min-aspect-ratio
+min-device-aspect-ratio
+-webkit-min-device-pixel-ratio
+min-device-height
+min-device-width
+min-height
+min-monochrome
+min-width
+min-resolution
+pointer
+resolution
+-webkit-transform-2d
+-webkit-transform-3d
+scan
+-webkit-animation
+-webkit-view-mode
diff --git a/Source/core/css/MediaList.cpp b/Source/core/css/MediaList.cpp
index 11ae84b..8f27f81 100644
--- a/Source/core/css/MediaList.cpp
+++ b/Source/core/css/MediaList.cpp
@@ -20,12 +20,13 @@
 #include "config.h"
 #include "core/css/MediaList.h"
 
+#include "MediaFeatureNames.h"
 #include "bindings/v8/ExceptionState.h"
 #include "core/css/parser/BisonCSSParser.h"
 #include "core/css/CSSStyleSheet.h"
-#include "core/css/MediaFeatureNames.h"
 #include "core/css/MediaQuery.h"
 #include "core/css/MediaQueryExp.h"
+#include "core/css/parser/MediaQueryParser.h"
 #include "core/dom/Document.h"
 #include "core/frame/DOMWindow.h"
 #include "wtf/text/StringBuilder.h"
@@ -57,29 +58,26 @@
 }
 
 MediaQuerySet::MediaQuerySet(const MediaQuerySet& o)
-    : RefCounted<MediaQuerySet>()
-    , m_queries(o.m_queries.size())
+    : m_queries(o.m_queries.size())
 {
     for (unsigned i = 0; i < m_queries.size(); ++i)
         m_queries[i] = o.m_queries[i]->copy();
 }
 
-MediaQuerySet::~MediaQuerySet()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQuerySet)
 
-PassRefPtr<MediaQuerySet> MediaQuerySet::create(const String& mediaString)
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQuerySet::create(const String& mediaString)
 {
     if (mediaString.isEmpty())
         return MediaQuerySet::create();
 
-    BisonCSSParser parser(strictCSSParserContext());
-    return parser.parseMediaQueryList(mediaString);
+    return MediaQueryParser::parse(mediaString);
+
 }
 
 bool MediaQuerySet::set(const String& mediaString)
 {
-    RefPtr<MediaQuerySet> result = create(mediaString);
+    RefPtrWillBeRawPtr<MediaQuerySet> result = create(mediaString);
     m_queries.swap(result->m_queries);
     return true;
 }
@@ -89,13 +87,13 @@
     // To "parse a media query" for a given string means to follow "the parse
     // a media query list" steps and return "null" if more than one media query
     // is returned, or else the returned media query.
-    RefPtr<MediaQuerySet> result = create(queryString);
+    RefPtrWillBeRawPtr<MediaQuerySet> result = create(queryString);
 
     // Only continue if exactly one media query is found, as described above.
     if (result->m_queries.size() != 1)
         return true;
 
-    OwnPtr<MediaQuery> newQuery = result->m_queries[0].release();
+    OwnPtrWillBeRawPtr<MediaQuery> newQuery = result->m_queries[0].release();
     ASSERT(newQuery);
 
     // If comparing with any of the media queries in the collection of media
@@ -115,13 +113,13 @@
     // To "parse a media query" for a given string means to follow "the parse
     // a media query list" steps and return "null" if more than one media query
     // is returned, or else the returned media query.
-    RefPtr<MediaQuerySet> result = create(queryStringToRemove);
+    RefPtrWillBeRawPtr<MediaQuerySet> result = create(queryStringToRemove);
 
     // Only continue if exactly one media query is found, as described above.
     if (result->m_queries.size() != 1)
         return true;
 
-    OwnPtr<MediaQuery> newQuery = result->m_queries[0].release();
+    OwnPtrWillBeRawPtr<MediaQuery> newQuery = result->m_queries[0].release();
     ASSERT(newQuery);
 
     // Remove any media query from the collection of media queries for which
@@ -139,7 +137,7 @@
     return found;
 }
 
-void MediaQuerySet::addMediaQuery(PassOwnPtr<MediaQuery> mediaQuery)
+void MediaQuerySet::addMediaQuery(PassOwnPtrWillBeRawPtr<MediaQuery> mediaQuery)
 {
     m_queries.append(mediaQuery);
 }
@@ -159,16 +157,25 @@
     return text.toString();
 }
 
+void MediaQuerySet::trace(Visitor* visitor)
+{
+    // We don't support tracing of vectors of OwnPtrs (ie. OwnPtr<Vector<OwnPtr<MediaQuery> > >).
+    // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
+#if ENABLE(OILPAN)
+    visitor->trace(m_queries);
+#endif
+}
+
 MediaList::MediaList(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
     : m_mediaQueries(mediaQueries)
     , m_parentStyleSheet(parentSheet)
-    , m_parentRule(0)
+    , m_parentRule(nullptr)
 {
 }
 
 MediaList::MediaList(MediaQuerySet* mediaQueries, CSSRule* parentRule)
     : m_mediaQueries(mediaQueries)
-    , m_parentStyleSheet(0)
+    , m_parentStyleSheet(nullptr)
     , m_parentRule(parentRule)
 {
 }
@@ -189,7 +196,7 @@
 
 String MediaList::item(unsigned index) const
 {
-    const Vector<OwnPtr<MediaQuery> >& queries = m_mediaQueries->queryVector();
+    const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queries = m_mediaQueries->queryVector();
     if (index < queries.size())
         return queries[index]->cssText();
     return String();
@@ -228,12 +235,19 @@
     m_mediaQueries = mediaQueries;
 }
 
+void MediaList::trace(Visitor* visitor)
+{
+    visitor->trace(m_mediaQueries);
+    visitor->trace(m_parentStyleSheet);
+    visitor->trace(m_parentRule);
+}
+
 static void addResolutionWarningMessageToConsole(Document* document, const String& serializedExpression, const CSSPrimitiveValue* value)
 {
     ASSERT(document);
     ASSERT(value);
 
-    DEFINE_STATIC_LOCAL(String, mediaQueryMessage, ("Consider using 'dppx' units instead of '%replacementUnits%', as in CSS '%replacementUnits%' means dots-per-CSS-%lengthUnit%, not dots-per-physical-%lengthUnit%, so does not correspond to the actual '%replacementUnits%' of a screen. In media query expression: "));
+    DEFINE_STATIC_LOCAL(String, mediaQueryMessage, ("Consider using 'dppx' units, as in CSS '%replacementUnits%' means dots-per-CSS-%lengthUnit%, not dots-per-physical-%lengthUnit%, so does not correspond to the actual '%replacementUnits%' of a screen. In media query expression: "));
     DEFINE_STATIC_LOCAL(String, mediaValueDPI, ("dpi"));
     DEFINE_STATIC_LOCAL(String, mediaValueDPCM, ("dpcm"));
     DEFINE_STATIC_LOCAL(String, lengthUnitInch, ("inch"));
@@ -252,7 +266,7 @@
     document->addConsoleMessage(CSSMessageSource, DebugMessageLevel, message.toString());
 }
 
-static inline bool isResolutionMediaFeature(const AtomicString& mediaFeature)
+static inline bool isResolutionMediaFeature(const String& mediaFeature)
 {
     return mediaFeature == MediaFeatureNames::resolutionMediaFeature
         || mediaFeature == MediaFeatureNames::maxResolutionMediaFeature
@@ -264,30 +278,37 @@
     if (!mediaQuerySet || !document)
         return;
 
-    const Vector<OwnPtr<MediaQuery> >& mediaQueries = mediaQuerySet->queryVector();
+    const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& mediaQueries = mediaQuerySet->queryVector();
     const size_t queryCount = mediaQueries.size();
 
     if (!queryCount)
         return;
 
+    CSSPrimitiveValue* suspiciousValue = 0;
+    bool dotsPerPixelUsed = false;
     for (size_t i = 0; i < queryCount; ++i) {
         const MediaQuery* query = mediaQueries[i].get();
         if (equalIgnoringCase(query->mediaType(), "print"))
             continue;
 
-        const ExpressionVector& expressions = query->expressions();
+        const ExpressionHeapVector& expressions = query->expressions();
         for (size_t j = 0; j < expressions.size(); ++j) {
             const MediaQueryExp* expression = expressions.at(j).get();
             if (isResolutionMediaFeature(expression->mediaFeature())) {
                 CSSValue* cssValue =  expression->value();
                 if (cssValue && cssValue->isPrimitiveValue()) {
                     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(cssValue);
-                    if (primitiveValue->isDotsPerInch() || primitiveValue->isDotsPerCentimeter())
-                        addResolutionWarningMessageToConsole(document, mediaQuerySet->mediaText(), primitiveValue);
+                    if (primitiveValue->isDotsPerPixel())
+                        dotsPerPixelUsed = true;
+                    else if (primitiveValue->isDotsPerInch() || primitiveValue->isDotsPerCentimeter())
+                        suspiciousValue = primitiveValue;
                 }
             }
         }
     }
+
+    if (suspiciousValue && !dotsPerPixelUsed)
+        addResolutionWarningMessageToConsole(document, mediaQuerySet->mediaText(), suspiciousValue);
 }
 
 }
diff --git a/Source/core/css/MediaList.h b/Source/core/css/MediaList.h
index 80223b0..108448e 100644
--- a/Source/core/css/MediaList.h
+++ b/Source/core/css/MediaList.h
@@ -22,6 +22,7 @@
 #define MediaList_h
 
 #include "core/dom/ExceptionCode.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -37,43 +38,45 @@
 class MediaList;
 class MediaQuery;
 
-class MediaQuerySet : public RefCounted<MediaQuerySet> {
+class MediaQuerySet : public RefCountedWillBeGarbageCollected<MediaQuerySet> {
+    DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQuerySet);
 public:
-    static PassRefPtr<MediaQuerySet> create()
+    static PassRefPtrWillBeRawPtr<MediaQuerySet> create()
     {
-        return adoptRef(new MediaQuerySet());
+        return adoptRefWillBeNoop(new MediaQuerySet());
     }
-    static PassRefPtr<MediaQuerySet> create(const String& mediaString);
-    ~MediaQuerySet();
+    static PassRefPtrWillBeRawPtr<MediaQuerySet> create(const String& mediaString);
 
     bool set(const String&);
     bool add(const String&);
     bool remove(const String&);
 
-    void addMediaQuery(PassOwnPtr<MediaQuery>);
+    void addMediaQuery(PassOwnPtrWillBeRawPtr<MediaQuery>);
 
-    const Vector<OwnPtr<MediaQuery> >& queryVector() const { return m_queries; }
+    const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queryVector() const { return m_queries; }
 
     String mediaText() const;
 
-    PassRefPtr<MediaQuerySet> copy() const { return adoptRef(new MediaQuerySet(*this)); }
+    PassRefPtrWillBeRawPtr<MediaQuerySet> copy() const { return adoptRefWillBeNoop(new MediaQuerySet(*this)); }
+
+    void trace(Visitor*);
 
 private:
     MediaQuerySet();
     MediaQuerySet(const MediaQuerySet&);
 
-    Vector<OwnPtr<MediaQuery> > m_queries;
+    WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> > m_queries;
 };
 
-class MediaList : public RefCounted<MediaList> {
+class MediaList : public RefCountedWillBeGarbageCollectedFinalized<MediaList> {
 public:
-    static PassRefPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
+    static PassRefPtrWillBeRawPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSStyleSheet* parentSheet)
     {
-        return adoptRef(new MediaList(mediaQueries, parentSheet));
+        return adoptRefWillBeNoop(new MediaList(mediaQueries, parentSheet));
     }
-    static PassRefPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSRule* parentRule)
+    static PassRefPtrWillBeRawPtr<MediaList> create(MediaQuerySet* mediaQueries, CSSRule* parentRule)
     {
-        return adoptRef(new MediaList(mediaQueries, parentRule));
+        return adoptRefWillBeNoop(new MediaList(mediaQueries, parentRule));
     }
 
     ~MediaList();
@@ -89,20 +92,28 @@
     // Not part of CSSOM.
     CSSRule* parentRule() const { return m_parentRule; }
     CSSStyleSheet* parentStyleSheet() const { return m_parentStyleSheet; }
-    void clearParentStyleSheet() { ASSERT(m_parentStyleSheet); m_parentStyleSheet = 0; }
-    void clearParentRule() { ASSERT(m_parentRule); m_parentRule = 0; }
+
+#if !ENABLE(OILPAN)
+    void clearParentStyleSheet() { ASSERT(m_parentStyleSheet); m_parentStyleSheet = nullptr; }
+    void clearParentRule() { ASSERT(m_parentRule); m_parentRule = nullptr; }
+#endif
+
     const MediaQuerySet* queries() const { return m_mediaQueries.get(); }
 
     void reattach(MediaQuerySet*);
 
+    void trace(Visitor*);
+
 private:
     MediaList();
     MediaList(MediaQuerySet*, CSSStyleSheet* parentSheet);
     MediaList(MediaQuerySet*, CSSRule* parentRule);
 
-    RefPtr<MediaQuerySet> m_mediaQueries;
-    CSSStyleSheet* m_parentStyleSheet;
-    CSSRule* m_parentRule;
+    RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
+    // Cleared in ~CSSStyleSheet destructor when oilpan is not enabled.
+    RawPtrWillBeMember<CSSStyleSheet> m_parentStyleSheet;
+    // Cleared in the ~CSSMediaRule and ~CSSImportRule destructors when oilpan is not enabled.
+    RawPtrWillBeMember<CSSRule> m_parentRule;
 };
 
 // Adds message to inspector console whenever dpi or dpcm values are used for "screen" media.
diff --git a/Source/core/css/MediaList.idl b/Source/core/css/MediaList.idl
index 20ef3ec..8db9886 100644
--- a/Source/core/css/MediaList.idl
+++ b/Source/core/css/MediaList.idl
@@ -25,6 +25,7 @@
 
 // Introduced in DOM Level 2:
 [
+    WillBeGarbageCollected
 ] interface MediaList {
 
     [TreatNullAs=NullString, TreatReturnedNullStringAs=Null] attribute DOMString mediaText;
diff --git a/Source/core/css/MediaQuery.cpp b/Source/core/css/MediaQuery.cpp
index 681ac13..42a7884 100644
--- a/Source/core/css/MediaQuery.cpp
+++ b/Source/core/css/MediaQuery.cpp
@@ -29,7 +29,9 @@
 #include "config.h"
 #include "core/css/MediaQuery.h"
 
+#include "MediaTypeNames.h"
 #include "core/css/MediaQueryExp.h"
+#include "core/html/parser/HTMLParserIdioms.h"
 #include "wtf/NonCopyingSort.h"
 #include "wtf/text/StringBuilder.h"
 
@@ -55,7 +57,7 @@
         return result.toString();
     }
 
-    if (m_mediaType != "all" || m_restrictor != None) {
+    if (m_mediaType != MediaTypeNames::all || m_restrictor != None) {
         result.append(m_mediaType);
         result.append(" and ");
     }
@@ -68,18 +70,23 @@
     return result.toString();
 }
 
-static bool expressionCompare(const OwnPtr<MediaQueryExp>& a, const OwnPtr<MediaQueryExp>& b)
+static bool expressionCompare(const OwnPtrWillBeMember<MediaQueryExp>& a, const OwnPtrWillBeMember<MediaQueryExp>& b)
 {
     return codePointCompare(a->serialize(), b->serialize()) < 0;
 }
 
-MediaQuery::MediaQuery(Restrictor r, const AtomicString& mediaType, PassOwnPtr<ExpressionVector> expressions)
+PassOwnPtrWillBeRawPtr<MediaQuery> MediaQuery::createNotAll()
+{
+    return adoptPtrWillBeNoop(new MediaQuery(MediaQuery::Not, "all", nullptr));
+}
+
+MediaQuery::MediaQuery(Restrictor r, const String& mediaType, PassOwnPtrWillBeRawPtr<ExpressionHeapVector> expressions)
     : m_restrictor(r)
-    , m_mediaType(mediaType.lower())
+    , m_mediaType(attemptStaticStringCreation(mediaType.lower()))
     , m_expressions(expressions)
 {
     if (!m_expressions) {
-        m_expressions = adoptPtr(new ExpressionVector);
+        m_expressions = adoptPtrWillBeNoop(new ExpressionHeapVector);
         return;
     }
 
@@ -100,7 +107,7 @@
 MediaQuery::MediaQuery(const MediaQuery& o)
     : m_restrictor(o.m_restrictor)
     , m_mediaType(o.m_mediaType)
-    , m_expressions(adoptPtr(new ExpressionVector(o.m_expressions->size())))
+    , m_expressions(adoptPtrWillBeNoop(new ExpressionHeapVector(o.m_expressions->size())))
     , m_serializationCache(o.m_serializationCache)
 {
     for (unsigned i = 0; i < m_expressions->size(); ++i)
@@ -126,4 +133,13 @@
     return m_serializationCache;
 }
 
+void MediaQuery::trace(Visitor* visitor)
+{
+    // We don't support tracing of vectors of OwnPtrs (ie. OwnPtr<Vector<OwnPtr<MediaQuery> > >).
+    // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
+#if ENABLE(OILPAN)
+    visitor->trace(m_expressions);
+#endif
+}
+
 }
diff --git a/Source/core/css/MediaQuery.h b/Source/core/css/MediaQuery.h
index fa5463e..ab9be6f 100644
--- a/Source/core/css/MediaQuery.h
+++ b/Source/core/css/MediaQuery.h
@@ -29,6 +29,7 @@
 #ifndef MediaQuery_h
 #define MediaQuery_h
 
+#include "heap/Handle.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/Vector.h"
 #include "wtf/text/StringHash.h"
@@ -37,32 +38,36 @@
 namespace WebCore {
 class MediaQueryExp;
 
-typedef Vector<OwnPtr<MediaQueryExp> > ExpressionVector;
+typedef WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > ExpressionHeapVector;
 
-class MediaQuery {
-    WTF_MAKE_FAST_ALLOCATED;
+class MediaQuery : public NoBaseWillBeGarbageCollectedFinalized<MediaQuery> {
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
     enum Restrictor {
         Only, Not, None
     };
 
-    MediaQuery(Restrictor, const AtomicString& mediaType, PassOwnPtr<ExpressionVector> exprs);
+    static PassOwnPtrWillBeRawPtr<MediaQuery> createNotAll();
+
+    MediaQuery(Restrictor, const String& mediaType, PassOwnPtrWillBeRawPtr<ExpressionHeapVector> exprs);
     ~MediaQuery();
 
     Restrictor restrictor() const { return m_restrictor; }
-    const ExpressionVector& expressions() const { return *m_expressions; }
-    const AtomicString& mediaType() const { return m_mediaType; }
+    const ExpressionHeapVector& expressions() const { return *m_expressions; }
+    const String& mediaType() const { return m_mediaType; }
     bool operator==(const MediaQuery& other) const;
     String cssText() const;
 
-    PassOwnPtr<MediaQuery> copy() const { return adoptPtr(new MediaQuery(*this)); }
+    PassOwnPtrWillBeRawPtr<MediaQuery> copy() const { return adoptPtrWillBeNoop(new MediaQuery(*this)); }
+
+    void trace(Visitor*);
 
 private:
     MediaQuery(const MediaQuery&);
 
     Restrictor m_restrictor;
-    AtomicString m_mediaType;
-    OwnPtr<ExpressionVector> m_expressions;
+    String m_mediaType;
+    OwnPtrWillBeMember<ExpressionHeapVector> m_expressions;
     String m_serializationCache;
 
     String serialize() const;
diff --git a/Source/core/css/MediaQueryEvaluator.cpp b/Source/core/css/MediaQueryEvaluator.cpp
index 07006bb..37847a7 100644
--- a/Source/core/css/MediaQueryEvaluator.cpp
+++ b/Source/core/css/MediaQueryEvaluator.cpp
@@ -31,22 +31,24 @@
 #include "core/css/MediaQueryEvaluator.h"
 
 #include "CSSValueKeywords.h"
+#include "MediaFeatureNames.h"
+#include "MediaFeatures.h"
+#include "MediaTypeNames.h"
 #include "core/css/CSSAspectRatioValue.h"
 #include "core/css/CSSHelper.h"
 #include "core/css/CSSPrimitiveValue.h"
 #include "core/css/CSSToLengthConversionData.h"
-#include "core/css/MediaFeatureNames.h"
 #include "core/css/MediaList.h"
 #include "core/css/MediaQuery.h"
 #include "core/css/resolver/MediaQueryResult.h"
 #include "core/dom/NodeRenderStyle.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/rendering/style/RenderStyle.h"
 #include "platform/PlatformScreen.h"
 #include "platform/geometry/FloatRect.h"
@@ -58,21 +60,21 @@
 
 enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix };
 
-typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, Frame*, MediaFeaturePrefix);
+typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, LocalFrame*, MediaFeaturePrefix);
 typedef HashMap<StringImpl*, EvalFunc> FunctionMap;
 static FunctionMap* gFunctionMap;
 
 MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
     : m_frame(0)
-    , m_style(0)
+    , m_style(nullptr)
     , m_expResult(mediaFeatureResult)
 {
 }
 
-MediaQueryEvaluator::MediaQueryEvaluator(const AtomicString& acceptedMediaType, bool mediaFeatureResult)
+MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult)
     : m_mediaType(acceptedMediaType)
     , m_frame(0)
-    , m_style(0)
+    , m_style(nullptr)
     , m_expResult(mediaFeatureResult)
 {
 }
@@ -80,12 +82,12 @@
 MediaQueryEvaluator::MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult)
     : m_mediaType(acceptedMediaType)
     , m_frame(0)
-    , m_style(0)
+    , m_style(nullptr)
     , m_expResult(mediaFeatureResult)
 {
 }
 
-MediaQueryEvaluator::MediaQueryEvaluator(const AtomicString& acceptedMediaType, Frame* frame, RenderStyle* style)
+MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, LocalFrame* frame, RenderStyle* style)
     : m_mediaType(acceptedMediaType)
     , m_frame(frame)
     , m_style(style)
@@ -97,10 +99,10 @@
 {
 }
 
-bool MediaQueryEvaluator::mediaTypeMatch(const AtomicString& mediaTypeToMatch) const
+bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const
 {
     return mediaTypeToMatch.isEmpty()
-        || equalIgnoringCase(mediaTypeToMatch, "all")
+        || equalIgnoringCase(mediaTypeToMatch, MediaTypeNames::all)
         || equalIgnoringCase(mediaTypeToMatch, m_mediaType);
 }
 
@@ -109,7 +111,7 @@
     // Like mediaTypeMatch, but without the special cases for "" and "all".
     ASSERT(mediaTypeToMatch);
     ASSERT(mediaTypeToMatch[0] != '\0');
-    ASSERT(!equalIgnoringCase(mediaTypeToMatch, AtomicString("all")));
+    ASSERT(!equalIgnoringCase(mediaTypeToMatch, MediaTypeNames::all));
     return equalIgnoringCase(mediaTypeToMatch, m_mediaType);
 }
 
@@ -123,7 +125,7 @@
     if (!querySet)
         return true;
 
-    const Vector<OwnPtr<MediaQuery> >& queries = querySet->queryVector();
+    const WillBeHeapVector<OwnPtrWillBeMember<MediaQuery> >& queries = querySet->queryVector();
     if (!queries.size())
         return true; // Empty query list evaluates to true.
 
@@ -133,13 +135,13 @@
         MediaQuery* query = queries[i].get();
 
         if (mediaTypeMatch(query->mediaType())) {
-            const ExpressionVector& expressions = query->expressions();
+            const ExpressionHeapVector& expressions = query->expressions();
             // Iterate through expressions, stop if any of them eval to false (AND semantics).
             size_t j = 0;
             for (; j < expressions.size(); ++j) {
                 bool exprResult = eval(expressions.at(j).get());
                 if (viewportDependentMediaQueryResults && expressions.at(j)->isViewportDependent())
-                    viewportDependentMediaQueryResults->append(adoptRef(new MediaQueryResult(*expressions.at(j), exprResult)));
+                    viewportDependentMediaQueryResults->append(adoptRefWillBeNoop(new MediaQueryResult(*expressions.at(j), exprResult)));
                 if (!exprResult)
                     break;
             }
@@ -187,7 +189,7 @@
     return false;
 }
 
-static bool colorMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool colorMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     int bitsPerComponent = screenDepthPerComponent(frame->view());
     float number;
@@ -197,7 +199,7 @@
     return bitsPerComponent != 0;
 }
 
-static bool colorIndexMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
+static bool colorIndexMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*, MediaFeaturePrefix op)
 {
     // FIXME: We currently assume that we do not support indexed displays, as it is unknown
     // how to retrieve the information if the display mode is indexed. This matches Firefox.
@@ -209,7 +211,7 @@
     return numberValue(value, number) && compareValue(0, static_cast<int>(number), op);
 }
 
-static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix op)
 {
     if (!screenIsMonochrome(frame->view())) {
         if (value) {
@@ -224,10 +226,10 @@
 
 static IntSize viewportSize(FrameView* view)
 {
-    return view->layoutSize(ScrollableArea::IncludeScrollbars);
+    return view->layoutSize(IncludeScrollbars);
 }
 
-static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix)
 {
     FrameView* view = frame->view();
     int width = viewportSize(view).width();
@@ -243,7 +245,7 @@
     return height >= 0 && width >= 0;
 }
 
-static bool aspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool aspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     if (value) {
         FrameView* view = frame->view();
@@ -255,7 +257,7 @@
     return true;
 }
 
-static bool deviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool deviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     if (value) {
         FloatRect sg = screenRect(frame->view());
@@ -267,7 +269,7 @@
     return true;
 }
 
-static bool evalResolution(CSSValue* value, Frame* frame, MediaFeaturePrefix op)
+static bool evalResolution(CSSValue* value, LocalFrame* frame, MediaFeaturePrefix op)
 {
     // According to MQ4, only 'screen', 'print' and 'speech' may match.
     // FIXME: What should speech match? https://www.w3.org/Style/CSS/Tracker/issues/348
@@ -315,19 +317,19 @@
     return compareValue(actualResolution, resolution->getFloatValue(CSSPrimitiveValue::CSS_DPPX), op);
 }
 
-static bool devicePixelRatioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool devicePixelRatioMediaFeatureEval(CSSValue *value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     UseCounter::count(frame->document(), UseCounter::PrefixedDevicePixelRatioMediaFeature);
 
     return (!value || toCSSPrimitiveValue(value)->isNumber()) && evalResolution(value, frame, op);
 }
 
-static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     return (!value || toCSSPrimitiveValue(value)->isResolution()) && evalResolution(value, frame, op);
 }
 
-static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op)
+static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*, MediaFeaturePrefix op)
 {
     // if output device is bitmap, grid: 0 == true
     // assume we have bitmap device
@@ -360,7 +362,7 @@
     return false;
 }
 
-static bool deviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool deviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix op)
 {
     if (value) {
         int length;
@@ -376,7 +378,7 @@
     return true;
 }
 
-static bool deviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool deviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix op)
 {
     if (value) {
         int length;
@@ -392,7 +394,7 @@
     return true;
 }
 
-static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix op)
 {
     FrameView* view = frame->view();
 
@@ -407,7 +409,7 @@
     return height;
 }
 
-static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
+static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix op)
 {
     FrameView* view = frame->view();
 
@@ -424,121 +426,121 @@
 
 // Rest of the functions are trampolines which set the prefix according to the media feature expression used.
 
-static bool minColorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minColorMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return colorMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxColorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxColorMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return colorMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return colorIndexMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return colorIndexMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return monochromeMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return monochromeMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return aspectRatioMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return aspectRatioMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return deviceAspectRatioMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return deviceAspectRatioMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     UseCounter::count(frame->document(), UseCounter::PrefixedMinDevicePixelRatioMediaFeature);
 
     return devicePixelRatioMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     UseCounter::count(frame->document(), UseCounter::PrefixedMaxDevicePixelRatioMediaFeature);
 
     return devicePixelRatioMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return heightMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return heightMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return widthMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return widthMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return deviceHeightMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return deviceHeightMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return deviceWidthMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return deviceWidthMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool minResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool minResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return resolutionMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool maxResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix)
+static bool maxResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFrame* frame, MediaFeaturePrefix)
 {
     return resolutionMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     UseCounter::count(frame->document(), UseCounter::PrefixedAnimationMediaFeature);
 
@@ -549,7 +551,7 @@
     return true;
 }
 
-static bool transform2dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool transform2dMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     UseCounter::count(frame->document(), UseCounter::PrefixedTransform2dMediaFeature);
 
@@ -560,7 +562,7 @@
     return true;
 }
 
-static bool transform3dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op)
+static bool transform3dMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix op)
 {
     UseCounter::count(frame->document(), UseCounter::PrefixedTransform3dMediaFeature);
 
@@ -581,7 +583,7 @@
     return returnValueIfNoParameter;
 }
 
-static bool viewModeMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool viewModeMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix)
 {
     UseCounter::count(frame->document(), UseCounter::PrefixedViewModeMediaFeature);
 
@@ -593,7 +595,7 @@
 
 enum PointerDeviceType { TouchPointer, MousePointer, NoPointer, UnknownPointer };
 
-static PointerDeviceType leastCapablePrimaryPointerDeviceType(Frame* frame)
+static PointerDeviceType leastCapablePrimaryPointerDeviceType(LocalFrame* frame)
 {
     if (frame->settings()->deviceSupportsTouch())
         return TouchPointer;
@@ -608,7 +610,7 @@
     return UnknownPointer;
 }
 
-static bool hoverMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool hoverMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix)
 {
     PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame);
 
@@ -629,7 +631,7 @@
         || (pointer == MousePointer && number == 1);
 }
 
-static bool pointerMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool pointerMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix)
 {
     PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame);
 
@@ -651,7 +653,7 @@
         || (pointer == MousePointer && id == CSSValueFine);
 }
 
-static bool scanMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix)
+static bool scanMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* frame, MediaFeaturePrefix)
 {
     // Scan only applies to 'tv' media.
     if (!equalIgnoringCase(frame->view()->mediaType(), "tv"))
@@ -673,7 +675,7 @@
 {
     // Create the table.
     gFunctionMap = new FunctionMap;
-#define ADD_TO_FUNCTIONMAP(name, str)  \
+#define ADD_TO_FUNCTIONMAP(name)  \
     gFunctionMap->set(name##MediaFeature.impl(), name##MediaFeatureEval);
     CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(ADD_TO_FUNCTIONMAP);
 #undef ADD_TO_FUNCTIONMAP
diff --git a/Source/core/css/MediaQueryEvaluator.h b/Source/core/css/MediaQueryEvaluator.h
index 60bd9cd..4b3f9cf 100644
--- a/Source/core/css/MediaQueryEvaluator.h
+++ b/Source/core/css/MediaQueryEvaluator.h
@@ -28,16 +28,18 @@
 #ifndef MediaQueryEvaluator_h
 #define MediaQueryEvaluator_h
 
+#include "heap/Handle.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
-class Frame;
+class LocalFrame;
 class MediaQueryExp;
 class MediaQueryResult;
 class MediaQuerySet;
 class RenderStyle;
 
-typedef Vector<RefPtr<MediaQueryResult> > MediaQueryResultList;
+typedef WillBeHeapVector<RefPtrWillBeMember<MediaQueryResult> > MediaQueryResultList;
+typedef WillBePersistentHeapVector<RefPtrWillBeMember<MediaQueryResult> > WillBePersistentMediaQueryResultList;
 
 /**
  * Class that evaluates css media queries as defined in
@@ -64,15 +66,15 @@
      *  Evaluator  returns true for acceptedMediaType and returns value of \mediafeatureResult
      *  for any media features
      */
-    MediaQueryEvaluator(const AtomicString& acceptedMediaType, bool mediaFeatureResult = false);
+    MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult = false);
     MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult = false);
 
     /** Creates evaluator which evaluates full media queries */
-    MediaQueryEvaluator(const AtomicString& acceptedMediaType, Frame*, RenderStyle*);
+    MediaQueryEvaluator(const String& acceptedMediaType, LocalFrame*, RenderStyle*);
 
     ~MediaQueryEvaluator();
 
-    bool mediaTypeMatch(const AtomicString& mediaTypeToMatch) const;
+    bool mediaTypeMatch(const String& mediaTypeToMatch) const;
     bool mediaTypeMatchSpecific(const char* mediaTypeToMatch) const;
 
     /** Evaluates a list of media queries */
@@ -82,8 +84,8 @@
     bool eval(const MediaQueryExp*) const;
 
 private:
-    AtomicString m_mediaType;
-    Frame* m_frame; // Not owned.
+    String m_mediaType;
+    LocalFrame* m_frame; // Not owned.
     RefPtr<RenderStyle> m_style;
     bool m_expResult;
 };
diff --git a/Source/core/css/MediaQueryExp.cpp b/Source/core/css/MediaQueryExp.cpp
index a7c5cf5..e1a4ffb 100644
--- a/Source/core/css/MediaQueryExp.cpp
+++ b/Source/core/css/MediaQueryExp.cpp
@@ -32,29 +32,32 @@
 
 #include "CSSValueKeywords.h"
 #include "core/css/CSSAspectRatioValue.h"
-#include "core/css/parser/BisonCSSParser.h"
+#include "core/css/CSSParserValues.h"
 #include "core/css/CSSPrimitiveValue.h"
+#include "core/html/parser/HTMLParserIdioms.h"
 #include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
 
-static inline bool featureWithCSSValueID(const AtomicString& mediaFeature, const CSSParserValue* value)
+using namespace MediaFeatureNames;
+
+static inline bool featureWithCSSValueID(const String& mediaFeature, const CSSParserValue* value)
 {
     if (!value->id)
         return false;
 
-    return mediaFeature == MediaFeatureNames::orientationMediaFeature
-        || mediaFeature == MediaFeatureNames::viewModeMediaFeature
-        || mediaFeature == MediaFeatureNames::pointerMediaFeature
-        || mediaFeature == MediaFeatureNames::scanMediaFeature;
+    return mediaFeature == orientationMediaFeature
+        || mediaFeature == viewModeMediaFeature
+        || mediaFeature == pointerMediaFeature
+        || mediaFeature == scanMediaFeature;
 }
 
-static inline bool featureWithValidIdent(const AtomicString& mediaFeature, CSSValueID ident)
+static inline bool featureWithValidIdent(const String& mediaFeature, CSSValueID ident)
 {
-    if (mediaFeature == MediaFeatureNames::orientationMediaFeature)
+    if (mediaFeature == orientationMediaFeature)
         return ident == CSSValuePortrait || ident == CSSValueLandscape;
 
-    if (mediaFeature == MediaFeatureNames::viewModeMediaFeature) {
+    if (mediaFeature == viewModeMediaFeature) {
         switch (ident) {
         case CSSValueWindowed:
         case CSSValueFloating:
@@ -67,175 +70,184 @@
         }
     }
 
-    if (mediaFeature == MediaFeatureNames::pointerMediaFeature)
+    if (mediaFeature == pointerMediaFeature)
         return ident == CSSValueNone || ident == CSSValueCoarse || ident == CSSValueFine;
 
-    if (mediaFeature == MediaFeatureNames::scanMediaFeature)
+    if (mediaFeature == scanMediaFeature)
         return ident == CSSValueInterlace || ident == CSSValueProgressive;
 
     ASSERT_NOT_REACHED();
     return false;
 }
 
-static inline bool featureWithValidPositiveLenghtOrNumber(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithValidPositiveLength(const String& mediaFeature, const CSSParserValue* value)
 {
-    if (!(((value->unit >= CSSPrimitiveValue::CSS_EMS && value->unit <= CSSPrimitiveValue::CSS_PC) || value->unit == CSSPrimitiveValue::CSS_REMS) || value->unit == CSSPrimitiveValue::CSS_NUMBER) || value->fValue < 0)
+    if (!(((value->unit >= CSSPrimitiveValue::CSS_EMS && value->unit <= CSSPrimitiveValue::CSS_PC) || value->unit == CSSPrimitiveValue::CSS_REMS) || (value->unit == CSSPrimitiveValue::CSS_NUMBER && !(value->fValue))) || value->fValue < 0)
         return false;
 
-    return mediaFeature == MediaFeatureNames::heightMediaFeature
-        || mediaFeature == MediaFeatureNames::maxHeightMediaFeature
-        || mediaFeature == MediaFeatureNames::minHeightMediaFeature
-        || mediaFeature == MediaFeatureNames::widthMediaFeature
-        || mediaFeature == MediaFeatureNames::maxWidthMediaFeature
-        || mediaFeature == MediaFeatureNames::minWidthMediaFeature
-        || mediaFeature == MediaFeatureNames::deviceHeightMediaFeature
-        || mediaFeature == MediaFeatureNames::maxDeviceHeightMediaFeature
-        || mediaFeature == MediaFeatureNames::minDeviceHeightMediaFeature
-        || mediaFeature == MediaFeatureNames::deviceWidthMediaFeature
-        || mediaFeature == MediaFeatureNames::maxDeviceWidthMediaFeature
-        || mediaFeature == MediaFeatureNames::minDeviceWidthMediaFeature;
+
+    return mediaFeature == heightMediaFeature
+        || mediaFeature == maxHeightMediaFeature
+        || mediaFeature == minHeightMediaFeature
+        || mediaFeature == widthMediaFeature
+        || mediaFeature == maxWidthMediaFeature
+        || mediaFeature == minWidthMediaFeature
+        || mediaFeature == deviceHeightMediaFeature
+        || mediaFeature == maxDeviceHeightMediaFeature
+        || mediaFeature == minDeviceHeightMediaFeature
+        || mediaFeature == deviceWidthMediaFeature
+        || mediaFeature == minDeviceWidthMediaFeature
+        || mediaFeature == maxDeviceWidthMediaFeature;
 }
 
-static inline bool featureWithValidDensity(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithValidDensity(const String& mediaFeature, const CSSParserValue* value)
 {
     if ((value->unit != CSSPrimitiveValue::CSS_DPPX && value->unit != CSSPrimitiveValue::CSS_DPI && value->unit != CSSPrimitiveValue::CSS_DPCM) || value->fValue <= 0)
         return false;
 
-    return mediaFeature == MediaFeatureNames::resolutionMediaFeature
-        || mediaFeature == MediaFeatureNames::maxResolutionMediaFeature
-        || mediaFeature == MediaFeatureNames::minResolutionMediaFeature;
+    return mediaFeature == resolutionMediaFeature
+        || mediaFeature == minResolutionMediaFeature
+        || mediaFeature == maxResolutionMediaFeature;
 }
 
-static inline bool featureWithPositiveInteger(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithPositiveInteger(const String& mediaFeature, const CSSParserValue* value)
 {
     if (!value->isInt || value->fValue < 0)
         return false;
 
-    return mediaFeature == MediaFeatureNames::colorMediaFeature
-        || mediaFeature == MediaFeatureNames::maxColorMediaFeature
-        || mediaFeature == MediaFeatureNames::minColorMediaFeature
-        || mediaFeature == MediaFeatureNames::colorIndexMediaFeature
-        || mediaFeature == MediaFeatureNames::maxColorIndexMediaFeature
-        || mediaFeature == MediaFeatureNames::minColorIndexMediaFeature
-        || mediaFeature == MediaFeatureNames::monochromeMediaFeature
-        || mediaFeature == MediaFeatureNames::minMonochromeMediaFeature
-        || mediaFeature == MediaFeatureNames::maxMonochromeMediaFeature;
+    return mediaFeature == colorMediaFeature
+        || mediaFeature == maxColorMediaFeature
+        || mediaFeature == minColorMediaFeature
+        || mediaFeature == colorIndexMediaFeature
+        || mediaFeature == maxColorIndexMediaFeature
+        || mediaFeature == minColorIndexMediaFeature
+        || mediaFeature == monochromeMediaFeature
+        || mediaFeature == maxMonochromeMediaFeature
+        || mediaFeature == minMonochromeMediaFeature;
 }
 
-static inline bool featureWithPositiveNumber(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithPositiveNumber(const String& mediaFeature, const CSSParserValue* value)
 {
     if (value->unit != CSSPrimitiveValue::CSS_NUMBER || value->fValue < 0)
         return false;
 
-    return mediaFeature == MediaFeatureNames::transform2dMediaFeature
-        || mediaFeature == MediaFeatureNames::transform3dMediaFeature
-        || mediaFeature == MediaFeatureNames::animationMediaFeature
-        || mediaFeature == MediaFeatureNames::devicePixelRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::maxDevicePixelRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::minDevicePixelRatioMediaFeature;
+    return mediaFeature == transform2dMediaFeature
+        || mediaFeature == transform3dMediaFeature
+        || mediaFeature == animationMediaFeature
+        || mediaFeature == devicePixelRatioMediaFeature
+        || mediaFeature == maxDevicePixelRatioMediaFeature
+        || mediaFeature == minDevicePixelRatioMediaFeature;
 }
 
-static inline bool featureWithZeroOrOne(const AtomicString& mediaFeature, const CSSParserValue* value)
+static inline bool featureWithZeroOrOne(const String& mediaFeature, const CSSParserValue* value)
 {
     if (!value->isInt || !(value->fValue == 1 || !value->fValue))
         return false;
 
-    return mediaFeature == MediaFeatureNames::gridMediaFeature
-        || mediaFeature == MediaFeatureNames::hoverMediaFeature;
+    return mediaFeature == gridMediaFeature
+        || mediaFeature == hoverMediaFeature;
 }
 
-static inline bool featureWithAspectRatio(const AtomicString& mediaFeature)
+static inline bool featureWithAspectRatio(const String& mediaFeature)
 {
-    return mediaFeature == MediaFeatureNames::aspectRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::deviceAspectRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::minAspectRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::maxAspectRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::minDeviceAspectRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::maxDeviceAspectRatioMediaFeature;
+    return mediaFeature == aspectRatioMediaFeature
+        || mediaFeature == deviceAspectRatioMediaFeature
+        || mediaFeature == minAspectRatioMediaFeature
+        || mediaFeature == maxAspectRatioMediaFeature
+        || mediaFeature == minDeviceAspectRatioMediaFeature
+        || mediaFeature == maxDeviceAspectRatioMediaFeature;
 }
 
-static inline bool featureWithoutValue(const AtomicString& mediaFeature)
+static inline bool featureWithoutValue(const String& mediaFeature)
 {
     // Media features that are prefixed by min/max cannot be used without a value.
-    return mediaFeature == MediaFeatureNames::monochromeMediaFeature
-        || mediaFeature == MediaFeatureNames::colorMediaFeature
-        || mediaFeature == MediaFeatureNames::colorIndexMediaFeature
-        || mediaFeature == MediaFeatureNames::gridMediaFeature
-        || mediaFeature == MediaFeatureNames::heightMediaFeature
-        || mediaFeature == MediaFeatureNames::widthMediaFeature
-        || mediaFeature == MediaFeatureNames::deviceHeightMediaFeature
-        || mediaFeature == MediaFeatureNames::deviceWidthMediaFeature
-        || mediaFeature == MediaFeatureNames::orientationMediaFeature
-        || mediaFeature == MediaFeatureNames::aspectRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::deviceAspectRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::hoverMediaFeature
-        || mediaFeature == MediaFeatureNames::transform2dMediaFeature
-        || mediaFeature == MediaFeatureNames::transform3dMediaFeature
-        || mediaFeature == MediaFeatureNames::animationMediaFeature
-        || mediaFeature == MediaFeatureNames::viewModeMediaFeature
-        || mediaFeature == MediaFeatureNames::pointerMediaFeature
-        || mediaFeature == MediaFeatureNames::devicePixelRatioMediaFeature
-        || mediaFeature == MediaFeatureNames::resolutionMediaFeature
-        || mediaFeature == MediaFeatureNames::scanMediaFeature;
+    return mediaFeature == monochromeMediaFeature
+        || mediaFeature == colorMediaFeature
+        || mediaFeature == colorIndexMediaFeature
+        || mediaFeature == gridMediaFeature
+        || mediaFeature == heightMediaFeature
+        || mediaFeature == widthMediaFeature
+        || mediaFeature == deviceHeightMediaFeature
+        || mediaFeature == deviceWidthMediaFeature
+        || mediaFeature == orientationMediaFeature
+        || mediaFeature == aspectRatioMediaFeature
+        || mediaFeature == deviceAspectRatioMediaFeature
+        || mediaFeature == hoverMediaFeature
+        || mediaFeature == transform2dMediaFeature
+        || mediaFeature == transform3dMediaFeature
+        || mediaFeature == animationMediaFeature
+        || mediaFeature == viewModeMediaFeature
+        || mediaFeature == pointerMediaFeature
+        || mediaFeature == devicePixelRatioMediaFeature
+        || mediaFeature == resolutionMediaFeature
+        || mediaFeature == scanMediaFeature;
 }
 
 bool MediaQueryExp::isViewportDependent() const
 {
-    return m_mediaFeature == MediaFeatureNames::widthMediaFeature
-        || m_mediaFeature == MediaFeatureNames::heightMediaFeature
-        || m_mediaFeature == MediaFeatureNames::minWidthMediaFeature
-        || m_mediaFeature == MediaFeatureNames::minHeightMediaFeature
-        || m_mediaFeature == MediaFeatureNames::maxWidthMediaFeature
-        || m_mediaFeature == MediaFeatureNames::maxHeightMediaFeature
-        || m_mediaFeature == MediaFeatureNames::orientationMediaFeature
-        || m_mediaFeature == MediaFeatureNames::aspectRatioMediaFeature
-        || m_mediaFeature == MediaFeatureNames::minAspectRatioMediaFeature
-        || m_mediaFeature == MediaFeatureNames::devicePixelRatioMediaFeature
-        || m_mediaFeature == MediaFeatureNames::resolutionMediaFeature
-        || m_mediaFeature == MediaFeatureNames::maxAspectRatioMediaFeature;
+    return m_mediaFeature == widthMediaFeature
+        || m_mediaFeature == heightMediaFeature
+        || m_mediaFeature == minWidthMediaFeature
+        || m_mediaFeature == minHeightMediaFeature
+        || m_mediaFeature == maxWidthMediaFeature
+        || m_mediaFeature == maxHeightMediaFeature
+        || m_mediaFeature == orientationMediaFeature
+        || m_mediaFeature == aspectRatioMediaFeature
+        || m_mediaFeature == minAspectRatioMediaFeature
+        || m_mediaFeature == devicePixelRatioMediaFeature
+        || m_mediaFeature == resolutionMediaFeature
+        || m_mediaFeature == maxAspectRatioMediaFeature;
 }
 
-MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, PassRefPtr<CSSValue> value)
+MediaQueryExp::MediaQueryExp(const MediaQueryExp& other)
+    : m_mediaFeature(other.mediaFeature())
+    , m_value(other.value())
+{
+}
+
+MediaQueryExp::MediaQueryExp(const String& mediaFeature, PassRefPtrWillBeRawPtr<CSSValue> value)
     : m_mediaFeature(mediaFeature)
     , m_value(value)
 {
 }
 
-PassOwnPtr<MediaQueryExp> MediaQueryExp::create(const AtomicString& mediaFeature, CSSParserValueList* valueList)
+// FIXME - create should not return a null.
+PassOwnPtrWillBeRawPtr<MediaQueryExp> MediaQueryExp::create(const String& mediaFeature, CSSParserValueList* valueList)
 {
-    RefPtr<CSSValue> cssValue;
+    RefPtrWillBeRawPtr<CSSValue> cssValue;
     bool isValid = false;
+    String lowerMediaFeature = attemptStaticStringCreation(mediaFeature.lower());
 
     // Create value for media query expression that must have 1 or more values.
-    if (valueList) {
+    if (valueList && valueList->size() > 0) {
         if (valueList->size() == 1) {
             CSSParserValue* value = valueList->current();
 
-            if (featureWithCSSValueID(mediaFeature, value)) {
+            if (featureWithCSSValueID(lowerMediaFeature, value)) {
                 // Media features that use CSSValueIDs.
                 cssValue = CSSPrimitiveValue::createIdentifier(value->id);
-                if (!featureWithValidIdent(mediaFeature, toCSSPrimitiveValue(cssValue.get())->getValueID()))
+                if (!featureWithValidIdent(lowerMediaFeature, toCSSPrimitiveValue(cssValue.get())->getValueID()))
                     cssValue.clear();
-            } else if (featureWithValidDensity(mediaFeature, value)) {
+            } else if (featureWithValidDensity(lowerMediaFeature, value)) {
                 // Media features that must have non-negative <density>, ie. dppx, dpi or dpcm.
                 cssValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
-            } else if (featureWithValidPositiveLenghtOrNumber(mediaFeature, value)) {
+            } else if (featureWithValidPositiveLength(lowerMediaFeature, value)) {
                 // Media features that must have non-negative <lenght> or number value.
                 cssValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
-            } else if (featureWithPositiveInteger(mediaFeature, value)) {
+            } else if (featureWithPositiveInteger(lowerMediaFeature, value)) {
                 // Media features that must have non-negative integer value.
                 cssValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);
-            } else if (featureWithPositiveNumber(mediaFeature, value)) {
+            } else if (featureWithPositiveNumber(lowerMediaFeature, value)) {
                 // Media features that must have non-negative number value.
                 cssValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);
-            } else if (featureWithZeroOrOne(mediaFeature, value)) {
+            } else if (featureWithZeroOrOne(lowerMediaFeature, value)) {
                 // Media features that must have (0|1) value.
                 cssValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_NUMBER);
             }
 
             isValid = cssValue;
 
-        } else if (valueList->size() == 3 && featureWithAspectRatio(mediaFeature)) {
+        } else if (valueList->size() == 3 && featureWithAspectRatio(lowerMediaFeature)) {
             // Create list of values.
             // Currently accepts only <integer>/<integer>.
             // Applicable to device-aspect-ratio and aspec-ratio.
@@ -261,14 +273,14 @@
             if (isValid)
                 cssValue = CSSAspectRatioValue::create(numeratorValue, denominatorValue);
         }
-    } else if (featureWithoutValue(mediaFeature)) {
+    } else if (featureWithoutValue(lowerMediaFeature)) {
         isValid = true;
     }
 
     if (!isValid)
         return nullptr;
 
-    return adoptPtr(new MediaQueryExp(mediaFeature, cssValue));
+    return adoptPtrWillBeNoop(new MediaQueryExp(lowerMediaFeature, cssValue));
 }
 
 MediaQueryExp::~MediaQueryExp()
diff --git a/Source/core/css/MediaQueryExp.h b/Source/core/css/MediaQueryExp.h
index 0586b0a..11ea6fd 100644
--- a/Source/core/css/MediaQueryExp.h
+++ b/Source/core/css/MediaQueryExp.h
@@ -29,22 +29,21 @@
 #ifndef MediaQueryExp_h
 #define MediaQueryExp_h
 
+#include "MediaFeatureNames.h"
 #include "core/css/CSSValue.h"
-#include "core/css/MediaFeatureNames.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/RefPtr.h"
-#include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 class CSSParserValueList;
 
-class MediaQueryExp {
-    WTF_MAKE_FAST_ALLOCATED;
+class MediaQueryExp : public NoBaseWillBeGarbageCollectedFinalized<MediaQueryExp> {
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
-    static PassOwnPtr<MediaQueryExp> create(const AtomicString& mediaFeature, CSSParserValueList*);
+    static PassOwnPtrWillBeRawPtr<MediaQueryExp> create(const String& mediaFeature, CSSParserValueList*);
     ~MediaQueryExp();
 
-    AtomicString mediaFeature() const { return m_mediaFeature; }
+    const String& mediaFeature() const { return m_mediaFeature; }
 
     CSSValue* value() const { return m_value.get(); }
 
@@ -59,13 +58,17 @@
 
     String serialize() const;
 
-    PassOwnPtr<MediaQueryExp> copy() const { return adoptPtr(new MediaQueryExp(*this)); }
+    PassOwnPtrWillBeRawPtr<MediaQueryExp> copy() const { return adoptPtrWillBeNoop(new MediaQueryExp(*this)); }
+
+    void trace(Visitor* visitor) { visitor->trace(m_value); }
+
+    MediaQueryExp(const MediaQueryExp& other);
 
 private:
-    MediaQueryExp(const AtomicString& mediaFeature, PassRefPtr<CSSValue>);
+    MediaQueryExp(const String&, PassRefPtrWillBeRawPtr<CSSValue>);
 
-    AtomicString m_mediaFeature;
-    RefPtr<CSSValue> m_value;
+    String m_mediaFeature;
+    RefPtrWillBeMember<CSSValue> m_value;
 };
 
 } // namespace
diff --git a/Source/core/css/MediaQueryList.cpp b/Source/core/css/MediaQueryList.cpp
index b55f3fb..4ada713 100644
--- a/Source/core/css/MediaQueryList.cpp
+++ b/Source/core/css/MediaQueryList.cpp
@@ -27,12 +27,12 @@
 
 namespace WebCore {
 
-PassRefPtr<MediaQueryList> MediaQueryList::create(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaQuerySet> media, bool matches)
+PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryList::create(PassRefPtrWillBeRawPtr<MediaQueryMatcher> vector, PassRefPtrWillBeRawPtr<MediaQuerySet> media, bool matches)
 {
-    return adoptRef(new MediaQueryList(vector, media, matches));
+    return adoptRefWillBeNoop(new MediaQueryList(vector, media, matches));
 }
 
-MediaQueryList::MediaQueryList(PassRefPtr<MediaQueryMatcher> vector, PassRefPtr<MediaQuerySet> media, bool matches)
+MediaQueryList::MediaQueryList(PassRefPtrWillBeRawPtr<MediaQueryMatcher> vector, PassRefPtrWillBeRawPtr<MediaQuerySet> media, bool matches)
     : m_matcher(vector)
     , m_media(media)
     , m_evaluationRound(m_matcher->evaluationRound())
@@ -41,16 +41,14 @@
 {
 }
 
-MediaQueryList::~MediaQueryList()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryList)
 
 String MediaQueryList::media() const
 {
     return m_media->mediaText();
 }
 
-void MediaQueryList::addListener(PassRefPtr<MediaQueryListListener> listener)
+void MediaQueryList::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)
 {
     if (!listener)
         return;
@@ -58,7 +56,7 @@
     m_matcher->addListener(listener, this);
 }
 
-void MediaQueryList::removeListener(PassRefPtr<MediaQueryListListener> listener)
+void MediaQueryList::removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener)
 {
     if (!listener)
         return;
@@ -91,4 +89,10 @@
     return m_matches;
 }
 
+void MediaQueryList::trace(Visitor* visitor)
+{
+    visitor->trace(m_matcher);
+    visitor->trace(m_media);
+}
+
 }
diff --git a/Source/core/css/MediaQueryList.h b/Source/core/css/MediaQueryList.h
index a15bc6a..f4af596 100644
--- a/Source/core/css/MediaQueryList.h
+++ b/Source/core/css/MediaQueryList.h
@@ -20,6 +20,7 @@
 #ifndef MediaQueryList_h
 #define MediaQueryList_h
 
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -36,25 +37,26 @@
 // retrieve the current value of the given media query and to add/remove listeners that
 // will be called whenever the value of the query changes.
 
-class MediaQueryList : public RefCounted<MediaQueryList> {
+class MediaQueryList FINAL : public RefCountedWillBeGarbageCollected<MediaQueryList> {
+    DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryList);
 public:
-    static PassRefPtr<MediaQueryList> create(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaQuerySet>, bool);
-    ~MediaQueryList();
-
+    static PassRefPtrWillBeRawPtr<MediaQueryList> create(PassRefPtrWillBeRawPtr<MediaQueryMatcher>, PassRefPtrWillBeRawPtr<MediaQuerySet>, bool);
     String media() const;
     bool matches();
 
-    void addListener(PassRefPtr<MediaQueryListListener>);
-    void removeListener(PassRefPtr<MediaQueryListListener>);
+    void addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>);
+    void removeListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>);
 
     void evaluate(MediaQueryEvaluator*, bool& notificationNeeded);
 
+    void trace(Visitor*);
+
 private:
-    MediaQueryList(PassRefPtr<MediaQueryMatcher>, PassRefPtr<MediaQuerySet>, bool matches);
+    MediaQueryList(PassRefPtrWillBeRawPtr<MediaQueryMatcher>, PassRefPtrWillBeRawPtr<MediaQuerySet>, bool matches);
     void setMatches(bool);
 
-    RefPtr<MediaQueryMatcher> m_matcher;
-    RefPtr<MediaQuerySet> m_media;
+    RefPtrWillBeMember<MediaQueryMatcher> m_matcher;
+    RefPtrWillBeMember<MediaQuerySet> m_media;
     unsigned m_evaluationRound; // Indicates if the query has been evaluated after the last style selector change.
     unsigned m_changeRound; // Used to know if the query has changed in the last style selector change.
     bool m_matches;
diff --git a/Source/core/css/MediaQueryList.idl b/Source/core/css/MediaQueryList.idl
index 7785d8d..c60c692 100644
--- a/Source/core/css/MediaQueryList.idl
+++ b/Source/core/css/MediaQueryList.idl
@@ -17,7 +17,8 @@
  *  Boston, MA 02110-1301, USA.
  */
 [
-    NoInterfaceObject
+    NoInterfaceObject,
+    WillBeGarbageCollected
 ] interface MediaQueryList {
     readonly attribute DOMString media;
     readonly attribute boolean matches;
diff --git a/Source/core/css/MediaQueryListListener.h b/Source/core/css/MediaQueryListListener.h
index fccf99d..cf0b743 100644
--- a/Source/core/css/MediaQueryListListener.h
+++ b/Source/core/css/MediaQueryListListener.h
@@ -22,6 +22,7 @@
 
 #include "bindings/v8/ScriptState.h"
 #include "bindings/v8/ScriptValue.h"
+#include "heap/Handle.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
@@ -30,20 +31,22 @@
 
 // See http://dev.w3.org/csswg/cssom-view/#the-mediaquerylist-interface
 
-class MediaQueryListListener : public RefCounted<MediaQueryListListener> {
+class MediaQueryListListener : public RefCountedWillBeGarbageCollectedFinalized<MediaQueryListListener> {
 public:
-    static PassRefPtr<MediaQueryListListener> create(const ScriptValue& value)
+    static PassRefPtrWillBeRawPtr<MediaQueryListListener> create(const ScriptValue& value)
     {
         if (!value.isFunction())
-            return 0;
-        return adoptRef(new MediaQueryListListener(value));
+            return nullptr;
+        return adoptRefWillBeNoop(new MediaQueryListListener(value));
     }
     void queryChanged(ScriptState*, MediaQueryList*);
 
     bool operator==(const MediaQueryListListener& other) const { return m_value == other.m_value; }
 
+    void trace(Visitor*) { }
+
 private:
-    MediaQueryListListener(const ScriptValue& value) : m_value(value) { }
+    explicit MediaQueryListListener(const ScriptValue& value) : m_value(value) { }
 
     ScriptValue m_value;
 };
diff --git a/Source/core/css/MediaQueryMatcher.cpp b/Source/core/css/MediaQueryMatcher.cpp
index 9051099..73ddfc6 100644
--- a/Source/core/css/MediaQueryMatcher.cpp
+++ b/Source/core/css/MediaQueryMatcher.cpp
@@ -26,12 +26,12 @@
 #include "core/css/MediaQueryListListener.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
-MediaQueryMatcher::Listener::Listener(PassRefPtr<MediaQueryListListener> listener, PassRefPtr<MediaQueryList> query)
+MediaQueryMatcher::Listener::Listener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
     : m_listener(listener)
     , m_query(query)
 {
@@ -49,6 +49,12 @@
         m_listener->queryChanged(state, m_query.get());
 }
 
+void MediaQueryMatcher::Listener::trace(Visitor* visitor)
+{
+    visitor->trace(m_listener);
+    visitor->trace(m_query);
+}
+
 MediaQueryMatcher::MediaQueryMatcher(Document* document)
     : m_document(document)
     , m_evaluationRound(1)
@@ -56,9 +62,7 @@
     ASSERT(m_document);
 }
 
-MediaQueryMatcher::~MediaQueryMatcher()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher)
 
 void MediaQueryMatcher::documentDestroyed()
 {
@@ -98,18 +102,18 @@
     return evaluator && evaluator->eval(media);
 }
 
-PassRefPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query)
+PassRefPtrWillBeRawPtr<MediaQueryList> MediaQueryMatcher::matchMedia(const String& query)
 {
     if (!m_document)
-        return 0;
+        return nullptr;
 
-    RefPtr<MediaQuerySet> media = MediaQuerySet::create(query);
+    RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(query);
     // Add warning message to inspector whenever dpi/dpcm values are used for "screen" media.
     reportMediaQueryWarningIfNeeded(m_document, media.get());
     return MediaQueryList::create(this, media, evaluate(media.get()));
 }
 
-void MediaQueryMatcher::addListener(PassRefPtr<MediaQueryListListener> listener, PassRefPtr<MediaQueryList> query)
+void MediaQueryMatcher::addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener> listener, PassRefPtrWillBeRawPtr<MediaQueryList> query)
 {
     if (!m_document)
         return;
@@ -119,7 +123,7 @@
             return;
     }
 
-    m_listeners.append(adoptPtr(new Listener(listener, query)));
+    m_listeners.append(adoptPtrWillBeNoop(new Listener(listener, query)));
 }
 
 void MediaQueryMatcher::removeListener(MediaQueryListListener* listener, MediaQueryList* query)
@@ -153,4 +157,13 @@
         m_listeners[i]->evaluate(scriptState, evaluator.get());
 }
 
+void MediaQueryMatcher::trace(Visitor* visitor)
+{
+    // We don't support tracing of vectors of OwnPtrs (ie. Vector<OwnPtr<Listener> >).
+    // Since this is a transitional object we are just ifdef'ing it out when oilpan is not enabled.
+#if ENABLE(OILPAN)
+    visitor->trace(m_listeners);
+#endif
+}
+
 }
diff --git a/Source/core/css/MediaQueryMatcher.h b/Source/core/css/MediaQueryMatcher.h
index 42945b4..fdec565 100644
--- a/Source/core/css/MediaQueryMatcher.h
+++ b/Source/core/css/MediaQueryMatcher.h
@@ -21,6 +21,7 @@
 #define MediaQueryMatcher_h
 
 #include "bindings/v8/ScriptState.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 #include "wtf/Vector.h"
@@ -38,35 +39,38 @@
 // whenever it is needed and to call the listeners if the corresponding query has changed.
 // The listeners must be called in the very same order in which they have been added.
 
-class MediaQueryMatcher : public RefCounted<MediaQueryMatcher> {
+class MediaQueryMatcher FINAL : public RefCountedWillBeGarbageCollected<MediaQueryMatcher> {
+    DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(MediaQueryMatcher);
 public:
-    static PassRefPtr<MediaQueryMatcher> create(Document* document) { return adoptRef(new MediaQueryMatcher(document)); }
-    ~MediaQueryMatcher();
+    static PassRefPtrWillBeRawPtr<MediaQueryMatcher> create(Document* document) { return adoptRefWillBeNoop(new MediaQueryMatcher(document)); }
     void documentDestroyed();
 
-    void addListener(PassRefPtr<MediaQueryListListener>, PassRefPtr<MediaQueryList>);
+    void addListener(PassRefPtrWillBeRawPtr<MediaQueryListListener>, PassRefPtrWillBeRawPtr<MediaQueryList>);
     void removeListener(MediaQueryListListener*, MediaQueryList*);
 
-    PassRefPtr<MediaQueryList> matchMedia(const String&);
+    PassRefPtrWillBeRawPtr<MediaQueryList> matchMedia(const String&);
 
     unsigned evaluationRound() const { return m_evaluationRound; }
     void styleResolverChanged();
     bool evaluate(const MediaQuerySet*);
 
-private:
-    class Listener {
-    public:
-        Listener(PassRefPtr<MediaQueryListListener>, PassRefPtr<MediaQueryList>);
-        ~Listener();
+    void trace(Visitor*);
 
+private:
+    class Listener : public NoBaseWillBeGarbageCollected<Listener> {
+    public:
+        Listener(PassRefPtrWillBeRawPtr<MediaQueryListListener>, PassRefPtrWillBeRawPtr<MediaQueryList>);
+        ~Listener();
         void evaluate(ScriptState*, MediaQueryEvaluator*);
 
         MediaQueryListListener* listener() { return m_listener.get(); }
         MediaQueryList* query() { return m_query.get(); }
 
+        void trace(Visitor*);
+
     private:
-        RefPtr<MediaQueryListListener> m_listener;
-        RefPtr<MediaQueryList> m_query;
+        RefPtrWillBeMember<MediaQueryListListener> m_listener;
+        RefPtrWillBeMember<MediaQueryList> m_query;
     };
 
     MediaQueryMatcher(Document*);
@@ -74,7 +78,7 @@
     AtomicString mediaType() const;
 
     Document* m_document;
-    Vector<OwnPtr<Listener> > m_listeners;
+    WillBeHeapVector<OwnPtrWillBeMember<Listener> > m_listeners;
 
     // This value is incremented at style selector changes.
     // It is used to avoid evaluating queries more then once and to make sure
diff --git a/Source/core/css/MediaQuerySetTest.cpp b/Source/core/css/MediaQuerySetTest.cpp
new file mode 100644
index 0000000..8746a17
--- /dev/null
+++ b/Source/core/css/MediaQuerySetTest.cpp
@@ -0,0 +1,143 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/MediaQuery.h"
+
+#include "core/css/MediaList.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/text/StringBuilder.h"
+
+#include <gtest/gtest.h>
+
+const unsigned outputCharArrayLen = 256;
+
+namespace WebCore {
+
+typedef struct {
+    const char* input;
+    const char* output;
+} TestCase;
+
+int getCharArray(String str, char* output)
+{
+    if (str.isNull())
+        return 0;
+
+    unsigned i;
+    if (str.is8Bit()) {
+        for (i = 0; i < str.length(); ++i)
+            output[i] = str.characters8()[i];
+    } else {
+        for (i = 0; i < str.length(); ++i)
+            output[i] = str.characters16()[i];
+    }
+    output[i++] = 0;
+    return i;
+}
+
+TEST(MediaQueryParserTest, Basic)
+{
+    // The first string represents the input string.
+    // The second string represents the output string, if present.
+    // Otherwise, the output string is identical to the first string.
+    TestCase testCases[] = {
+        {"screen", 0},
+        {"screen and (color)", 0},
+        {"all and (min-width:500px)", "(min-width: 500px)"},
+        {"(min-width:500px)", "(min-width: 500px)"},
+        {"screen and (color), projection and (color)", 0},
+        {"not screen and (color)", 0},
+        {"only screen and (color)", 0},
+        {"screen and (color), projection and (color)", 0},
+        {"aural and (device-aspect-ratio: 16/9)", 0},
+        {"speech and (min-device-width: 800px)", 0},
+        {"example", 0},
+        {"screen and (max-weight: 3kg) and (color), (monochrome)", "not all, (monochrome)"},
+        {"(min-width: -100px)", "not all"},
+        {"(example, all,), speech", "not all, speech"},
+        {"&test, screen", "not all, screen"},
+        {"print and (min-width: 25cm)", 0},
+        {"screen and (min-width: 400px) and (max-width: 700px)", "screen and (max-width: 700px) and (min-width: 400px)"},
+        {"screen and (device-width: 800px)", 0},
+        {"screen and (device-height: 60em)", 0},
+        {"screen and (device-aspect-ratio: 16/9)", 0},
+        {"(device-aspect-ratio: 16.0/9.0)", "not all"},
+        {"(device-aspect-ratio: 16/ 9)", "(device-aspect-ratio: 16/9)"},
+        {"(device-aspect-ratio: 16/\r9)", "(device-aspect-ratio: 16/9)"},
+        {"all and (color)", "(color)"},
+        {"all and (min-color: 1)", "(min-color: 1)"},
+        {"all and (min-color: 1.0)", "not all"},
+        {"all and (min-color: 2)", "(min-color: 2)"},
+        {"all and (color-index)", "(color-index)"},
+        {"all and (min-color-index: 1)", "(min-color-index: 1)"},
+        {"all and (monochrome)", "(monochrome)"},
+        {"all and (min-monochrome: 1)", "(min-monochrome: 1)"},
+        {"all and (min-monochrome: 2)", "(min-monochrome: 2)"},
+        {"print and (monochrome)", 0},
+        {"handheld and (grid) and (max-width: 15em)", 0},
+        {"handheld and (grid) and (max-device-height: 7em)", 0},
+        {"screen and (max-width: 50%)", "not all"},
+        {"screen and (max-WIDTH: 500px)", "screen and (max-width: 500px)"},
+        {"screen and (max-width: 24.4em)", 0},
+        {"screen and (max-width: 24.4EM)", "screen and (max-width: 24.4em)"},
+        {"screen and (max-width: blabla)", "not all"},
+        {"screen and (max-width: 1)", "not all"},
+        {"screen and (max-width: 0)", 0},
+        {"screen and (max-width: 1deg)", "not all"},
+        {"handheld and (min-width: 20em), \nscreen and (min-width: 20em)", "handheld and (min-width: 20em), screen and (min-width: 20em)"},
+        {"print and (min-resolution: 300dpi)", 0},
+        {"print and (min-resolution: 118dpcm)", 0},
+        {"(resolution: 0.83333333333333333333dppx)", "(resolution: 0.8333333333333334dppx)"},
+        {"(resolution: 2.4dppx)", 0},
+        {"all and(color)", "not all"},
+        {"all and (", "not all"},
+        {"test;,all", "not all, all"},
+        {"(color:20example)", "not all"},
+        {"not braille", 0},
+        {",screen", "not all, screen"},
+        {",all", "not all, all"},
+        {",,all,,", "not all, not all, all, not all, not all"},
+        {",,all,, ", "not all, not all, all, not all, not all"},
+        {",screen,,&invalid,,", "not all, screen, not all, not all, not all, not all"},
+        {",screen,,(invalid,),,", "not all, screen, not all, not all, not all, not all"},
+        {",(all,),,", "not all, not all, not all, not all"},
+        {",", "not all, not all"},
+        {"  ", ""},
+        {"(color", "(color)"},
+        {"(min-color: 2", "(min-color: 2)"},
+        {"(orientation: portrait)", 0},
+        {"tv and (scan: progressive)", 0},
+        {"(pointer: coarse)", 0},
+        {"(min-orientation:portrait)", "not all"},
+        {"all and (orientation:portrait)", "(orientation: portrait)"},
+        {"all and (orientation:landscape)", "(orientation: landscape)"},
+        {"NOT braille, tv AND (max-width: 200px) and (min-WIDTH: 100px) and (orientation: landscape), (color)",
+            "not braille, tv and (max-width: 200px) and (min-width: 100px) and (orientation: landscape), (color)"},
+        {0, 0} // Do not remove the terminator line.
+    };
+
+    for (unsigned i = 0; testCases[i].input; ++i) {
+        RefPtrWillBeRawPtr<MediaQuerySet> querySet = MediaQuerySet::create(testCases[i].input);
+        StringBuilder output;
+        char outputCharArray[outputCharArrayLen];
+        size_t j = 0;
+        while (j < querySet->queryVector().size()) {
+            String queryText = querySet->queryVector()[j]->cssText();
+            output.append(queryText);
+            ++j;
+            if (j >= querySet->queryVector().size())
+                break;
+            output.append(", ");
+        }
+        ASSERT(output.length() < outputCharArrayLen);
+        getCharArray(output.toString(), outputCharArray);
+        if (testCases[i].output)
+            ASSERT_STREQ(testCases[i].output, outputCharArray);
+        else
+            ASSERT_STREQ(testCases[i].input, outputCharArray);
+    }
+}
+
+} // namespace
diff --git a/Source/core/css/MediaTypeNames.in b/Source/core/css/MediaTypeNames.in
new file mode 100644
index 0000000..556996d
--- /dev/null
+++ b/Source/core/css/MediaTypeNames.in
@@ -0,0 +1,15 @@
+namespace="MediaType"
+export=""
+
+# http://www.w3.org/TR/CSS2/media.html#media-types
+
+all
+braille
+embossed
+handheld
+print
+projection
+screen
+speech
+tty
+tv
diff --git a/Source/core/css/PageRuleCollector.cpp b/Source/core/css/PageRuleCollector.cpp
index e449452..7d9e4ec 100644
--- a/Source/core/css/PageRuleCollector.cpp
+++ b/Source/core/css/PageRuleCollector.cpp
@@ -73,7 +73,7 @@
         return;
 
     rules->compactRulesIfNeeded();
-    Vector<StyleRulePage*> matchedPageRules;
+    WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> > matchedPageRules;
     matchPageRulesForList(matchedPageRules, rules->pageRules(), m_isLeftPage, m_isFirstPage, m_pageName);
     if (matchedPageRules.isEmpty())
         return;
@@ -81,7 +81,7 @@
     std::stable_sort(matchedPageRules.begin(), matchedPageRules.end(), comparePageRules);
 
     for (unsigned i = 0; i < matchedPageRules.size(); i++)
-        m_result.addMatchedProperties(matchedPageRules[i]->properties());
+        m_result.addMatchedProperties(&matchedPageRules[i]->properties());
 }
 
 static bool checkPageSelectorComponents(const CSSSelector* selector, bool isLeftPage, bool isFirstPage, const String& pageName)
@@ -104,7 +104,7 @@
     return true;
 }
 
-void PageRuleCollector::matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName)
+void PageRuleCollector::matchPageRulesForList(WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& matchedRules, const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& rules, bool isLeftPage, bool isFirstPage, const String& pageName)
 {
     for (unsigned i = 0; i < rules.size(); ++i) {
         StyleRulePage* rule = rules[i];
@@ -113,8 +113,8 @@
             continue;
 
         // If the rule has no properties to apply, then ignore it.
-        const StylePropertySet* properties = rule->properties();
-        if (!properties || properties->isEmpty())
+        const StylePropertySet& properties = rule->properties();
+        if (properties.isEmpty())
             continue;
 
         // Add this rule to our list of matched rules.
diff --git a/Source/core/css/PageRuleCollector.h b/Source/core/css/PageRuleCollector.h
index 8325161..af63280 100644
--- a/Source/core/css/PageRuleCollector.h
+++ b/Source/core/css/PageRuleCollector.h
@@ -31,6 +31,7 @@
 class StyleRulePage;
 
 class PageRuleCollector {
+    STACK_ALLOCATED();
 public:
     PageRuleCollector(const RenderStyle* rootElementStyle, int pageIndex);
 
@@ -43,7 +44,7 @@
     bool isFirstPage(int pageIndex) const;
     String pageName(int pageIndex) const;
 
-    void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>& rules, bool isLeftPage, bool isFirstPage, const String& pageName);
+    void matchPageRulesForList(WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& matchedRules, const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& rules, bool isLeftPage, bool isFirstPage, const String& pageName);
 
     const bool m_isLeftPage;
     const bool m_isFirstPage;
diff --git a/Source/core/css/Pair.cpp b/Source/core/css/Pair.cpp
index 650b213..5362b6b 100644
--- a/Source/core/css/Pair.cpp
+++ b/Source/core/css/Pair.cpp
@@ -7,8 +7,6 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(Pair);
-
 void Pair::trace(Visitor* visitor)
 {
     visitor->trace(m_first);
diff --git a/Source/core/css/Pair.h b/Source/core/css/Pair.h
index e36d8d4..5cafb53 100644
--- a/Source/core/css/Pair.h
+++ b/Source/core/css/Pair.h
@@ -33,7 +33,6 @@
 // border-radius and background-size, but (FIXME) border-spacing and background-position could be converted over to use
 // it (eliminating some extra -webkit- internal properties).
 class Pair FINAL : public RefCountedWillBeGarbageCollected<Pair> {
-    DECLARE_GC_INFO;
 public:
     enum IdenticalValuesPolicy { DropIdenticalValues, KeepIdenticalValues };
 
@@ -67,8 +66,8 @@
 
 private:
     Pair()
-        : m_first(0)
-        , m_second(0)
+        : m_first(nullptr)
+        , m_second(nullptr)
         , m_identicalValuesPolicy(DropIdenticalValues) { }
 
     Pair(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> first, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> second, IdenticalValuesPolicy identicalValuesPolicy)
diff --git a/Source/core/css/PropertySetCSSStyleDeclaration.cpp b/Source/core/css/PropertySetCSSStyleDeclaration.cpp
index 3b17129..0f09c42 100644
--- a/Source/core/css/PropertySetCSSStyleDeclaration.cpp
+++ b/Source/core/css/PropertySetCSSStyleDeclaration.cpp
@@ -28,11 +28,9 @@
 #include "core/css/parser/BisonCSSParser.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/StylePropertySet.h"
-#include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/MutationObserverInterestGroup.h"
 #include "core/dom/MutationRecord.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/inspector/InspectorInstrumentation.h"
 
 using namespace std;
@@ -139,48 +137,40 @@
 
 unsigned AbstractPropertySetCSSStyleDeclaration::length() const
 {
-    return propertySet()->propertyCount();
+    return propertySet().propertyCount();
 }
 
 String AbstractPropertySetCSSStyleDeclaration::item(unsigned i) const
 {
-    if (i >= propertySet()->propertyCount())
+    if (i >= propertySet().propertyCount())
         return "";
-    return propertySet()->propertyAt(i).cssName();
+    return propertySet().propertyAt(i).cssName();
 }
 
 String AbstractPropertySetCSSStyleDeclaration::cssText() const
 {
-    return propertySet()->asText();
+    return propertySet().asText();
 }
 
 void AbstractPropertySetCSSStyleDeclaration::setCSSText(const String& text, ExceptionState& exceptionState)
 {
-    if (parentElement()) {
-        ContentSecurityPolicy* csp = parentElement()->document().contentSecurityPolicy();
-        if (!csp->allowStyleEval()) {
-            exceptionState.throwSecurityError(csp->styleEvalDisabledErrorMessage());
-            return;
-        }
-    }
-
     StyleAttributeMutationScope mutationScope(this);
     willMutate();
 
     // FIXME: Detect syntax errors and set exceptionState.
-    propertySet()->parseDeclaration(text, contextStyleSheet());
+    propertySet().parseDeclaration(text, contextStyleSheet());
 
     didMutate(PropertyChanged);
 
     mutationScope.enqueueMutationRecord();
 }
 
-PassRefPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
+PassRefPtrWillBeRawPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValue(const String& propertyName)
 {
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (!propertyID)
-        return 0;
-    return cloneAndCacheForCSSOM(propertySet()->getPropertyCSSValue(propertyID).get());
+        return nullptr;
+    return cloneAndCacheForCSSOM(propertySet().getPropertyCSSValue(propertyID).get());
 }
 
 String AbstractPropertySetCSSStyleDeclaration::getPropertyValue(const String &propertyName)
@@ -188,7 +178,7 @@
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (!propertyID)
         return String();
-    return propertySet()->getPropertyValue(propertyID);
+    return propertySet().getPropertyValue(propertyID);
 }
 
 String AbstractPropertySetCSSStyleDeclaration::getPropertyPriority(const String& propertyName)
@@ -196,7 +186,7 @@
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (!propertyID)
         return String();
-    return propertySet()->propertyIsImportant(propertyID) ? "important" : "";
+    return propertySet().propertyIsImportant(propertyID) ? "important" : "";
 }
 
 String AbstractPropertySetCSSStyleDeclaration::getPropertyShorthand(const String& propertyName)
@@ -204,7 +194,7 @@
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (!propertyID)
         return String();
-    CSSPropertyID shorthandID = propertySet()->getPropertyShorthand(propertyID);
+    CSSPropertyID shorthandID = propertySet().getPropertyShorthand(propertyID);
     if (!shorthandID)
         return String();
     return getPropertyNameString(shorthandID);
@@ -215,7 +205,7 @@
     CSSPropertyID propertyID = cssPropertyID(propertyName);
     if (!propertyID)
         return false;
-    return propertySet()->isPropertyImplicit(propertyID);
+    return propertySet().isPropertyImplicit(propertyID);
 }
 
 void AbstractPropertySetCSSStyleDeclaration::setProperty(const String& propertyName, const String& value, const String& priority, ExceptionState& exceptionState)
@@ -225,11 +215,13 @@
     if (!propertyID)
         return;
 
-    bool important = priority.find("important", 0, false) != kNotFound;
+    bool important = equalIgnoringCase(priority, "important");
+    if (!important && !priority.isEmpty())
+        return;
 
     willMutate();
 
-    bool changed = propertySet()->setProperty(propertyID, value, important, contextStyleSheet());
+    bool changed = propertySet().setProperty(propertyID, value, important, contextStyleSheet());
 
     didMutate(changed ? PropertyChanged : NoChanges);
 
@@ -250,7 +242,7 @@
     willMutate();
 
     String result;
-    bool changed = propertySet()->removeProperty(propertyID, &result);
+    bool changed = propertySet().removeProperty(propertyID, &result);
 
     didMutate(changed ? PropertyChanged : NoChanges);
 
@@ -259,14 +251,14 @@
     return result;
 }
 
-PassRefPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
+PassRefPtrWillBeRawPtr<CSSValue> AbstractPropertySetCSSStyleDeclaration::getPropertyCSSValueInternal(CSSPropertyID propertyID)
 {
-    return propertySet()->getPropertyCSSValue(propertyID);
+    return propertySet().getPropertyCSSValue(propertyID);
 }
 
 String AbstractPropertySetCSSStyleDeclaration::getPropertyValueInternal(CSSPropertyID propertyID)
 {
-    return propertySet()->getPropertyValue(propertyID);
+    return propertySet().getPropertyValue(propertyID);
 }
 
 void AbstractPropertySetCSSStyleDeclaration::setPropertyInternal(CSSPropertyID propertyID, const String& value, bool important, ExceptionState&)
@@ -274,7 +266,7 @@
     StyleAttributeMutationScope mutationScope(this);
     willMutate();
 
-    bool changed = propertySet()->setProperty(propertyID, value, important, contextStyleSheet());
+    bool changed = propertySet().setProperty(propertyID, value, important, contextStyleSheet());
 
     didMutate(changed ? PropertyChanged : NoChanges);
 
@@ -290,9 +282,9 @@
     // The map is here to maintain the object identity of the CSSValues over multiple invocations.
     // FIXME: It is likely that the identity is not important for web compatibility and this code should be removed.
     if (!m_cssomCSSValueClones)
-        m_cssomCSSValueClones = adoptPtr(new HashMap<CSSValue*, RefPtr<CSSValue> >);
+        m_cssomCSSValueClones = adoptPtrWillBeNoop(new WillBeHeapHashMap<CSSValue*, RefPtrWillBeMember<CSSValue> >);
 
-    RefPtr<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtr<CSSValue>()).storedValue->value;
+    RefPtrWillBeMember<CSSValue>& clonedValue = m_cssomCSSValueClones->add(internalValue, RefPtrWillBeMember<CSSValue>()).storedValue->value;
     if (!clonedValue)
         clonedValue = internalValue->cloneForCSSOM();
     return clonedValue.get();
@@ -306,15 +298,15 @@
 
 PassRefPtr<MutableStylePropertySet> AbstractPropertySetCSSStyleDeclaration::copyProperties() const
 {
-    return propertySet()->mutableCopy();
+    return propertySet().mutableCopy();
 }
 
 bool AbstractPropertySetCSSStyleDeclaration::cssPropertyMatches(CSSPropertyID propertyID, const CSSValue* propertyValue) const
 {
-    return propertySet()->propertyMatches(propertyID, propertyValue);
+    return propertySet().propertyMatches(propertyID, propertyValue);
 }
 
-StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(MutableStylePropertySet* propertySetArg, CSSRule* parentRule)
+StyleRuleCSSStyleDeclaration::StyleRuleCSSStyleDeclaration(MutableStylePropertySet& propertySetArg, CSSRule* parentRule)
     : PropertySetCSSStyleDeclaration(propertySetArg)
     , m_refCount(1)
     , m_parentRule(parentRule)
@@ -360,15 +352,14 @@
     return m_parentRule ? m_parentRule->parentStyleSheet() : 0;
 }
 
-void StyleRuleCSSStyleDeclaration::reattach(MutableStylePropertySet* propertySet)
+void StyleRuleCSSStyleDeclaration::reattach(MutableStylePropertySet& propertySet)
 {
-    ASSERT(propertySet);
     m_propertySet->deref();
-    m_propertySet = propertySet;
+    m_propertySet = &propertySet;
     m_propertySet->ref();
 }
 
-MutableStylePropertySet* InlineCSSStyleDeclaration::propertySet() const
+MutableStylePropertySet& InlineCSSStyleDeclaration::propertySet() const
 {
     return m_parentElement->ensureMutableInlineStyle();
 }
@@ -391,7 +382,7 @@
 
 CSSStyleSheet* InlineCSSStyleDeclaration::parentStyleSheet() const
 {
-    return m_parentElement ? m_parentElement->document().elementSheet() : 0;
+    return m_parentElement ? &m_parentElement->document().elementSheet() : 0;
 }
 
 void InlineCSSStyleDeclaration::ref()
diff --git a/Source/core/css/PropertySetCSSStyleDeclaration.h b/Source/core/css/PropertySetCSSStyleDeclaration.h
index 6860e4c..1bc15a9 100644
--- a/Source/core/css/PropertySetCSSStyleDeclaration.h
+++ b/Source/core/css/PropertySetCSSStyleDeclaration.h
@@ -50,7 +50,7 @@
     virtual CSSRule* parentRule() const OVERRIDE { return 0; }
     virtual unsigned length() const OVERRIDE FINAL;
     virtual String item(unsigned index) const OVERRIDE FINAL;
-    virtual PassRefPtr<CSSValue> getPropertyCSSValue(const String& propertyName) OVERRIDE FINAL;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(const String& propertyName) OVERRIDE FINAL;
     virtual String getPropertyValue(const String& propertyName) OVERRIDE FINAL;
     virtual String getPropertyPriority(const String& propertyName) OVERRIDE FINAL;
     virtual String getPropertyShorthand(const String& propertyName) OVERRIDE FINAL;
@@ -59,7 +59,7 @@
     virtual String removeProperty(const String& propertyName, ExceptionState&) OVERRIDE FINAL;
     virtual String cssText() const OVERRIDE FINAL;
     virtual void setCSSText(const String&, ExceptionState&) OVERRIDE FINAL;
-    virtual PassRefPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) OVERRIDE FINAL;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValueInternal(CSSPropertyID) OVERRIDE FINAL;
     virtual String getPropertyValueInternal(CSSPropertyID) OVERRIDE FINAL;
     virtual void setPropertyInternal(CSSPropertyID, const String& value, bool important, ExceptionState&) OVERRIDE FINAL;
 
@@ -72,28 +72,28 @@
     enum MutationType { NoChanges, PropertyChanged };
     virtual void willMutate() { }
     virtual void didMutate(MutationType) { }
-    virtual MutableStylePropertySet* propertySet() const = 0;
+    virtual MutableStylePropertySet& propertySet() const = 0;
 
-    OwnPtr<HashMap<CSSValue*, RefPtr<CSSValue> > > m_cssomCSSValueClones;
+    OwnPtrWillBePersistent<WillBeHeapHashMap<CSSValue*, RefPtrWillBeMember<CSSValue> > > m_cssomCSSValueClones;
 };
 
 class PropertySetCSSStyleDeclaration : public AbstractPropertySetCSSStyleDeclaration {
 public:
-    PropertySetCSSStyleDeclaration(MutableStylePropertySet* propertySet) : m_propertySet(propertySet) { }
+    PropertySetCSSStyleDeclaration(MutableStylePropertySet& propertySet) : m_propertySet(&propertySet) { }
 
     virtual void ref() OVERRIDE;
     virtual void deref() OVERRIDE;
 
 protected:
-    virtual MutableStylePropertySet* propertySet() const OVERRIDE FINAL { return m_propertySet; }
+    virtual MutableStylePropertySet& propertySet() const OVERRIDE FINAL { ASSERT(m_propertySet); return *m_propertySet; }
 
-    MutableStylePropertySet* m_propertySet;
+    MutableStylePropertySet* m_propertySet; // Cannot be null
 };
 
 class StyleRuleCSSStyleDeclaration FINAL : public PropertySetCSSStyleDeclaration
 {
 public:
-    static PassRefPtr<StyleRuleCSSStyleDeclaration> create(MutableStylePropertySet* propertySet, CSSRule* parentRule)
+    static PassRefPtr<StyleRuleCSSStyleDeclaration> create(MutableStylePropertySet& propertySet, CSSRule* parentRule)
     {
         return adoptRef(new StyleRuleCSSStyleDeclaration(propertySet, parentRule));
     }
@@ -103,10 +103,10 @@
     virtual void ref() OVERRIDE;
     virtual void deref() OVERRIDE;
 
-    void reattach(MutableStylePropertySet*);
+    void reattach(MutableStylePropertySet&);
 
 private:
-    StyleRuleCSSStyleDeclaration(MutableStylePropertySet*, CSSRule*);
+    StyleRuleCSSStyleDeclaration(MutableStylePropertySet&, CSSRule*);
     virtual ~StyleRuleCSSStyleDeclaration();
 
     virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE;
@@ -129,7 +129,7 @@
     }
 
 private:
-    virtual MutableStylePropertySet* propertySet() const OVERRIDE;
+    virtual MutableStylePropertySet& propertySet() const OVERRIDE;
     virtual void ref() OVERRIDE;
     virtual void deref() OVERRIDE;
     virtual CSSStyleSheet* parentStyleSheet() const OVERRIDE;
diff --git a/Source/core/css/RGBColor.cpp b/Source/core/css/RGBColor.cpp
index b441d4e..9994d23 100644
--- a/Source/core/css/RGBColor.cpp
+++ b/Source/core/css/RGBColor.cpp
@@ -30,9 +30,9 @@
 
 namespace WebCore {
 
-PassRefPtr<RGBColor> RGBColor::create(unsigned rgbColor)
+PassRefPtrWillBeRawPtr<RGBColor> RGBColor::create(unsigned rgbColor)
 {
-    return adoptRef(new RGBColor(rgbColor));
+    return adoptRefWillBeNoop(new RGBColor(rgbColor));
 }
 
 PassRefPtrWillBeRawPtr<CSSPrimitiveValue> RGBColor::red()
diff --git a/Source/core/css/RGBColor.h b/Source/core/css/RGBColor.h
index 6ed676e..9e672ba 100644
--- a/Source/core/css/RGBColor.h
+++ b/Source/core/css/RGBColor.h
@@ -27,6 +27,7 @@
 #ifndef RGBColor_h
 #define RGBColor_h
 
+#include "heap/Handle.h"
 #include "platform/graphics/Color.h"
 #include "wtf/RefCounted.h"
 
@@ -34,9 +35,9 @@
 
     class CSSPrimitiveValue;
 
-    class RGBColor : public RefCounted<RGBColor> {
+    class RGBColor : public RefCountedWillBeGarbageCollected<RGBColor> {
     public:
-        static PassRefPtr<RGBColor> create(unsigned rgbColor);
+        static PassRefPtrWillBeRawPtr<RGBColor> create(unsigned rgbColor);
 
         PassRefPtrWillBeRawPtr<CSSPrimitiveValue> red();
         PassRefPtrWillBeRawPtr<CSSPrimitiveValue> green();
@@ -45,6 +46,8 @@
 
         Color color() const { return Color(m_rgbColor); }
 
+        void trace(Visitor*) { }
+
     private:
         RGBColor(unsigned rgbColor)
             : m_rgbColor(rgbColor)
diff --git a/Source/core/css/RGBColor.idl b/Source/core/css/RGBColor.idl
index 09fa76e..398fe1b 100644
--- a/Source/core/css/RGBColor.idl
+++ b/Source/core/css/RGBColor.idl
@@ -19,6 +19,7 @@
  */
 
 [
+    WillBeGarbageCollected
 ] interface RGBColor {
     readonly attribute CSSPrimitiveValue  red;
     readonly attribute CSSPrimitiveValue  green;
diff --git a/Source/core/css/Rect.cpp b/Source/core/css/Rect.cpp
new file mode 100644
index 0000000..13afc70
--- /dev/null
+++ b/Source/core/css/Rect.cpp
@@ -0,0 +1,20 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/Rect.h"
+
+namespace WebCore {
+
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(RectBase)
+
+void RectBase::trace(Visitor* visitor)
+{
+    visitor->trace(m_top);
+    visitor->trace(m_right);
+    visitor->trace(m_bottom);
+    visitor->trace(m_left);
+}
+
+}
diff --git a/Source/core/css/Rect.h b/Source/core/css/Rect.h
index 3808888..2f9e08e 100644
--- a/Source/core/css/Rect.h
+++ b/Source/core/css/Rect.h
@@ -27,7 +27,8 @@
 
 namespace WebCore {
 
-class RectBase {
+class RectBase : public RefCountedWillBeGarbageCollected<RectBase> {
+    DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(RectBase);
 public:
     CSSPrimitiveValue* top() const { return m_top.get(); }
     CSSPrimitiveValue* right() const { return m_right.get(); }
@@ -47,30 +48,30 @@
             && compareCSSValuePtr(m_bottom, other.m_bottom);
     }
 
+    void trace(Visitor*);
+
 protected:
     RectBase() { }
     RectBase(const RectBase& cloneFrom)
-        : m_top(cloneFrom.m_top ? cloneFrom.m_top->cloneForCSSOM() : 0)
-        , m_right(cloneFrom.m_right ? cloneFrom.m_right->cloneForCSSOM() : 0)
-        , m_bottom(cloneFrom.m_bottom ? cloneFrom.m_bottom->cloneForCSSOM() : 0)
-        , m_left(cloneFrom.m_left ? cloneFrom.m_left->cloneForCSSOM() : 0)
+        : m_top(cloneFrom.m_top ? cloneFrom.m_top->cloneForCSSOM() : nullptr)
+        , m_right(cloneFrom.m_right ? cloneFrom.m_right->cloneForCSSOM() : nullptr)
+        , m_bottom(cloneFrom.m_bottom ? cloneFrom.m_bottom->cloneForCSSOM() : nullptr)
+        , m_left(cloneFrom.m_left ? cloneFrom.m_left->cloneForCSSOM() : nullptr)
     {
     }
 
-    ~RectBase() { }
-
 private:
-    RefPtr<CSSPrimitiveValue> m_top;
-    RefPtr<CSSPrimitiveValue> m_right;
-    RefPtr<CSSPrimitiveValue> m_bottom;
-    RefPtr<CSSPrimitiveValue> m_left;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_top;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_right;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_bottom;
+    RefPtrWillBeMember<CSSPrimitiveValue> m_left;
 };
 
-class Rect : public RectBase, public RefCounted<Rect> {
+class Rect : public RectBase {
 public:
-    static PassRefPtr<Rect> create() { return adoptRef(new Rect); }
+    static PassRefPtrWillBeRawPtr<Rect> create() { return adoptRefWillBeNoop(new Rect); }
 
-    PassRefPtr<Rect> cloneForCSSOM() const { return adoptRef(new Rect(*this)); }
+    PassRefPtrWillBeRawPtr<Rect> cloneForCSSOM() const { return adoptRefWillBeNoop(new Rect(*this)); }
 
     String cssText() const
     {
@@ -79,18 +80,22 @@
 
 private:
     Rect() { }
-    Rect(const Rect& cloneFrom) : RectBase(cloneFrom), RefCounted<Rect>() { }
+    Rect(const Rect& cloneFrom) : RectBase(cloneFrom) { }
     static String generateCSSString(const String& top, const String& right, const String& bottom, const String& left)
     {
         return "rect(" + top + ' ' + right + ' ' + bottom + ' ' + left + ')';
     }
+
+    // NOTE: If adding fields to this class please make the RectBase trace
+    // method virtual and add a trace method in this subclass tracing the new
+    // fields.
 };
 
-class Quad : public RectBase, public RefCounted<Quad> {
+class Quad : public RectBase {
 public:
-    static PassRefPtr<Quad> create() { return adoptRef(new Quad); }
+    static PassRefPtrWillBeRawPtr<Quad> create() { return adoptRefWillBeNoop(new Quad); }
 
-    PassRefPtr<Quad> cloneForCSSOM() const { return adoptRef(new Quad(*this)); }
+    PassRefPtrWillBeRawPtr<Quad> cloneForCSSOM() const { return adoptRefWillBeNoop(new Quad(*this)); }
 
     String cssText() const
     {
@@ -99,7 +104,7 @@
 
 private:
     Quad() { }
-    Quad(const Quad& cloneFrom) : RectBase(cloneFrom), RefCounted<Quad>() { }
+    Quad(const Quad& cloneFrom) : RectBase(cloneFrom) { }
     static String generateCSSString(const String& top, const String& right, const String& bottom, const String& left)
     {
         StringBuilder result;
@@ -120,6 +125,10 @@
         }
         return result.toString();
     }
+
+    // NOTE: If adding fields to this class please make the RectBase trace
+    // method virtual and add a trace method in this subclass tracing the new
+    // fields.
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/Rect.idl b/Source/core/css/Rect.idl
index 3eac82f..87336d5 100644
--- a/Source/core/css/Rect.idl
+++ b/Source/core/css/Rect.idl
@@ -18,6 +18,7 @@
  */
 
 [
+    WillBeGarbageCollected
 ] interface Rect {
     readonly attribute CSSPrimitiveValue  top;
     readonly attribute CSSPrimitiveValue  right;
diff --git a/Source/core/css/RemoteFontFaceSource.cpp b/Source/core/css/RemoteFontFaceSource.cpp
new file mode 100644
index 0000000..9b15954
--- /dev/null
+++ b/Source/core/css/RemoteFontFaceSource.cpp
@@ -0,0 +1,179 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/RemoteFontFaceSource.h"
+
+#include "core/css/CSSCustomFontData.h"
+#include "core/css/CSSFontFace.h"
+#include "platform/fonts/FontCache.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+#include "public/platform/Platform.h"
+#include "wtf/CurrentTime.h"
+
+namespace WebCore {
+
+RemoteFontFaceSource::RemoteFontFaceSource(FontResource* font)
+    : m_font(font)
+{
+    m_font->addClient(this);
+}
+
+RemoteFontFaceSource::~RemoteFontFaceSource()
+{
+    m_font->removeClient(this);
+    pruneTable();
+}
+
+void RemoteFontFaceSource::pruneTable()
+{
+    if (m_fontDataTable.isEmpty())
+        return;
+
+    for (FontDataTable::iterator it = m_fontDataTable.begin(); it != m_fontDataTable.end(); ++it) {
+        SimpleFontData* fontData = it->value.get();
+        if (fontData && fontData->customFontData())
+            fontData->customFontData()->clearFontFaceSource();
+    }
+    m_fontDataTable.clear();
+}
+
+bool RemoteFontFaceSource::isLoading() const
+{
+    return !m_font->stillNeedsLoad() && !m_font->isLoaded();
+}
+
+bool RemoteFontFaceSource::isLoaded() const
+{
+    return m_font->isLoaded();
+}
+
+bool RemoteFontFaceSource::isValid() const
+{
+    return !m_font->errorOccurred();
+}
+
+void RemoteFontFaceSource::didStartFontLoad(FontResource*)
+{
+    // Avoid duplicated reports when multiple CSSFontFaceSource are registered
+    // at this FontResource.
+    if (!m_fontDataTable.isEmpty())
+        m_histograms.loadStarted();
+}
+
+void RemoteFontFaceSource::fontLoaded(FontResource*)
+{
+    if (!m_fontDataTable.isEmpty())
+        m_histograms.recordRemoteFont(m_font.get());
+
+    pruneTable();
+    if (m_face)
+        m_face->fontLoaded(this);
+}
+
+void RemoteFontFaceSource::fontLoadWaitLimitExceeded(FontResource*)
+{
+    pruneTable();
+    if (m_face)
+        m_face->fontLoadWaitLimitExceeded(this);
+
+    m_histograms.recordFallbackTime(m_font.get());
+}
+
+PassRefPtr<SimpleFontData> RemoteFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+    if (!isLoaded())
+        return createLoadingFallbackFontData(fontDescription);
+
+    // Create new FontPlatformData from our CGFontRef, point size and ATSFontRef.
+    if (!m_font->ensureCustomFontData())
+        return nullptr;
+
+    m_histograms.recordFallbackTime(m_font.get());
+
+    return SimpleFontData::create(
+        m_font->platformDataFromCustomData(fontDescription.effectiveFontSize(),
+            fontDescription.isSyntheticBold(), fontDescription.isSyntheticItalic(),
+            fontDescription.orientation(), fontDescription.widthVariant()), CustomFontData::create());
+}
+
+PassRefPtr<SimpleFontData> RemoteFontFaceSource::createLoadingFallbackFontData(const FontDescription& fontDescription)
+{
+    // This temporary font is not retained and should not be returned.
+    FontCachePurgePreventer fontCachePurgePreventer;
+    SimpleFontData* temporaryFont = FontCache::fontCache()->getNonRetainedLastResortFallbackFont(fontDescription);
+    if (!temporaryFont) {
+        ASSERT_NOT_REACHED();
+        return nullptr;
+    }
+    RefPtr<CSSCustomFontData> cssFontData = CSSCustomFontData::create(this, m_font->exceedsFontLoadWaitLimit() ? CSSCustomFontData::VisibleFallback : CSSCustomFontData::InvisibleFallback);
+    return SimpleFontData::create(temporaryFont->platformData(), cssFontData);
+}
+
+void RemoteFontFaceSource::beginLoadIfNeeded()
+{
+    if (m_face)
+        m_face->beginLoadIfNeeded(this);
+}
+
+bool RemoteFontFaceSource::ensureFontData()
+{
+    return m_font->ensureCustomFontData();
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::loadStarted()
+{
+    if (!m_loadStartTime)
+        m_loadStartTime = currentTimeMS();
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::fallbackFontPainted()
+{
+    if (!m_fallbackPaintTime)
+        m_fallbackPaintTime = currentTimeMS();
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::recordFallbackTime(const FontResource* font)
+{
+    if (m_fallbackPaintTime <= 0)
+        return;
+    int duration = static_cast<int>(currentTimeMS() - m_fallbackPaintTime);
+    blink::Platform::current()->histogramCustomCounts("WebFont.BlankTextShownTime", duration, 0, 10000, 50);
+    m_fallbackPaintTime = -1;
+}
+
+void RemoteFontFaceSource::FontLoadHistograms::recordRemoteFont(const FontResource* font)
+{
+    if (m_loadStartTime > 0 && font && !font->isLoading()) {
+        int duration = static_cast<int>(currentTimeMS() - m_loadStartTime);
+        blink::Platform::current()->histogramCustomCounts(histogramName(font), duration, 0, 10000, 50);
+        m_loadStartTime = -1;
+
+        enum { Miss, Hit, DataUrl, CacheHitEnumMax };
+        int histogramValue = font->url().protocolIsData() ? DataUrl
+            : font->response().wasCached() ? Hit
+            : Miss;
+        blink::Platform::current()->histogramEnumeration("WebFont.CacheHit", histogramValue, CacheHitEnumMax);
+    }
+}
+
+const char* RemoteFontFaceSource::FontLoadHistograms::histogramName(const FontResource* font)
+{
+    if (font->errorOccurred())
+        return "WebFont.DownloadTime.LoadError";
+
+    unsigned size = font->encodedSize();
+    if (size < 10 * 1024)
+        return "WebFont.DownloadTime.0.Under10KB";
+    if (size < 50 * 1024)
+        return "WebFont.DownloadTime.1.10KBTo50KB";
+    if (size < 100 * 1024)
+        return "WebFont.DownloadTime.2.50KBTo100KB";
+    if (size < 1024 * 1024)
+        return "WebFont.DownloadTime.3.100KBTo1MB";
+    return "WebFont.DownloadTime.4.Over1MB";
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/RemoteFontFaceSource.h b/Source/core/css/RemoteFontFaceSource.h
new file mode 100644
index 0000000..500a7d7
--- /dev/null
+++ b/Source/core/css/RemoteFontFaceSource.h
@@ -0,0 +1,65 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef RemoteFontFaceSource_h
+#define RemoteFontFaceSource_h
+
+#include "core/css/CSSFontFaceSource.h"
+#include "core/fetch/FontResource.h"
+#include "core/fetch/ResourcePtr.h"
+
+namespace WebCore {
+
+class RemoteFontFaceSource : public CSSFontFaceSource, public FontResourceClient {
+public:
+    RemoteFontFaceSource(FontResource*);
+    virtual ~RemoteFontFaceSource();
+
+    virtual FontResource* resource() OVERRIDE { return m_font.get(); }
+    virtual bool isLoading() const OVERRIDE;
+    virtual bool isLoaded() const OVERRIDE;
+    virtual bool isValid() const OVERRIDE;
+
+    void beginLoadIfNeeded();
+    virtual bool ensureFontData();
+
+#if ENABLE(SVG_FONTS)
+    virtual bool isSVGFontFaceSource() const { return false; }
+#endif
+
+    virtual void didStartFontLoad(FontResource*) OVERRIDE;
+    virtual void fontLoaded(FontResource*) OVERRIDE;
+    virtual void fontLoadWaitLimitExceeded(FontResource*) OVERRIDE;
+
+    // For UMA reporting
+    virtual bool hadBlankText() OVERRIDE { return m_histograms.hadBlankText(); }
+    void paintRequested() { m_histograms.fallbackFontPainted(); }
+
+protected:
+    virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+    PassRefPtr<SimpleFontData> createLoadingFallbackFontData(const FontDescription&);
+    void pruneTable();
+
+private:
+    class FontLoadHistograms {
+    public:
+        FontLoadHistograms() : m_loadStartTime(0), m_fallbackPaintTime(0) { }
+        void loadStarted();
+        void fallbackFontPainted();
+        void recordRemoteFont(const FontResource*);
+        void recordFallbackTime(const FontResource*);
+        bool hadBlankText() { return m_fallbackPaintTime; }
+    private:
+        const char* histogramName(const FontResource*);
+        double m_loadStartTime;
+        double m_fallbackPaintTime;
+    };
+
+    ResourcePtr<FontResource> m_font;
+    FontLoadHistograms m_histograms;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp
index b52569a..7b57fdc 100644
--- a/Source/core/css/RuleFeature.cpp
+++ b/Source/core/css/RuleFeature.cpp
@@ -36,41 +36,94 @@
 #include "core/css/RuleSet.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/dom/Node.h"
+#include "core/dom/NodeRenderStyle.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/rendering/RenderObject.h"
 #include "wtf/BitVector.h"
 
 namespace WebCore {
 
 static bool isSkippableComponentForInvalidation(const CSSSelector& selector)
 {
-    if (selector.matchesPseudoElement() || selector.pseudoType() == CSSSelector::PseudoHost)
+    if (selector.m_match == CSSSelector::Tag
+        || selector.m_match == CSSSelector::Id
+        || selector.isAttributeSelector())
+        return true;
+    if (selector.m_match == CSSSelector::PseudoElement) {
+        switch (selector.m_pseudoType) {
+        case CSSSelector::PseudoBefore:
+        case CSSSelector::PseudoAfter:
+        case CSSSelector::PseudoBackdrop:
+            return true;
+        default:
+            return false;
+        }
+    }
+    if (selector.m_match != CSSSelector::PseudoClass)
         return false;
-    return true;
+    switch (selector.pseudoType()) {
+    case CSSSelector::PseudoEmpty:
+    case CSSSelector::PseudoFirstChild:
+    case CSSSelector::PseudoFirstOfType:
+    case CSSSelector::PseudoLastChild:
+    case CSSSelector::PseudoLastOfType:
+    case CSSSelector::PseudoOnlyChild:
+    case CSSSelector::PseudoOnlyOfType:
+    case CSSSelector::PseudoNthChild:
+    case CSSSelector::PseudoNthOfType:
+    case CSSSelector::PseudoNthLastChild:
+    case CSSSelector::PseudoNthLastOfType:
+    case CSSSelector::PseudoLink:
+    case CSSSelector::PseudoVisited:
+    case CSSSelector::PseudoAnyLink:
+    case CSSSelector::PseudoHover:
+    case CSSSelector::PseudoDrag:
+    case CSSSelector::PseudoFocus:
+    case CSSSelector::PseudoActive:
+    case CSSSelector::PseudoChecked:
+    case CSSSelector::PseudoEnabled:
+    case CSSSelector::PseudoDefault:
+    case CSSSelector::PseudoDisabled:
+    case CSSSelector::PseudoOptional:
+    case CSSSelector::PseudoRequired:
+    case CSSSelector::PseudoReadOnly:
+    case CSSSelector::PseudoReadWrite:
+    case CSSSelector::PseudoValid:
+    case CSSSelector::PseudoInvalid:
+    case CSSSelector::PseudoIndeterminate:
+    case CSSSelector::PseudoTarget:
+    case CSSSelector::PseudoLang:
+    case CSSSelector::PseudoRoot:
+    case CSSSelector::PseudoScope:
+    case CSSSelector::PseudoInRange:
+    case CSSSelector::PseudoOutOfRange:
+    case CSSSelector::PseudoUnresolved:
+        return true;
+    default:
+        return false;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
 }
 
-// This method is somewhat conservative in what it acceptss.
-static bool supportsClassDescendantInvalidation(const CSSSelector& selector)
+// This method is somewhat conservative in what it accepts.
+RuleFeatureSet::InvalidationSetMode RuleFeatureSet::supportsClassDescendantInvalidation(const CSSSelector& selector)
 {
     bool foundDescendantRelation = false;
-    bool foundAncestorIdent = false;
     bool foundIdent = false;
     for (const CSSSelector* component = &selector; component; component = component->tagHistory()) {
 
-        // FIXME: We should allow pseudo elements, but we need to change how they hook
-        // into recalcStyle by moving them to recalcOwnStyle instead of recalcChildStyle.
-
         // FIXME: next up: Tag and Id.
         if (component->m_match == CSSSelector::Class) {
             if (!foundDescendantRelation)
                 foundIdent = true;
-            else
-                foundAncestorIdent = true;
         } else if (!isSkippableComponentForInvalidation(*component)) {
-            return false;
+            return foundDescendantRelation ? UseLocalStyleChange : UseSubtreeStyleChange;
         }
-        // FIXME: We can probably support ChildTree and DescendantTree.
+        // FIXME: We can probably support ShadowAll and ShadowDeep.
         switch (component->relation()) {
         case CSSSelector::Descendant:
         case CSSSelector::Child:
@@ -79,10 +132,10 @@
         case CSSSelector::SubSelector:
             continue;
         default:
-            return false;
+            return UseLocalStyleChange;
         }
     }
-    return foundDescendantRelation && foundAncestorIdent && foundIdent;
+    return foundIdent ? AddFeatures : UseLocalStyleChange;
 }
 
 void extractClassIdOrTag(const CSSSelector& selector, Vector<AtomicString>& classes, AtomicString& id, AtomicString& tagName)
@@ -100,22 +153,29 @@
 {
 }
 
-bool RuleFeatureSet::updateClassInvalidationSets(const CSSSelector& selector)
+RuleFeatureSet::InvalidationSetMode RuleFeatureSet::updateClassInvalidationSets(const CSSSelector& selector)
 {
-    if (!supportsClassDescendantInvalidation(selector))
-        return false;
+    InvalidationSetMode mode = supportsClassDescendantInvalidation(selector);
+    if (mode != AddFeatures)
+        return mode;
 
     Vector<AtomicString> classes;
     AtomicString id;
     AtomicString tagName;
 
     const CSSSelector* lastSelector = &selector;
-    for (; lastSelector->relation() == CSSSelector::SubSelector; lastSelector = lastSelector->tagHistory()) {
+    for (; lastSelector; lastSelector = lastSelector->tagHistory()) {
         extractClassIdOrTag(*lastSelector, classes, id, tagName);
+        if (lastSelector->m_match == CSSSelector::Class)
+            ensureClassInvalidationSet(lastSelector->value());
+        if (lastSelector->relation() != CSSSelector::SubSelector)
+            break;
     }
-    extractClassIdOrTag(*lastSelector, classes, id, tagName);
 
-    for (const CSSSelector* current = &selector ; current; current = current->tagHistory()) {
+    if (!lastSelector)
+        return AddFeatures;
+
+    for (const CSSSelector* current = lastSelector->tagHistory(); current; current = current->tagHistory()) {
         if (current->m_match == CSSSelector::Class) {
             DescendantInvalidationSet& invalidationSet = ensureClassInvalidationSet(current->value());
             if (!id.isEmpty())
@@ -127,7 +187,7 @@
             }
         }
     }
-    return true;
+    return AddFeatures;
 }
 
 void RuleFeatureSet::addAttributeInASelector(const AtomicString& attributeName)
@@ -138,16 +198,11 @@
 void RuleFeatureSet::collectFeaturesFromRuleData(const RuleData& ruleData)
 {
     FeatureMetadata metadata;
-    bool selectorUsesClassInvalidationSet = false;
+    InvalidationSetMode mode = UseSubtreeStyleChange;
     if (m_targetedStyleRecalcEnabled)
-        selectorUsesClassInvalidationSet = updateClassInvalidationSets(ruleData.selector());
+        mode = updateClassInvalidationSets(ruleData.selector());
 
-    SelectorFeatureCollectionMode collectionMode;
-    if (selectorUsesClassInvalidationSet)
-        collectionMode = DontProcessClasses;
-    else
-        collectionMode = ProcessClasses;
-    collectFeaturesFromSelector(ruleData.selector(), metadata, collectionMode);
+    collectFeaturesFromSelector(ruleData.selector(), metadata, mode);
     m_metadata.add(metadata);
 
     if (metadata.foundSiblingSelector)
@@ -156,15 +211,9 @@
         uncommonAttributeRules.append(RuleFeature(ruleData.rule(), ruleData.selectorIndex(), ruleData.hasDocumentSecurityOrigin()));
 }
 
-bool RuleFeatureSet::classInvalidationRequiresSubtreeRecalc(const AtomicString& className)
-{
-    DescendantInvalidationSet* set = m_classInvalidationSets.get(className);
-    return set && set->wholeSubtreeInvalid();
-}
-
 DescendantInvalidationSet& RuleFeatureSet::ensureClassInvalidationSet(const AtomicString& className)
 {
-    InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(className, 0);
+    InvalidationSetMap::AddResult addResult = m_classInvalidationSets.add(className, nullptr);
     if (addResult.isNewEntry)
         addResult.storedValue->value = DescendantInvalidationSet::create();
     return *addResult.storedValue->value;
@@ -172,19 +221,20 @@
 
 void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector)
 {
-    collectFeaturesFromSelector(selector, m_metadata, ProcessClasses);
+    collectFeaturesFromSelector(selector, m_metadata, UseSubtreeStyleChange);
 }
 
-void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, RuleFeatureSet::FeatureMetadata& metadata, SelectorFeatureCollectionMode collectionMode)
+void RuleFeatureSet::collectFeaturesFromSelector(const CSSSelector& selector, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode)
 {
     unsigned maxDirectAdjacentSelectors = 0;
 
     for (const CSSSelector* current = &selector; current; current = current->tagHistory()) {
         if (current->m_match == CSSSelector::Id) {
             metadata.idsInRules.add(current->value());
-        } else if (current->m_match == CSSSelector::Class && collectionMode == ProcessClasses) {
+        } else if (current->m_match == CSSSelector::Class && mode != AddFeatures) {
             DescendantInvalidationSet& invalidationSet = ensureClassInvalidationSet(current->value());
-            invalidationSet.setWholeSubtreeInvalid();
+            if (mode == UseSubtreeStyleChange)
+                invalidationSet.setWholeSubtreeInvalid();
         } else if (current->isAttributeSelector()) {
             metadata.attrsInRules.add(current->attribute().localName());
         }
@@ -200,21 +250,22 @@
         if (current->isSiblingSelector())
             metadata.foundSiblingSelector = true;
 
-        collectFeaturesFromSelectorList(current->selectorList(), metadata, collectionMode);
+        collectFeaturesFromSelectorList(current->selectorList(), metadata, mode);
+
+        if (mode == UseLocalStyleChange && current->relation() != CSSSelector::SubSelector)
+            mode = UseSubtreeStyleChange;
     }
 
     ASSERT(!maxDirectAdjacentSelectors);
 }
 
-void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* selectorList, RuleFeatureSet::FeatureMetadata& metadata, SelectorFeatureCollectionMode collectionMode)
+void RuleFeatureSet::collectFeaturesFromSelectorList(const CSSSelectorList* selectorList, RuleFeatureSet::FeatureMetadata& metadata, InvalidationSetMode mode)
 {
     if (!selectorList)
         return;
 
-    for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector)) {
-        for (const CSSSelector* subSelector = selector; subSelector; subSelector = subSelector->tagHistory())
-            collectFeaturesFromSelector(*subSelector, metadata, collectionMode);
-    }
+    for (const CSSSelector* selector = selectorList->first(); selector; selector = CSSSelectorList::next(*selector))
+        collectFeaturesFromSelector(*selector, metadata, mode);
 }
 
 void RuleFeatureSet::FeatureMetadata::add(const FeatureMetadata& other)
@@ -232,7 +283,6 @@
 
 void RuleFeatureSet::FeatureMetadata::clear()
 {
-
     idsInRules.clear();
     attrsInRules.clear();
     usesFirstLineRules = false;
@@ -248,50 +298,31 @@
 
     m_metadata.add(other.m_metadata);
 
-    siblingRules.append(other.siblingRules);
-    uncommonAttributeRules.append(other.uncommonAttributeRules);
+    siblingRules.appendVector(other.siblingRules);
+    uncommonAttributeRules.appendVector(other.uncommonAttributeRules);
 }
 
 void RuleFeatureSet::clear()
 {
-    m_metadata.clear();
     siblingRules.clear();
     uncommonAttributeRules.clear();
+    m_metadata.clear();
+    m_classInvalidationSets.clear();
+    m_pendingInvalidationMap.clear();
 }
 
 void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, Element* element)
 {
-    if (computeInvalidationSetsForClassChange(changedClasses, element)) {
-        // FIXME: remove eager calls to setNeedsStyleRecalc here, and instead reuse the invalidation tree walk.
-        // This code remains for now out of conservatism about avoiding performance regressions before TargetedStyleRecalc is launched.
-        element->setNeedsStyleRecalc(SubtreeStyleChange);
+    unsigned changedSize = changedClasses.size();
+    for (unsigned i = 0; i < changedSize; ++i) {
+        addClassToInvalidationSet(changedClasses[i], element);
     }
 }
 
 void RuleFeatureSet::scheduleStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element* element)
 {
-    if (computeInvalidationSetsForClassChange(oldClasses, newClasses, element)) {
-        // FIXME: remove eager calls to setNeedsStyleRecalc here, and instead reuse the invalidation tree walk.
-        // This code remains for now out of conservatism about avoiding performance regressions before TargetedStyleRecalc is launched.
-        element->setNeedsStyleRecalc(SubtreeStyleChange);
-    }
-}
-
-bool RuleFeatureSet::computeInvalidationSetsForClassChange(const SpaceSplitString& changedClasses, Element* element)
-{
-    unsigned changedSize = changedClasses.size();
-    for (unsigned i = 0; i < changedSize; ++i) {
-        if (classInvalidationRequiresSubtreeRecalc(changedClasses[i]))
-            return true;
-        addClassToInvalidationSet(changedClasses[i], element);
-    }
-    return false;
-}
-
-bool RuleFeatureSet::computeInvalidationSetsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element* element)
-{
     if (!oldClasses.size())
-        return computeInvalidationSetsForClassChange(newClasses, element);
+        scheduleStyleInvalidationForClassChange(newClasses, element);
 
     // Class vectors tend to be very short. This is faster than using a hash table.
     BitVector remainingClassBits;
@@ -309,28 +340,21 @@
             }
         }
         // Class was added.
-        if (!found) {
-            if (classInvalidationRequiresSubtreeRecalc(newClasses[i]))
-                return true;
+        if (!found)
             addClassToInvalidationSet(newClasses[i], element);
-        }
     }
 
     for (unsigned i = 0; i < oldClasses.size(); ++i) {
         if (remainingClassBits.quickGet(i))
             continue;
-
         // Class was removed.
-        if (classInvalidationRequiresSubtreeRecalc(oldClasses[i]))
-            return true;
         addClassToInvalidationSet(oldClasses[i], element);
     }
-    return false;
 }
 
 void RuleFeatureSet::addClassToInvalidationSet(const AtomicString& className, Element* element)
 {
-    if (DescendantInvalidationSet* invalidationSet = m_classInvalidationSets.get(className)) {
+    if (RefPtr<DescendantInvalidationSet> invalidationSet = m_classInvalidationSets.get(className)) {
         ensurePendingInvalidationList(element).append(invalidationSet);
         element->setNeedsStyleInvalidation();
     }
@@ -338,9 +362,9 @@
 
 RuleFeatureSet::InvalidationList& RuleFeatureSet::ensurePendingInvalidationList(Element* element)
 {
-    PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(element, 0);
+    PendingInvalidationMap::AddResult addResult = m_pendingInvalidationMap.add(element, nullptr);
     if (addResult.isNewEntry)
-        addResult.storedValue->value = new InvalidationList;
+        addResult.storedValue->value = adoptPtr(new InvalidationList);
     return *addResult.storedValue->value;
 }
 
@@ -348,56 +372,63 @@
 {
     Vector<AtomicString> invalidationClasses;
     if (Element* documentElement = document.documentElement()) {
-        if (documentElement->childNeedsStyleInvalidation()) {
+        if (documentElement->childNeedsStyleInvalidation())
             invalidateStyleForClassChange(documentElement, invalidationClasses, false);
-        }
     }
     document.clearChildNeedsStyleInvalidation();
+    document.clearNeedsStyleInvalidation();
     m_pendingInvalidationMap.clear();
 }
 
+void RuleFeatureSet::clearStyleInvalidation(Node* node)
+{
+    node->clearChildNeedsStyleInvalidation();
+    node->clearNeedsStyleInvalidation();
+    if (node->isElementNode())
+        m_pendingInvalidationMap.remove(toElement(node));
+}
+
 bool RuleFeatureSet::invalidateStyleForClassChangeOnChildren(Element* element, Vector<AtomicString>& invalidationClasses, bool foundInvalidationSet)
 {
     bool someChildrenNeedStyleRecalc = false;
     for (ShadowRoot* root = element->youngestShadowRoot(); root; root = root->olderShadowRoot()) {
-        for (Node* child = root->firstChild(); child; child = child->nextSibling()) {
-            if (child->isElementNode()) {
-                Element* childElement = toElement(child);
-                bool childRecalced = invalidateStyleForClassChange(childElement, invalidationClasses, foundInvalidationSet);
-                someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
-            }
-        }
-    }
-    for (Node* child = element->firstChild(); child; child = child->nextSibling()) {
-        if (child->isElementNode()) {
-            Element* childElement = toElement(child);
-            bool childRecalced = invalidateStyleForClassChange(childElement, invalidationClasses, foundInvalidationSet);
+        for (Element* child = ElementTraversal::firstWithin(*root); child; child = ElementTraversal::nextSibling(*child)) {
+            bool childRecalced = invalidateStyleForClassChange(child, invalidationClasses, foundInvalidationSet);
             someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
         }
+        root->clearChildNeedsStyleInvalidation();
+        root->clearNeedsStyleInvalidation();
+    }
+    for (Element* child = ElementTraversal::firstWithin(*element); child; child = ElementTraversal::nextSibling(*child)) {
+        bool childRecalced = invalidateStyleForClassChange(child, invalidationClasses, foundInvalidationSet);
+        someChildrenNeedStyleRecalc = someChildrenNeedStyleRecalc || childRecalced;
     }
     return someChildrenNeedStyleRecalc;
 }
 
 bool RuleFeatureSet::invalidateStyleForClassChange(Element* element, Vector<AtomicString>& invalidationClasses, bool foundInvalidationSet)
 {
+    bool thisElementNeedsStyleRecalc = false;
     int oldSize = invalidationClasses.size();
     if (element->needsStyleInvalidation()) {
         if (InvalidationList* invalidationList = m_pendingInvalidationMap.get(element)) {
+            // FIXME: it's really only necessary to clone the render style for this element, not full style recalc.
+            thisElementNeedsStyleRecalc = true;
             foundInvalidationSet = true;
             for (InvalidationList::const_iterator it = invalidationList->begin(); it != invalidationList->end(); ++it) {
                 if ((*it)->wholeSubtreeInvalid()) {
                     element->setNeedsStyleRecalc(SubtreeStyleChange);
-                    invalidationClasses.remove(oldSize, invalidationClasses.size() - oldSize);
-                    element->clearChildNeedsStyleInvalidation();
-                    return true;
+                    // Even though we have set needsStyleRecalc on the whole subtree, we need to keep walking over the subtree
+                    // in order to clear the invalidation dirty bits on all elements.
+                    // FIXME: we can optimize this by having a dedicated function that just traverses the tree and removes the dirty bits,
+                    // without checking classes etc.
+                    break;
                 }
                 (*it)->getClasses(invalidationClasses);
             }
         }
     }
 
-    bool thisElementNeedsStyleRecalc = false;
-
     if (element->hasClass()) {
         const SpaceSplitString& classNames = element->classNames();
         for (Vector<AtomicString>::const_iterator it = invalidationClasses.begin(); it != invalidationClasses.end(); ++it) {
@@ -408,20 +439,29 @@
         }
     }
 
+    bool someChildrenNeedStyleRecalc = false;
     // foundInvalidationSet will be true if we are in a subtree of a node with a DescendantInvalidationSet on it.
     // We need to check all nodes in the subtree of such a node.
     if (foundInvalidationSet || element->childNeedsStyleInvalidation()) {
-        bool someChildrenNeedStyleRecalc = invalidateStyleForClassChangeOnChildren(element, invalidationClasses, foundInvalidationSet);
-        // We only need to possibly recalc style if this node is in the subtree of a node with a DescendantInvalidationSet on it.
-        if (foundInvalidationSet)
-            thisElementNeedsStyleRecalc = thisElementNeedsStyleRecalc || someChildrenNeedStyleRecalc;
+        someChildrenNeedStyleRecalc = invalidateStyleForClassChangeOnChildren(element, invalidationClasses, foundInvalidationSet);
     }
 
-    if (thisElementNeedsStyleRecalc)
+    if (thisElementNeedsStyleRecalc) {
         element->setNeedsStyleRecalc(LocalStyleChange);
+    } else if (foundInvalidationSet && someChildrenNeedStyleRecalc) {
+        // Clone the RenderStyle in order to preserve correct style sharing, if possible. Otherwise recalc style.
+        if (RenderObject* renderer = element->renderer()) {
+            ASSERT(renderer->style());
+            renderer->setStyleInternal(RenderStyle::clone(renderer->style()));
+        } else {
+            element->setNeedsStyleRecalc(LocalStyleChange);
+        }
+    }
 
     invalidationClasses.remove(oldSize, invalidationClasses.size() - oldSize);
     element->clearChildNeedsStyleInvalidation();
+    element->clearNeedsStyleInvalidation();
+
     return thisElementNeedsStyleRecalc;
 }
 
diff --git a/Source/core/css/RuleFeature.h b/Source/core/css/RuleFeature.h
index bdce85f..df44c3e 100644
--- a/Source/core/css/RuleFeature.h
+++ b/Source/core/css/RuleFeature.h
@@ -30,6 +30,7 @@
 namespace WebCore {
 
 class Document;
+class Node;
 class ShadowRoot;
 class StyleRule;
 class CSSSelector;
@@ -88,6 +89,9 @@
 
     void computeStyleInvalidation(Document&);
 
+    // Clears all style invalidation state for the passed node.
+    void clearStyleInvalidation(Node*);
+
     int hasIdsInSelectors() const
     {
         return m_metadata.idsInRules.size() > 0;
@@ -102,8 +106,8 @@
 
 private:
     typedef HashMap<AtomicString, RefPtr<DescendantInvalidationSet> > InvalidationSetMap;
-    typedef Vector<DescendantInvalidationSet*> InvalidationList;
-    typedef HashMap<Element*, InvalidationList*> PendingInvalidationMap;
+    typedef Vector<RefPtr<DescendantInvalidationSet> > InvalidationList;
+    typedef HashMap<Element*, OwnPtr<InvalidationList> > PendingInvalidationMap;
     struct FeatureMetadata {
         FeatureMetadata()
             : usesFirstLineRules(false)
@@ -120,21 +124,19 @@
         HashSet<AtomicString> attrsInRules;
     };
 
-    // These return true if setNeedsStyleRecalc() should be run on the Element, as a fallback.
-    bool computeInvalidationSetsForClassChange(const SpaceSplitString& changedClasses, Element*);
-    bool computeInvalidationSetsForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Element*);
-
-    enum SelectorFeatureCollectionMode {
-        ProcessClasses,
-        DontProcessClasses
+    enum InvalidationSetMode {
+        AddFeatures,
+        UseLocalStyleChange,
+        UseSubtreeStyleChange
     };
 
-    void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&, SelectorFeatureCollectionMode processClasses);
-    void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&, SelectorFeatureCollectionMode processClasses);
+    static InvalidationSetMode supportsClassDescendantInvalidation(const CSSSelector&);
 
-    bool classInvalidationRequiresSubtreeRecalc(const AtomicString& className);
+    void collectFeaturesFromSelector(const CSSSelector&, FeatureMetadata&, InvalidationSetMode);
+    void collectFeaturesFromSelectorList(const CSSSelectorList*, FeatureMetadata&, InvalidationSetMode);
+
     DescendantInvalidationSet& ensureClassInvalidationSet(const AtomicString& className);
-    bool updateClassInvalidationSets(const CSSSelector&);
+    InvalidationSetMode updateClassInvalidationSets(const CSSSelector&);
 
     void addClassToInvalidationSet(const AtomicString& className, Element*);
 
diff --git a/Source/core/css/RuleSet.cpp b/Source/core/css/RuleSet.cpp
index 7e048b8..9f406af 100644
--- a/Source/core/css/RuleSet.cpp
+++ b/Source/core/css/RuleSet.cpp
@@ -40,9 +40,12 @@
 #include "core/css/StyleRuleImport.h"
 #include "core/css/StyleSheetContents.h"
 #include "core/html/track/TextTrackCue.h"
+#include "heap/HeapTerminatedArrayBuilder.h"
 #include "platform/TraceEvent.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
+#include "wtf/TerminatedArrayBuilder.h"
+
 namespace WebCore {
 
 using namespace HTMLNames;
@@ -119,76 +122,6 @@
     return PropertyWhitelistNone;
 }
 
-namespace {
-
-// FIXME: Should we move this class to WTF?
-template<typename T>
-class TerminatedArrayBuilder {
-public:
-    explicit TerminatedArrayBuilder(PassOwnPtr<T> array)
-        : m_array(array)
-        , m_count(0)
-        , m_capacity(0)
-    {
-        if (!m_array)
-            return;
-        for (T* item = m_array.get(); !item->isLastInArray(); ++item)
-            ++m_count;
-        ++m_count; // To count the last item itself.
-        m_capacity = m_count;
-    }
-
-    void grow(size_t count)
-    {
-        ASSERT(count);
-        if (!m_array) {
-            ASSERT(!m_count);
-            ASSERT(!m_capacity);
-            m_capacity = count;
-            m_array = adoptPtr(static_cast<T*>(fastMalloc(m_capacity * sizeof(T))));
-            return;
-        }
-        m_capacity += count;
-        m_array = adoptPtr(static_cast<T*>(fastRealloc(m_array.leakPtr(), m_capacity * sizeof(T))));
-        m_array.get()[m_count - 1].setLastInArray(false);
-    }
-
-    void append(const T& item)
-    {
-        RELEASE_ASSERT(m_count < m_capacity);
-        ASSERT(!item.isLastInArray());
-        m_array.get()[m_count++] = item;
-    }
-
-    PassOwnPtr<T> release()
-    {
-        RELEASE_ASSERT(m_count == m_capacity);
-        if (m_array)
-            m_array.get()[m_count - 1].setLastInArray(true);
-        assertValid();
-        return m_array.release();
-    }
-
-private:
-#ifndef NDEBUG
-    void assertValid()
-    {
-        for (size_t i = 0; i < m_count; ++i) {
-            bool isLastInArray = (i + 1 == m_count);
-            ASSERT(m_array.get()[i].isLastInArray() == isLastInArray);
-        }
-    }
-#else
-    void assertValid() { }
-#endif
-
-    OwnPtr<T> m_array;
-    size_t m_count;
-    size_t m_capacity;
-};
-
-}
-
 RuleData::RuleData(StyleRule* rule, unsigned selectorIndex, unsigned position, AddRuleFlags addRuleFlags)
     : m_rule(rule)
     , m_selectorIndex(selectorIndex)
@@ -210,9 +143,9 @@
 
 void RuleSet::addToRuleSet(const AtomicString& key, PendingRuleMap& map, const RuleData& ruleData)
 {
-    OwnPtr<LinkedStack<RuleData> >& rules = map.add(key, nullptr).storedValue->value;
+    OwnPtrWillBeMember<WillBeHeapLinkedStack<RuleData> >& rules = map.add(key, nullptr).storedValue->value;
     if (!rules)
-        rules = adoptPtr(new LinkedStack<RuleData>);
+        rules = adoptPtrWillBeNoop(new WillBeHeapLinkedStack<RuleData>);
     rules->push(ruleData);
 }
 
@@ -333,7 +266,7 @@
     m_keyframesRules.append(rule);
 }
 
-void RuleSet::addChildRules(const Vector<RefPtr<StyleRuleBase> >& rules, const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags)
+void RuleSet::addChildRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules, const MediaQueryEvaluator& medium, AddRuleFlags addRuleFlags)
 {
     for (unsigned i = 0; i < rules.size(); ++i) {
         StyleRuleBase* rule = rules[i].get();
@@ -376,7 +309,7 @@
     ASSERT(sheet);
 
     addRuleFlags = static_cast<AddRuleFlags>(addRuleFlags | RuleCanUseFastCheckSelector);
-    const Vector<RefPtr<StyleRuleImport> >& importRules = sheet->importRules();
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> >& importRules = sheet->importRules();
     for (unsigned i = 0; i < importRules.size(); ++i) {
         StyleRuleImport* importRule = importRules[i].get();
         if (importRule->styleSheet() && (!importRule->mediaQueries() || medium.eval(importRule->mediaQueries(), &m_viewportDependentMediaQueryResults)))
@@ -396,10 +329,10 @@
 {
     PendingRuleMap::iterator end = pendingMap.end();
     for (PendingRuleMap::iterator it = pendingMap.begin(); it != end; ++it) {
-        OwnPtr<LinkedStack<RuleData> > pendingRules = it->value.release();
+        OwnPtrWillBeRawPtr<WillBeHeapLinkedStack<RuleData> > pendingRules = it->value.release();
         CompactRuleMap::ValueType* compactRules = compactMap.add(it->key, nullptr).storedValue;
 
-        TerminatedArrayBuilder<RuleData> builder(compactRules->value.release());
+        WillBeHeapTerminatedArrayBuilder<RuleData> builder(compactRules->value.release());
         builder.grow(pendingRules->size());
         while (!pendingRules->isEmpty()) {
             builder.append(pendingRules->peek());
@@ -413,7 +346,7 @@
 void RuleSet::compactRules()
 {
     ASSERT(m_pendingRules);
-    OwnPtr<PendingRuleMaps> pendingRules = m_pendingRules.release();
+    OwnPtrWillBeRawPtr<PendingRuleMaps> pendingRules = m_pendingRules.release();
     compactPendingRules(pendingRules->idRules, m_idRules);
     compactPendingRules(pendingRules->classRules, m_classRules);
     compactPendingRules(pendingRules->tagRules, m_tagRules);
@@ -430,11 +363,53 @@
     m_shadowDistributedRules.shrinkToFit();
 }
 
-#ifndef NDEBUG
+void MinimalRuleData::trace(Visitor* visitor)
+{
+    visitor->trace(m_rule);
+}
 
+void RuleData::trace(Visitor* visitor)
+{
+    visitor->trace(m_rule);
+}
+
+void RuleSet::PendingRuleMaps::trace(Visitor* visitor)
+{
+    visitor->trace(idRules);
+    visitor->trace(classRules);
+    visitor->trace(tagRules);
+    visitor->trace(shadowPseudoElementRules);
+}
+
+void RuleSet::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+    visitor->trace(m_idRules);
+    visitor->trace(m_classRules);
+    visitor->trace(m_tagRules);
+    visitor->trace(m_shadowPseudoElementRules);
+    visitor->trace(m_linkPseudoClassRules);
+    visitor->trace(m_cuePseudoRules);
+    visitor->trace(m_focusPseudoClassRules);
+    visitor->trace(m_universalRules);
+    visitor->trace(m_pageRules);
+    visitor->trace(m_viewportRules);
+    visitor->trace(m_fontFaceRules);
+    visitor->trace(m_keyframesRules);
+    visitor->trace(m_treeBoundaryCrossingRules);
+    visitor->trace(m_shadowDistributedRules);
+    visitor->trace(m_viewportDependentMediaQueryResults);
+    visitor->trace(m_pendingRules);
+#ifndef NDEBUG
+    visitor->trace(m_allRules);
+#endif
+#endif
+}
+
+#ifndef NDEBUG
 void RuleSet::show()
 {
-    for (Vector<RuleData>::const_iterator it = m_allRules.begin(); it != m_allRules.end(); ++it)
+    for (WillBeHeapVector<RuleData>::const_iterator it = m_allRules.begin(); it != m_allRules.end(); ++it)
         it->selector().show();
 }
 #endif
diff --git a/Source/core/css/RuleSet.h b/Source/core/css/RuleSet.h
index 1bee268..d2c2657 100644
--- a/Source/core/css/RuleSet.h
+++ b/Source/core/css/RuleSet.h
@@ -27,9 +27,12 @@
 #include "core/css/RuleFeature.h"
 #include "core/css/StyleRule.h"
 #include "core/css/resolver/MediaQueryResult.h"
+#include "heap/HeapLinkedStack.h"
+#include "heap/HeapTerminatedArray.h"
 #include "wtf/Forward.h"
 #include "wtf/HashMap.h"
 #include "wtf/LinkedStack.h"
+#include "wtf/TerminatedArray.h"
 
 namespace WebCore {
 
@@ -48,7 +51,9 @@
 class MediaQueryEvaluator;
 class StyleSheetContents;
 
-struct MinimalRuleData {
+class MinimalRuleData {
+    ALLOW_ONLY_INLINE_ALLOCATION();
+public:
     MinimalRuleData(StyleRule* rule, unsigned selectorIndex, AddRuleFlags flags)
     : m_rule(rule)
     , m_selectorIndex(selectorIndex)
@@ -56,13 +61,15 @@
     {
     }
 
-    StyleRule* m_rule;
+    void trace(Visitor*);
+
+    RawPtrWillBeMember<StyleRule> m_rule;
     unsigned m_selectorIndex;
     AddRuleFlags m_flags;
 };
 
 class RuleData {
-    WTF_MAKE_FAST_ALLOCATED;
+    ALLOW_ONLY_INLINE_ALLOCATION();
 public:
     RuleData(StyleRule*, unsigned selectorIndex, unsigned position, AddRuleFlags);
 
@@ -86,8 +93,10 @@
     static const unsigned maximumIdentifierCount = 4;
     const unsigned* descendantSelectorIdentifierHashes() const { return m_descendantSelectorIdentifierHashes; }
 
+    void trace(Visitor*);
+
 private:
-    StyleRule* m_rule;
+    RawPtrWillBeMember<StyleRule> m_rule;
     unsigned m_selectorIndex : 12;
     unsigned m_isLastInArray : 1; // We store an array of RuleData objects in a primitive array.
     // This number was picked fairly arbitrarily. We can probably lower it if we need to.
@@ -114,10 +123,11 @@
 
 COMPILE_ASSERT(sizeof(RuleData) == sizeof(SameSizeAsRuleData), RuleData_should_stay_small);
 
-class RuleSet {
-    WTF_MAKE_NONCOPYABLE(RuleSet); WTF_MAKE_FAST_ALLOCATED;
+class RuleSet : public NoBaseWillBeGarbageCollectedFinalized<RuleSet> {
+    WTF_MAKE_NONCOPYABLE(RuleSet);
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
-    static PassOwnPtr<RuleSet> create() { return adoptPtr(new RuleSet); }
+    static PassOwnPtrWillBeRawPtr<RuleSet> create() { return adoptPtrWillBeNoop(new RuleSet); }
 
     void addRulesFromSheet(StyleSheetContents*, const MediaQueryEvaluator&, AddRuleFlags = RuleHasNoSpecialState);
     void addStyleRule(StyleRule*, AddRuleFlags);
@@ -125,20 +135,20 @@
 
     const RuleFeatureSet& features() const { return m_features; }
 
-    const RuleData* idRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_idRules.get(key); }
-    const RuleData* classRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_classRules.get(key); }
-    const RuleData* tagRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_tagRules.get(key); }
-    const RuleData* shadowPseudoElementRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_shadowPseudoElementRules.get(key); }
-    const Vector<RuleData>* linkPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_linkPseudoClassRules; }
-    const Vector<RuleData>* cuePseudoRules() const { ASSERT(!m_pendingRules); return &m_cuePseudoRules; }
-    const Vector<RuleData>* focusPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_focusPseudoClassRules; }
-    const Vector<RuleData>* universalRules() const { ASSERT(!m_pendingRules); return &m_universalRules; }
-    const Vector<StyleRulePage*>& pageRules() const { ASSERT(!m_pendingRules); return m_pageRules; }
-    const Vector<StyleRuleViewport*>& viewportRules() const { ASSERT(!m_pendingRules); return m_viewportRules; }
-    const Vector<StyleRuleFontFace*>& fontFaceRules() const { return m_fontFaceRules; }
-    const Vector<StyleRuleKeyframes*>& keyframesRules() const { return m_keyframesRules; }
-    const Vector<MinimalRuleData>& treeBoundaryCrossingRules() const { return m_treeBoundaryCrossingRules; }
-    const Vector<MinimalRuleData>& shadowDistributedRules() const { return m_shadowDistributedRules; }
+    const WillBeHeapTerminatedArray<RuleData>* idRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_idRules.get(key); }
+    const WillBeHeapTerminatedArray<RuleData>* classRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_classRules.get(key); }
+    const WillBeHeapTerminatedArray<RuleData>* tagRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_tagRules.get(key); }
+    const WillBeHeapTerminatedArray<RuleData>* shadowPseudoElementRules(const AtomicString& key) const { ASSERT(!m_pendingRules); return m_shadowPseudoElementRules.get(key); }
+    const WillBeHeapVector<RuleData>* linkPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_linkPseudoClassRules; }
+    const WillBeHeapVector<RuleData>* cuePseudoRules() const { ASSERT(!m_pendingRules); return &m_cuePseudoRules; }
+    const WillBeHeapVector<RuleData>* focusPseudoClassRules() const { ASSERT(!m_pendingRules); return &m_focusPseudoClassRules; }
+    const WillBeHeapVector<RuleData>* universalRules() const { ASSERT(!m_pendingRules); return &m_universalRules; }
+    const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& pageRules() const { ASSERT(!m_pendingRules); return m_pageRules; }
+    const WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> >& viewportRules() const { ASSERT(!m_pendingRules); return m_viewportRules; }
+    const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> >& fontFaceRules() const { return m_fontFaceRules; }
+    const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> >& keyframesRules() const { return m_keyframesRules; }
+    const WillBeHeapVector<MinimalRuleData>& treeBoundaryCrossingRules() const { return m_treeBoundaryCrossingRules; }
+    const WillBeHeapVector<MinimalRuleData>& shadowDistributedRules() const { return m_shadowDistributedRules; }
     const MediaQueryResultList& viewportDependentMediaQueryResults() const { return m_viewportDependentMediaQueryResults; }
 
     unsigned ruleCount() const { return m_ruleCount; }
@@ -154,17 +164,11 @@
     void show();
 #endif
 
-    struct RuleSetSelectorPair {
-        RuleSetSelectorPair(const CSSSelector* selector, PassOwnPtr<RuleSet> ruleSet) : selector(selector), ruleSet(ruleSet) { }
-        RuleSetSelectorPair(const RuleSetSelectorPair& rs) : selector(rs.selector), ruleSet(const_cast<RuleSetSelectorPair*>(&rs)->ruleSet.release()) { }
-
-        const CSSSelector* selector;
-        OwnPtr<RuleSet> ruleSet;
-    };
+    void trace(Visitor*);
 
 private:
-    typedef HashMap<AtomicString, OwnPtr<LinkedStack<RuleData> > > PendingRuleMap;
-    typedef HashMap<AtomicString, OwnPtr<RuleData> > CompactRuleMap;
+    typedef WillBeHeapHashMap<AtomicString, OwnPtrWillBeMember<WillBeHeapLinkedStack<RuleData> > > PendingRuleMap;
+    typedef WillBeHeapHashMap<AtomicString, OwnPtrWillBeMember<WillBeHeapTerminatedArray<RuleData> > > CompactRuleMap;
 
     RuleSet()
         : m_ruleCount(0)
@@ -177,23 +181,31 @@
     void addFontFaceRule(StyleRuleFontFace*);
     void addKeyframesRule(StyleRuleKeyframes*);
 
-    void addChildRules(const Vector<RefPtr<StyleRuleBase> >&, const MediaQueryEvaluator& medium, AddRuleFlags);
+    void addChildRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >&, const MediaQueryEvaluator& medium, AddRuleFlags);
     bool findBestRuleSetAndAdd(const CSSSelector&, RuleData&);
 
     void compactRules();
     static void compactPendingRules(PendingRuleMap&, CompactRuleMap&);
 
-    struct PendingRuleMaps {
+    class PendingRuleMaps : public NoBaseWillBeGarbageCollected<PendingRuleMaps> {
+    public:
+        static PassOwnPtrWillBeRawPtr<PendingRuleMaps> create() { return adoptPtrWillBeNoop(new PendingRuleMaps); }
+
         PendingRuleMap idRules;
         PendingRuleMap classRules;
         PendingRuleMap tagRules;
         PendingRuleMap shadowPseudoElementRules;
+
+        void trace(Visitor*);
+
+    private:
+        PendingRuleMaps() { }
     };
 
     PendingRuleMaps* ensurePendingRules()
     {
         if (!m_pendingRules)
-            m_pendingRules = adoptPtr(new PendingRuleMaps);
+            m_pendingRules = PendingRuleMaps::create();
         return m_pendingRules.get();
     }
 
@@ -201,28 +213,42 @@
     CompactRuleMap m_classRules;
     CompactRuleMap m_tagRules;
     CompactRuleMap m_shadowPseudoElementRules;
-    Vector<RuleData> m_linkPseudoClassRules;
-    Vector<RuleData> m_cuePseudoRules;
-    Vector<RuleData> m_focusPseudoClassRules;
-    Vector<RuleData> m_universalRules;
+    WillBeHeapVector<RuleData> m_linkPseudoClassRules;
+    WillBeHeapVector<RuleData> m_cuePseudoRules;
+    WillBeHeapVector<RuleData> m_focusPseudoClassRules;
+    WillBeHeapVector<RuleData> m_universalRules;
     RuleFeatureSet m_features;
-    Vector<StyleRulePage*> m_pageRules;
-    Vector<StyleRuleViewport*> m_viewportRules;
-    Vector<StyleRuleFontFace*> m_fontFaceRules;
-    Vector<StyleRuleKeyframes*> m_keyframesRules;
-    Vector<MinimalRuleData> m_treeBoundaryCrossingRules;
-    Vector<MinimalRuleData> m_shadowDistributedRules;
+    WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> > m_pageRules;
+    WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> > m_viewportRules;
+    WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> > m_fontFaceRules;
+    WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > m_keyframesRules;
+    WillBeHeapVector<MinimalRuleData> m_treeBoundaryCrossingRules;
+    WillBeHeapVector<MinimalRuleData> m_shadowDistributedRules;
 
     MediaQueryResultList m_viewportDependentMediaQueryResults;
 
     unsigned m_ruleCount;
-    OwnPtr<PendingRuleMaps> m_pendingRules;
+    OwnPtrWillBeMember<PendingRuleMaps> m_pendingRules;
 
 #ifndef NDEBUG
-    Vector<RuleData> m_allRules;
+    WillBeHeapVector<RuleData> m_allRules;
 #endif
 };
 
 } // namespace WebCore
 
+namespace WTF {
+
+template <> struct VectorTraits<WebCore::RuleData> : VectorTraitsBase<WebCore::RuleData> {
+    static const bool canInitializeWithMemset = true;
+    static const bool canMoveWithMemcpy = true;
+};
+
+template <> struct VectorTraits<WebCore::MinimalRuleData> : VectorTraitsBase<WebCore::MinimalRuleData> {
+    static const bool canInitializeWithMemset = true;
+    static const bool canMoveWithMemcpy = true;
+};
+
+}
+
 #endif // RuleSet_h
diff --git a/Source/core/css/RuleSetTest.cpp b/Source/core/css/RuleSetTest.cpp
index 7fb09a4..622ab24 100644
--- a/Source/core/css/RuleSetTest.cpp
+++ b/Source/core/css/RuleSetTest.cpp
@@ -42,9 +42,9 @@
     helper.addCSSRules("summary::-webkit-details-marker { }");
     RuleSet& ruleSet = helper.ruleSet();
     AtomicString str("-webkit-details-marker");
-    const RuleData* ruleData = ruleSet.shadowPseudoElementRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
-    ASSERT_EQ(str, CSSTestHelper::getRule(ruleData, 0).selector().value());
+    const TerminatedArray<RuleData>* rules = ruleSet.shadowPseudoElementRules(str);
+    ASSERT_EQ(1u, rules->size());
+    ASSERT_EQ(str, rules->at(0).selector().value());
 }
 
 TEST(RuleSetTest, findBestRuleSetAndAdd_Id)
@@ -54,9 +54,9 @@
     helper.addCSSRules("#id { }");
     RuleSet& ruleSet = helper.ruleSet();
     AtomicString str("id");
-    const RuleData* ruleData = ruleSet.idRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
-    ASSERT_EQ(str, CSSTestHelper::getRule(ruleData, 0).selector().value());
+    const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+    ASSERT_EQ(1u, rules->size());
+    ASSERT_EQ(str, rules->at(0).selector().value());
 }
 
 TEST(RuleSetTest, findBestRuleSetAndAdd_NthChild)
@@ -66,9 +66,9 @@
     helper.addCSSRules("div:nth-child(2) { }");
     RuleSet& ruleSet = helper.ruleSet();
     AtomicString str("div");
-    const RuleData* ruleData = ruleSet.tagRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
-    ASSERT_EQ(str, CSSTestHelper::getRule(ruleData, 0).selector().tagQName().localName());
+    const TerminatedArray<RuleData>* rules = ruleSet.tagRules(str);
+    ASSERT_EQ(1u, rules->size());
+    ASSERT_EQ(str, rules->at(0).selector().tagQName().localName());
 }
 
 TEST(RuleSetTest, findBestRuleSetAndAdd_ClassThenId)
@@ -79,10 +79,10 @@
     RuleSet& ruleSet = helper.ruleSet();
     AtomicString str("id");
     // id is prefered over class even if class preceeds it in the selector.
-    const RuleData* ruleData = ruleSet.idRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
+    const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+    ASSERT_EQ(1u, rules->size());
     AtomicString classStr("class");
-    ASSERT_EQ(classStr, CSSTestHelper::getRule(ruleData, 0).selector().value());
+    ASSERT_EQ(classStr, rules->at(0).selector().value());
 }
 
 TEST(RuleSetTest, findBestRuleSetAndAdd_IdThenClass)
@@ -92,9 +92,9 @@
     helper.addCSSRules("#id.class { }");
     RuleSet& ruleSet = helper.ruleSet();
     AtomicString str("id");
-    const RuleData* ruleData = ruleSet.idRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
-    ASSERT_EQ(str, CSSTestHelper::getRule(ruleData, 0).selector().value());
+    const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+    ASSERT_EQ(1u, rules->size());
+    ASSERT_EQ(str, rules->at(0).selector().value());
 }
 
 TEST(RuleSetTest, findBestRuleSetAndAdd_AttrThenId)
@@ -104,10 +104,10 @@
     helper.addCSSRules("[attr]#id { }");
     RuleSet& ruleSet = helper.ruleSet();
     AtomicString str("id");
-    const RuleData* ruleData = ruleSet.idRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
+    const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+    ASSERT_EQ(1u, rules->size());
     AtomicString attrStr("attr");
-    ASSERT_EQ(attrStr, CSSTestHelper::getRule(ruleData, 0).selector().attribute().localName());
+    ASSERT_EQ(attrStr, rules->at(0).selector().attribute().localName());
 }
 
 TEST(RuleSetTest, findBestRuleSetAndAdd_TagThenAttrThenId)
@@ -117,23 +117,10 @@
     helper.addCSSRules("div[attr]#id { }");
     RuleSet& ruleSet = helper.ruleSet();
     AtomicString str("id");
-    const RuleData* ruleData = ruleSet.idRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
+    const TerminatedArray<RuleData>* rules = ruleSet.idRules(str);
+    ASSERT_EQ(1u, rules->size());
     AtomicString tagStr("div");
-    ASSERT_EQ(tagStr, CSSTestHelper::getRule(ruleData, 0).selector().tagQName().localName());
-}
-
-TEST(RuleSetTest, findBestRuleSetAndAdd_DivWithContent)
-{
-    CSSTestHelper helper;
-
-    helper.addCSSRules("div::content { }");
-    RuleSet& ruleSet = helper.ruleSet();
-    AtomicString str("div");
-    const RuleData* ruleData = ruleSet.tagRules(str);
-    ASSERT_EQ(1, CSSTestHelper::numRules(ruleData));
-    AtomicString valueStr("content");
-    ASSERT_EQ(valueStr, CSSTestHelper::getRule(ruleData, 0).selector().value());
+    ASSERT_EQ(tagStr, rules->at(0).selector().tagQName().localName());
 }
 
 } // namespace WebCore
diff --git a/Source/core/css/RuntimeCSSEnabled.cpp b/Source/core/css/RuntimeCSSEnabled.cpp
index d4c8b20..7c39d9e 100644
--- a/Source/core/css/RuntimeCSSEnabled.cpp
+++ b/Source/core/css/RuntimeCSSEnabled.cpp
@@ -106,7 +106,6 @@
     };
     setCSSPropertiesEnabled(animationProperties, WTF_ARRAY_LENGTH(animationProperties), RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled());
 
-    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyBackgroundBlendMode, RuntimeEnabledFeatures::cssCompositingEnabled());
     RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyMixBlendMode, RuntimeEnabledFeatures::cssCompositingEnabled());
     RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyIsolation, RuntimeEnabledFeatures::cssCompositingEnabled());
     RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyTouchAction, RuntimeEnabledFeatures::cssTouchActionEnabled());
@@ -115,6 +114,7 @@
     RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyMaskSourceType, RuntimeEnabledFeatures::cssMaskSourceTypeEnabled());
     RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyColumnFill, RuntimeEnabledFeatures::regionBasedColumnsEnabled());
     RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyScrollBehavior, RuntimeEnabledFeatures::cssomSmoothScrollEnabled());
+    RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyWillChange, RuntimeEnabledFeatures::cssWillChangeEnabled());
 
     // InternalCallback is an implementation detail, rather than an experimental feature, and should never be exposed to the web.
     RuntimeCSSEnabled::setCSSPropertyEnabled(CSSPropertyInternalCallback, false);
diff --git a/Source/core/css/SVGCSSComputedStyleDeclaration.cpp b/Source/core/css/SVGCSSComputedStyleDeclaration.cpp
index 4cdac90..bb904d7 100644
--- a/Source/core/css/SVGCSSComputedStyleDeclaration.cpp
+++ b/Source/core/css/SVGCSSComputedStyleDeclaration.cpp
@@ -42,11 +42,11 @@
         case GO_270DEG:
             return CSSPrimitiveValue::create(270.0f, CSSPrimitiveValue::CSS_DEG);
         default:
-            return 0;
+            return nullptr;
     }
 }
 
-static PassRefPtr<CSSValue> strokeDashArrayToCSSValueList(PassRefPtr<SVGLengthList> passDashes)
+static PassRefPtrWillBeRawPtr<CSSValue> strokeDashArrayToCSSValueList(PassRefPtr<SVGLengthList> passDashes)
 {
     RefPtr<SVGLengthList> dashes = passDashes;
 
@@ -62,7 +62,7 @@
     return list.release();
 }
 
-static PassRefPtr<CSSValue> paintOrderToCSSValueList(EPaintOrder paintorder)
+static PassRefPtrWillBeRawPtr<CSSValue> paintOrderToCSSValueList(EPaintOrder paintorder)
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     do {
@@ -91,11 +91,11 @@
     return paint.release();
 }
 
-PassRefPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
+PassRefPtrWillBeRawPtr<CSSValue> CSSComputedStyleDeclaration::getSVGPropertyCSSValue(CSSPropertyID propertyID, EUpdateLayout updateLayout) const
 {
     Node* node = m_node.get();
     if (!node)
-        return 0;
+        return nullptr;
 
     // Make sure our layout is up to date before we allow a query on these attributes.
     if (updateLayout)
@@ -103,11 +103,11 @@
 
     RenderStyle* style = node->computedStyle();
     if (!style)
-        return 0;
+        return nullptr;
 
     const SVGRenderStyle* svgStyle = style->svgStyle();
     if (!svgStyle)
-        return 0;
+        return nullptr;
 
     switch (propertyID) {
         case CSSPropertyClipRule:
@@ -198,7 +198,7 @@
                     return SVGLength::toCSSPrimitiveValue(svgStyle->baselineShiftValue());
             }
             ASSERT_NOT_REACHED();
-            return 0;
+            return nullptr;
         }
         case CSSPropertyBufferedRendering:
             return CSSPrimitiveValue::create(svgStyle->bufferedRendering());
@@ -211,7 +211,7 @@
             if (svgStyle->glyphOrientationVertical() == GO_AUTO)
                 return CSSPrimitiveValue::createIdentifier(CSSValueAuto);
 
-            return 0;
+            return nullptr;
         }
         case CSSPropertyPaintOrder:
             return paintOrderToCSSValueList(svgStyle->paintOrder());
@@ -230,7 +230,7 @@
         ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propertyID);
     }
     WTF_LOG_ERROR("unimplemented propertyID: %d", propertyID);
-    return 0;
+    return nullptr;
 }
 
 }
diff --git a/Source/core/css/SVGCSSParser.cpp b/Source/core/css/SVGCSSParser.cpp
deleted file mode 100644
index d6e080e..0000000
--- a/Source/core/css/SVGCSSParser.cpp
+++ /dev/null
@@ -1,429 +0,0 @@
-/*
-    Copyright (C) 2008 Eric Seidel <eric@webkit.org>
-    Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
-                  2004, 2005, 2007, 2010 Rob Buis <buis@kde.org>
-    Copyright (C) 2005, 2006 Apple Computer, Inc.
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public License
-    along with this library; see the file COPYING.LIB.  If not, write to
-    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
-    Boston, MA 02110-1301, USA.
-*/
-
-#include "config.h"
-
-#include "CSSPropertyNames.h"
-#include "CSSValueKeywords.h"
-#include "RuntimeEnabledFeatures.h"
-#include "core/css/parser/BisonCSSParser.h"
-#include "core/css/CSSValueList.h"
-#include "core/rendering/RenderTheme.h"
-#include "core/svg/SVGPaint.h"
-
-using namespace std;
-
-namespace WebCore {
-
-static bool isSystemColor(int id)
-{
-    return (id >= CSSValueActiveborder && id <= CSSValueWindowtext) || id == CSSValueMenu;
-}
-
-bool BisonCSSParser::parseSVGValue(CSSPropertyID propId, bool important)
-{
-    CSSParserValue* value = m_valueList->current();
-    if (!value)
-        return false;
-
-    CSSValueID id = value->id;
-
-    bool valid_primitive = false;
-    RefPtr<CSSValue> parsedValue;
-
-    switch (propId) {
-    /* The comment to the right defines all valid value of these
-     * properties as defined in SVG 1.1, Appendix N. Property index */
-    case CSSPropertyAlignmentBaseline:
-    // auto | baseline | before-edge | text-before-edge | middle |
-    // central | after-edge | text-after-edge | ideographic | alphabetic |
-    // hanging | mathematical | inherit
-        if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle ||
-          (id >= CSSValueBeforeEdge && id <= CSSValueMathematical))
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyBaselineShift:
-    // baseline | super | sub | <percentage> | <length> | inherit
-        if (id == CSSValueBaseline || id == CSSValueSub ||
-           id >= CSSValueSuper)
-            valid_primitive = true;
-        else
-            valid_primitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
-        break;
-
-    case CSSPropertyDominantBaseline:
-    // auto | use-script | no-change | reset-size | ideographic |
-    // alphabetic | hanging | mathematical | central | middle |
-    // text-after-edge | text-before-edge | inherit
-        if (id == CSSValueAuto || id == CSSValueMiddle ||
-          (id >= CSSValueUseScript && id <= CSSValueResetSize) ||
-          (id >= CSSValueCentral && id <= CSSValueMathematical))
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyEnableBackground:
-    // accumulate | new [x] [y] [width] [height] | inherit
-        if (id == CSSValueAccumulate) // TODO : new
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyMarkerStart:
-    case CSSPropertyMarkerMid:
-    case CSSPropertyMarkerEnd:
-    case CSSPropertyMask:
-        if (id == CSSValueNone)
-            valid_primitive = true;
-        else if (value->unit == CSSPrimitiveValue::CSS_URI) {
-            parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
-            if (parsedValue)
-                m_valueList->next();
-        }
-        break;
-
-    case CSSPropertyClipRule:            // nonzero | evenodd | inherit
-    case CSSPropertyFillRule:
-        if (id == CSSValueNonzero || id == CSSValueEvenodd)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeMiterlimit:   // <miterlimit> | inherit
-        valid_primitive = validUnit(value, FNumber | FNonNeg, SVGAttributeMode);
-        break;
-
-    case CSSPropertyStrokeLinejoin:   // miter | round | bevel | inherit
-        if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeLinecap:    // butt | round | square | inherit
-        if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeOpacity:   // <opacity-value> | inherit
-    case CSSPropertyFillOpacity:
-    case CSSPropertyStopOpacity:
-    case CSSPropertyFloodOpacity:
-        valid_primitive = (!id && validUnit(value, FNumber | FPercent, SVGAttributeMode));
-        break;
-
-    case CSSPropertyShapeRendering:
-    // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
-        if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
-            id == CSSValueCrispedges || id == CSSValueGeometricprecision)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyImageRendering:  // auto | optimizeSpeed |
-    case CSSPropertyColorRendering:  // optimizeQuality | inherit
-        if (id == CSSValueAuto || id == CSSValueOptimizespeed ||
-            id == CSSValueOptimizequality)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyBufferedRendering: // auto | dynamic | static
-        if (id == CSSValueAuto || id == CSSValueDynamic || id == CSSValueStatic)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyColorProfile: // auto | sRGB | <name> | <uri> inherit
-        if (id == CSSValueAuto || id == CSSValueSrgb)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyColorInterpolation:   // auto | sRGB | linearRGB | inherit
-    case CSSPropertyColorInterpolationFilters:
-        if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb)
-            valid_primitive = true;
-        break;
-
-    /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
-     * correctly and allows optimization in applyRule(..)
-     */
-
-    case CSSPropertyTextAnchor:    // start | middle | end | inherit
-        if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyGlyphOrientationVertical: // auto | <angle> | inherit
-        if (id == CSSValueAuto) {
-            valid_primitive = true;
-            break;
-        }
-    /* fallthrough intentional */
-    case CSSPropertyGlyphOrientationHorizontal: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
-        if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
-            parsedValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_DEG);
-
-            if (parsedValue)
-                m_valueList->next();
-        }
-        break;
-
-    case CSSPropertyFill:                 // <paint> | inherit
-    case CSSPropertyStroke:               // <paint> | inherit
-        {
-            if (id == CSSValueNone)
-                parsedValue = SVGPaint::createNone();
-            else if (id == CSSValueCurrentcolor)
-                parsedValue = SVGPaint::createCurrentColor();
-            else if (isSystemColor(id))
-                parsedValue = SVGPaint::createColor(RenderTheme::theme().systemColor(id));
-            else if (value->unit == CSSPrimitiveValue::CSS_URI) {
-                RGBA32 c = Color::transparent;
-                if (m_valueList->next()) {
-                    if (parseColorFromValue(m_valueList->current(), c))
-                        parsedValue = SVGPaint::createURIAndColor(value->string, c);
-                    else if (m_valueList->current()->id == CSSValueNone)
-                        parsedValue = SVGPaint::createURIAndNone(value->string);
-                    else if (m_valueList->current()->id == CSSValueCurrentcolor)
-                        parsedValue = SVGPaint::createURIAndCurrentColor(value->string);
-                }
-                if (!parsedValue)
-                    parsedValue = SVGPaint::createURI(value->string);
-            } else
-                parsedValue = parseSVGPaint();
-
-            if (parsedValue)
-                m_valueList->next();
-        }
-        break;
-
-    case CSSPropertyStopColor: // TODO : icccolor
-    case CSSPropertyFloodColor:
-    case CSSPropertyLightingColor:
-        if (isSystemColor(id))
-            parsedValue = SVGColor::createFromColor(RenderTheme::theme().systemColor(id));
-        else if ((id >= CSSValueAqua && id <= CSSValueTransparent) ||
-                (id >= CSSValueAliceblue && id <= CSSValueYellowgreen) || id == CSSValueGrey)
-            parsedValue = SVGColor::createFromString(value->string);
-        else if (id == CSSValueCurrentcolor)
-            parsedValue = SVGColor::createCurrentColor();
-        else // TODO : svgcolor (iccColor)
-            parsedValue = parseSVGColor();
-
-        if (parsedValue)
-            m_valueList->next();
-
-        break;
-
-    case CSSPropertyPaintOrder:
-        if (!RuntimeEnabledFeatures::svgPaintOrderEnabled())
-            return false;
-
-        if (m_valueList->size() == 1 && id == CSSValueNormal)
-            valid_primitive = true;
-        else if ((parsedValue = parsePaintOrder()))
-            m_valueList->next();
-        break;
-
-    case CSSPropertyVectorEffect: // none | non-scaling-stroke | inherit
-        if (id == CSSValueNone || id == CSSValueNonScalingStroke)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyWritingMode:
-    // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
-        if (id == CSSValueLrTb || id == CSSValueRlTb || id == CSSValueTbRl || id == CSSValueLr || id == CSSValueRl || id == CSSValueTb)
-            valid_primitive = true;
-        break;
-
-    case CSSPropertyStrokeWidth:         // <length> | inherit
-    case CSSPropertyStrokeDashoffset:
-        valid_primitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
-        break;
-    case CSSPropertyStrokeDasharray:     // none | <dasharray> | inherit
-        if (id == CSSValueNone)
-            valid_primitive = true;
-        else
-            parsedValue = parseSVGStrokeDasharray();
-
-        break;
-
-    case CSSPropertyKerning:              // auto | normal | <length> | inherit
-        if (id == CSSValueAuto || id == CSSValueNormal)
-            valid_primitive = true;
-        else
-            valid_primitive = validUnit(value, FLength, SVGAttributeMode);
-        break;
-
-    case CSSPropertyClipPath:    // <uri> | none | inherit
-    case CSSPropertyFilter:
-        if (id == CSSValueNone)
-            valid_primitive = true;
-        else if (value->unit == CSSPrimitiveValue::CSS_URI) {
-            parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
-            if (parsedValue)
-                m_valueList->next();
-        }
-        break;
-    case CSSPropertyMaskType: // luminance | alpha | inherit
-        if (id == CSSValueLuminance || id == CSSValueAlpha)
-            valid_primitive = true;
-        break;
-
-    /* shorthand properties */
-    case CSSPropertyMarker:
-    {
-        ShorthandScope scope(this, propId);
-        BisonCSSParser::ImplicitScope implicitScope(this, PropertyImplicit);
-        if (!parseValue(CSSPropertyMarkerStart, important))
-            return false;
-        if (m_valueList->current()) {
-            rollbackLastProperties(1);
-            return false;
-        }
-        CSSValue* value = m_parsedProperties.last().value();
-        addProperty(CSSPropertyMarkerMid, value, important);
-        addProperty(CSSPropertyMarkerEnd, value, important);
-        return true;
-    }
-    default:
-        // If you crash here, it's because you added a css property and are not handling it
-        // in either this switch statement or the one in BisonCSSParser::parseValue
-        ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
-        return false;
-    }
-
-    if (valid_primitive) {
-        if (id != 0)
-            parsedValue = CSSPrimitiveValue::createIdentifier(id);
-        else if (value->unit == CSSPrimitiveValue::CSS_STRING)
-            parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
-        else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
-            parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
-        else if (value->unit >= CSSParserValue::Q_EMS)
-            parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
-        if (isCalculation(value)) {
-            // FIXME calc() http://webkit.org/b/16662 : actually create a CSSPrimitiveValue here, ie
-            // parsedValue = CSSPrimitiveValue::create(m_parsedCalculation.release());
-            m_parsedCalculation.release();
-            parsedValue = 0;
-        }
-        m_valueList->next();
-    }
-    if (!parsedValue || (m_valueList->current() && !inShorthand()))
-        return false;
-
-    addProperty(propId, parsedValue.release(), important);
-    return true;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseSVGStrokeDasharray()
-{
-    RefPtrWillBeRawPtr<CSSValueList> ret = CSSValueList::createCommaSeparated();
-    CSSParserValue* value = m_valueList->current();
-    bool valid_primitive = true;
-    while (value) {
-        valid_primitive = validUnit(value, FLength | FPercent | FNonNeg, SVGAttributeMode);
-        if (!valid_primitive)
-            break;
-        if (value->id != 0)
-            ret->append(CSSPrimitiveValue::createIdentifier(value->id));
-        else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
-            ret->append(CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
-        value = m_valueList->next();
-        if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
-            value = m_valueList->next();
-    }
-    if (!valid_primitive)
-        return 0;
-    return ret.release();
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseSVGPaint()
-{
-    RGBA32 c = Color::transparent;
-    if (!parseColorFromValue(m_valueList->current(), c))
-        return SVGPaint::createUnknown();
-    return SVGPaint::createColor(Color(c));
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseSVGColor()
-{
-    RGBA32 c = Color::transparent;
-    if (!parseColorFromValue(m_valueList->current(), c))
-        return 0;
-    return SVGColor::createFromColor(Color(c));
-}
-
-// normal | [ fill || stroke || markers ]
-PassRefPtr<CSSValue> BisonCSSParser::parsePaintOrder() const
-{
-    if (m_valueList->size() > 3)
-        return 0;
-
-    CSSParserValue* value = m_valueList->current();
-    if (!value)
-        return 0;
-
-    RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
-
-    // The default paint-order is: Fill, Stroke, Markers.
-    bool seenFill = false,
-         seenStroke = false,
-         seenMarkers = false;
-
-    do {
-        switch (value->id) {
-        case CSSValueNormal:
-            // normal inside [fill || stroke || markers] not valid
-            return 0;
-        case CSSValueFill:
-            if (seenFill)
-                return 0;
-
-            seenFill = true;
-            break;
-        case CSSValueStroke:
-            if (seenStroke)
-                return 0;
-
-            seenStroke = true;
-            break;
-        case CSSValueMarkers:
-            if (seenMarkers)
-                return 0;
-
-            seenMarkers = true;
-            break;
-        default:
-            return 0;
-        }
-
-        parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
-    } while ((value = m_valueList->next()));
-
-    // fill out the rest of the paint order
-    if (!seenFill)
-        parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
-    if (!seenStroke)
-        parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
-    if (!seenMarkers)
-        parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
-
-    return parsedValues.release();
-}
-
-}
diff --git a/Source/core/css/SelectorChecker.cpp b/Source/core/css/SelectorChecker.cpp
index 3a00ae5..c6e5f46 100644
--- a/Source/core/css/SelectorChecker.cpp
+++ b/Source/core/css/SelectorChecker.cpp
@@ -35,10 +35,12 @@
 #include "core/dom/ElementTraversal.h"
 #include "core/dom/FullscreenElementStack.h"
 #include "core/dom/NodeRenderStyle.h"
+#include "core/dom/SiblingRuleHelper.h"
 #include "core/dom/Text.h"
 #include "core/dom/shadow/InsertionPoint.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/editing/FrameSelection.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLDocument.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLInputElement.h"
@@ -47,7 +49,6 @@
 #include "core/html/track/vtt/VTTElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/RenderScrollbar.h"
 #include "core/rendering/style/RenderStyle.h"
@@ -68,11 +69,12 @@
 static bool matchesCustomPseudoElement(const Element* element, const CSSSelector& selector)
 {
     ShadowRoot* root = element->containingShadowRoot();
-    if (!root || root->type() != ShadowRoot::UserAgentShadowRoot)
+    if (!root)
         return false;
-
     if (element->shadowPseudoId() != selector.value())
         return false;
+    if (selector.pseudoType() == CSSSelector::PseudoWebKitCustomElement && root->type() != ShadowRoot::UserAgentShadowRoot)
+        return false;
 
     return true;
 }
@@ -83,12 +85,21 @@
     if (allowToCrossBoundary)
         return context.element->parentOrShadowHostElement();
 
-    // If context.scope is not a shadow host, we cannot walk up from a shadow root to its shadow host.
-    if (!(context.behaviorAtBoundary & SelectorChecker::ScopeIsShadowHost))
+    // If context.scope is a shadow host, we should walk up from a shadow root to its shadow host.
+    if (context.behaviorAtBoundary & SelectorChecker::ScopeIsShadowHost)
+        return context.element->parentOrShadowHostElement();
+
+    if ((context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope)
         return context.element->parentElement();
 
-    // If behaviorAtBoundary is StaysWithInTreeScope, we cannot walk up from a shadow root to its shadow host.
-    return (context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope ? context.element->parentOrShadowHostElement() : context.element->parentElement();
+    // If context.scope is some element in some shadow tree and querySelector initialized the context,
+    // e.g. shadowRoot.querySelector(':host *'),
+    // (a) context.element has the same treescope as context.scope, need to walk up to its shadow host.
+    // (b) Otherwise, should not walk up from a shadow root to a shadow host.
+    if (context.scope && context.scope->treeScope() == context.element->treeScope())
+        return context.element->parentOrShadowHostElement();
+
+    return context.element->parentElement();
 }
 
 bool SelectorChecker::scopeContainsLastMatchedElement(const SelectorCheckingContext& context) const
@@ -115,7 +126,12 @@
 
 static inline bool nextSelectorExceedsScope(const SelectorChecker::SelectorCheckingContext& context)
 {
-    return context.element == context.scope && (context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope;
+    if ((context.behaviorAtBoundary & SelectorChecker::BoundaryBehaviorMask) != SelectorChecker::StaysWithinTreeScope)
+        return context.element == context.scope;
+
+    if (context.scope && context.scope->isInShadowTree())
+        return context.element == context.scope->containingShadowRoot()->host();
+    return false;
 }
 
 // Recursive check of selectors and combinators
@@ -136,9 +152,6 @@
         if (context.selector->isCustomPseudoElement()) {
             if (!matchesCustomPseudoElement(context.element, *context.selector))
                 return SelectorFailsLocally;
-        } else if (context.selector->isContentPseudoElement()) {
-            if (!context.element->isInShadowTree() || !context.element->isInsertionPoint())
-                return SelectorFailsLocally;
         } else {
             if ((!context.elementStyle && m_mode == ResolvingStyle) || m_mode == QueryingRules)
                 return SelectorFailsLocally;
@@ -261,10 +274,14 @@
             nextContext.elementStyle = 0;
             return match(nextContext, siblingTraversalStrategy, result);
         }
+
+    case CSSSelector::ShadowContent:
+        return matchForShadowDistributed(context.element, siblingTraversalStrategy, nextContext, result);
+
     case CSSSelector::DirectAdjacent:
         if (m_mode == ResolvingStyle) {
-            if (Element* parent = parentElement(context))
-                parent->setChildrenAffectedByDirectAdjacentRules();
+            if (Node* parent = context.element->parentElementOrShadowRoot())
+                SiblingRuleHelper(parent).setChildrenAffectedByDirectAdjacentRules();
         }
         nextContext.element = ElementTraversal::previousSibling(*context.element);
         if (!nextContext.element)
@@ -275,8 +292,8 @@
 
     case CSSSelector::IndirectAdjacent:
         if (m_mode == ResolvingStyle) {
-            if (Element* parent = parentElement(context))
-                parent->setChildrenAffectedByForwardPositionalRules();
+            if (Node* parent = context.element->parentElementOrShadowRoot())
+                SiblingRuleHelper(parent).setChildrenAffectedByForwardPositionalRules();
         }
         nextContext.element = ElementTraversal::previousSibling(*context.element);
         nextContext.isSubSelector = false;
@@ -289,7 +306,7 @@
         return SelectorFailsAllSiblings;
 
     case CSSSelector::ShadowPseudo:
-    case CSSSelector::ChildTree:
+    case CSSSelector::Shadow:
         {
             // If we're in the same tree-scope as the scoping element, then following a shadow descendant combinator would escape that and thus the scope.
             if (context.scope && context.scope->treeScope() == context.element->treeScope() && (context.behaviorAtBoundary & BoundaryBehaviorMask) != StaysWithinTreeScope)
@@ -304,7 +321,7 @@
             return this->match(nextContext, siblingTraversalStrategy, result);
         }
 
-    case CSSSelector::DescendantTree:
+    case CSSSelector::ShadowDeep:
         {
             nextContext.isSubSelector = false;
             nextContext.elementStyle = 0;
@@ -362,9 +379,9 @@
     return false;
 }
 
-static bool attributeValueMatches(const Attribute* attributeItem, CSSSelector::Match match, const AtomicString& selectorValue, bool caseSensitive)
+static bool attributeValueMatches(const Attribute& attributeItem, CSSSelector::Match match, const AtomicString& selectorValue, bool caseSensitive)
 {
-    const AtomicString& value = attributeItem->value();
+    const AtomicString& value = attributeItem.value();
     if (value.isNull())
         return false;
 
@@ -439,10 +456,11 @@
 
     const AtomicString& selectorValue =  selector.value();
 
-    for (size_t i = 0; i < element.attributeCount(); ++i) {
-        const Attribute* attributeItem = element.attributeItem(i);
+    unsigned attributeCount = element.attributeCount();
+    for (size_t i = 0; i < attributeCount; ++i) {
+        const Attribute& attributeItem = element.attributeItem(i);
 
-        if (!attributeItem->matches(selectorAttr))
+        if (!attributeItem.matches(selectorAttr))
             continue;
 
         if (attributeValueMatches(attributeItem, match, selectorValue, true))
@@ -474,7 +492,7 @@
     bool elementIsHostInItsShadowTree = isHostInItsShadowTree(element, context.behaviorAtBoundary, context.scope);
 
     if (selector.m_match == CSSSelector::Tag)
-        return SelectorChecker::tagMatches(element, selector.tagQName(), elementIsHostInItsShadowTree ? MatchingHostInItsShadowTree : MatchingElement);
+        return SelectorChecker::tagMatches(element, selector.tagQName()) && !elementIsHostInItsShadowTree;
 
     if (selector.m_match == CSSSelector::Class)
         return element.hasClass() && element.classNames().contains(selector.value()) && !elementIsHostInItsShadowTree;
@@ -547,11 +565,11 @@
             }
         case CSSSelector::PseudoFirstChild:
             // first-child matches the first child that is an element
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
                 bool result = siblingTraversalStrategy.isFirstChild(element);
                 if (m_mode == ResolvingStyle) {
                     RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
-                    parent->setChildrenAffectedByFirstChildRules();
+                    SiblingRuleHelper(parent).setChildrenAffectedByFirstChildRules();
                     if (result && childStyle)
                         childStyle->setFirstChildState();
                 }
@@ -560,20 +578,21 @@
             break;
         case CSSSelector::PseudoFirstOfType:
             // first-of-type matches the first element of its type
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
                 bool result = siblingTraversalStrategy.isFirstOfType(element, element.tagQName());
                 if (m_mode == ResolvingStyle)
-                    parent->setChildrenAffectedByForwardPositionalRules();
+                    SiblingRuleHelper(parent).setChildrenAffectedByForwardPositionalRules();
                 return result;
             }
             break;
         case CSSSelector::PseudoLastChild:
             // last-child matches the last child that is an element
-            if (Element* parent = element.parentElement()) {
-                bool result = parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
+            if (Node* parent = element.parentElementOrShadowRoot()) {
+                SiblingRuleHelper helper(parent);
+                bool result = helper.isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
                 if (m_mode == ResolvingStyle) {
                     RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
-                    parent->setChildrenAffectedByLastChildRules();
+                    helper.setChildrenAffectedByLastChildRules();
                     if (result && childStyle)
                         childStyle->setLastChildState();
                 }
@@ -582,22 +601,24 @@
             break;
         case CSSSelector::PseudoLastOfType:
             // last-of-type matches the last element of its type
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
+                SiblingRuleHelper helper(parent);
                 if (m_mode == ResolvingStyle)
-                    parent->setChildrenAffectedByBackwardPositionalRules();
-                if (!parent->isFinishedParsingChildren())
+                    helper.setChildrenAffectedByBackwardPositionalRules();
+                if (!helper.isFinishedParsingChildren())
                     return false;
                 return siblingTraversalStrategy.isLastOfType(element, element.tagQName());
             }
             break;
         case CSSSelector::PseudoOnlyChild:
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
+                SiblingRuleHelper helper(parent);
                 bool firstChild = siblingTraversalStrategy.isFirstChild(element);
-                bool onlyChild = firstChild && parent->isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
+                bool onlyChild = firstChild && helper.isFinishedParsingChildren() && siblingTraversalStrategy.isLastChild(element);
                 if (m_mode == ResolvingStyle) {
                     RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
-                    parent->setChildrenAffectedByFirstChildRules();
-                    parent->setChildrenAffectedByLastChildRules();
+                    helper.setChildrenAffectedByFirstChildRules();
+                    helper.setChildrenAffectedByLastChildRules();
                     if (firstChild && childStyle)
                         childStyle->setFirstChildState();
                     if (onlyChild && childStyle)
@@ -608,12 +629,13 @@
             break;
         case CSSSelector::PseudoOnlyOfType:
             // FIXME: This selector is very slow.
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
+                SiblingRuleHelper helper(parent);
                 if (m_mode == ResolvingStyle) {
-                    parent->setChildrenAffectedByForwardPositionalRules();
-                    parent->setChildrenAffectedByBackwardPositionalRules();
+                    helper.setChildrenAffectedByForwardPositionalRules();
+                    helper.setChildrenAffectedByBackwardPositionalRules();
                 }
-                if (!parent->isFinishedParsingChildren())
+                if (!helper.isFinishedParsingChildren())
                     return false;
                 return siblingTraversalStrategy.isFirstOfType(element, element.tagQName()) && siblingTraversalStrategy.isLastOfType(element, element.tagQName());
             }
@@ -621,14 +643,14 @@
         case CSSSelector::PseudoNthChild:
             if (!selector.parseNth())
                 break;
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
                 int count = 1 + siblingTraversalStrategy.countElementsBefore(element);
                 if (m_mode == ResolvingStyle) {
                     RenderStyle* childStyle = context.elementStyle ? context.elementStyle : element.renderStyle();
                     element.setChildIndex(count);
                     if (childStyle)
                         childStyle->setUnique();
-                    parent->setChildrenAffectedByForwardPositionalRules();
+                    SiblingRuleHelper(parent).setChildrenAffectedByForwardPositionalRules();
                 }
 
                 if (selector.matchNth(count))
@@ -638,10 +660,10 @@
         case CSSSelector::PseudoNthOfType:
             if (!selector.parseNth())
                 break;
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
                 int count = 1 + siblingTraversalStrategy.countElementsOfTypeBefore(element, element.tagQName());
                 if (m_mode == ResolvingStyle)
-                    parent->setChildrenAffectedByForwardPositionalRules();
+                    SiblingRuleHelper(parent).setChildrenAffectedByForwardPositionalRules();
 
                 if (selector.matchNth(count))
                     return true;
@@ -650,10 +672,11 @@
         case CSSSelector::PseudoNthLastChild:
             if (!selector.parseNth())
                 break;
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
+                SiblingRuleHelper helper(parent);
                 if (m_mode == ResolvingStyle)
-                    parent->setChildrenAffectedByBackwardPositionalRules();
-                if (!parent->isFinishedParsingChildren())
+                    helper.setChildrenAffectedByBackwardPositionalRules();
+                if (!helper.isFinishedParsingChildren())
                     return false;
                 int count = 1 + siblingTraversalStrategy.countElementsAfter(element);
                 if (selector.matchNth(count))
@@ -663,10 +686,11 @@
         case CSSSelector::PseudoNthLastOfType:
             if (!selector.parseNth())
                 break;
-            if (Element* parent = element.parentElement()) {
+            if (Node* parent = element.parentElementOrShadowRoot()) {
+                SiblingRuleHelper helper(parent);
                 if (m_mode == ResolvingStyle)
-                    parent->setChildrenAffectedByBackwardPositionalRules();
-                if (!parent->isFinishedParsingChildren())
+                    helper.setChildrenAffectedByBackwardPositionalRules();
+                if (!helper.isFinishedParsingChildren())
                     return false;
 
                 int count = 1 + siblingTraversalStrategy.countElementsOfTypeAfter(element, element.tagQName());
@@ -721,7 +745,7 @@
         case CSSSelector::PseudoHover:
             // If we're in quirks mode, then hover should never match anchors with no
             // href and *:hover should not match anything. This is important for sites like wsj.com.
-            if (m_strictParsing || context.isSubSelector || (selector.m_match == CSSSelector::Tag && selector.tagQName() != anyQName() && !element.hasTagName(aTag)) || element.isLink()) {
+            if (m_strictParsing || context.isSubSelector || (selector.m_match == CSSSelector::Tag && selector.tagQName() != anyQName() && !isHTMLAnchorElement(element)) || element.isLink()) {
                 if (m_mode == ResolvingStyle) {
                     if (context.elementStyle)
                         context.elementStyle->setAffectedByHover();
@@ -735,7 +759,7 @@
         case CSSSelector::PseudoActive:
             // If we're in quirks mode, then :active should never match anchors with no
             // href and *:active should not match anything.
-            if (m_strictParsing || context.isSubSelector || (selector.m_match == CSSSelector::Tag && selector.tagQName() != anyQName() && !element.hasTagName(aTag)) || element.isLink()) {
+            if (m_strictParsing || context.isSubSelector || (selector.m_match == CSSSelector::Tag && selector.tagQName() != anyQName() && !isHTMLAnchorElement(element)) || element.isLink()) {
                 if (m_mode == ResolvingStyle) {
                     if (context.elementStyle)
                         context.elementStyle->setAffectedByActive();
@@ -747,7 +771,7 @@
             }
             break;
         case CSSSelector::PseudoEnabled:
-            if (element.isFormControlElement() || element.hasTagName(optionTag) || element.hasTagName(optgroupTag))
+            if (element.isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
                 return !element.isDisabledFormControl();
             break;
         case CSSSelector::PseudoFullPageMedia:
@@ -756,7 +780,7 @@
         case CSSSelector::PseudoDefault:
             return element.isDefaultButtonForForm();
         case CSSSelector::PseudoDisabled:
-            if (element.isFormControlElement() || element.hasTagName(optionTag) || element.hasTagName(optgroupTag))
+            if (element.isFormControlElement() || isHTMLOptionElement(element) || isHTMLOptGroupElement(element))
                 return element.isDisabledFormControl();
             break;
         case CSSSelector::PseudoReadOnly:
@@ -775,7 +799,7 @@
             return element.willValidate() && !element.isValidFormControlElement();
         case CSSSelector::PseudoChecked:
             {
-                if (element.hasTagName(inputTag)) {
+                if (isHTMLInputElement(element)) {
                     HTMLInputElement& inputElement = toHTMLInputElement(element);
                     // Even though WinIE allows checked and indeterminate to
                     // co-exist, the CSS selector spec says that you can't be
@@ -784,7 +808,7 @@
                     // test for matching the pseudo.
                     if (inputElement.shouldAppearChecked() && !inputElement.shouldAppearIndeterminate())
                         return true;
-                } else if (element.hasTagName(optionTag) && toHTMLOptionElement(element).selected())
+                } else if (isHTMLOptionElement(element) && toHTMLOptionElement(element).selected())
                     return true;
                 break;
             }
@@ -815,7 +839,7 @@
             // context's Document is in the fullscreen state has the 'full-screen' pseudoclass applied.
             if (element.isFrameElementBase() && element.containsFullScreenElement())
                 return true;
-            if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&element.document())) {
+            if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(element.document())) {
                 if (!fullscreen->webkitIsFullScreen())
                     return false;
                 return element == fullscreen->webkitCurrentFullScreenElement();
@@ -826,7 +850,7 @@
         case CSSSelector::PseudoFullScreenDocument:
             // While a Document is in the fullscreen state, the 'full-screen-document' pseudoclass applies
             // to all elements of that Document.
-            if (!FullscreenElementStack::isFullScreen(&element.document()))
+            if (!FullscreenElementStack::isFullScreen(element.document()))
                 return false;
             return true;
         case CSSSelector::PseudoInRange:
@@ -857,7 +881,10 @@
         case CSSSelector::PseudoAncestor:
             {
                 // :host only matches a shadow host when :host is in a shadow tree of the shadow host.
-                if (!context.scope || !(context.behaviorAtBoundary & ScopeIsShadowHost) || context.scope != element)
+                if (!context.scope)
+                    return false;
+                const ContainerNode* shadowHost = (context.behaviorAtBoundary & ScopeIsShadowHost) ? context.scope : (context.scope->isInShadowTree() ? context.scope->shadowHost() : 0);
+                if (!shadowHost || shadowHost != element)
                     return false;
                 ASSERT(element.shadow());
 
@@ -874,7 +901,7 @@
                 // If one of simple selectors matches an element, returns SelectorMatches. Just "OR".
                 for (subContext.selector = selector.selectorList()->first(); subContext.selector; subContext.selector = CSSSelectorList::next(*subContext.selector)) {
                     subContext.behaviorAtBoundary = ScopeIsShadowHostInPseudoHostParameter;
-                    subContext.scope = context.scope;
+                    subContext.scope = shadowHost;
                     // Use NodeRenderingTraversal to traverse a composed ancestor list of a given element.
                     Element* nextElement = &element;
                     do {
diff --git a/Source/core/css/SelectorChecker.h b/Source/core/css/SelectorChecker.h
index fd98ccc..dc0787e 100644
--- a/Source/core/css/SelectorChecker.h
+++ b/Source/core/css/SelectorChecker.h
@@ -59,11 +59,6 @@
         ScopeIsShadowHostInPseudoHostParameter = ScopeIsShadowHost | TreatShadowHostAsNormalScope
     };
 
-    enum MatchingTagType {
-        MatchingElement = 0,
-        MatchingHostInItsShadowTree
-    };
-
     struct SelectorCheckingContext {
         // Initial selector constructor
         SelectorCheckingContext(const CSSSelector& selector, Element* element, VisitedMatchType visitedMatchType)
@@ -114,7 +109,7 @@
 
     Mode mode() const { return m_mode; }
 
-    static bool tagMatches(const Element&, const QualifiedName&, MatchingTagType = MatchingElement);
+    static bool tagMatches(const Element&, const QualifiedName&);
     static bool isCommonPseudoClassSelector(const CSSSelector&);
     static bool matchesFocusPseudoClass(const Element&);
     static bool checkExactAttribute(const Element&, const QualifiedName& selectorAttributeName, const StringImpl* value);
@@ -154,12 +149,12 @@
         || pseudoType == CSSSelector::PseudoFocus;
 }
 
-inline bool SelectorChecker::tagMatches(const Element& element, const QualifiedName& tagQName, MatchingTagType matchingTagType)
+inline bool SelectorChecker::tagMatches(const Element& element, const QualifiedName& tagQName)
 {
     if (tagQName == anyQName())
         return true;
     const AtomicString& localName = tagQName.localName();
-    if (localName != starAtom && (localName != element.localName() || matchingTagType == MatchingHostInItsShadowTree))
+    if (localName != starAtom && localName != element.localName())
         return false;
     const AtomicString& namespaceURI = tagQName.namespaceURI();
     return namespaceURI == starAtom || namespaceURI == element.namespaceURI();
@@ -171,8 +166,8 @@
         return false;
     unsigned size = element.attributeCount();
     for (unsigned i = 0; i < size; ++i) {
-        const Attribute* attribute = element.attributeItem(i);
-        if (attribute->matches(selectorAttributeName) && (!value || attribute->value().impl() == value))
+        const Attribute& attribute = element.attributeItem(i);
+        if (attribute.matches(selectorAttributeName) && (!value || attribute.value().impl() == value))
             return true;
     }
     return false;
@@ -180,7 +175,11 @@
 
 inline bool SelectorChecker::isHostInItsShadowTree(const Element& element, BehaviorAtBoundary behaviorAtBoundary, const ContainerNode* scope)
 {
-    return (behaviorAtBoundary & (ScopeIsShadowHost | TreatShadowHostAsNormalScope)) == ScopeIsShadowHost && scope == element;
+    if ((behaviorAtBoundary & (ScopeIsShadowHost | TreatShadowHostAsNormalScope)) == ScopeIsShadowHost)
+        return scope == element;
+    if (scope && scope->isInShadowTree())
+        return scope->shadowHost() == element;
+    return false;
 }
 
 }
diff --git a/Source/core/css/SelectorFilter.cpp b/Source/core/css/SelectorFilter.cpp
index 352ae8f..1cc16fb 100644
--- a/Source/core/css/SelectorFilter.cpp
+++ b/Source/core/css/SelectorFilter.cpp
@@ -157,11 +157,15 @@
                 return;
             }
             // Fall through.
-        case CSSSelector::ChildTree:
-        case CSSSelector::DescendantTree:
+        case CSSSelector::Shadow:
+        case CSSSelector::ShadowDeep:
             skipOverSubselectors = false;
             collectDescendantSelectorIdentifierHashes(*current, hash);
             break;
+        case CSSSelector::ShadowContent:
+            // Disable fastRejectSelector.
+            *identifierHashes = 0;
+            return;
         }
         if (hash == end)
             return;
diff --git a/Source/core/css/StyleInvalidationAnalysis.cpp b/Source/core/css/StyleInvalidationAnalysis.cpp
index bc59425..d312b04 100644
--- a/Source/core/css/StyleInvalidationAnalysis.cpp
+++ b/Source/core/css/StyleInvalidationAnalysis.cpp
@@ -37,7 +37,7 @@
 
 namespace WebCore {
 
-StyleInvalidationAnalysis::StyleInvalidationAnalysis(const Vector<StyleSheetContents*>& sheets)
+StyleInvalidationAnalysis::StyleInvalidationAnalysis(const WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& sheets)
     : m_dirtiesAllStyle(false)
 {
     for (unsigned i = 0; i < sheets.size() && !m_dirtiesAllStyle; ++i)
@@ -58,7 +58,7 @@
             CSSSelector::Relation relation = current->relation();
             // FIXME: it would be better to use setNeedsStyleRecalc for all shadow hosts matching
             // scopeSelector. Currently requests full style recalc.
-            if (relation == CSSSelector::DescendantTree || relation == CSSSelector::ChildTree)
+            if (relation == CSSSelector::ShadowDeep || relation == CSSSelector::Shadow)
                 return false;
             if (relation != CSSSelector::Descendant && relation != CSSSelector::Child && relation != CSSSelector::SubSelector)
                 break;
@@ -76,7 +76,7 @@
 
 static bool hasDistributedRule(StyleSheetContents* styleSheetContents)
 {
-    const Vector<RefPtr<StyleRuleBase> >& rules = styleSheetContents->childRules();
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules = styleSheetContents->childRules();
     for (unsigned i = 0; i < rules.size(); i++) {
         const StyleRuleBase* rule = rules[i].get();
         if (!rule->isStyleRule())
@@ -147,7 +147,7 @@
 
     // See if all rules on the sheet are scoped to some specific ids or classes.
     // Then test if we actually have any of those in the tree at the moment.
-    const Vector<RefPtr<StyleRuleImport> >& importRules = styleSheetContents->importRules();
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> >& importRules = styleSheetContents->importRules();
     for (unsigned i = 0; i < importRules.size(); ++i) {
         if (!importRules[i]->styleSheet())
             continue;
@@ -157,13 +157,13 @@
     }
     if (styleSheetContents->hasSingleOwnerNode()) {
         Node* ownerNode = styleSheetContents->singleOwnerNode();
-        if (ownerNode && ownerNode->hasTagName(HTMLNames::styleTag) && toHTMLStyleElement(ownerNode)->isRegisteredAsScoped()) {
+        if (isHTMLStyleElement(ownerNode) && toHTMLStyleElement(*ownerNode).isRegisteredAsScoped()) {
             m_scopingNodes.append(determineScopingNodeForStyleScoped(toHTMLStyleElement(ownerNode), styleSheetContents));
             return;
         }
     }
 
-    const Vector<RefPtr<StyleRuleBase> >& rules = styleSheetContents->childRules();
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules = styleSheetContents->childRules();
     for (unsigned i = 0; i < rules.size(); i++) {
         StyleRuleBase* rule = rules[i].get();
         if (!rule->isStyleRule()) {
diff --git a/Source/core/css/StyleInvalidationAnalysis.h b/Source/core/css/StyleInvalidationAnalysis.h
index 79cf3d8..3f93d44 100644
--- a/Source/core/css/StyleInvalidationAnalysis.h
+++ b/Source/core/css/StyleInvalidationAnalysis.h
@@ -26,6 +26,7 @@
 #ifndef StyleInvalidationAnalysis_h
 #define StyleInvalidationAnalysis_h
 
+#include "heap/Handle.h"
 #include "wtf/HashSet.h"
 #include "wtf/Vector.h"
 #include "wtf/text/StringImpl.h"
@@ -38,7 +39,7 @@
 
 class StyleInvalidationAnalysis {
 public:
-    StyleInvalidationAnalysis(const Vector<StyleSheetContents*>&);
+    StyleInvalidationAnalysis(const WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >&);
 
     bool dirtiesAllStyle() const { return m_dirtiesAllStyle; }
     void invalidateStyle(Document&);
diff --git a/Source/core/css/StyleMedia.cpp b/Source/core/css/StyleMedia.cpp
index 791ef27..8b34d7e 100644
--- a/Source/core/css/StyleMedia.cpp
+++ b/Source/core/css/StyleMedia.cpp
@@ -30,12 +30,12 @@
 #include "core/css/MediaQueryEvaluator.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
-StyleMedia::StyleMedia(Frame* frame)
+StyleMedia::StyleMedia(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
 }
@@ -63,7 +63,7 @@
     StyleResolver& styleResolver = document->ensureStyleResolver();
     RefPtr<RenderStyle> rootStyle = styleResolver.styleForElement(documentElement, 0 /*defaultParent*/, DisallowStyleSharing, MatchOnlyUserAgentRules);
 
-    RefPtr<MediaQuerySet> media = MediaQuerySet::create();
+    RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create();
     if (!media->set(query))
         return false;
 
diff --git a/Source/core/css/StyleMedia.h b/Source/core/css/StyleMedia.h
index e2cd69b..fb83c42 100644
--- a/Source/core/css/StyleMedia.h
+++ b/Source/core/css/StyleMedia.h
@@ -33,17 +33,17 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 
 class StyleMedia : public RefCounted<StyleMedia>, public DOMWindowProperty {
 public:
-    static PassRefPtr<StyleMedia> create(Frame* frame) { return adoptRef(new StyleMedia(frame));}
+    static PassRefPtr<StyleMedia> create(LocalFrame* frame) { return adoptRef(new StyleMedia(frame));}
 
     AtomicString type() const;
     bool matchMedium(const String&) const;
 
 private:
-    explicit StyleMedia(Frame*);
+    explicit StyleMedia(LocalFrame*);
 };
 
 } // namespace
diff --git a/Source/core/css/StylePropertySerializer.cpp b/Source/core/css/StylePropertySerializer.cpp
index 171e6a3..d1ab840 100644
--- a/Source/core/css/StylePropertySerializer.cpp
+++ b/Source/core/css/StylePropertySerializer.cpp
@@ -45,15 +45,24 @@
 {
 }
 
+String StylePropertySerializer::getPropertyText(CSSPropertyID propertyID, const String& value, bool isImportant, bool isNotFirstDecl) const
+{
+    StringBuilder result;
+    if (isNotFirstDecl)
+        result.append(' ');
+    result.append(getPropertyName(propertyID));
+    result.appendLiteral(": ");
+    result.append(value);
+    if (isImportant)
+        result.appendLiteral(" !important");
+    result.append(';');
+    return result.toString();
+}
+
 String StylePropertySerializer::asText() const
 {
     StringBuilder result;
 
-    int positionXPropertyIndex = -1;
-    int positionYPropertyIndex = -1;
-    int repeatXPropertyIndex = -1;
-    int repeatYPropertyIndex = -1;
-
     BitArray<numCSSProperties> shorthandPropertyUsed;
     BitArray<numCSSProperties> shorthandPropertyAppeared;
 
@@ -69,17 +78,17 @@
         String value;
 
         switch (propertyID) {
+        case CSSPropertyBackgroundAttachment:
+        case CSSPropertyBackgroundClip:
+        case CSSPropertyBackgroundColor:
+        case CSSPropertyBackgroundImage:
+        case CSSPropertyBackgroundOrigin:
         case CSSPropertyBackgroundPositionX:
-            positionXPropertyIndex = n;
-            continue;
         case CSSPropertyBackgroundPositionY:
-            positionYPropertyIndex = n;
-            continue;
+        case CSSPropertyBackgroundSize:
         case CSSPropertyBackgroundRepeatX:
-            repeatXPropertyIndex = n;
-            continue;
         case CSSPropertyBackgroundRepeatY:
-            repeatYPropertyIndex = n;
+            shorthandPropertyAppeared.set(CSSPropertyBackground - firstCSSProperty);
             continue;
         case CSSPropertyContent:
             if (property.value()->isValueList())
@@ -224,80 +233,11 @@
         if (value == "initial" && !CSSProperty::isInheritedProperty(propertyID))
             continue;
 
-        if (numDecls++)
-            result.append(' ');
-        result.append(getPropertyName(propertyID));
-        result.appendLiteral(": ");
-        result.append(value);
-        if (property.isImportant())
-            result.appendLiteral(" !important");
-        result.append(';');
+        result.append(getPropertyText(propertyID, value, property.isImportant(), numDecls++));
     }
 
-    // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output.
-    // It is required because background-position-x/y are non-standard properties and WebKit generated output
-    // would not work in Firefox (<rdar://problem/5143183>)
-    // It would be a better solution if background-position was CSS_PAIR.
-    if (positionXPropertyIndex != -1 && positionYPropertyIndex != -1 && m_propertySet.propertyAt(positionXPropertyIndex).isImportant() == m_propertySet.propertyAt(positionYPropertyIndex).isImportant()) {
-        StylePropertySet::PropertyReference positionXProperty = m_propertySet.propertyAt(positionXPropertyIndex);
-        StylePropertySet::PropertyReference positionYProperty = m_propertySet.propertyAt(positionYPropertyIndex);
-
-        if (numDecls++)
-            result.append(' ');
-        result.appendLiteral("background-position: ");
-        if (positionXProperty.value()->isValueList() || positionYProperty.value()->isValueList())
-            result.append(getLayeredShorthandValue(backgroundPositionShorthand()));
-        else {
-            result.append(positionXProperty.value()->cssText());
-            result.append(' ');
-            result.append(positionYProperty.value()->cssText());
-        }
-        if (positionXProperty.isImportant())
-            result.appendLiteral(" !important");
-        result.append(';');
-    } else {
-        if (positionXPropertyIndex != -1) {
-            if (numDecls++)
-                result.append(' ');
-            result.append(m_propertySet.propertyAt(positionXPropertyIndex).cssText());
-        }
-        if (positionYPropertyIndex != -1) {
-            if (numDecls++)
-                result.append(' ');
-            result.append(m_propertySet.propertyAt(positionYPropertyIndex).cssText());
-        }
-    }
-
-    // FIXME: We need to do the same for background-repeat.
-    if (repeatXPropertyIndex != -1 && repeatYPropertyIndex != -1 && m_propertySet.propertyAt(repeatXPropertyIndex).isImportant() == m_propertySet.propertyAt(repeatYPropertyIndex).isImportant()) {
-        StylePropertySet::PropertyReference repeatXProperty = m_propertySet.propertyAt(repeatXPropertyIndex);
-        StylePropertySet::PropertyReference repeatYProperty = m_propertySet.propertyAt(repeatYPropertyIndex);
-
-        if (numDecls++)
-            result.append(' ');
-        result.appendLiteral("background-repeat: ");
-        if (repeatXProperty.value()->isValueList() || repeatYProperty.value()->isValueList())
-            result.append(getLayeredShorthandValue(backgroundRepeatShorthand()));
-        else {
-            result.append(repeatXProperty.value()->cssText());
-            result.append(' ');
-            result.append(repeatYProperty.value()->cssText());
-        }
-        if (repeatXProperty.isImportant())
-            result.appendLiteral(" !important");
-        result.append(';');
-    } else {
-        if (repeatXPropertyIndex != -1) {
-            if (numDecls++)
-                result.append(' ');
-            result.append(m_propertySet.propertyAt(repeatXPropertyIndex).cssText());
-        }
-        if (repeatYPropertyIndex != -1) {
-            if (numDecls++)
-                result.append(' ');
-            result.append(m_propertySet.propertyAt(repeatYPropertyIndex).cssText());
-        }
-    }
+    if (shorthandPropertyAppeared.get(CSSPropertyBackground - firstCSSProperty))
+        appendBackgroundPropertyAsText(result, numDecls);
 
     ASSERT(!numDecls ^ !result.isEmpty());
     return result.toString();
@@ -314,7 +254,7 @@
     case CSSPropertyBackgroundPosition:
         return getLayeredShorthandValue(backgroundPositionShorthand());
     case CSSPropertyBackgroundRepeat:
-        return getLayeredShorthandValue(backgroundRepeatShorthand());
+        return backgroundRepeatPropertyValue();
     case CSSPropertyBackground:
         return getLayeredShorthandValue(backgroundShorthand());
     case CSSPropertyBorder:
@@ -380,7 +320,7 @@
     case CSSPropertyWebkitAnimation:
         return getLayeredShorthandValue(webkitAnimationShorthand());
     case CSSPropertyMarker: {
-        RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyMarkerStart);
+        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyMarkerStart);
         if (value)
             return value->cssText();
         return String();
@@ -394,8 +334,8 @@
 
 String StylePropertySerializer::borderSpacingValue(const StylePropertyShorthand& shorthand) const
 {
-    RefPtr<CSSValue> horizontalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[0]);
-    RefPtr<CSSValue> verticalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[1]);
+    RefPtrWillBeRawPtr<CSSValue> horizontalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[0]);
+    RefPtrWillBeRawPtr<CSSValue> verticalValue = m_propertySet.getPropertyCSSValue(shorthand.properties()[1]);
 
     // While standard border-spacing property does not allow specifying border-spacing-vertical without
     // specifying border-spacing-horizontal <http://www.w3.org/TR/CSS21/tables.html#separated-borders>,
@@ -534,7 +474,7 @@
 
     const unsigned size = shorthand.length();
     // Begin by collecting the properties into an array.
-    Vector< RefPtr<CSSValue> > values(size);
+    WillBeHeapVector<RefPtrWillBeMember<CSSValue> > values(size);
     size_t numLayers = 0;
 
     for (unsigned i = 0; i < size; ++i) {
@@ -560,7 +500,7 @@
         bool useSingleWordShorthand = false;
         bool foundPositionYCSSProperty = false;
         for (unsigned j = 0; j < size; j++) {
-            RefPtr<CSSValue> value;
+            RefPtrWillBeRawPtr<CSSValue> value;
             if (values[j]) {
                 if (values[j]->isBaseValueList())
                     value = toCSSValueList(values[j].get())->item(i);
@@ -570,9 +510,11 @@
                     // Color only belongs in the last layer.
                     if (shorthand.properties()[j] == CSSPropertyBackgroundColor) {
                         if (i != numLayers - 1)
-                            value = 0;
-                    } else if (i) // Other singletons only belong in the first layer.
-                        value = 0;
+                            value = nullptr;
+                    } else if (i) {
+                        // Other singletons only belong in the first layer.
+                        value = nullptr;
+                    }
                 }
             }
 
@@ -585,8 +527,8 @@
                 // BUG 49055: make sure the value was not reset in the layer check just above.
                 if ((j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyBackgroundRepeatY && value)
                     || (j < size - 1 && shorthand.properties()[j + 1] == CSSPropertyWebkitMaskRepeatY && value)) {
-                    RefPtr<CSSValue> yValue;
-                    RefPtr<CSSValue> nextValue = values[j + 1];
+                    RefPtrWillBeRawPtr<CSSValue> yValue;
+                    RefPtrWillBeRawPtr<CSSValue> nextValue = values[j + 1];
                     if (nextValue->isValueList())
                         yValue = toCSSValueList(nextValue.get())->itemWithoutBoundsCheck(i);
                     else
@@ -682,7 +624,7 @@
     StringBuilder result;
     for (unsigned i = 0; i < shorthand.length(); ++i) {
         if (!m_propertySet.isPropertyImplicit(shorthand.properties()[i])) {
-            RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+            RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
             if (!value)
                 return String();
             String valueText = value->cssText();
@@ -711,7 +653,7 @@
     String res;
     bool lastPropertyWasImportant = false;
     for (unsigned i = 0; i < shorthand.length(); ++i) {
-        RefPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
         // FIXME: CSSInitialValue::cssText should generate the right value.
         if (!value)
             return String();
@@ -759,4 +701,151 @@
     return result.isEmpty() ? String() : result.toString();
 }
 
+String StylePropertySerializer::backgroundRepeatPropertyValue() const
+{
+    RefPtrWillBeRawPtr<CSSValue> repeatX = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatX);
+    RefPtrWillBeRawPtr<CSSValue> repeatY = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundRepeatY);
+    if (!repeatX || !repeatY)
+        return String();
+    if (repeatX->cssValueType() != repeatY->cssValueType())
+        return String();
+    if (m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX) != m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatY))
+        return String();
+
+    StringBuilder builder;
+    switch (repeatX->cssValueType()) {
+    case CSSValue::CSS_INHERIT:
+    case CSSValue::CSS_INITIAL:
+        return repeatX->cssText();
+
+    case CSSValue::CSS_PRIMITIVE_VALUE:
+        {
+            CSSValueID repeatXValueId = toCSSPrimitiveValue(repeatX.get())->getValueID();
+            CSSValueID repeatYValueId = toCSSPrimitiveValue(repeatY.get())->getValueID();
+            if (repeatXValueId == repeatYValueId)
+                return repeatX->cssText();
+
+            if (repeatXValueId == CSSValueNoRepeat && repeatYValueId == CSSValueRepeat) {
+                builder.append("repeat-y");
+                break;
+            }
+            if (repeatXValueId == CSSValueRepeat && repeatYValueId == CSSValueNoRepeat) {
+                builder.append("repeat-x");
+                break;
+            }
+            // Fall through intentional.
+        }
+    case CSSValue::CSS_CUSTOM:
+    case CSSValue::CSS_VALUE_LIST:
+    default:
+        builder.append(repeatX->cssText());
+        builder.append(' ');
+        builder.append(repeatY->cssText());
+        break;
+    }
+    return builder.toString();
+}
+
+void StylePropertySerializer::appendBackgroundPropertyAsText(StringBuilder& result, unsigned& numDecls) const
+{
+    if (isPropertyShorthandAvailable(backgroundShorthand())) {
+        String backgroundValue = getPropertyValue(CSSPropertyBackground);
+        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundImage);
+        result.append(getPropertyText(CSSPropertyBackground, backgroundValue, isImportant, numDecls++));
+        return;
+    }
+    if (shorthandHasOnlyInitialOrInheritedValue(backgroundShorthand())) {
+        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundImage);
+        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundImage);
+        result.append(getPropertyText(CSSPropertyBackground, value->cssText(), isImportant, numDecls++));
+        return;
+    }
+
+    // backgroundShorthandProperty without layered shorhand properties
+    const CSSPropertyID backgroundPropertyIds[] = {
+        CSSPropertyBackgroundImage,
+        CSSPropertyBackgroundAttachment,
+        CSSPropertyBackgroundColor,
+        CSSPropertyBackgroundSize,
+        CSSPropertyBackgroundOrigin,
+        CSSPropertyBackgroundClip
+    };
+
+    for (unsigned i = 0; i < WTF_ARRAY_LENGTH(backgroundPropertyIds); ++i) {
+        CSSPropertyID propertyID = backgroundPropertyIds[i];
+        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(propertyID);
+        if (!value)
+            continue;
+        result.append(getPropertyText(propertyID, value->cssText(), m_propertySet.propertyIsImportant(propertyID), numDecls++));
+    }
+
+    // FIXME: This is a not-so-nice way to turn x/y positions into single background-position in output.
+    // It is required because background-position-x/y are non-standard properties and WebKit generated output
+    // would not work in Firefox (<rdar://problem/5143183>)
+    // It would be a better solution if background-position was CSS_PAIR.
+    if (shorthandHasOnlyInitialOrInheritedValue(backgroundPositionShorthand())) {
+        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX);
+        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
+        result.append(getPropertyText(CSSPropertyBackgroundPosition, value->cssText(), isImportant, numDecls++));
+    } else if (isPropertyShorthandAvailable(backgroundPositionShorthand())) {
+        String positionValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundPosition);
+        bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
+        if (!positionValue.isNull())
+            result.append(getPropertyText(CSSPropertyBackgroundPosition, positionValue, isImportant, numDecls++));
+    } else {
+        // should check background-position-x or background-position-y.
+        if (RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionX)) {
+            if (!value->isImplicitInitialValue()) {
+                bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionX);
+                result.append(getPropertyText(CSSPropertyBackgroundPositionX, value->cssText(), isImportant, numDecls++));
+            }
+        }
+        if (RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(CSSPropertyBackgroundPositionY)) {
+            if (!value->isImplicitInitialValue()) {
+                bool isImportant = m_propertySet.propertyIsImportant(CSSPropertyBackgroundPositionY);
+                result.append(getPropertyText(CSSPropertyBackgroundPositionY, value->cssText(), isImportant, numDecls++));
+            }
+        }
+    }
+
+    String repeatValue = m_propertySet.getPropertyValue(CSSPropertyBackgroundRepeat);
+    if (!repeatValue.isNull())
+        result.append(getPropertyText(CSSPropertyBackgroundRepeat, repeatValue, m_propertySet.propertyIsImportant(CSSPropertyBackgroundRepeatX), numDecls++));
+}
+
+bool StylePropertySerializer::isPropertyShorthandAvailable(const StylePropertyShorthand& shorthand) const
+{
+    ASSERT(shorthand.length() > 0);
+
+    bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[0]);
+    for (unsigned i = 0; i < shorthand.length(); ++i) {
+        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+        if (!value || (value->isInitialValue() && !value->isImplicitInitialValue()) || value->isInheritedValue())
+            return false;
+        if (isImportant != m_propertySet.propertyIsImportant(shorthand.properties()[i]))
+            return false;
+    }
+    return true;
+}
+
+bool StylePropertySerializer::shorthandHasOnlyInitialOrInheritedValue(const StylePropertyShorthand& shorthand) const
+{
+    ASSERT(shorthand.length() > 0);
+    bool isImportant = m_propertySet.propertyIsImportant(shorthand.properties()[0]);
+    bool isInitialValue = true;
+    bool isInheritedValue = true;
+    for (unsigned i = 0; i < shorthand.length(); ++i) {
+        RefPtrWillBeRawPtr<CSSValue> value = m_propertySet.getPropertyCSSValue(shorthand.properties()[i]);
+        if (!value)
+            return false;
+        if (!value->isInitialValue())
+            isInitialValue = false;
+        if (!value->isInheritedValue())
+            isInheritedValue = false;
+        if (isImportant != m_propertySet.propertyIsImportant(shorthand.properties()[i]))
+            return false;
+    }
+    return isInitialValue || isInheritedValue;
+}
+
 }
diff --git a/Source/core/css/StylePropertySerializer.h b/Source/core/css/StylePropertySerializer.h
index 55d1027..ed9bc6a 100644
--- a/Source/core/css/StylePropertySerializer.h
+++ b/Source/core/css/StylePropertySerializer.h
@@ -45,6 +45,11 @@
     String getShorthandValue(const StylePropertyShorthand&) const;
     String fontValue() const;
     void appendFontLonghandValueIfExplicit(CSSPropertyID, StringBuilder& result, String& value) const;
+    String backgroundRepeatPropertyValue() const;
+    String getPropertyText(CSSPropertyID, const String& value, bool isImportant, bool isNotFirstDecl) const;
+    bool isPropertyShorthandAvailable(const StylePropertyShorthand&) const;
+    bool shorthandHasOnlyInitialOrInheritedValue(const StylePropertyShorthand&) const;
+    void appendBackgroundPropertyAsText(StringBuilder& result, unsigned& numDecls) const;
 
     const StylePropertySet& m_propertySet;
 };
diff --git a/Source/core/css/StylePropertySet.cpp b/Source/core/css/StylePropertySet.cpp
index 6a333f6..b7e7972 100644
--- a/Source/core/css/StylePropertySet.cpp
+++ b/Source/core/css/StylePropertySet.cpp
@@ -50,8 +50,12 @@
 PassRefPtr<ImmutableStylePropertySet> ImmutableStylePropertySet::create(const CSSProperty* properties, unsigned count, CSSParserMode cssParserMode)
 {
     ASSERT(count <= MaxArraySize);
+#if ENABLE(OILPAN)
+    void* slot = Heap::allocate<StylePropertySet>(sizeForImmutableStylePropertySetWithPropertyCount(count));
+#else
     void* slot = WTF::fastMalloc(sizeForImmutableStylePropertySetWithPropertyCount(count));
-    return adoptRef(new (slot) ImmutableStylePropertySet(properties, count, cssParserMode));
+#endif // ENABLE(OILPAN)
+    return adoptRefWillBeRefCountedGarbageCollected(new (slot) ImmutableStylePropertySet(properties, count, cssParserMode));
 }
 
 PassRefPtr<ImmutableStylePropertySet> StylePropertySet::immutableCopyIfNeeded() const
@@ -79,7 +83,7 @@
     : StylePropertySet(cssParserMode, length)
 {
     StylePropertyMetadata* metadataArray = const_cast<StylePropertyMetadata*>(this->metadataArray());
-    CSSValue** valueArray = const_cast<CSSValue**>(this->valueArray());
+    RawPtrWillBeMember<CSSValue>* valueArray = const_cast<RawPtrWillBeMember<CSSValue>*>(this->valueArray());
     for (unsigned i = 0; i < m_arraySize; ++i) {
         metadataArray[i] = properties[i].metadata();
         valueArray[i] = properties[i].value();
@@ -89,9 +93,35 @@
 
 ImmutableStylePropertySet::~ImmutableStylePropertySet()
 {
-    CSSValue** valueArray = const_cast<CSSValue**>(this->valueArray());
+#if !ENABLE(OILPAN)
+    RawPtrWillBeMember<CSSValue>* valueArray = const_cast<RawPtrWillBeMember<CSSValue>*>(this->valueArray());
     for (unsigned i = 0; i < m_arraySize; ++i)
         valueArray[i]->deref();
+#endif
+}
+
+int ImmutableStylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
+{
+    // Convert here propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+    // the compiler converting it to an int multiple times in the loop.
+    uint16_t id = static_cast<uint16_t>(propertyID);
+    for (int n = m_arraySize - 1 ; n >= 0; --n) {
+        if (metadataArray()[n].m_propertyID == id) {
+            // Only enabled or internal properties should be part of the style.
+            ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
+            return n;
+        }
+    }
+
+    return -1;
+}
+
+void ImmutableStylePropertySet::traceAfterDispatch(Visitor* visitor)
+{
+    const RawPtrWillBeMember<CSSValue>* values = valueArray();
+    for (unsigned i = 0; i < m_arraySize; i++)
+        visitor->trace(values[i]);
+    StylePropertySet::traceAfterDispatch(visitor);
 }
 
 MutableStylePropertySet::MutableStylePropertySet(const StylePropertySet& other)
@@ -108,21 +138,39 @@
 
 String StylePropertySet::getPropertyValue(CSSPropertyID propertyID) const
 {
-    RefPtr<CSSValue> value = getPropertyCSSValue(propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(propertyID);
     if (value)
         return value->cssText();
 
     return StylePropertySerializer(*this).getPropertyValue(propertyID);
 }
 
-PassRefPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSPropertyID propertyID) const
+PassRefPtrWillBeRawPtr<CSSValue> StylePropertySet::getPropertyCSSValue(CSSPropertyID propertyID) const
 {
     int foundPropertyIndex = findPropertyIndex(propertyID);
     if (foundPropertyIndex == -1)
-        return 0;
+        return nullptr;
     return propertyAt(foundPropertyIndex).value();
 }
 
+void StylePropertySet::trace(Visitor* visitor)
+{
+    if (m_isMutable)
+        toMutableStylePropertySet(this)->traceAfterDispatch(visitor);
+    else
+        toImmutableStylePropertySet(this)->traceAfterDispatch(visitor);
+}
+
+#if ENABLE(OILPAN)
+void StylePropertySet::finalize()
+{
+    if (m_isMutable)
+        toMutableStylePropertySet(this)->~MutableStylePropertySet();
+    else
+        toImmutableStylePropertySet(this)->~ImmutableStylePropertySet();
+}
+#endif
+
 bool MutableStylePropertySet::removeShorthandProperty(CSSPropertyID propertyID)
 {
     StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
@@ -220,7 +268,7 @@
     return BisonCSSParser::parseValue(this, propertyID, value, important, cssParserMode(), contextStyleSheet);
 }
 
-void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtr<CSSValue> prpValue, bool important)
+void MutableStylePropertySet::setProperty(CSSPropertyID propertyID, PassRefPtrWillBeRawPtr<CSSValue> prpValue, bool important)
 {
     StylePropertyShorthand shorthand = shorthandForProperty(propertyID);
     if (!shorthand.length()) {
@@ -230,7 +278,7 @@
 
     removePropertiesInSet(shorthand.properties(), shorthand.length());
 
-    RefPtr<CSSValue> value = prpValue;
+    RefPtrWillBeRawPtr<CSSValue> value = prpValue;
     for (unsigned i = 0; i < shorthand.length(); ++i)
         m_propertyVector.append(CSSProperty(shorthand.properties()[i], value, important));
 }
@@ -303,7 +351,7 @@
     parser.parseDeclaration(this, styleDeclaration, 0, contextStyleSheet);
 }
 
-void MutableStylePropertySet::addParsedProperties(const Vector<CSSProperty, 256>& properties)
+void MutableStylePropertySet::addParsedProperties(const WillBeHeapVector<CSSProperty, 256>& properties)
 {
     m_propertyVector.reserveCapacity(m_propertyVector.size() + properties.size());
     for (unsigned i = 0; i < properties.size(); ++i)
@@ -403,7 +451,7 @@
     for (unsigned i = 0; i < length; ++i)
         toRemove.add(set[i]);
 
-    Vector<CSSProperty> newProperties;
+    WillBeHeapVector<CSSProperty> newProperties;
     newProperties.reserveInitialCapacity(m_propertyVector.size());
 
     unsigned size = m_propertyVector.size();
@@ -422,21 +470,6 @@
     return changed;
 }
 
-int StylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
-{
-    // Convert here propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
-    // the compiler converting it to an int multiple times in the loop.
-    uint16_t id = static_cast<uint16_t>(propertyID);
-    for (int n = propertyCount() - 1 ; n >= 0; --n) {
-        if (id == propertyAt(n).propertyMetadata().m_propertyID) {
-            // Only enabled or internal properties should be part of the style.
-            ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
-            return n;
-        }
-    }
-    return -1;
-}
-
 CSSProperty* MutableStylePropertySet::findCSSPropertyWithID(CSSPropertyID propertyID)
 {
     int foundPropertyIndex = findPropertyIndex(propertyID);
@@ -483,15 +516,15 @@
 
 PassRefPtr<MutableStylePropertySet> StylePropertySet::mutableCopy() const
 {
-    return adoptRef(new MutableStylePropertySet(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new MutableStylePropertySet(*this));
 }
 
 PassRefPtr<MutableStylePropertySet> StylePropertySet::copyPropertiesInSet(const Vector<CSSPropertyID>& properties) const
 {
-    Vector<CSSProperty, 256> list;
+    WillBeHeapVector<CSSProperty, 256> list;
     list.reserveInitialCapacity(properties.size());
     for (unsigned i = 0; i < properties.size(); ++i) {
-        RefPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
+        RefPtrWillBeRawPtr<CSSValue> value = getPropertyCSSValue(properties[i]);
         if (value)
             list.append(CSSProperty(properties[i], value.release(), false));
     }
@@ -507,10 +540,32 @@
         ASSERT(!m_cssomWrapper->parentElement());
         return m_cssomWrapper.get();
     }
-    m_cssomWrapper = adoptPtr(new PropertySetCSSStyleDeclaration(this));
+    m_cssomWrapper = adoptPtr(new PropertySetCSSStyleDeclaration(*this));
     return m_cssomWrapper.get();
 }
 
+int MutableStylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
+{
+    // Convert here propertyID into an uint16_t to compare it with the metadata's m_propertyID to avoid
+    // the compiler converting it to an int multiple times in the loop.
+    uint16_t id = static_cast<uint16_t>(propertyID);
+    for (int n = m_propertyVector.size() - 1 ; n >= 0; --n) {
+        if (m_propertyVector.at(n).metadata().m_propertyID == id) {
+            // Only enabled or internal properties should be part of the style.
+            ASSERT(RuntimeCSSEnabled::isCSSPropertyEnabled(propertyID) || isInternalProperty(propertyID));
+            return n;
+        }
+    }
+
+    return -1;
+}
+
+void MutableStylePropertySet::traceAfterDispatch(Visitor* visitor)
+{
+    visitor->trace(m_propertyVector);
+    StylePropertySet::traceAfterDispatch(visitor);
+}
+
 unsigned StylePropertySet::averageSizeInBytes()
 {
     // Please update this if the storage scheme changes so that this longer reflects the actual size.
@@ -518,7 +573,7 @@
 }
 
 // See the function above if you need to update this.
-struct SameSizeAsStylePropertySet : public RefCounted<SameSizeAsStylePropertySet> {
+struct SameSizeAsStylePropertySet : public RefCountedWillBeRefCountedGarbageCollected<SameSizeAsStylePropertySet> {
     unsigned bitfield;
 };
 COMPILE_ASSERT(sizeof(StylePropertySet) == sizeof(SameSizeAsStylePropertySet), style_property_set_should_stay_small);
@@ -532,12 +587,12 @@
 
 PassRefPtr<MutableStylePropertySet> MutableStylePropertySet::create(CSSParserMode cssParserMode)
 {
-    return adoptRef(new MutableStylePropertySet(cssParserMode));
+    return adoptRefWillBeRefCountedGarbageCollected(new MutableStylePropertySet(cssParserMode));
 }
 
 PassRefPtr<MutableStylePropertySet> MutableStylePropertySet::create(const CSSProperty* properties, unsigned count)
 {
-    return adoptRef(new MutableStylePropertySet(properties, count));
+    return adoptRefWillBeRefCountedGarbageCollected(new MutableStylePropertySet(properties, count));
 }
 
 String StylePropertySet::PropertyReference::cssName() const
diff --git a/Source/core/css/StylePropertySet.h b/Source/core/css/StylePropertySet.h
index 73e7bf5..549cc98 100644
--- a/Source/core/css/StylePropertySet.h
+++ b/Source/core/css/StylePropertySet.h
@@ -41,12 +41,20 @@
 class StylePropertyShorthand;
 class StyleSheetContents;
 
-class StylePropertySet : public RefCounted<StylePropertySet> {
+class StylePropertySet : public RefCountedWillBeRefCountedGarbageCollected<StylePropertySet> {
     friend class PropertyReference;
 public:
+
+#if ENABLE(OILPAN)
+    // When oilpan is enabled override the finalize method to dispatch to the subclasses'
+    // destructor. This can be removed once the MutableStylePropertySet's OwnPtr is moved
+    // to the heap.
+    void finalize();
+#else
     // Override RefCounted's deref() to ensure operator delete is called on
     // the appropriate subclass type.
     void deref();
+#endif
 
     class PropertyReference {
     public:
@@ -87,7 +95,7 @@
     PropertyReference propertyAt(unsigned index) const { return PropertyReference(*this, index); }
     int findPropertyIndex(CSSPropertyID) const;
 
-    PassRefPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
+    PassRefPtrWillBeRawPtr<CSSValue> getPropertyCSSValue(CSSPropertyID) const;
     String getPropertyValue(CSSPropertyID) const;
 
     bool propertyIsImportant(CSSPropertyID) const;
@@ -117,6 +125,9 @@
 
     bool propertyMatches(CSSPropertyID, const CSSValue*) const;
 
+    void trace(Visitor*);
+    void traceAfterDispatch(Visitor*) { }
+
 protected:
 
     enum { MaxArraySize = (1 << 28) - 1 };
@@ -147,8 +158,16 @@
 
     unsigned propertyCount() const { return m_arraySize; }
 
-    const CSSValue** valueArray() const;
+    const RawPtrWillBeMember<CSSValue>* valueArray() const;
     const StylePropertyMetadata* metadataArray() const;
+    int findPropertyIndex(CSSPropertyID) const;
+
+    void traceAfterDispatch(Visitor*);
+
+    void* operator new(std::size_t, void* location)
+    {
+        return location;
+    }
 
     void* m_storage;
 
@@ -156,14 +175,14 @@
     ImmutableStylePropertySet(const CSSProperty*, unsigned count, CSSParserMode);
 };
 
-inline const CSSValue** ImmutableStylePropertySet::valueArray() const
+inline const RawPtrWillBeMember<CSSValue>* ImmutableStylePropertySet::valueArray() const
 {
-    return reinterpret_cast<const CSSValue**>(const_cast<const void**>(&(this->m_storage)));
+    return reinterpret_cast<const RawPtrWillBeMember<CSSValue>*>(const_cast<const void**>(&(this->m_storage)));
 }
 
 inline const StylePropertyMetadata* ImmutableStylePropertySet::metadataArray() const
 {
-    return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>(&(this->m_storage))[m_arraySize * sizeof(CSSValue*)]);
+    return reinterpret_cast<const StylePropertyMetadata*>(&reinterpret_cast<const char*>(&(this->m_storage))[m_arraySize * sizeof(RawPtrWillBeMember<CSSValue>)]);
 }
 
 DEFINE_TYPE_CASTS(ImmutableStylePropertySet, StylePropertySet, set, !set->isMutable(), !set.isMutable());
@@ -181,12 +200,12 @@
 
     unsigned propertyCount() const { return m_propertyVector.size(); }
 
-    void addParsedProperties(const Vector<CSSProperty, 256>&);
+    void addParsedProperties(const WillBeHeapVector<CSSProperty, 256>&);
     void addParsedProperty(const CSSProperty&);
 
     // These expand shorthand properties into multiple properties.
     bool setProperty(CSSPropertyID, const String& value, bool important = false, StyleSheetContents* contextStyleSheet = 0);
-    void setProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important = false);
+    void setProperty(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important = false);
 
     // These do not. FIXME: This is too messy, we can do better.
     bool setProperty(CSSPropertyID, CSSValueID identifier, bool important = false);
@@ -208,8 +227,9 @@
     void parseDeclaration(const String& styleDeclaration, StyleSheetContents* contextStyleSheet);
 
     CSSStyleDeclaration* ensureCSSStyleDeclaration();
+    int findPropertyIndex(CSSPropertyID) const;
 
-    Vector<CSSProperty, 4> m_propertyVector;
+    void traceAfterDispatch(Visitor*);
 
 private:
     explicit MutableStylePropertySet(CSSParserMode);
@@ -221,6 +241,8 @@
     OwnPtr<PropertySetCSSStyleDeclaration> m_cssomWrapper;
 
     friend class StylePropertySet;
+
+    WillBeHeapVector<CSSProperty, 4> m_propertyVector;
 };
 
 DEFINE_TYPE_CASTS(MutableStylePropertySet, StylePropertySet, set, set->isMutable(), set.isMutable());
@@ -256,6 +278,7 @@
     return !propertyCount();
 }
 
+#if !ENABLE(OILPAN)
 inline void StylePropertySet::deref()
 {
     if (!derefBase())
@@ -266,6 +289,14 @@
     else
         delete toImmutableStylePropertySet(this);
 }
+#endif // !ENABLE(OILPAN)
+
+inline int StylePropertySet::findPropertyIndex(CSSPropertyID propertyID) const
+{
+    if (m_isMutable)
+        return toMutableStylePropertySet(this)->findPropertyIndex(propertyID);
+    return toImmutableStylePropertySet(this)->findPropertyIndex(propertyID);
+}
 
 } // namespace WebCore
 
diff --git a/Source/core/css/StyleRule.cpp b/Source/core/css/StyleRule.cpp
index 669c523..08e62bd 100644
--- a/Source/core/css/StyleRule.cpp
+++ b/Source/core/css/StyleRule.cpp
@@ -36,22 +36,100 @@
 
 namespace WebCore {
 
-struct SameSizeAsStyleRuleBase : public WTF::RefCountedBase {
+struct SameSizeAsStyleRuleBase : public RefCountedWillBeRefCountedGarbageCollected<SameSizeAsStyleRuleBase> {
     unsigned bitfields;
 };
 
 COMPILE_ASSERT(sizeof(StyleRuleBase) <= sizeof(SameSizeAsStyleRuleBase), StyleRuleBase_should_stay_small);
 
-PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
+PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet) const
 {
     return createCSSOMWrapper(parentSheet, 0);
 }
 
-PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
+PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSRule* parentRule) const
 {
     return createCSSOMWrapper(0, parentRule);
 }
 
+void StyleRuleBase::trace(Visitor* visitor)
+{
+    switch (type()) {
+    case Style:
+        toStyleRule(this)->traceAfterDispatch(visitor);
+        return;
+    case Page:
+        toStyleRulePage(this)->traceAfterDispatch(visitor);
+        return;
+    case FontFace:
+        toStyleRuleFontFace(this)->traceAfterDispatch(visitor);
+        return;
+    case Media:
+        toStyleRuleMedia(this)->traceAfterDispatch(visitor);
+        return;
+    case Supports:
+        toStyleRuleSupports(this)->traceAfterDispatch(visitor);
+        return;
+    case Import:
+        toStyleRuleImport(this)->traceAfterDispatch(visitor);
+        return;
+    case Keyframes:
+        toStyleRuleKeyframes(this)->traceAfterDispatch(visitor);
+        return;
+    case Viewport:
+        toStyleRuleViewport(this)->traceAfterDispatch(visitor);
+        return;
+    case Filter:
+        toStyleRuleFilter(this)->traceAfterDispatch(visitor);
+        return;
+    case Unknown:
+    case Charset:
+    case Keyframe:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    ASSERT_NOT_REACHED();
+}
+
+void StyleRuleBase::finalize()
+{
+    switch (type()) {
+    case Style:
+        toStyleRule(this)->~StyleRule();
+        return;
+    case Page:
+        toStyleRulePage(this)->~StyleRulePage();
+        return;
+    case FontFace:
+        toStyleRuleFontFace(this)->~StyleRuleFontFace();
+        return;
+    case Media:
+        toStyleRuleMedia(this)->~StyleRuleMedia();
+        return;
+    case Supports:
+        toStyleRuleSupports(this)->~StyleRuleSupports();
+        return;
+    case Import:
+        toStyleRuleImport(this)->~StyleRuleImport();
+        return;
+    case Keyframes:
+        toStyleRuleKeyframes(this)->~StyleRuleKeyframes();
+        return;
+    case Viewport:
+        toStyleRuleViewport(this)->~StyleRuleViewport();
+        return;
+    case Filter:
+        toStyleRuleFilter(this)->~StyleRuleFilter();
+        return;
+    case Unknown:
+    case Charset:
+    case Keyframe:
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    ASSERT_NOT_REACHED();
+}
+
 void StyleRuleBase::destroy()
 {
     switch (type()) {
@@ -91,7 +169,7 @@
     ASSERT_NOT_REACHED();
 }
 
-PassRefPtr<StyleRuleBase> StyleRuleBase::copy() const
+PassRefPtrWillBeRawPtr<StyleRuleBase> StyleRuleBase::copy() const
 {
     switch (type()) {
     case Style:
@@ -107,7 +185,7 @@
     case Import:
         // FIXME: Copy import rules.
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     case Keyframes:
         return toStyleRuleKeyframes(this)->copy();
     case Viewport:
@@ -118,15 +196,15 @@
     case Charset:
     case Keyframe:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
-PassRefPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const
+PassRefPtrWillBeRawPtr<CSSRule> StyleRuleBase::createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const
 {
-    RefPtr<CSSRule> rule;
+    RefPtrWillBeRawPtr<CSSRule> rule;
     StyleRuleBase* self = const_cast<StyleRuleBase*>(this);
     switch (type()) {
     case Style:
@@ -160,7 +238,7 @@
     case Charset:
     case Keyframe:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
     if (parentRule)
         rule->setParentRule(parentRule);
@@ -188,11 +266,11 @@
 {
 }
 
-MutableStylePropertySet* StyleRule::mutableProperties()
+MutableStylePropertySet& StyleRule::mutableProperties()
 {
     if (!m_properties->isMutable())
         m_properties = m_properties->mutableCopy();
-    return toMutableStylePropertySet(m_properties);
+    return *toMutableStylePropertySet(m_properties);
 }
 
 void StyleRule::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -216,11 +294,11 @@
 {
 }
 
-MutableStylePropertySet* StyleRulePage::mutableProperties()
+MutableStylePropertySet& StyleRulePage::mutableProperties()
 {
     if (!m_properties->isMutable())
         m_properties = m_properties->mutableCopy();
-    return toMutableStylePropertySet(m_properties);
+    return *toMutableStylePropertySet(m_properties);
 }
 
 void StyleRulePage::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -243,11 +321,11 @@
 {
 }
 
-MutableStylePropertySet* StyleRuleFontFace::mutableProperties()
+MutableStylePropertySet& StyleRuleFontFace::mutableProperties()
 {
     if (!m_properties->isMutable())
         m_properties = m_properties->mutableCopy();
-    return toMutableStylePropertySet(m_properties);
+    return *toMutableStylePropertySet(m_properties);
 }
 
 void StyleRuleFontFace::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -255,7 +333,7 @@
     m_properties = properties;
 }
 
-StyleRuleGroup::StyleRuleGroup(Type type, Vector<RefPtr<StyleRuleBase> >& adoptRule)
+StyleRuleGroup::StyleRuleGroup(Type type, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRule)
     : StyleRuleBase(type)
 {
     m_childRules.swap(adoptRule);
@@ -269,7 +347,7 @@
         m_childRules[i] = o.m_childRules[i]->copy();
 }
 
-void StyleRuleGroup::wrapperInsertRule(unsigned index, PassRefPtr<StyleRuleBase> rule)
+void StyleRuleGroup::wrapperInsertRule(unsigned index, PassRefPtrWillBeRawPtr<StyleRuleBase> rule)
 {
     m_childRules.insert(index, rule);
 }
@@ -279,7 +357,13 @@
     m_childRules.remove(index);
 }
 
-StyleRuleMedia::StyleRuleMedia(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+void StyleRuleGroup::traceAfterDispatch(Visitor* visitor)
+{
+    visitor->trace(m_childRules);
+    StyleRuleBase::traceAfterDispatch(visitor);
+}
+
+StyleRuleMedia::StyleRuleMedia(PassRefPtrWillBeRawPtr<MediaQuerySet> media, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
     : StyleRuleGroup(Media, adoptRules)
     , m_mediaQueries(media)
 {
@@ -292,7 +376,13 @@
         m_mediaQueries = o.m_mediaQueries->copy();
 }
 
-StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+void StyleRuleMedia::traceAfterDispatch(Visitor* visitor)
+{
+    visitor->trace(m_mediaQueries);
+    StyleRuleGroup::traceAfterDispatch(visitor);
+}
+
+StyleRuleSupports::StyleRuleSupports(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
     : StyleRuleGroup(Supports, adoptRules)
     , m_conditionText(conditionText)
     , m_conditionIsSupported(conditionIsSupported)
@@ -321,11 +411,11 @@
 {
 }
 
-MutableStylePropertySet* StyleRuleViewport::mutableProperties()
+MutableStylePropertySet& StyleRuleViewport::mutableProperties()
 {
     if (!m_properties->isMutable())
         m_properties = m_properties->mutableCopy();
-    return toMutableStylePropertySet(m_properties);
+    return *toMutableStylePropertySet(m_properties);
 }
 
 void StyleRuleViewport::setProperties(PassRefPtr<StylePropertySet> properties)
@@ -350,11 +440,11 @@
 {
 }
 
-MutableStylePropertySet* StyleRuleFilter::mutableProperties()
+MutableStylePropertySet& StyleRuleFilter::mutableProperties()
 {
     if (!m_properties->isMutable())
         m_properties = m_properties->mutableCopy();
-    return toMutableStylePropertySet(m_properties);
+    return *toMutableStylePropertySet(m_properties);
 }
 
 void StyleRuleFilter::setProperties(PassRefPtr<StylePropertySet> properties)
diff --git a/Source/core/css/StyleRule.h b/Source/core/css/StyleRule.h
index c868971..12d2e40 100644
--- a/Source/core/css/StyleRule.h
+++ b/Source/core/css/StyleRule.h
@@ -24,6 +24,7 @@
 
 #include "core/css/CSSSelectorList.h"
 #include "core/css/MediaList.h"
+#include "heap/Handle.h"
 #include "wtf/RefPtr.h"
 
 namespace WebCore {
@@ -34,8 +35,8 @@
 class MutableStylePropertySet;
 class StylePropertySet;
 
-class StyleRuleBase : public WTF::RefCountedBase {
-    WTF_MAKE_FAST_ALLOCATED;
+class StyleRuleBase : public RefCountedWillBeGarbageCollectedFinalized<StyleRuleBase> {
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
     enum Type {
         Unknown, // Not used.
@@ -65,149 +66,167 @@
     bool isImportRule() const { return type() == Import; }
     bool isFilterRule() const { return type() == Filter; }
 
-    PassRefPtr<StyleRuleBase> copy() const;
+    PassRefPtrWillBeRawPtr<StyleRuleBase> copy() const;
 
+#if !ENABLE(OILPAN)
     void deref()
     {
         if (derefBase())
             destroy();
     }
+#endif // !ENABLE(OILPAN)
 
     // FIXME: There shouldn't be any need for the null parent version.
-    PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = 0) const;
-    PassRefPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
+    PassRefPtrWillBeRawPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet = 0) const;
+    PassRefPtrWillBeRawPtr<CSSRule> createCSSOMWrapper(CSSRule* parentRule) const;
+
+    void trace(Visitor*);
+    void traceAfterDispatch(Visitor*) { };
+    void finalize();
 
 protected:
     StyleRuleBase(Type type) : m_type(type) { }
-    StyleRuleBase(const StyleRuleBase& o) : WTF::RefCountedBase(), m_type(o.m_type) { }
+    StyleRuleBase(const StyleRuleBase& o) : m_type(o.m_type) { }
 
     ~StyleRuleBase() { }
 
 private:
     void destroy();
 
-    PassRefPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
+    PassRefPtrWillBeRawPtr<CSSRule> createCSSOMWrapper(CSSStyleSheet* parentSheet, CSSRule* parentRule) const;
 
     unsigned m_type : 5;
 };
 
 class StyleRule : public StyleRuleBase {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
-    static PassRefPtr<StyleRule> create() { return adoptRef(new StyleRule()); }
+    static PassRefPtrWillBeRawPtr<StyleRule> create() { return adoptRefWillBeNoop(new StyleRule()); }
 
     ~StyleRule();
 
     const CSSSelectorList& selectorList() const { return m_selectorList; }
-    const StylePropertySet* properties() const { return m_properties.get(); }
-    MutableStylePropertySet* mutableProperties();
+    const StylePropertySet& properties() const { return *m_properties; }
+    MutableStylePropertySet& mutableProperties();
 
     void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); }
     void setProperties(PassRefPtr<StylePropertySet>);
 
-    PassRefPtr<StyleRule> copy() const { return adoptRef(new StyleRule(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRule> copy() const { return adoptRefWillBeNoop(new StyleRule(*this)); }
 
     static unsigned averageSizeInBytes();
 
+    void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
+
 private:
     StyleRule();
     StyleRule(const StyleRule&);
 
-    RefPtr<StylePropertySet> m_properties;
+    RefPtr<StylePropertySet> m_properties; // Cannot be null.
     CSSSelectorList m_selectorList;
 };
 
 class StyleRuleFontFace : public StyleRuleBase {
 public:
-    static PassRefPtr<StyleRuleFontFace> create() { return adoptRef(new StyleRuleFontFace); }
+    static PassRefPtrWillBeRawPtr<StyleRuleFontFace> create() { return adoptRefWillBeNoop(new StyleRuleFontFace); }
 
     ~StyleRuleFontFace();
 
-    const StylePropertySet* properties() const { return m_properties.get(); }
-    MutableStylePropertySet* mutableProperties();
+    const StylePropertySet& properties() const { return *m_properties; }
+    MutableStylePropertySet& mutableProperties();
 
     void setProperties(PassRefPtr<StylePropertySet>);
 
-    PassRefPtr<StyleRuleFontFace> copy() const { return adoptRef(new StyleRuleFontFace(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRuleFontFace> copy() const { return adoptRefWillBeNoop(new StyleRuleFontFace(*this)); }
+
+    void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
 
 private:
     StyleRuleFontFace();
     StyleRuleFontFace(const StyleRuleFontFace&);
 
-    RefPtr<StylePropertySet> m_properties;
+    RefPtr<StylePropertySet> m_properties; // Cannot be null.
 };
 
 class StyleRulePage : public StyleRuleBase {
 public:
-    static PassRefPtr<StyleRulePage> create() { return adoptRef(new StyleRulePage); }
+    static PassRefPtrWillBeRawPtr<StyleRulePage> create() { return adoptRefWillBeNoop(new StyleRulePage); }
 
     ~StyleRulePage();
 
     const CSSSelector* selector() const { return m_selectorList.first(); }
-    const StylePropertySet* properties() const { return m_properties.get(); }
-    MutableStylePropertySet* mutableProperties();
+    const StylePropertySet& properties() const { return *m_properties; }
+    MutableStylePropertySet& mutableProperties();
 
     void parserAdoptSelectorVector(Vector<OwnPtr<CSSParserSelector> >& selectors) { m_selectorList.adoptSelectorVector(selectors); }
     void wrapperAdoptSelectorList(CSSSelectorList& selectors) { m_selectorList.adopt(selectors); }
     void setProperties(PassRefPtr<StylePropertySet>);
 
-    PassRefPtr<StyleRulePage> copy() const { return adoptRef(new StyleRulePage(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRulePage> copy() const { return adoptRefWillBeNoop(new StyleRulePage(*this)); }
+
+    void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
 
 private:
     StyleRulePage();
     StyleRulePage(const StyleRulePage&);
 
-    RefPtr<StylePropertySet> m_properties;
+    RefPtr<StylePropertySet> m_properties; // Cannot be null.
     CSSSelectorList m_selectorList;
 };
 
 class StyleRuleGroup : public StyleRuleBase {
 public:
-    const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& childRules() const { return m_childRules; }
 
-    void wrapperInsertRule(unsigned, PassRefPtr<StyleRuleBase>);
+    void wrapperInsertRule(unsigned, PassRefPtrWillBeRawPtr<StyleRuleBase>);
     void wrapperRemoveRule(unsigned);
 
+    void traceAfterDispatch(Visitor*);
+
 protected:
-    StyleRuleGroup(Type, Vector<RefPtr<StyleRuleBase> >& adoptRule);
+    StyleRuleGroup(Type, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRule);
     StyleRuleGroup(const StyleRuleGroup&);
 
 private:
-    Vector<RefPtr<StyleRuleBase> > m_childRules;
+    WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_childRules;
 };
 
 class StyleRuleMedia : public StyleRuleGroup {
 public:
-    static PassRefPtr<StyleRuleMedia> create(PassRefPtr<MediaQuerySet> media, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+    static PassRefPtrWillBeRawPtr<StyleRuleMedia> create(PassRefPtrWillBeRawPtr<MediaQuerySet> media, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
     {
-        return adoptRef(new StyleRuleMedia(media, adoptRules));
+        return adoptRefWillBeNoop(new StyleRuleMedia(media, adoptRules));
     }
 
     MediaQuerySet* mediaQueries() const { return m_mediaQueries.get(); }
 
-    PassRefPtr<StyleRuleMedia> copy() const { return adoptRef(new StyleRuleMedia(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRuleMedia> copy() const { return adoptRefWillBeNoop(new StyleRuleMedia(*this)); }
+
+    void traceAfterDispatch(Visitor*);
 
 private:
-    StyleRuleMedia(PassRefPtr<MediaQuerySet>, Vector<RefPtr<StyleRuleBase> >& adoptRules);
+    StyleRuleMedia(PassRefPtrWillBeRawPtr<MediaQuerySet>, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules);
     StyleRuleMedia(const StyleRuleMedia&);
 
-    RefPtr<MediaQuerySet> m_mediaQueries;
+    RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
 };
 
 class StyleRuleSupports : public StyleRuleGroup {
 public:
-    static PassRefPtr<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules)
+    static PassRefPtrWillBeRawPtr<StyleRuleSupports> create(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules)
     {
-        return adoptRef(new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
+        return adoptRefWillBeNoop(new StyleRuleSupports(conditionText, conditionIsSupported, adoptRules));
     }
 
     String conditionText() const { return m_conditionText; }
     bool conditionIsSupported() const { return m_conditionIsSupported; }
-    PassRefPtr<StyleRuleSupports> copy() const { return adoptRef(new StyleRuleSupports(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRuleSupports> copy() const { return adoptRefWillBeNoop(new StyleRuleSupports(*this)); }
+
+    void traceAfterDispatch(Visitor* visitor) { StyleRuleGroup::traceAfterDispatch(visitor); }
 
 private:
-    StyleRuleSupports(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase> >& adoptRules);
+    StyleRuleSupports(const String& conditionText, bool conditionIsSupported, WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& adoptRules);
     StyleRuleSupports(const StyleRuleSupports&);
 
     String m_conditionText;
@@ -216,38 +235,42 @@
 
 class StyleRuleViewport : public StyleRuleBase {
 public:
-    static PassRefPtr<StyleRuleViewport> create() { return adoptRef(new StyleRuleViewport); }
+    static PassRefPtrWillBeRawPtr<StyleRuleViewport> create() { return adoptRefWillBeNoop(new StyleRuleViewport); }
 
     ~StyleRuleViewport();
 
-    const StylePropertySet* properties() const { return m_properties.get(); }
-    MutableStylePropertySet* mutableProperties();
+    const StylePropertySet& properties() const { return *m_properties; }
+    MutableStylePropertySet& mutableProperties();
 
     void setProperties(PassRefPtr<StylePropertySet>);
 
-    PassRefPtr<StyleRuleViewport> copy() const { return adoptRef(new StyleRuleViewport(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRuleViewport> copy() const { return adoptRefWillBeNoop(new StyleRuleViewport(*this)); }
+
+    void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
 
 private:
     StyleRuleViewport();
     StyleRuleViewport(const StyleRuleViewport&);
 
-    RefPtr<StylePropertySet> m_properties;
+    RefPtr<StylePropertySet> m_properties; // Cannot be null
 };
 
 class StyleRuleFilter : public StyleRuleBase {
 public:
-    static PassRefPtr<StyleRuleFilter> create(const String& filterName) { return adoptRef(new StyleRuleFilter(filterName)); }
+    static PassRefPtrWillBeRawPtr<StyleRuleFilter> create(const String& filterName) { return adoptRefWillBeNoop(new StyleRuleFilter(filterName)); }
 
     ~StyleRuleFilter();
 
     const String& filterName() const { return m_filterName; }
 
-    const StylePropertySet* properties() const { return m_properties.get(); }
-    MutableStylePropertySet* mutableProperties();
+    const StylePropertySet& properties() const { return *m_properties; }
+    MutableStylePropertySet& mutableProperties();
 
     void setProperties(PassRefPtr<StylePropertySet>);
 
-    PassRefPtr<StyleRuleFilter> copy() const { return adoptRef(new StyleRuleFilter(*this)); }
+    PassRefPtrWillBeRawPtr<StyleRuleFilter> copy() const { return adoptRefWillBeNoop(new StyleRuleFilter(*this)); }
+
+    void traceAfterDispatch(Visitor* visitor) { StyleRuleBase::traceAfterDispatch(visitor); }
 
 private:
     StyleRuleFilter(const String&);
diff --git a/Source/core/css/StyleRuleImport.cpp b/Source/core/css/StyleRuleImport.cpp
index 0c6732a..3a31c70 100644
--- a/Source/core/css/StyleRuleImport.cpp
+++ b/Source/core/css/StyleRuleImport.cpp
@@ -31,14 +31,14 @@
 
 namespace WebCore {
 
-PassRefPtr<StyleRuleImport> StyleRuleImport::create(const String& href, PassRefPtr<MediaQuerySet> media)
+PassRefPtrWillBeRawPtr<StyleRuleImport> StyleRuleImport::create(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
 {
-    return adoptRef(new StyleRuleImport(href, media));
+    return adoptRefWillBeNoop(new StyleRuleImport(href, media));
 }
 
-StyleRuleImport::StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet> media)
+StyleRuleImport::StyleRuleImport(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet> media)
     : StyleRuleBase(Import)
-    , m_parentStyleSheet(0)
+    , m_parentStyleSheet(nullptr)
     , m_styleSheetClient(this)
     , m_strHref(href)
     , m_mediaQueries(media)
@@ -51,12 +51,22 @@
 
 StyleRuleImport::~StyleRuleImport()
 {
+#if !ENABLE(OILPAN)
     if (m_styleSheet)
         m_styleSheet->clearOwnerRule();
+#endif
     if (m_resource)
         m_resource->removeClient(&m_styleSheetClient);
 }
 
+void StyleRuleImport::traceAfterDispatch(Visitor* visitor)
+{
+    visitor->trace(m_parentStyleSheet);
+    visitor->trace(m_mediaQueries);
+    visitor->trace(m_styleSheet);
+    StyleRuleBase::traceAfterDispatch(visitor);
+}
+
 void StyleRuleImport::setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource* cachedStyleSheet)
 {
     if (m_styleSheet)
diff --git a/Source/core/css/StyleRuleImport.h b/Source/core/css/StyleRuleImport.h
index 687ca8a..5b15c26 100644
--- a/Source/core/css/StyleRuleImport.h
+++ b/Source/core/css/StyleRuleImport.h
@@ -25,6 +25,7 @@
 #include "core/css/StyleRule.h"
 #include "core/fetch/ResourcePtr.h"
 #include "core/fetch/StyleSheetResourceClient.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -33,15 +34,15 @@
 class StyleSheetContents;
 
 class StyleRuleImport : public StyleRuleBase {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
-    static PassRefPtr<StyleRuleImport> create(const String& href, PassRefPtr<MediaQuerySet>);
+    static PassRefPtrWillBeRawPtr<StyleRuleImport> create(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet>);
 
     ~StyleRuleImport();
 
     StyleSheetContents* parentStyleSheet() const { return m_parentStyleSheet; }
     void setParentStyleSheet(StyleSheetContents* sheet) { ASSERT(sheet); m_parentStyleSheet = sheet; }
-    void clearParentStyleSheet() { m_parentStyleSheet = 0; }
+    void clearParentStyleSheet() { m_parentStyleSheet = nullptr; }
 
     String href() const { return m_strHref; }
     StyleSheetContents* styleSheet() const { return m_styleSheet.get(); }
@@ -51,7 +52,10 @@
 
     void requestStyleSheet();
 
+    void traceAfterDispatch(Visitor*);
+
 private:
+    // FIXME: inherit from StyleSheetResourceClient directly to eliminate raw back pointer, as there are no space savings in this.
     // NOTE: We put the StyleSheetResourceClient in a member instead of inheriting from it
     // to avoid adding a vptr to StyleRuleImport.
     class ImportedStyleSheetClient FINAL : public StyleSheetResourceClient {
@@ -69,14 +73,14 @@
     void setCSSStyleSheet(const String& href, const KURL& baseURL, const String& charset, const CSSStyleSheetResource*);
     friend class ImportedStyleSheetClient;
 
-    StyleRuleImport(const String& href, PassRefPtr<MediaQuerySet>);
+    StyleRuleImport(const String& href, PassRefPtrWillBeRawPtr<MediaQuerySet>);
 
-    StyleSheetContents* m_parentStyleSheet;
+    RawPtrWillBeMember<StyleSheetContents> m_parentStyleSheet;
 
     ImportedStyleSheetClient m_styleSheetClient;
     String m_strHref;
-    RefPtr<MediaQuerySet> m_mediaQueries;
-    RefPtr<StyleSheetContents> m_styleSheet;
+    RefPtrWillBeMember<MediaQuerySet> m_mediaQueries;
+    RefPtrWillBeMember<StyleSheetContents> m_styleSheet;
     ResourcePtr<CSSStyleSheetResource> m_resource;
     bool m_loading;
 };
diff --git a/Source/core/css/StyleSheet.h b/Source/core/css/StyleSheet.h
index 2207b5a..e92a7d6 100644
--- a/Source/core/css/StyleSheet.h
+++ b/Source/core/css/StyleSheet.h
@@ -22,6 +22,7 @@
 #define StyleSheet_h
 
 #include "core/css/CSSParserMode.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 
@@ -33,7 +34,7 @@
 class Node;
 class StyleSheet;
 
-class StyleSheet : public RefCounted<StyleSheet> {
+class StyleSheet : public RefCountedWillBeRefCountedGarbageCollected<StyleSheet> {
 public:
     virtual ~StyleSheet();
 
@@ -51,6 +52,8 @@
     virtual KURL baseURL() const = 0;
     virtual bool isLoading() const = 0;
     virtual bool isCSSStyleSheet() const { return false; }
+
+    virtual void trace(Visitor*) = 0;
 };
 
 } // namespace
diff --git a/Source/core/css/StyleSheetContents.cpp b/Source/core/css/StyleSheetContents.cpp
index 87e4144..091de77 100644
--- a/Source/core/css/StyleSheetContents.cpp
+++ b/Source/core/css/StyleSheetContents.cpp
@@ -38,8 +38,6 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(StyleSheetContents);
-
 // Rough size estimate for the memory cache.
 unsigned StyleSheetContents::estimatedSizeInBytes() const
 {
@@ -73,7 +71,7 @@
 }
 
 StyleSheetContents::StyleSheetContents(const StyleSheetContents& o)
-    : m_ownerRule(0)
+    : m_ownerRule(nullptr)
     , m_originalURL(o.m_originalURL)
     , m_encodingFromCharsetRule(o.m_encodingFromCharsetRule)
     , m_importRules(o.m_importRules.size())
@@ -99,8 +97,10 @@
 
 StyleSheetContents::~StyleSheetContents()
 {
+#if !ENABLE(OILPAN)
     StyleEngine::removeSheet(this);
     clearRules();
+#endif
 }
 
 void StyleSheetContents::setHasSyntacticallyValidCSSHeader(bool isValidCss)
@@ -145,7 +145,7 @@
     return maybeCacheable();
 }
 
-void StyleSheetContents::parserAppendRule(PassRefPtr<StyleRuleBase> rule)
+void StyleSheetContents::parserAppendRule(PassRefPtrWillBeRawPtr<StyleRuleBase> rule)
 {
     ASSERT(!rule->isCharsetRule());
     if (rule->isImportRule()) {
@@ -225,7 +225,7 @@
     m_encodingFromCharsetRule = encoding;
 }
 
-bool StyleSheetContents::wrapperInsertRule(PassRefPtr<StyleRuleBase> rule, unsigned index)
+bool StyleSheetContents::wrapperInsertRule(PassRefPtrWillBeRawPtr<StyleRuleBase> rule, unsigned index)
 {
     ASSERT(m_isMutable);
     ASSERT_WITH_SECURITY_IMPLICATION(index <= ruleCount());
@@ -374,11 +374,7 @@
         return parentSheet->loadCompleted();
 
     StyleSheetContents* root = rootStyleSheet();
-    for (unsigned i = 0; i < root->m_clients.size(); ++i) {
-        if (!root->m_clients[i]->loadCompleted())
-            return false;
-    }
-    return true;
+    return root->m_loadingClients.isEmpty();
 }
 
 void StyleSheetContents::checkLoaded()
@@ -389,7 +385,7 @@
     // Avoid |this| being deleted by scripts that run via
     // ScriptableDocumentParser::executeScriptsWaitingForResources().
     // See https://bugs.webkit.org/show_bug.cgi?id=95106
-    RefPtr<StyleSheetContents> protect(this);
+    RefPtrWillBeRawPtr<StyleSheetContents> protect(this);
 
     StyleSheetContents* parentSheet = parentStyleSheet();
     if (parentSheet) {
@@ -398,21 +394,29 @@
     }
 
     StyleSheetContents* root = rootStyleSheet();
-    if (root->m_clients.isEmpty())
+    if (root->m_loadingClients.isEmpty())
         return;
 
-    Vector<CSSStyleSheet*> clients(root->m_clients);
-    for (unsigned i = 0; i < clients.size(); ++i) {
-        // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via
-        // ScriptableDocumentParser::executeScriptsWaitingForResources().
-        RefPtr<CSSStyleSheet> protectClient(clients[i]);
+    // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via
+    // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also protect
+    // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoaded|
+    // method.
+    //
+    // When a sheet is loaded it is moved from the set of loading clients
+    // to the set of completed clients. We therefore need the copy in order to
+    // not modify the set while iterating it.
+    WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > loadingClients;
+    copyToVector(m_loadingClients, loadingClients);
 
-        if (clients[i]->loadCompleted())
+    for (unsigned i = 0; i < loadingClients.size(); ++i) {
+        if (loadingClients[i]->loadCompleted())
             continue;
 
-        RefPtr<Node> ownerNode = clients[i]->ownerNode();
-        if (clients[i]->sheetLoaded())
-            ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
+        // sheetLoaded might be invoked after its owner node is removed from document.
+        if (RefPtr<Node> ownerNode = loadingClients[i]->ownerNode()) {
+            if (loadingClients[i]->sheetLoaded())
+                ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoadErrorOccur);
+        }
     }
 }
 
@@ -429,8 +433,17 @@
 void StyleSheetContents::startLoadingDynamicSheet()
 {
     StyleSheetContents* root = rootStyleSheet();
-    for (unsigned i = 0; i < root->m_clients.size(); ++i)
-        root->m_clients[i]->startLoadingDynamicSheet();
+    for (ClientsIterator it = root->m_loadingClients.begin(); it != root->m_loadingClients.end(); ++it)
+        (*it)->startLoadingDynamicSheet();
+    // Copy the completed clients to a vector for iteration.
+    // startLoadingDynamicSheet will move the style sheet from the
+    // completed state to the loading state which modifies the set of
+    // completed clients. We therefore need the copy in order to not
+    // modify the set of completed clients while iterating it.
+    WillBeHeapVector<RawPtrWillBeMember<CSSStyleSheet> > completedClients;
+    copyToVector(root->m_completedClients, completedClients);
+    for (unsigned i = 0; i < completedClients.size(); ++i)
+        completedClients[i]->startLoadingDynamicSheet();
 }
 
 StyleSheetContents* StyleSheetContents::rootStyleSheet() const
@@ -443,19 +456,17 @@
 
 bool StyleSheetContents::hasSingleOwnerNode() const
 {
-    StyleSheetContents* root = rootStyleSheet();
-    if (root->m_clients.isEmpty())
-        return false;
-    return root->m_clients.size() == 1;
+    return rootStyleSheet()->hasOneClient();
 }
 
 Node* StyleSheetContents::singleOwnerNode() const
 {
     StyleSheetContents* root = rootStyleSheet();
-    if (root->m_clients.isEmpty())
+    if (!root->hasOneClient())
         return 0;
-    ASSERT(root->m_clients.size() == 1);
-    return root->m_clients[0]->ownerNode();
+    if (root->m_loadingClients.size())
+        return (*root->m_loadingClients.begin())->ownerNode();
+    return (*root->m_completedClients.begin())->ownerNode();
 }
 
 Document* StyleSheetContents::singleOwnerDocument() const
@@ -470,17 +481,17 @@
     return m_parserContext.completeURL(url);
 }
 
-static bool childRulesHaveFailedOrCanceledSubresources(const Vector<RefPtr<StyleRuleBase> >& rules)
+static bool childRulesHaveFailedOrCanceledSubresources(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules)
 {
     for (unsigned i = 0; i < rules.size(); ++i) {
         const StyleRuleBase* rule = rules[i].get();
         switch (rule->type()) {
         case StyleRuleBase::Style:
-            if (toStyleRule(rule)->properties()->hasFailedOrCanceledSubresources())
+            if (toStyleRule(rule)->properties().hasFailedOrCanceledSubresources())
                 return true;
             break;
         case StyleRuleBase::FontFace:
-            if (toStyleRuleFontFace(rule)->properties()->hasFailedOrCanceledSubresources())
+            if (toStyleRuleFontFace(rule)->properties().hasFailedOrCanceledSubresources())
                 return true;
             break;
         case StyleRuleBase::Media:
@@ -516,15 +527,29 @@
 
 void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
 {
-    ASSERT(!m_clients.contains(sheet));
-    m_clients.append(sheet);
+    ASSERT(!m_loadingClients.contains(sheet) && !m_completedClients.contains(sheet));
+    m_loadingClients.add(sheet);
 }
 
 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet)
 {
-    size_t position = m_clients.find(sheet);
-    ASSERT(position != kNotFound);
-    m_clients.remove(position);
+    ASSERT(m_loadingClients.contains(sheet) || m_completedClients.contains(sheet));
+    m_loadingClients.remove(sheet);
+    m_completedClients.remove(sheet);
+}
+
+void StyleSheetContents::clientLoadCompleted(CSSStyleSheet* sheet)
+{
+    ASSERT(m_loadingClients.contains(sheet));
+    m_loadingClients.remove(sheet);
+    m_completedClients.add(sheet);
+}
+
+void StyleSheetContents::clientLoadStarted(CSSStyleSheet* sheet)
+{
+    ASSERT(m_completedClients.contains(sheet));
+    m_completedClients.remove(sheet);
+    m_loadingClients.add(sheet);
 }
 
 void StyleSheetContents::addedToMemoryCache()
@@ -556,6 +581,14 @@
     return *m_ruleSet.get();
 }
 
+static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >& clients)
+{
+    for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) {
+        if (Document* document = (*it)->ownerDocument())
+            document->styleEngine()->clearResolver();
+    }
+}
+
 void StyleSheetContents::clearRuleSet()
 {
     if (StyleSheetContents* parentSheet = parentStyleSheet())
@@ -569,24 +602,27 @@
 
     // Clearing the ruleSet means we need to recreate the styleResolver data structures.
     // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet.
-    for (size_t i = 0; i < m_clients.size(); ++i) {
-        if (Document* document = m_clients[i]->ownerDocument())
-            document->styleEngine()->clearResolver();
-    }
+    clearResolvers(m_loadingClients);
+    clearResolvers(m_completedClients);
     m_ruleSet.clear();
 }
 
+static void removeFontFaceRules(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >& clients, const StyleRuleFontFace* fontFaceRule)
+{
+    for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) {
+        if (Node* ownerNode = (*it)->ownerNode())
+            ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule));
+    }
+}
+
 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontFaceRule)
 {
     StyleSheetContents* root = rootStyleSheet();
-
-    for (unsigned i = 0; i < root->m_clients.size(); ++i) {
-        if (Node* ownerNode = root->m_clients[0]->ownerNode())
-            ownerNode->document().styleEngine()->removeFontFaceRules(Vector<const StyleRuleFontFace*>(1, fontFaceRule));
-    }
+    removeFontFaceRules(root->m_loadingClients, fontFaceRule);
+    removeFontFaceRules(root->m_completedClients, fontFaceRule);
 }
 
-static void findFontFaceRulesFromRules(const Vector<RefPtr<StyleRuleBase> >& rules, Vector<const StyleRuleFontFace*>& fontFaceRules)
+static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
 {
     for (unsigned i = 0; i < rules.size(); ++i) {
         StyleRuleBase* rule = rules[i].get();
@@ -602,7 +638,7 @@
     }
 }
 
-void StyleSheetContents::findFontFaceRules(Vector<const StyleRuleFontFace*>& fontFaceRules)
+void StyleSheetContents::findFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
 {
     for (unsigned i = 0; i < m_importRules.size(); ++i) {
         if (!m_importRules[i]->styleSheet())
@@ -613,8 +649,14 @@
     findFontFaceRulesFromRules(childRules(), fontFaceRules);
 }
 
-void StyleSheetContents::trace(Visitor*)
+void StyleSheetContents::trace(Visitor* visitor)
 {
+    visitor->trace(m_ownerRule);
+    visitor->trace(m_importRules);
+    visitor->trace(m_childRules);
+    visitor->trace(m_loadingClients);
+    visitor->trace(m_completedClients);
+    visitor->trace(m_ruleSet);
 }
 
 }
diff --git a/Source/core/css/StyleSheetContents.h b/Source/core/css/StyleSheetContents.h
index b71d392..8090f8e 100644
--- a/Source/core/css/StyleSheetContents.h
+++ b/Source/core/css/StyleSheetContents.h
@@ -23,6 +23,7 @@
 
 #include "core/css/CSSParserMode.h"
 #include "core/css/RuleSet.h"
+#include "heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/HashMap.h"
 #include "wtf/ListHashSet.h"
@@ -44,20 +45,19 @@
 class StyleRuleFontFace;
 class StyleRuleImport;
 
-class StyleSheetContents : public RefCountedWillBeRefCountedGarbageCollected<StyleSheetContents> {
-    DECLARE_GC_INFO
+class StyleSheetContents : public RefCountedWillBeGarbageCollectedFinalized<StyleSheetContents> {
 public:
     static PassRefPtrWillBeRawPtr<StyleSheetContents> create(const CSSParserContext& context)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new StyleSheetContents(0, String(), context));
+        return adoptRefWillBeNoop(new StyleSheetContents(0, String(), context));
     }
     static PassRefPtrWillBeRawPtr<StyleSheetContents> create(const String& originalURL, const CSSParserContext& context)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new StyleSheetContents(0, originalURL, context));
+        return adoptRefWillBeNoop(new StyleSheetContents(0, originalURL, context));
     }
     static PassRefPtrWillBeRawPtr<StyleSheetContents> create(StyleRuleImport* ownerRule, const String& originalURL, const CSSParserContext& context)
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new StyleSheetContents(ownerRule, originalURL, context));
+        return adoptRefWillBeNoop(new StyleSheetContents(ownerRule, originalURL, context));
     }
 
     ~StyleSheetContents();
@@ -95,10 +95,10 @@
 
     void setHasFontFaceRule(bool b) { m_hasFontFaceRule = b; }
     bool hasFontFaceRule() const { return m_hasFontFaceRule; }
-    void findFontFaceRules(Vector<const StyleRuleFontFace*>& fontFaceRules);
+    void findFontFaceRules(WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules);
 
     void parserAddNamespace(const AtomicString& prefix, const AtomicString& uri);
-    void parserAppendRule(PassRefPtr<StyleRuleBase>);
+    void parserAppendRule(PassRefPtrWillBeRawPtr<StyleRuleBase>);
     void parserSetEncodingFromCharsetRule(const String& encoding);
     void parserSetUsesRemUnits(bool b) { m_usesRemUnits = b; }
 
@@ -107,14 +107,14 @@
     bool hasCharsetRule() const { return !m_encodingFromCharsetRule.isNull(); }
     String encodingFromCharsetRule() const { return m_encodingFromCharsetRule; }
     // Rules other than @charset and @import.
-    const Vector<RefPtr<StyleRuleBase> >& childRules() const { return m_childRules; }
-    const Vector<RefPtr<StyleRuleImport> >& importRules() const { return m_importRules; }
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> >& childRules() const { return m_childRules; }
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> >& importRules() const { return m_importRules; }
 
     void notifyLoadedSheet(const CSSStyleSheetResource*);
 
     StyleSheetContents* parentStyleSheet() const;
     StyleRuleImport* ownerRule() const { return m_ownerRule; }
-    void clearOwnerRule() { m_ownerRule = 0; }
+    void clearOwnerRule() { m_ownerRule = nullptr; }
 
     // Note that href is the URL that started the redirect chain that led to
     // this style sheet. This property probably isn't useful for much except
@@ -129,14 +129,19 @@
 
     unsigned estimatedSizeInBytes() const;
 
-    bool wrapperInsertRule(PassRefPtr<StyleRuleBase>, unsigned index);
+    bool wrapperInsertRule(PassRefPtrWillBeRawPtr<StyleRuleBase>, unsigned index);
     void wrapperDeleteRule(unsigned index);
 
-    PassRefPtr<StyleSheetContents> copy() const { return adoptRef(new StyleSheetContents(*this)); }
+    PassRefPtrWillBeRawPtr<StyleSheetContents> copy() const
+    {
+        return adoptRefWillBeNoop(new StyleSheetContents(*this));
+    }
 
     void registerClient(CSSStyleSheet*);
     void unregisterClient(CSSStyleSheet*);
-    bool hasOneClient() { return m_clients.size() == 1; }
+    bool hasOneClient() { return (m_loadingClients.size() + m_completedClients.size()) == 1; }
+    void clientLoadCompleted(CSSStyleSheet*);
+    void clientLoadStarted(CSSStyleSheet*);
 
     bool isMutable() const { return m_isMutable; }
     void setMutable() { m_isMutable = true; }
@@ -162,13 +167,13 @@
 
     void clearCharsetRule();
 
-    StyleRuleImport* m_ownerRule;
+    RawPtrWillBeMember<StyleRuleImport> m_ownerRule;
 
     String m_originalURL;
 
     String m_encodingFromCharsetRule;
-    Vector<RefPtr<StyleRuleImport> > m_importRules;
-    Vector<RefPtr<StyleRuleBase> > m_childRules;
+    WillBeHeapVector<RefPtrWillBeMember<StyleRuleImport> > m_importRules;
+    WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_childRules;
     typedef HashMap<AtomicString, AtomicString> PrefixNamespaceURIMap;
     PrefixNamespaceURIMap m_namespaces;
 
@@ -182,8 +187,11 @@
 
     CSSParserContext m_parserContext;
 
-    Vector<CSSStyleSheet*> m_clients;
-    OwnPtr<RuleSet> m_ruleSet;
+    WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> > m_loadingClients;
+    WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> > m_completedClients;
+    typedef WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator ClientsIterator;
+
+    OwnPtrWillBeMember<RuleSet> m_ruleSet;
 };
 
 } // namespace
diff --git a/Source/core/css/StyleSheetList.cpp b/Source/core/css/StyleSheetList.cpp
index 10f5905..d05babe 100644
--- a/Source/core/css/StyleSheetList.cpp
+++ b/Source/core/css/StyleSheetList.cpp
@@ -40,7 +40,7 @@
 {
 }
 
-inline const Vector<RefPtr<StyleSheet> >& StyleSheetList::styleSheets()
+inline const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& StyleSheetList::styleSheets()
 {
     if (!m_treeScope)
         return m_detachedStyleSheets;
@@ -60,7 +60,7 @@
 
 StyleSheet* StyleSheetList::item(unsigned index)
 {
-    const Vector<RefPtr<StyleSheet> >& sheets = styleSheets();
+    const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheets = styleSheets();
     return index < sheets.size() ? sheets[index].get() : 0;
 }
 
@@ -76,9 +76,7 @@
     // But unicity of stylesheet ids is good practice anyway ;)
     // FIXME: We should figure out if we should change this or fix the spec.
     Element* element = m_treeScope->getElementById(name);
-    if (element && element->hasTagName(styleTag))
-        return toHTMLStyleElement(element);
-    return 0;
+    return isHTMLStyleElement(element) ? toHTMLStyleElement(element) : 0;
 }
 
 CSSStyleSheet* StyleSheetList::anonymousNamedGetter(const AtomicString& name)
@@ -89,4 +87,9 @@
     return item->sheet();
 }
 
+void StyleSheetList::trace(Visitor* visitor)
+{
+    visitor->trace(m_detachedStyleSheets);
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/StyleSheetList.h b/Source/core/css/StyleSheetList.h
index 9750565..5786cfa 100644
--- a/Source/core/css/StyleSheetList.h
+++ b/Source/core/css/StyleSheetList.h
@@ -33,9 +33,9 @@
 class HTMLStyleElement;
 class StyleSheet;
 
-class StyleSheetList : public RefCounted<StyleSheetList> {
+class StyleSheetList : public RefCountedWillBeGarbageCollectedFinalized<StyleSheetList> {
 public:
-    static PassRefPtr<StyleSheetList> create(TreeScope* treeScope) { return adoptRef(new StyleSheetList(treeScope)); }
+    static PassRefPtrWillBeRawPtr<StyleSheetList> create(TreeScope* treeScope) { return adoptRefWillBeNoop(new StyleSheetList(treeScope)); }
     ~StyleSheetList();
 
     unsigned length();
@@ -43,18 +43,19 @@
 
     HTMLStyleElement* getNamedItem(const AtomicString&) const;
 
-    // FIXME: Should return a reference.
-    Document* document() { return &m_treeScope->document(); }
+    Document* document() { return m_treeScope ? &m_treeScope->document() : 0; }
 
     void detachFromDocument();
     CSSStyleSheet* anonymousNamedGetter(const AtomicString&);
 
+    void trace(Visitor*);
+
 private:
     StyleSheetList(TreeScope*);
-    const Vector<RefPtr<StyleSheet> >& styleSheets();
+    const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheets();
 
     TreeScope* m_treeScope;
-    Vector<RefPtr<StyleSheet> > m_detachedStyleSheets;
+    WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > m_detachedStyleSheets;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/StyleSheetList.idl b/Source/core/css/StyleSheetList.idl
index 104a387..3da2d91 100644
--- a/Source/core/css/StyleSheetList.idl
+++ b/Source/core/css/StyleSheetList.idl
@@ -21,6 +21,7 @@
 // Introduced in DOM Level 2:
 [
     SetWrapperReferenceFrom=document,
+    WillBeGarbageCollected
 ] interface StyleSheetList {
     readonly attribute unsigned long length;
     getter StyleSheet item(unsigned long index);
diff --git a/Source/core/css/TreeBoundaryCrossingRules.cpp b/Source/core/css/TreeBoundaryCrossingRules.cpp
index 30a5604..4184d9f 100644
--- a/Source/core/css/TreeBoundaryCrossingRules.cpp
+++ b/Source/core/css/TreeBoundaryCrossingRules.cpp
@@ -39,7 +39,7 @@
     if (m_treeBoundaryCrossingRuleSetMap.contains(scopingNode)) {
         m_treeBoundaryCrossingRuleSetMap.get(scopingNode)->addRule(rule, selectorIndex, addRuleFlags);
     } else {
-        OwnPtr<RuleSet> ruleSetForScope = RuleSet::create();
+        OwnPtrWillBeRawPtr<RuleSet> ruleSetForScope = RuleSet::create();
         ruleSetForScope->addRule(rule, selectorIndex, addRuleFlags);
         m_treeBoundaryCrossingRuleSetMap.add(scopingNode, ruleSetForScope.release());
         m_scopingNodes.add(scopingNode);
diff --git a/Source/core/css/TreeBoundaryCrossingRules.h b/Source/core/css/TreeBoundaryCrossingRules.h
index 9c7be24..9e391e2 100644
--- a/Source/core/css/TreeBoundaryCrossingRules.h
+++ b/Source/core/css/TreeBoundaryCrossingRules.h
@@ -50,7 +50,7 @@
 
 private:
     DocumentOrderedList m_scopingNodes;
-    typedef HashMap<const ContainerNode*, OwnPtr<RuleSet> > TreeBoundaryCrossingRuleSetMap;
+    typedef WillBePersistentHeapHashMap<const ContainerNode*, OwnPtrWillBeMember<RuleSet> > TreeBoundaryCrossingRuleSetMap;
     TreeBoundaryCrossingRuleSetMap m_treeBoundaryCrossingRuleSetMap;
 };
 
diff --git a/Source/core/css/WebKitCSSMatrix.idl b/Source/core/css/WebKitCSSMatrix.idl
index 0016fcf..18f93ed 100644
--- a/Source/core/css/WebKitCSSMatrix.idl
+++ b/Source/core/css/WebKitCSSMatrix.idl
@@ -27,7 +27,8 @@
 [
     Constructor([Default=NullString] optional DOMString cssValue),
     ImplementedAs=CSSMatrix,
-    RaisesException=Constructor
+    RaisesException=Constructor,
+    WillBeGarbageCollected
 ] interface WebKitCSSMatrix {
 
     // These attributes are simple aliases for certain elements of the 4x4 matrix
diff --git a/Source/core/css/analyzer/DescendantInvalidationSet.cpp b/Source/core/css/analyzer/DescendantInvalidationSet.cpp
index e4c04af..5dd11f9 100644
--- a/Source/core/css/analyzer/DescendantInvalidationSet.cpp
+++ b/Source/core/css/analyzer/DescendantInvalidationSet.cpp
@@ -43,43 +43,93 @@
 
 void DescendantInvalidationSet::combine(const DescendantInvalidationSet& other)
 {
-    m_allDescendantsMightBeInvalid = m_allDescendantsMightBeInvalid || other.m_allDescendantsMightBeInvalid;
     // No longer bother combining data structures, since the whole subtree is deemed invalid.
-    if (m_allDescendantsMightBeInvalid)
+    if (wholeSubtreeInvalid())
         return;
 
-    HashSet<AtomicString>::const_iterator end = other.m_classes.end();
-    for (HashSet<AtomicString>::const_iterator it = other.m_classes.begin(); it != end; ++it)
-        addClass(*it);
+    if (other.wholeSubtreeInvalid()) {
+        setWholeSubtreeInvalid();
+        return;
+    }
 
-    end = other.m_ids.end();
-    for (HashSet<AtomicString>::const_iterator it = other.m_ids.begin(); it != end; ++it)
-        addId(*it);
+    if (other.m_classes) {
+        HashSet<AtomicString>::const_iterator end = other.m_classes->end();
+        for (HashSet<AtomicString>::const_iterator it = other.m_classes->begin(); it != end; ++it)
+            addClass(*it);
+    }
 
-    end = other.m_tagNames.end();
-    for (HashSet<AtomicString>::const_iterator it = other.m_tagNames.begin(); it != end; ++it)
-        addTagName(*it);
+    if (other.m_ids) {
+        HashSet<AtomicString>::const_iterator end = other.m_ids->end();
+        for (HashSet<AtomicString>::const_iterator it = other.m_ids->begin(); it != end; ++it)
+            addId(*it);
+    }
+
+    if (other.m_tagNames) {
+        HashSet<AtomicString>::const_iterator end = other.m_tagNames->end();
+        for (HashSet<AtomicString>::const_iterator it = other.m_tagNames->begin(); it != end; ++it)
+            addTagName(*it);
+    }
+}
+
+HashSet<AtomicString>& DescendantInvalidationSet::ensureClassSet()
+{
+    if (!m_classes)
+        m_classes = adoptPtr(new HashSet<AtomicString>);
+    return *m_classes;
+}
+
+HashSet<AtomicString>& DescendantInvalidationSet::ensureIdSet()
+{
+    if (!m_ids)
+        m_ids = adoptPtr(new HashSet<AtomicString>);
+    return *m_ids;
+}
+
+HashSet<AtomicString>& DescendantInvalidationSet::ensureTagNameSet()
+{
+    if (!m_tagNames)
+        m_tagNames = adoptPtr(new HashSet<AtomicString>);
+    return *m_tagNames;
 }
 
 void DescendantInvalidationSet::addClass(const AtomicString& className)
 {
-    m_classes.add(className);
+    if (wholeSubtreeInvalid())
+        return;
+    ensureClassSet().add(className);
 }
 
 void DescendantInvalidationSet::addId(const AtomicString& id)
 {
-    m_ids.add(id);
+    if (wholeSubtreeInvalid())
+        return;
+    ensureIdSet().add(id);
 }
 
 void DescendantInvalidationSet::addTagName(const AtomicString& tagName)
 {
-    m_tagNames.add(tagName);
+    if (wholeSubtreeInvalid())
+        return;
+    ensureTagNameSet().add(tagName);
 }
 
-void DescendantInvalidationSet::getClasses(Vector<AtomicString>& classes)
+void DescendantInvalidationSet::getClasses(Vector<AtomicString>& classes) const
 {
-    for (HashSet<AtomicString>::const_iterator it = m_classes.begin(); it != m_classes.end(); ++it)
+    if (!m_classes)
+        return;
+    for (HashSet<AtomicString>::const_iterator it = m_classes->begin(); it != m_classes->end(); ++it)
         classes.append(*it);
 }
 
+void DescendantInvalidationSet::setWholeSubtreeInvalid()
+{
+    if (m_allDescendantsMightBeInvalid)
+        return;
+
+    m_allDescendantsMightBeInvalid = true;
+    m_classes = nullptr;
+    m_ids = nullptr;
+    m_tagNames = nullptr;
+}
+
 } // namespace WebCore
diff --git a/Source/core/css/analyzer/DescendantInvalidationSet.h b/Source/core/css/analyzer/DescendantInvalidationSet.h
index 38e58b7..ce83b85 100644
--- a/Source/core/css/analyzer/DescendantInvalidationSet.h
+++ b/Source/core/css/analyzer/DescendantInvalidationSet.h
@@ -58,21 +58,24 @@
     void addTagName(const AtomicString& tagName);
 
     // Appends the classes in this DescendantInvalidationSet to the vector.
-    void getClasses(Vector<AtomicString>& classes);
+    void getClasses(Vector<AtomicString>& classes) const;
 
-    void setWholeSubtreeInvalid() { m_allDescendantsMightBeInvalid = true; };
-    bool wholeSubtreeInvalid() { return m_allDescendantsMightBeInvalid; }
+    void setWholeSubtreeInvalid();
+    bool wholeSubtreeInvalid() const { return m_allDescendantsMightBeInvalid; }
 private:
     DescendantInvalidationSet();
 
-    bool invalidateElementSubtreeInternal(Element*);
+    HashSet<AtomicString>& ensureClassSet();
+    HashSet<AtomicString>& ensureIdSet();
+    HashSet<AtomicString>& ensureTagNameSet();
+
     // If true, all descendants might be invalidated, so a full subtree recalc is required.
     bool m_allDescendantsMightBeInvalid;
 
     // FIXME: optimize this if it becomes a memory issue.
-    HashSet<AtomicString> m_classes;
-    HashSet<AtomicString> m_ids;
-    HashSet<AtomicString> m_tagNames;
+    OwnPtr<HashSet<AtomicString> > m_classes;
+    OwnPtr<HashSet<AtomicString> > m_ids;
+    OwnPtr<HashSet<AtomicString> > m_tagNames;
 };
 
 } // namespace WebCore
diff --git a/Source/core/css/analyzer/DescendantInvalidationSetTest.cpp b/Source/core/css/analyzer/DescendantInvalidationSetTest.cpp
new file mode 100644
index 0000000..fb2e480
--- /dev/null
+++ b/Source/core/css/analyzer/DescendantInvalidationSetTest.cpp
@@ -0,0 +1,76 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/analyzer/DescendantInvalidationSet.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+// Once we setWholeSubtreeInvalid, we should not keep the HashSets.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_AddBefore)
+{
+    RefPtr<DescendantInvalidationSet> set = DescendantInvalidationSet::create();
+    set->addClass("a");
+    set->setWholeSubtreeInvalid();
+
+    Vector<AtomicString> classes;
+    set->getClasses(classes);
+
+    ASSERT_TRUE(classes.isEmpty());
+}
+
+// Don't (re)create HashSets if we've already setWholeSubtreeInvalid.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_AddAfter)
+{
+    RefPtr<DescendantInvalidationSet> set = DescendantInvalidationSet::create();
+    set->setWholeSubtreeInvalid();
+    set->addClass("a");
+
+    Vector<AtomicString> classes;
+    set->getClasses(classes);
+
+    ASSERT_TRUE(classes.isEmpty());
+}
+
+// No need to keep the HashSets when combining with a wholeSubtreeInvalid set.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_Combine_1)
+{
+    RefPtr<DescendantInvalidationSet> set1 = DescendantInvalidationSet::create();
+    RefPtr<DescendantInvalidationSet> set2 = DescendantInvalidationSet::create();
+
+    set1->addClass("a");
+    set2->setWholeSubtreeInvalid();
+
+    set1->combine(*set2);
+
+    Vector<AtomicString> classes;
+    set1->getClasses(classes);
+
+    ASSERT_TRUE(set1->wholeSubtreeInvalid());
+    ASSERT_TRUE(classes.isEmpty());
+}
+
+// No need to add HashSets from combining set when we already have wholeSubtreeInvalid.
+TEST(DescendantInvalidationSetTest, SubtreeInvalid_Combine_2)
+{
+    RefPtr<DescendantInvalidationSet> set1 = DescendantInvalidationSet::create();
+    RefPtr<DescendantInvalidationSet> set2 = DescendantInvalidationSet::create();
+
+    set1->setWholeSubtreeInvalid();
+    set2->addClass("a");
+
+    set1->combine(*set2);
+
+    Vector<AtomicString> classes;
+    set1->getClasses(classes);
+
+    ASSERT_TRUE(set1->wholeSubtreeInvalid());
+    ASSERT_TRUE(classes.isEmpty());
+}
+
+} // namespace
diff --git a/Source/core/css/html.css b/Source/core/css/html.css
index df9dd1e..bea688b 100644
--- a/Source/core/css/html.css
+++ b/Source/core/css/html.css
@@ -390,11 +390,11 @@
 }
 
 /* Form controls don't go vertical. */
-input, textarea, keygen, select, button, isindex, meter, progress {
+input, textarea, keygen, select, button, meter, progress {
     -webkit-writing-mode: horizontal-tb !important;
 }
 
-input, textarea, keygen, select, button, isindex {
+input, textarea, keygen, select, button {
     margin: 0__qem;
     font: -webkit-small-control;
     color: initial;
@@ -412,7 +412,7 @@
     display: none
 }
 
-input, input[type="password"], input[type="search"], isindex {
+input, input[type="password"], input[type="search"] {
     -webkit-appearance: textfield;
     padding: 1px;
     background-color: white;
@@ -662,7 +662,7 @@
     pointer-events: none !important;
 }
 
-input::-webkit-input-placeholder, isindex::-webkit-input-placeholder {
+input::-webkit-input-placeholder {
     white-space: pre;
     word-wrap: normal;
     overflow: hidden;
@@ -771,6 +771,10 @@
     border-style: outset
 }
 
+datalist {
+    display: none
+}
+
 area, param {
     display: none
 }
@@ -807,6 +811,21 @@
     -webkit-user-modify: read-only !important;
 }
 
+input[type="color"][list] {
+    -webkit-appearance: menulist;
+    width: 88px;
+    height: 23px
+}
+
+input[type="color"][list]::-webkit-color-swatch-wrapper {
+    padding-left: 8px;
+    padding-right: 24px;
+}
+
+input[type="color"][list]::-webkit-color-swatch {
+    border-color: #000000;
+}
+
 input::-webkit-calendar-picker-indicator {
     display: inline-block;
     width: 0.66em;
@@ -1044,7 +1063,7 @@
     outline: none
 }
   
-input:focus, textarea:focus, isindex:focus, keygen:focus, select:focus {
+input:focus, textarea:focus, keygen:focus, select:focus {
     outline-offset: -2px
 }
 
diff --git a/Source/core/css/mediaControls.css b/Source/core/css/mediaControls.css
index 9aa9d39..eafe386 100644
--- a/Source/core/css/mediaControls.css
+++ b/Source/core/css/mediaControls.css
@@ -115,7 +115,7 @@
     color: inherit;
 }
 
-audio::-webkit-media-controls-overlay-play-button, video::-webkit-media-controls-overlay-play-button {
+audio::-webkit-media-controls-overlay-enclosure, video::-webkit-media-controls-overlay-enclosure {
     display: none;
 }
 
diff --git a/Source/core/css/mediaControlsAndroid.css b/Source/core/css/mediaControlsAndroid.css
index 35a0bb4..73d5adb 100644
--- a/Source/core/css/mediaControlsAndroid.css
+++ b/Source/core/css/mediaControlsAndroid.css
@@ -38,10 +38,6 @@
     height: 40px;
 }
 
-audio::-webkit-media-controls-overlay-enclosure {
-    display: none;
-}
-
 video::-webkit-media-controls-overlay-enclosure {
     display: flex;
     position: relative;
diff --git a/Source/core/css/parser/BisonCSSParser-in.cpp b/Source/core/css/parser/BisonCSSParser-in.cpp
index 6376586..8ab5561 100644
--- a/Source/core/css/parser/BisonCSSParser-in.cpp
+++ b/Source/core/css/parser/BisonCSSParser-in.cpp
@@ -104,84 +104,6 @@
 namespace WebCore {
 
 static const unsigned INVALID_NUM_PARSED_PROPERTIES = UINT_MAX;
-static const double MAX_SCALE = 1000000;
-
-template <unsigned N>
-static bool equal(const CSSParserString& a, const char (&b)[N])
-{
-    unsigned length = N - 1; // Ignore the trailing null character
-    if (a.length() != length)
-        return false;
-
-    return a.is8Bit() ? WTF::equal(a.characters8(), reinterpret_cast<const LChar*>(b), length) : WTF::equal(a.characters16(), reinterpret_cast<const LChar*>(b), length);
-}
-
-template <unsigned N>
-static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N])
-{
-    unsigned length = N - 1; // Ignore the trailing null character
-    if (a.length() != length)
-        return false;
-
-    return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF::equalIgnoringCase(b, a.characters16(), length);
-}
-
-template <unsigned N>
-static bool equalIgnoringCase(CSSParserValue* value, const char (&b)[N])
-{
-    ASSERT(value->unit == CSSPrimitiveValue::CSS_IDENT || value->unit == CSSPrimitiveValue::CSS_STRING);
-    return equalIgnoringCase(value->string, b);
-}
-
-static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveValuePair(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> first, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> second, Pair::IdenticalValuesPolicy identicalValuesPolicy = Pair::DropIdenticalValues)
-{
-    return cssValuePool().createValue(Pair::create(first, second, identicalValuesPolicy));
-}
-
-class AnimationParseContext {
-public:
-    AnimationParseContext()
-        : m_animationPropertyKeywordAllowed(true)
-        , m_firstAnimationCommitted(false)
-        , m_hasSeenAnimationPropertyKeyword(false)
-    {
-    }
-
-    void commitFirstAnimation()
-    {
-        m_firstAnimationCommitted = true;
-    }
-
-    bool hasCommittedFirstAnimation() const
-    {
-        return m_firstAnimationCommitted;
-    }
-
-    void commitAnimationPropertyKeyword()
-    {
-        m_animationPropertyKeywordAllowed = false;
-    }
-
-    bool animationPropertyKeywordAllowed() const
-    {
-        return m_animationPropertyKeywordAllowed;
-    }
-
-    bool hasSeenAnimationPropertyKeyword() const
-    {
-        return m_hasSeenAnimationPropertyKeyword;
-    }
-
-    void sawAnimationPropertyKeyword()
-    {
-        m_hasSeenAnimationPropertyKeyword = true;
-    }
-
-private:
-    bool m_animationPropertyKeywordAllowed;
-    bool m_firstAnimationCommitted;
-    bool m_hasSeenAnimationPropertyKeyword;
-};
 
 BisonCSSParser::BisonCSSParser(const CSSParserContext& context)
     : m_context(context)
@@ -191,9 +113,6 @@
     , m_supportsCondition(false)
     , m_selectorListForParseSelector(0)
     , m_numParsedPropertiesBeforeMarginBox(INVALID_NUM_PARSED_PROPERTIES)
-    , m_inParseShorthand(0)
-    , m_currentShorthand(CSSPropertyInvalid)
-    , m_implicitShorthand(false)
     , m_hasFontFaceOnlyValues(false)
     , m_hadSyntacticallyValidCSSRule(false)
     , m_logErrors(false)
@@ -244,14 +163,14 @@
     cssyyparse(this);
     sheet->shrinkToFit();
     m_source = 0;
-    m_rule = 0;
+    m_rule = nullptr;
     m_lineEndings.clear();
     m_ignoreErrors = false;
     m_logErrors = false;
     m_tokenizer.m_internal = true;
 }
 
-PassRefPtr<StyleRuleBase> BisonCSSParser::parseRule(StyleSheetContents* sheet, const String& string)
+PassRefPtrWillBeRawPtr<StyleRuleBase> BisonCSSParser::parseRule(StyleSheetContents* sheet, const String& string)
 {
     setStyleSheet(sheet);
     m_allowNamespaceDeclarations = false;
@@ -333,14 +252,14 @@
     }
 
     if (validPrimitive) {
-        RefPtr<CSSValue> value = cssValuePool().createIdentifierValue(valueID);
+        RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createIdentifierValue(valueID);
         declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
         return true;
     }
     RGBA32 color;
-    if (!BisonCSSParser::fastParseColor(color, string, !quirksMode && string[0] != '#'))
+    if (!CSSPropertyParser::fastParseColor(color, string, !quirksMode && string[0] != '#'))
         return false;
-    RefPtr<CSSValue> value = cssValuePool().createColorValue(color);
+    RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createColorValue(color);
     declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
     return true;
 }
@@ -439,12 +358,12 @@
     if (number < 0 && !acceptsNegativeNumbers)
         return false;
 
-    RefPtr<CSSValue> value = cssValuePool().createValue(number, unit);
+    RefPtrWillBeRawPtr<CSSValue> value = cssValuePool().createValue(number, unit);
     declaration->addParsedProperty(CSSProperty(propertyId, value.release(), important));
     return true;
 }
 
-static inline bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext& parserContext)
+bool isValidKeywordPropertyAndValue(CSSPropertyID propertyId, int valueID, const CSSParserContext& parserContext)
 {
     if (!valueID)
         return false;
@@ -815,7 +734,7 @@
     return false;
 }
 
-static inline bool isKeywordPropertyID(CSSPropertyID propertyId)
+bool isKeywordPropertyID(CSSPropertyID propertyId)
 {
     switch (propertyId) {
     case CSSPropertyMixBlendMode:
@@ -943,7 +862,7 @@
     if (!valueID)
         return false;
 
-    RefPtr<CSSValue> value;
+    RefPtrWillBeRawPtr<CSSValue> value;
     if (valueID == CSSValueInherit)
         value = cssValuePool().createInheritedValue();
     else if (valueID == CSSValueInitial)
@@ -984,7 +903,7 @@
     static const int shortestValidTransformStringLength = 12;
 
     if (end - pos < shortestValidTransformStringLength)
-        return 0;
+        return nullptr;
 
     if ((pos[0] != 't' && pos[0] != 'T')
         || (pos[1] != 'r' && pos[1] != 'R')
@@ -995,7 +914,7 @@
         || (pos[6] != 'a' && pos[6] != 'A')
         || (pos[7] != 't' && pos[7] != 'T')
         || (pos[8] != 'e' && pos[8] != 'E'))
-        return 0;
+        return nullptr;
 
     CSSTransformValue::TransformOperationType transformType;
     unsigned expectedArgumentCount = 1;
@@ -1015,13 +934,13 @@
         expectedArgumentCount = 3;
         argumentStart = 12;
     } else {
-        return 0;
+        return nullptr;
     }
     pos += argumentStart;
 
     RefPtrWillBeRawPtr<CSSTransformValue> transformValue = CSSTransformValue::create(transformType);
     if (!parseTransformTranslateArguments(pos, end, expectedArgumentCount, transformValue.get()))
-        return 0;
+        return nullptr;
     return transformValue.release();
 }
 
@@ -1034,13 +953,13 @@
             ++pos;
         RefPtrWillBeRawPtr<CSSTransformValue> transformValue = parseTranslateTransformValue(pos, end);
         if (!transformValue)
-            return 0;
+            return nullptr;
         if (!transformList)
             transformList = CSSValueList::createSpaceSeparated();
         transformList->append(transformValue.release());
         if (pos < end) {
             if (isCSSSpace(*pos))
-                return 0;
+                return nullptr;
         }
     }
     return transformList.release();
@@ -1073,25 +992,25 @@
 PassRefPtrWillBeRawPtr<CSSValueList> BisonCSSParser::parseFontFaceValue(const AtomicString& string)
 {
     if (string.isEmpty())
-        return 0;
+        return nullptr;
     RefPtr<MutableStylePropertySet> dummyStyle = MutableStylePropertySet::create();
     if (!parseValue(dummyStyle.get(), CSSPropertyFontFamily, string, false, HTMLQuirksMode, 0))
-        return 0;
+        return nullptr;
 
-    RefPtr<CSSValue> fontFamily = dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily);
+    RefPtrWillBeRawPtr<CSSValue> fontFamily = dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily);
     if (!fontFamily->isValueList())
-        return 0;
+        return nullptr;
 
     return toCSSValueList(dummyStyle->getPropertyCSSValue(CSSPropertyFontFamily).get());
 }
 
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationTimingFunctionValue(const String& string)
+PassRefPtrWillBeRawPtr<CSSValue> BisonCSSParser::parseAnimationTimingFunctionValue(const String& string)
 {
     if (string.isEmpty())
-        return 0;
+        return nullptr;
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
     if (!parseValue(style.get(), CSSPropertyAnimationTimingFunction, string, false, HTMLStandardMode, 0))
-        return 0;
+        return nullptr;
 
     return style->getPropertyCSSValue(CSSPropertyAnimationTimingFunction);
 }
@@ -1155,7 +1074,7 @@
         cssyyparse(this);
     }
 
-    m_rule = 0;
+    m_rule = nullptr;
     m_id = CSSPropertyInvalid;
 
     bool ok = false;
@@ -1175,7 +1094,7 @@
 bool BisonCSSParser::parseColor(RGBA32& color, const String& string, bool strict)
 {
     // First try creating a color specified by name, rgba(), rgb() or "#" syntax.
-    if (fastParseColor(color, string, strict))
+    if (CSSPropertyParser::fastParseColor(color, string, strict))
         return true;
 
     BisonCSSParser parser(strictCSSParserContext());
@@ -1200,26 +1119,17 @@
 {
     setupParser("@-internal-decls color:", string, "");
     cssyyparse(this);
-    m_rule = 0;
+    m_rule = nullptr;
 
     return !m_parsedProperties.isEmpty() && m_parsedProperties.first().id() == CSSPropertyColor;
 }
 
-// FIXME: This is copied from SVGCSSParser.cpp
-static bool isSystemColor(int id)
+bool BisonCSSParser::parseSystemColor(RGBA32& color, const String& string)
 {
-    return (id >= CSSValueActiveborder && id <= CSSValueWindowtext) || id == CSSValueMenu;
-}
-
-bool BisonCSSParser::parseSystemColor(RGBA32& color, const String& string, Document* document)
-{
-    if (!document)
-        return false;
-
     CSSParserString cssColor;
     cssColor.init(string);
     CSSValueID id = cssValueKeywordID(cssColor);
-    if (!isSystemColor(id))
+    if (!CSSPropertyParser::isSystemColor(id))
         return false;
 
     Color parsedColor = RenderTheme::theme().systemColor(id);
@@ -1241,9 +1151,9 @@
 PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseInlineStyleDeclaration(const String& string, Element* element)
 {
     Document& document = element->document();
-    CSSParserContext context = CSSParserContext(document.elementSheet()->contents()->parserContext(), UseCounter::getFrom(&document));
+    CSSParserContext context = CSSParserContext(document.elementSheet().contents()->parserContext(), UseCounter::getFrom(&document));
     context.setMode((element->isHTMLElement() && !document.inQuirksMode()) ? HTMLStandardMode : HTMLQuirksMode);
-    return BisonCSSParser(context).parseDeclaration(string, document.elementSheet()->contents());
+    return BisonCSSParser(context).parseDeclaration(string, document.elementSheet().contents());
 }
 
 PassRefPtr<ImmutableStylePropertySet> BisonCSSParser::parseDeclaration(const String& string, StyleSheetContents* contextStyleSheet)
@@ -1252,7 +1162,7 @@
 
     setupParser("@-internal-decls ", string, "");
     cssyyparse(this);
-    m_rule = 0;
+    m_rule = nullptr;
 
     if (m_hasFontFaceOnlyValues)
         deleteFontFaceOnlyValues();
@@ -1281,7 +1191,7 @@
         cssyyparse(this);
     }
 
-    m_rule = 0;
+    m_rule = nullptr;
 
     bool ok = false;
     if (m_hasFontFaceOnlyValues)
@@ -1298,7 +1208,7 @@
     return ok;
 }
 
-PassRefPtr<MediaQuerySet> BisonCSSParser::parseMediaQueryList(const String& string)
+PassRefPtrWillBeRawPtr<MediaQuerySet> BisonCSSParser::parseMediaQueryList(const String& string)
 {
     ASSERT(!m_mediaList);
 
@@ -1311,7 +1221,7 @@
     return m_mediaList.release();
 }
 
-static inline void filterProperties(bool important, const BisonCSSParser::ParsedPropertyVector& input, Vector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties)
+static inline void filterProperties(bool important, const WillBeHeapVector<CSSProperty, 256>& input, WillBeHeapVector<CSSProperty, 256>& output, size_t& unusedEntries, BitArray<numCSSProperties>& seenProperties)
 {
     // Add properties in reverse order so that highest priority definitions are reached first. Duplicate definitions can then be ignored when found.
     for (int i = input.size() - 1; i >= 0; --i) {
@@ -1330,7 +1240,7 @@
 {
     BitArray<numCSSProperties> seenProperties;
     size_t unusedEntries = m_parsedProperties.size();
-    Vector<CSSProperty, 256> results(unusedEntries);
+    WillBeHeapVector<CSSProperty, 256> results(unusedEntries);
 
     // Important properties have higher priority, so add them first. Duplicate definitions can then be ignored when found.
     filterProperties(true, m_parsedProperties, results, unusedEntries, seenProperties);
@@ -1343,42 +1253,6 @@
     return ImmutableStylePropertySet::create(results.data(), results.size(), mode);
 }
 
-void BisonCSSParser::addPropertyWithPrefixingVariant(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important, bool implicit)
-{
-    RefPtr<CSSValue> val = value.get();
-    addProperty(propId, value, important, implicit);
-
-    CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propId);
-    if (prefixingVariant == propId)
-        return;
-
-    if (m_currentShorthand) {
-        // We can't use ShorthandScope here as we can already be inside one (e.g we are parsing CSSTransition).
-        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
-        addProperty(prefixingVariant, val.release(), important, implicit);
-        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
-    } else {
-        addProperty(prefixingVariant, val.release(), important, implicit);
-    }
-}
-
-void BisonCSSParser::addProperty(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important, bool implicit)
-{
-    // This property doesn't belong to a shorthand.
-    if (!m_currentShorthand) {
-        m_parsedProperties.append(CSSProperty(propId, value, important, false, CSSPropertyInvalid, m_implicitShorthand || implicit));
-        return;
-    }
-
-    Vector<StylePropertyShorthand, 4> shorthands;
-    getMatchingShorthandsForLonghand(propId, &shorthands);
-    // The longhand does not belong to multiple shorthands.
-    if (shorthands.size() == 1)
-        m_parsedProperties.append(CSSProperty(propId, value, important, true, CSSPropertyInvalid, m_implicitShorthand || implicit));
-    else
-        m_parsedProperties.append(CSSProperty(propId, value, important, true, indexOfShorthandForLonghand(m_currentShorthand, shorthands), m_implicitShorthand || implicit));
-}
-
 void BisonCSSParser::rollbackLastProperties(int num)
 {
     ASSERT(num >= 0);
@@ -1393,215 +1267,6 @@
     m_hasFontFaceOnlyValues = false;
 }
 
-KURL BisonCSSParser::completeURL(const String& url) const
-{
-    return m_context.completeURL(url);
-}
-
-bool BisonCSSParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc)
-{
-    bool mustBeNonNegative = unitflags & FNonNeg;
-
-    if (!parseCalculation(value, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll))
-        return false;
-
-    bool b = false;
-    switch (m_parsedCalculation->category()) {
-    case CalcLength:
-        b = (unitflags & FLength);
-        break;
-    case CalcPercent:
-        b = (unitflags & FPercent);
-        if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
-            b = false;
-        break;
-    case CalcNumber:
-        b = (unitflags & FNumber);
-        if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
-            b = true;
-        if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
-            b = false;
-        break;
-    case CalcPercentLength:
-        b = (unitflags & FPercent) && (unitflags & FLength);
-        break;
-    case CalcPercentNumber:
-        b = (unitflags & FPercent) && (unitflags & FNumber);
-        break;
-    case CalcOther:
-        break;
-    }
-    if (!b || releaseCalc == ReleaseParsedCalcValue)
-        m_parsedCalculation.release();
-    return b;
-}
-
-inline bool BisonCSSParser::shouldAcceptUnitLessValues(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode)
-{
-    // Quirks mode and presentation attributes accept unit less values.
-    return (unitflags & (FLength | FAngle | FTime)) && (!value->fValue || isUnitLessLengthParsingEnabledForMode(cssParserMode));
-}
-
-bool BisonCSSParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode, ReleaseParsedCalcValueCondition releaseCalc)
-{
-    if (isCalculation(value))
-        return validCalculationUnit(value, unitflags, releaseCalc);
-
-    bool b = false;
-    switch (value->unit) {
-    case CSSPrimitiveValue::CSS_NUMBER:
-        b = (unitflags & FNumber);
-        if (!b && shouldAcceptUnitLessValues(value, unitflags, cssParserMode)) {
-            value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX :
-                          ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
-            b = true;
-        }
-        if (!b && (unitflags & FInteger) && value->isInt)
-            b = true;
-        if (!b && (unitflags & FPositiveInteger) && value->isInt && value->fValue > 0)
-            b = true;
-        break;
-    case CSSPrimitiveValue::CSS_PERCENTAGE:
-        b = (unitflags & FPercent);
-        break;
-    case CSSParserValue::Q_EMS:
-    case CSSPrimitiveValue::CSS_EMS:
-    case CSSPrimitiveValue::CSS_REMS:
-    case CSSPrimitiveValue::CSS_CHS:
-    case CSSPrimitiveValue::CSS_EXS:
-    case CSSPrimitiveValue::CSS_PX:
-    case CSSPrimitiveValue::CSS_CM:
-    case CSSPrimitiveValue::CSS_MM:
-    case CSSPrimitiveValue::CSS_IN:
-    case CSSPrimitiveValue::CSS_PT:
-    case CSSPrimitiveValue::CSS_PC:
-    case CSSPrimitiveValue::CSS_VW:
-    case CSSPrimitiveValue::CSS_VH:
-    case CSSPrimitiveValue::CSS_VMIN:
-    case CSSPrimitiveValue::CSS_VMAX:
-        b = (unitflags & FLength);
-        break;
-    case CSSPrimitiveValue::CSS_MS:
-    case CSSPrimitiveValue::CSS_S:
-        b = (unitflags & FTime);
-        break;
-    case CSSPrimitiveValue::CSS_DEG:
-    case CSSPrimitiveValue::CSS_RAD:
-    case CSSPrimitiveValue::CSS_GRAD:
-    case CSSPrimitiveValue::CSS_TURN:
-        b = (unitflags & FAngle);
-        break;
-    case CSSPrimitiveValue::CSS_DPPX:
-    case CSSPrimitiveValue::CSS_DPI:
-    case CSSPrimitiveValue::CSS_DPCM:
-        b = (unitflags & FResolution);
-        break;
-    case CSSPrimitiveValue::CSS_HZ:
-    case CSSPrimitiveValue::CSS_KHZ:
-    case CSSPrimitiveValue::CSS_DIMENSION:
-    default:
-        break;
-    }
-    if (b && unitflags & FNonNeg && value->fValue < 0)
-        b = false;
-    return b;
-}
-
-inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::createPrimitiveNumericValue(CSSParserValue* value)
-{
-    if (m_parsedCalculation) {
-        ASSERT(isCalculation(value));
-        return CSSPrimitiveValue::create(m_parsedCalculation.release());
-    }
-
-    ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
-        || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
-        || (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
-        || (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM));
-    return cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
-}
-
-inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::createPrimitiveStringValue(CSSParserValue* value)
-{
-    ASSERT(value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT);
-    return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING);
-}
-
-static inline bool isComma(CSSParserValue* value)
-{
-    return value && value->unit == CSSParserValue::Operator && value->iValue == ',';
-}
-
-static inline bool isForwardSlashOperator(CSSParserValue* value)
-{
-    ASSERT(value);
-    return value->unit == CSSParserValue::Operator && value->iValue == '/';
-}
-
-static bool isGeneratedImageValue(CSSParserValue* val)
-{
-    if (val->unit != CSSParserValue::Function)
-        return false;
-
-    return equalIgnoringCase(val->function->name, "-webkit-gradient(")
-        || equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")
-        || equalIgnoringCase(val->function->name, "linear-gradient(")
-        || equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")
-        || equalIgnoringCase(val->function->name, "repeating-linear-gradient(")
-        || equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")
-        || equalIgnoringCase(val->function->name, "radial-gradient(")
-        || equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")
-        || equalIgnoringCase(val->function->name, "repeating-radial-gradient(")
-        || equalIgnoringCase(val->function->name, "-webkit-canvas(")
-        || equalIgnoringCase(val->function->name, "-webkit-cross-fade(");
-}
-
-bool BisonCSSParser::validWidthOrHeight(CSSParserValue* value)
-{
-    int id = value->id;
-    if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent)
-        return true;
-    return !id && validUnit(value, FLength | FPercent | FNonNeg);
-}
-
-inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::parseValidPrimitive(CSSValueID identifier, CSSParserValue* value)
-{
-    if (identifier)
-        return cssValuePool().createIdentifierValue(identifier);
-    if (value->unit == CSSPrimitiveValue::CSS_STRING)
-        return createPrimitiveStringValue(value);
-    if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
-        return createPrimitiveNumericValue(value);
-    if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
-        return createPrimitiveNumericValue(value);
-    if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
-        return createPrimitiveNumericValue(value);
-    if (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM)
-        return createPrimitiveNumericValue(value);
-    if (value->unit >= CSSParserValue::Q_EMS)
-        return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
-    if (isCalculation(value))
-        return CSSPrimitiveValue::create(m_parsedCalculation.release());
-
-    return 0;
-}
-
-void BisonCSSParser::addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue> prpValue, bool important)
-{
-    const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
-    unsigned shorthandLength = shorthand.length();
-    if (!shorthandLength) {
-        addProperty(propId, prpValue, important);
-        return;
-    }
-
-    RefPtr<CSSValue> value = prpValue;
-    ShorthandScope scope(this, propId);
-    const CSSPropertyID* longhands = shorthand.properties();
-    for (unsigned i = 0; i < shorthandLength; ++i)
-        addProperty(longhands[i], value, important);
-}
-
 void BisonCSSParser::setCurrentProperty(CSSPropertyID propId)
 {
     m_id = propId;
@@ -1609,6761 +1274,10 @@
 
 bool BisonCSSParser::parseValue(CSSPropertyID propId, bool important)
 {
-    if (!isInternalPropertyAndValueParsingEnabledForMode(m_context.mode()) && isInternalProperty(propId))
-        return false;
-
-    // We don't count the UA style sheet in our statistics.
-    if (m_context.useCounter())
-        m_context.useCounter()->count(m_context, propId);
-
-    if (!m_valueList)
-        return false;
-
-    CSSParserValue* value = m_valueList->current();
-
-    if (!value)
-        return false;
-
-    if (inViewport()) {
-        // Allow @viewport rules from UA stylesheets even if the feature is disabled.
-        if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_context.mode()))
-            return false;
-
-        return parseViewportProperty(propId, important);
-    }
-
-    // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function.
-    // FIXME: This is to avoid having to pass parsedCalc to all validUnit callers.
-    ASSERT(!m_parsedCalculation);
-
-    CSSValueID id = value->id;
-
-    int num = inShorthand() ? 1 : m_valueList->size();
-
-    if (id == CSSValueInherit) {
-        if (num != 1)
-            return false;
-        addExpandedPropertyForValue(propId, cssValuePool().createInheritedValue(), important);
-        return true;
-    }
-    else if (id == CSSValueInitial) {
-        if (num != 1)
-            return false;
-        addExpandedPropertyForValue(propId, cssValuePool().createExplicitInitialValue(), important);
-        return true;
-    }
-
-    if (isKeywordPropertyID(propId)) {
-        if (!isValidKeywordPropertyAndValue(propId, id, m_context))
-            return false;
-        if (m_valueList->next() && !inShorthand())
-            return false;
-        addProperty(propId, cssValuePool().createIdentifierValue(id), important);
-        return true;
-    }
-
-    bool validPrimitive = false;
-    RefPtr<CSSValue> parsedValue;
-
-    switch (propId) {
-    case CSSPropertySize:                 // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
-        return parseSize(propId, important);
-
-    case CSSPropertyQuotes:               // [<string> <string>]+ | none | inherit
-        if (id)
-            validPrimitive = true;
-        else
-            return parseQuotes(propId, important);
-        break;
-    case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | isolate-override | plaintext | inherit
-        if (id == CSSValueNormal
-            || id == CSSValueEmbed
-            || id == CSSValueBidiOverride
-            || id == CSSValueWebkitIsolate
-            || id == CSSValueWebkitIsolateOverride
-            || id == CSSValueWebkitPlaintext)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyContent:              // [ <string> | <uri> | <counter> | attr(X) | open-quote |
-        // close-quote | no-open-quote | no-close-quote ]+ | inherit
-        return parseContent(propId, important);
-
-    case CSSPropertyClip:                 // <shape> | auto | inherit
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else if (value->unit == CSSParserValue::Function)
-            return parseClipShape(propId, important);
-        break;
-
-    /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
-     * correctly and allows optimization in WebCore::applyRule(..)
-     */
-    case CSSPropertyOverflow: {
-        ShorthandScope scope(this, propId);
-        if (num != 1 || !parseValue(CSSPropertyOverflowY, important))
-            return false;
-
-        RefPtr<CSSValue> overflowXValue;
-
-        // FIXME: -webkit-paged-x or -webkit-paged-y only apply to overflow-y. If this value has been
-        // set using the shorthand, then for now overflow-x will default to auto, but once we implement
-        // pagination controls, it should default to hidden. If the overflow-y value is anything but
-        // paged-x or paged-y, then overflow-x and overflow-y should have the same value.
-        if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY)
-            overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto);
-        else
-            overflowXValue = m_parsedProperties.last().value();
-        addProperty(CSSPropertyOverflowX, overflowXValue.release(), important);
-        return true;
-    }
-
-    case CSSPropertyTextAlign:
-        // left | right | center | justify | -webkit-left | -webkit-right | -webkit-center | -webkit-match-parent
-        // | start | end | <string> | inherit | -webkit-auto (converted to start)
-        if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd
-            || value->unit == CSSPrimitiveValue::CSS_STRING)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyFontWeight:  { // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
-        if (m_valueList->size() != 1)
-            return false;
-        return parseFontWeight(important);
-    }
-    case CSSPropertyBorderSpacing: {
-        if (num == 1) {
-            ShorthandScope scope(this, CSSPropertyBorderSpacing);
-            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important))
-                return false;
-            CSSValue* value = m_parsedProperties.last().value();
-            addProperty(CSSPropertyWebkitBorderVerticalSpacing, value, important);
-            return true;
-        }
-        else if (num == 2) {
-            ShorthandScope scope(this, CSSPropertyBorderSpacing);
-            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important) || !parseValue(CSSPropertyWebkitBorderVerticalSpacing, important))
-                return false;
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyWebkitBorderHorizontalSpacing:
-    case CSSPropertyWebkitBorderVerticalSpacing:
-        validPrimitive = validUnit(value, FLength | FNonNeg);
-        break;
-    case CSSPropertyOutlineColor:        // <color> | invert | inherit
-        // Outline color has "invert" as additional keyword.
-        // Also, we want to allow the special focus color even in HTML Standard parsing mode.
-        if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
-            validPrimitive = true;
-            break;
-        }
-        /* nobreak */
-    case CSSPropertyBackgroundColor: // <color> | inherit
-    case CSSPropertyBorderTopColor: // <color> | inherit
-    case CSSPropertyBorderRightColor:
-    case CSSPropertyBorderBottomColor:
-    case CSSPropertyBorderLeftColor:
-    case CSSPropertyWebkitBorderStartColor:
-    case CSSPropertyWebkitBorderEndColor:
-    case CSSPropertyWebkitBorderBeforeColor:
-    case CSSPropertyWebkitBorderAfterColor:
-    case CSSPropertyColor: // <color> | inherit
-    case CSSPropertyTextDecorationColor: // CSS3 text decoration colors
-    case CSSPropertyTextLineThroughColor:
-    case CSSPropertyTextUnderlineColor:
-    case CSSPropertyTextOverlineColor:
-    case CSSPropertyWebkitColumnRuleColor:
-    case CSSPropertyWebkitTextEmphasisColor:
-    case CSSPropertyWebkitTextFillColor:
-    case CSSPropertyWebkitTextStrokeColor:
-        if (propId == CSSPropertyTextDecorationColor
-            && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
-            return false;
-
-        if ((id >= CSSValueAqua && id <= CSSValueWebkitText) || id == CSSValueMenu) {
-            validPrimitive = isValueAllowedInMode(id, m_context.mode());
-        } else {
-            parsedValue = parseColor();
-            if (parsedValue)
-                m_valueList->next();
-        }
-        break;
-
-    case CSSPropertyCursor: {
-        // Grammar defined by CSS3 UI and modified by CSS4 images:
-        // [ [<image> [<x> <y>]?,]*
-        // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
-        // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
-        // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help |
-        // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | -webkit-zoom-in
-        // -webkit-zoom-out | all-scroll | -webkit-grab | -webkit-grabbing ] ] | inherit
-        RefPtrWillBeRawPtr<CSSValueList> list;
-        while (value) {
-            RefPtr<CSSValue> image = 0;
-            if (value->unit == CSSPrimitiveValue::CSS_URI) {
-                String uri = value->string;
-                if (!uri.isNull())
-                    image = CSSImageValue::create(completeURL(uri));
-            } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
-                image = parseImageSet(m_valueList.get());
-                if (!image)
-                    break;
-            } else
-                break;
-
-            Vector<int> coords;
-            value = m_valueList->next();
-            while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
-                coords.append(int(value->fValue));
-                value = m_valueList->next();
-            }
-            bool hasHotSpot = false;
-            IntPoint hotSpot(-1, -1);
-            int nrcoords = coords.size();
-            if (nrcoords > 0 && nrcoords != 2)
-                return false;
-            if (nrcoords == 2) {
-                hasHotSpot = true;
-                hotSpot = IntPoint(coords[0], coords[1]);
-            }
-
-            if (!list)
-                list = CSSValueList::createCommaSeparated();
-
-            if (image)
-                list->append(CSSCursorImageValue::create(image, hasHotSpot, hotSpot));
-
-            if (!value || !(value->unit == CSSParserValue::Operator && value->iValue == ','))
-                return false;
-            value = m_valueList->next(); // comma
-        }
-        if (list) {
-            if (!value)
-                return false;
-            if (inQuirksMode() && value->id == CSSValueHand) // MSIE 5 compatibility :/
-                list->append(cssValuePool().createIdentifierValue(CSSValuePointer));
-            else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)
-                list->append(cssValuePool().createIdentifierValue(value->id));
-            m_valueList->next();
-            parsedValue = list.release();
-            break;
-        } else if (value) {
-            id = value->id;
-            if (inQuirksMode() && value->id == CSSValueHand) { // MSIE 5 compatibility :/
-                id = CSSValuePointer;
-                validPrimitive = true;
-            } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)
-                validPrimitive = true;
-        } else {
-            ASSERT_NOT_REACHED();
-            return false;
-        }
-        break;
-    }
-
-    case CSSPropertyBackgroundBlendMode:
-    case CSSPropertyBackgroundAttachment:
-    case CSSPropertyBackgroundClip:
-    case CSSPropertyWebkitBackgroundClip:
-    case CSSPropertyWebkitBackgroundComposite:
-    case CSSPropertyBackgroundImage:
-    case CSSPropertyBackgroundOrigin:
-    case CSSPropertyMaskSourceType:
-    case CSSPropertyWebkitBackgroundOrigin:
-    case CSSPropertyBackgroundPosition:
-    case CSSPropertyBackgroundPositionX:
-    case CSSPropertyBackgroundPositionY:
-    case CSSPropertyBackgroundSize:
-    case CSSPropertyWebkitBackgroundSize:
-    case CSSPropertyBackgroundRepeat:
-    case CSSPropertyBackgroundRepeatX:
-    case CSSPropertyBackgroundRepeatY:
-    case CSSPropertyWebkitMaskClip:
-    case CSSPropertyWebkitMaskComposite:
-    case CSSPropertyWebkitMaskImage:
-    case CSSPropertyWebkitMaskOrigin:
-    case CSSPropertyWebkitMaskPosition:
-    case CSSPropertyWebkitMaskPositionX:
-    case CSSPropertyWebkitMaskPositionY:
-    case CSSPropertyWebkitMaskSize:
-    case CSSPropertyWebkitMaskRepeat:
-    case CSSPropertyWebkitMaskRepeatX:
-    case CSSPropertyWebkitMaskRepeatY:
-    {
-        RefPtr<CSSValue> val1;
-        RefPtr<CSSValue> val2;
-        CSSPropertyID propId1, propId2;
-        bool result = false;
-        if (parseFillProperty(propId, propId1, propId2, val1, val2)) {
-            OwnPtr<ShorthandScope> shorthandScope;
-            if (propId == CSSPropertyBackgroundPosition ||
-                propId == CSSPropertyBackgroundRepeat ||
-                propId == CSSPropertyWebkitMaskPosition ||
-                propId == CSSPropertyWebkitMaskRepeat) {
-                shorthandScope = adoptPtr(new ShorthandScope(this, propId));
-            }
-            addProperty(propId1, val1.release(), important);
-            if (val2)
-                addProperty(propId2, val2.release(), important);
-            result = true;
-        }
-        m_implicitShorthand = false;
-        return result;
-    }
-    case CSSPropertyObjectPosition:
-        return RuntimeEnabledFeatures::objectFitPositionEnabled() && parseObjectPosition(important);
-    case CSSPropertyListStyleImage:     // <uri> | none | inherit
-    case CSSPropertyBorderImageSource:
-    case CSSPropertyWebkitMaskBoxImageSource:
-        if (id == CSSValueNone) {
-            parsedValue = cssValuePool().createIdentifierValue(CSSValueNone);
-            m_valueList->next();
-        } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
-            parsedValue = CSSImageValue::create(completeURL(value->string));
-            m_valueList->next();
-        } else if (isGeneratedImageValue(value)) {
-            if (parseGeneratedImage(m_valueList.get(), parsedValue))
-                m_valueList->next();
-            else
-                return false;
-        }
-        else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
-            parsedValue = parseImageSet(m_valueList.get());
-            if (!parsedValue)
-                return false;
-            m_valueList->next();
-        }
-        break;
-
-    case CSSPropertyWebkitTextStrokeWidth:
-    case CSSPropertyOutlineWidth:        // <border-width> | inherit
-    case CSSPropertyBorderTopWidth:     //// <border-width> | inherit
-    case CSSPropertyBorderRightWidth:   //   Which is defined as
-    case CSSPropertyBorderBottomWidth:  //   thin | medium | thick | <length>
-    case CSSPropertyBorderLeftWidth:
-    case CSSPropertyWebkitBorderStartWidth:
-    case CSSPropertyWebkitBorderEndWidth:
-    case CSSPropertyWebkitBorderBeforeWidth:
-    case CSSPropertyWebkitBorderAfterWidth:
-    case CSSPropertyWebkitColumnRuleWidth:
-        if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FLength | FNonNeg);
-        break;
-
-    case CSSPropertyLetterSpacing:       // normal | <length> | inherit
-    case CSSPropertyWordSpacing:         // normal | <length> | inherit
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FLength);
-        break;
-
-    case CSSPropertyTextIndent:
-        parsedValue = parseTextIndent();
-        break;
-
-    case CSSPropertyPaddingTop:          //// <padding-width> | inherit
-    case CSSPropertyPaddingRight:        //   Which is defined as
-    case CSSPropertyPaddingBottom:       //   <length> | <percentage>
-    case CSSPropertyPaddingLeft:         ////
-    case CSSPropertyWebkitPaddingStart:
-    case CSSPropertyWebkitPaddingEnd:
-    case CSSPropertyWebkitPaddingBefore:
-    case CSSPropertyWebkitPaddingAfter:
-        validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
-        break;
-
-    case CSSPropertyMaxWidth:
-    case CSSPropertyWebkitMaxLogicalWidth:
-    case CSSPropertyMaxHeight:
-    case CSSPropertyWebkitMaxLogicalHeight:
-        validPrimitive = (id == CSSValueNone || validWidthOrHeight(value));
-        break;
-
-    case CSSPropertyMinWidth:
-    case CSSPropertyWebkitMinLogicalWidth:
-    case CSSPropertyMinHeight:
-    case CSSPropertyWebkitMinLogicalHeight:
-        validPrimitive = validWidthOrHeight(value);
-        break;
-
-    case CSSPropertyWidth:
-    case CSSPropertyWebkitLogicalWidth:
-    case CSSPropertyHeight:
-    case CSSPropertyWebkitLogicalHeight:
-        validPrimitive = (id == CSSValueAuto || validWidthOrHeight(value));
-        break;
-
-    case CSSPropertyFontSize:
-        return parseFontSize(important);
-
-    case CSSPropertyFontVariant:         // normal | small-caps | inherit
-        return parseFontVariant(important);
-
-    case CSSPropertyVerticalAlign:
-        // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
-        // <percentage> | <length> | inherit
-
-        if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FLength | FPercent));
-        break;
-
-    case CSSPropertyBottom:               // <length> | <percentage> | auto | inherit
-    case CSSPropertyLeft:                 // <length> | <percentage> | auto | inherit
-    case CSSPropertyRight:                // <length> | <percentage> | auto | inherit
-    case CSSPropertyTop:                  // <length> | <percentage> | auto | inherit
-    case CSSPropertyMarginTop:           //// <margin-width> | inherit
-    case CSSPropertyMarginRight:         //   Which is defined as
-    case CSSPropertyMarginBottom:        //   <length> | <percentage> | auto | inherit
-    case CSSPropertyMarginLeft:          ////
-    case CSSPropertyWebkitMarginStart:
-    case CSSPropertyWebkitMarginEnd:
-    case CSSPropertyWebkitMarginBefore:
-    case CSSPropertyWebkitMarginAfter:
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FLength | FPercent));
-        break;
-
-    case CSSPropertyOrphans: // <integer> | inherit | auto (We've added support for auto for backwards compatibility)
-    case CSSPropertyWidows: // <integer> | inherit | auto (Ditto)
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FPositiveInteger, HTMLQuirksMode));
-        break;
-
-    case CSSPropertyZIndex: // auto | <integer> | inherit
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FInteger, HTMLQuirksMode));
-        break;
-
-    case CSSPropertyLineHeight:
-        return parseLineHeight(important);
-    case CSSPropertyCounterIncrement:    // [ <identifier> <integer>? ]+ | none | inherit
-        if (id != CSSValueNone)
-            return parseCounter(propId, 1, important);
-        validPrimitive = true;
-        break;
-    case CSSPropertyCounterReset:        // [ <identifier> <integer>? ]+ | none | inherit
-        if (id != CSSValueNone)
-            return parseCounter(propId, 0, important);
-        validPrimitive = true;
-        break;
-    case CSSPropertyFontFamily:
-        // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
-    {
-        parsedValue = parseFontFamily();
-        break;
-    }
-
-    case CSSPropertyTextDecoration:
-        // Fall through 'text-decoration-line' parsing if CSS 3 Text Decoration
-        // is disabled to match CSS 2.1 rules for parsing 'text-decoration'.
-        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) {
-            // [ <text-decoration-line> || <text-decoration-style> || <text-decoration-color> ] | inherit
-            return parseShorthand(CSSPropertyTextDecoration, textDecorationShorthand(), important);
-        }
-    case CSSPropertyWebkitTextDecorationsInEffect:
-    case CSSPropertyTextDecorationLine:
-        // none | [ underline || overline || line-through || blink ] | inherit
-        return parseTextDecoration(propId, important);
-
-    case CSSPropertyTextDecorationStyle:
-        // solid | double | dotted | dashed | wavy
-        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()
-            && (id == CSSValueSolid || id == CSSValueDouble || id == CSSValueDotted || id == CSSValueDashed || id == CSSValueWavy))
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyTextUnderlinePosition:
-        // auto | under | inherit
-        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
-            return parseTextUnderlinePosition(important);
-        return false;
-
-    case CSSPropertyZoom:          // normal | reset | document | <number> | <percentage> | inherit
-        if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode));
-        break;
-
-    case CSSPropertySrc: // Only used within @font-face and @-webkit-filter, so cannot use inherit | initial or be !important. This is a list of urls or local references.
-        return parseFontFaceSrc();
-
-    case CSSPropertyUnicodeRange:
-        return parseFontFaceUnicodeRange();
-
-    /* CSS3 properties */
-
-    case CSSPropertyBorderImage:
-    case CSSPropertyWebkitMaskBoxImage:
-        return parseBorderImageShorthand(propId, important);
-    case CSSPropertyWebkitBorderImage: {
-        if (RefPtr<CSSValue> result = parseBorderImage(propId)) {
-            addProperty(propId, result, important);
-            return true;
-        }
-        return false;
-    }
-
-    case CSSPropertyBorderImageOutset:
-    case CSSPropertyWebkitMaskBoxImageOutset: {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> result;
-        if (parseBorderImageOutset(result)) {
-            addProperty(propId, result, important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderImageRepeat:
-    case CSSPropertyWebkitMaskBoxImageRepeat: {
-        RefPtr<CSSValue> result;
-        if (parseBorderImageRepeat(result)) {
-            addProperty(propId, result, important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderImageSlice:
-    case CSSPropertyWebkitMaskBoxImageSlice: {
-        RefPtrWillBeRawPtr<CSSBorderImageSliceValue> result;
-        if (parseBorderImageSlice(propId, result)) {
-            addProperty(propId, result, important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderImageWidth:
-    case CSSPropertyWebkitMaskBoxImageWidth: {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> result;
-        if (parseBorderImageWidth(result)) {
-            addProperty(propId, result, important);
-            return true;
-        }
-        break;
-    }
-    case CSSPropertyBorderTopRightRadius:
-    case CSSPropertyBorderTopLeftRadius:
-    case CSSPropertyBorderBottomLeftRadius:
-    case CSSPropertyBorderBottomRightRadius: {
-        if (num != 1 && num != 2)
-            return false;
-        validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
-        if (!validPrimitive)
-            return false;
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1 = createPrimitiveNumericValue(value);
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2;
-        if (num == 2) {
-            value = m_valueList->next();
-            validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
-            if (!validPrimitive)
-                return false;
-            parsedValue2 = createPrimitiveNumericValue(value);
-        } else
-            parsedValue2 = parsedValue1;
-
-        addProperty(propId, createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release()), important);
-        return true;
-    }
-    case CSSPropertyTabSize:
-        validPrimitive = validUnit(value, FInteger | FNonNeg);
-        break;
-    case CSSPropertyWebkitAspectRatio:
-        return parseAspectRatio(important);
-    case CSSPropertyBorderRadius:
-    case CSSPropertyWebkitBorderRadius:
-        return parseBorderRadius(propId, important);
-    case CSSPropertyOutlineOffset:
-        validPrimitive = validUnit(value, FLength);
-        break;
-    case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
-    case CSSPropertyBoxShadow:
-    case CSSPropertyWebkitBoxShadow:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(m_valueList.get(), propId);
-            if (shadowValueList) {
-                addProperty(propId, shadowValueList.release(), important);
-                m_valueList->next();
-                return true;
-            }
-            return false;
-        }
-        break;
-    case CSSPropertyWebkitBoxReflect:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else
-            return parseReflect(propId, important);
-        break;
-    case CSSPropertyOpacity:
-        validPrimitive = validUnit(value, FNumber);
-        break;
-    case CSSPropertyWebkitBoxFlex:
-        validPrimitive = validUnit(value, FNumber);
-        break;
-    case CSSPropertyWebkitBoxFlexGroup:
-        validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode);
-        break;
-    case CSSPropertyWebkitBoxOrdinalGroup:
-        validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode) && value->fValue;
-        break;
-    case CSSPropertyWebkitFilter:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            RefPtr<CSSValue> val = parseFilter();
-            if (val) {
-                addProperty(propId, val, important);
-                return true;
-            }
-            return false;
-        }
-        break;
-    case CSSPropertyFlex: {
-        ShorthandScope scope(this, propId);
-        if (id == CSSValueNone) {
-            addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
-            addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
-            addProperty(CSSPropertyFlexBasis, cssValuePool().createIdentifierValue(CSSValueAuto), important);
-            return true;
-        }
-        return parseFlex(m_valueList.get(), important);
-    }
-    case CSSPropertyFlexBasis:
-        // FIXME: Support intrinsic dimensions too.
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
-        break;
-    case CSSPropertyFlexGrow:
-    case CSSPropertyFlexShrink:
-        validPrimitive = validUnit(value, FNumber | FNonNeg);
-        break;
-    case CSSPropertyOrder:
-        validPrimitive = validUnit(value, FInteger, HTMLStandardMode);
-        break;
-    case CSSPropertyInternalMarqueeIncrement:
-        if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FLength | FPercent);
-        break;
-    case CSSPropertyInternalMarqueeRepetition:
-        if (id == CSSValueInfinite)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FInteger | FNonNeg);
-        break;
-    case CSSPropertyInternalMarqueeSpeed:
-        if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FTime | FInteger | FNonNeg);
-        break;
-    case CSSPropertyWebkitTransform:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            RefPtr<CSSValue> transformValue = parseTransform();
-            if (transformValue) {
-                addProperty(propId, transformValue.release(), important);
-                return true;
-            }
-            return false;
-        }
-        break;
-    case CSSPropertyWebkitTransformOrigin:
-    case CSSPropertyWebkitTransformOriginX:
-    case CSSPropertyWebkitTransformOriginY:
-    case CSSPropertyWebkitTransformOriginZ: {
-        RefPtr<CSSValue> val1;
-        RefPtr<CSSValue> val2;
-        RefPtr<CSSValue> val3;
-        CSSPropertyID propId1, propId2, propId3;
-        if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
-            addProperty(propId1, val1.release(), important);
-            if (val2)
-                addProperty(propId2, val2.release(), important);
-            if (val3)
-                addProperty(propId3, val3.release(), important);
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyWebkitPerspective:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else {
-            // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
-            if (validUnit(value, FNumber | FLength | FNonNeg)) {
-                RefPtr<CSSValue> val = createPrimitiveNumericValue(value);
-                if (val) {
-                    addProperty(propId, val.release(), important);
-                    return true;
-                }
-                return false;
-            }
-        }
-        break;
-    case CSSPropertyWebkitPerspectiveOrigin:
-    case CSSPropertyWebkitPerspectiveOriginX:
-    case CSSPropertyWebkitPerspectiveOriginY: {
-        RefPtr<CSSValue> val1;
-        RefPtr<CSSValue> val2;
-        CSSPropertyID propId1, propId2;
-        if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
-            addProperty(propId1, val1.release(), important);
-            if (val2)
-                addProperty(propId2, val2.release(), important);
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyAnimationDelay:
-    case CSSPropertyAnimationDirection:
-    case CSSPropertyAnimationDuration:
-    case CSSPropertyAnimationFillMode:
-    case CSSPropertyAnimationName:
-    case CSSPropertyAnimationPlayState:
-    case CSSPropertyAnimationIterationCount:
-    case CSSPropertyAnimationTimingFunction:
-        if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
-            break;
-    case CSSPropertyWebkitAnimationDelay:
-    case CSSPropertyWebkitAnimationDirection:
-    case CSSPropertyWebkitAnimationDuration:
-    case CSSPropertyWebkitAnimationFillMode:
-    case CSSPropertyWebkitAnimationName:
-    case CSSPropertyWebkitAnimationPlayState:
-    case CSSPropertyWebkitAnimationIterationCount:
-    case CSSPropertyWebkitAnimationTimingFunction:
-    case CSSPropertyTransitionDelay:
-    case CSSPropertyTransitionDuration:
-    case CSSPropertyTransitionTimingFunction:
-    case CSSPropertyTransitionProperty:
-    case CSSPropertyWebkitTransitionDelay:
-    case CSSPropertyWebkitTransitionDuration:
-    case CSSPropertyWebkitTransitionTimingFunction:
-    case CSSPropertyWebkitTransitionProperty: {
-        RefPtr<CSSValue> val;
-        AnimationParseContext context;
-        if (parseAnimationProperty(propId, val, context)) {
-            addPropertyWithPrefixingVariant(propId, val.release(), important);
-            return true;
-        }
-        return false;
-    }
-
-    case CSSPropertyJustifySelf:
-        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
-            return false;
-
-        return parseItemPositionOverflowPosition(propId, important);
-    case CSSPropertyGridAutoColumns:
-    case CSSPropertyGridAutoRows:
-        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridTrackSize(*m_valueList);
-        break;
-
-    case CSSPropertyGridTemplateColumns:
-    case CSSPropertyGridTemplateRows:
-        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
-            return false;
-        return parseGridTrackList(propId, important);
-
-    case CSSPropertyGridColumnEnd:
-    case CSSPropertyGridColumnStart:
-    case CSSPropertyGridRowEnd:
-    case CSSPropertyGridRowStart:
-        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridPosition();
-        break;
-
-    case CSSPropertyGridColumn:
-    case CSSPropertyGridRow:
-        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
-            return false;
-        return parseGridItemPositionShorthand(propId, important);
-
-    case CSSPropertyGridArea:
-        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
-            return false;
-        return parseGridAreaShorthand(important);
-
-    case CSSPropertyGridTemplateAreas:
-        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
-            return false;
-        parsedValue = parseGridTemplateAreas();
-        break;
-
-    case CSSPropertyWebkitMarginCollapse: {
-        if (num == 1) {
-            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
-            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important))
-                return false;
-            CSSValue* value = m_parsedProperties.last().value();
-            addProperty(webkitMarginCollapseShorthand().properties()[1], value, important);
-            return true;
-        }
-        else if (num == 2) {
-            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
-            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important) || !parseValue(webkitMarginCollapseShorthand().properties()[1], important))
-                return false;
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyTextLineThroughWidth:
-    case CSSPropertyTextOverlineWidth:
-    case CSSPropertyTextUnderlineWidth:
-        if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin ||
-            id == CSSValueMedium || id == CSSValueThick)
-            validPrimitive = true;
-        else
-            validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent);
-        break;
-    case CSSPropertyWebkitColumnCount:
-        parsedValue = parseColumnCount();
-        break;
-    case CSSPropertyWebkitColumnGap:         // normal | <length>
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FLength | FNonNeg);
-        break;
-    case CSSPropertyWebkitColumnAxis:
-        if (id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto)
-            validPrimitive = true;
-        break;
-    case CSSPropertyWebkitColumnProgression:
-        if (id == CSSValueNormal || id == CSSValueReverse)
-            validPrimitive = true;
-        break;
-    case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
-        if (id == CSSValueAll || id == CSSValueNone)
-            validPrimitive = true;
-        else
-            validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1;
-        break;
-    case CSSPropertyWebkitColumnWidth:         // auto | <length>
-        parsedValue = parseColumnWidth();
-        break;
-    // End of CSS3 properties
-
-    // Apple specific properties.  These will never be standardized and are purely to
-    // support custom WebKit-based Apple applications.
-    case CSSPropertyWebkitLineClamp:
-        // When specifying number of lines, don't allow 0 as a valid value
-        // When specifying either type of unit, require non-negative integers
-        validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, HTMLQuirksMode));
-        break;
-
-    case CSSPropertyWebkitFontSizeDelta:           // <length>
-        validPrimitive = validUnit(value, FLength);
-        break;
-
-    case CSSPropertyWebkitHighlight:
-        if (id == CSSValueNone || value->unit == CSSPrimitiveValue::CSS_STRING)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitHyphenateCharacter:
-        if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitLocale:
-        if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
-            validPrimitive = true;
-        break;
-
-    // End Apple-specific properties
-
-    case CSSPropertyWebkitAppRegion:
-        if (id >= CSSValueDrag && id <= CSSValueNoDrag)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitTapHighlightColor:
-        if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu
-            || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) {
-            validPrimitive = true;
-        } else {
-            parsedValue = parseColor();
-            if (parsedValue)
-                m_valueList->next();
-        }
-        break;
-
-        /* shorthand properties */
-    case CSSPropertyBackground: {
-        // Position must come before color in this array because a plain old "0" is a legal color
-        // in quirks mode but it's usually the X coordinate of a position.
-        const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat,
-                                   CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin,
-                                   CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize };
-        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
-    }
-    case CSSPropertyWebkitMask: {
-        const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat,
-            CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip, CSSPropertyWebkitMaskSize };
-        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
-    }
-    case CSSPropertyBorder:
-        // [ 'border-width' || 'border-style' || <color> ] | inherit
-    {
-        if (parseShorthand(propId, parsingShorthandForProperty(CSSPropertyBorder), important)) {
-            // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as
-            // though a value of none was specified for the image.
-            addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool().createImplicitInitialValue(), important);
-            return true;
-        }
-        return false;
-    }
-    case CSSPropertyBorderTop:
-        // [ 'border-top-width' || 'border-style' || <color> ] | inherit
-        return parseShorthand(propId, borderTopShorthand(), important);
-    case CSSPropertyBorderRight:
-        // [ 'border-right-width' || 'border-style' || <color> ] | inherit
-        return parseShorthand(propId, borderRightShorthand(), important);
-    case CSSPropertyBorderBottom:
-        // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit
-        return parseShorthand(propId, borderBottomShorthand(), important);
-    case CSSPropertyBorderLeft:
-        // [ 'border-left-width' || 'border-style' || <color> ] | inherit
-        return parseShorthand(propId, borderLeftShorthand(), important);
-    case CSSPropertyWebkitBorderStart:
-        return parseShorthand(propId, webkitBorderStartShorthand(), important);
-    case CSSPropertyWebkitBorderEnd:
-        return parseShorthand(propId, webkitBorderEndShorthand(), important);
-    case CSSPropertyWebkitBorderBefore:
-        return parseShorthand(propId, webkitBorderBeforeShorthand(), important);
-    case CSSPropertyWebkitBorderAfter:
-        return parseShorthand(propId, webkitBorderAfterShorthand(), important);
-    case CSSPropertyOutline:
-        // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
-        return parseShorthand(propId, outlineShorthand(), important);
-    case CSSPropertyBorderColor:
-        // <color>{1,4} | inherit
-        return parse4Values(propId, borderColorShorthand().properties(), important);
-    case CSSPropertyBorderWidth:
-        // <border-width>{1,4} | inherit
-        return parse4Values(propId, borderWidthShorthand().properties(), important);
-    case CSSPropertyBorderStyle:
-        // <border-style>{1,4} | inherit
-        return parse4Values(propId, borderStyleShorthand().properties(), important);
-    case CSSPropertyMargin:
-        // <margin-width>{1,4} | inherit
-        return parse4Values(propId, marginShorthand().properties(), important);
-    case CSSPropertyPadding:
-        // <padding-width>{1,4} | inherit
-        return parse4Values(propId, paddingShorthand().properties(), important);
-    case CSSPropertyFlexFlow:
-        return parseShorthand(propId, flexFlowShorthand(), important);
-    case CSSPropertyFont:
-        // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
-        // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
-        if (id >= CSSValueCaption && id <= CSSValueStatusBar)
-            validPrimitive = true;
-        else
-            return parseFont(important);
-        break;
-    case CSSPropertyListStyle:
-        return parseShorthand(propId, listStyleShorthand(), important);
-    case CSSPropertyWebkitColumns:
-        return parseColumnsShorthand(important);
-    case CSSPropertyWebkitColumnRule:
-        return parseShorthand(propId, webkitColumnRuleShorthand(), important);
-    case CSSPropertyWebkitTextStroke:
-        return parseShorthand(propId, webkitTextStrokeShorthand(), important);
-    case CSSPropertyAnimation:
-        if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
-            break;
-    case CSSPropertyWebkitAnimation:
-        return parseAnimationShorthand(propId, important);
-    case CSSPropertyTransition:
-    case CSSPropertyWebkitTransition:
-        return parseTransitionShorthand(propId, important);
-    case CSSPropertyInvalid:
-        return false;
-    case CSSPropertyPage:
-        return parsePage(propId, important);
-    case CSSPropertyFontStretch:
-        return false;
-    // CSS Text Layout Module Level 3: Vertical writing support
-    case CSSPropertyWebkitTextEmphasis:
-        return parseShorthand(propId, webkitTextEmphasisShorthand(), important);
-
-    case CSSPropertyWebkitTextEmphasisStyle:
-        return parseTextEmphasisStyle(important);
-
-    case CSSPropertyWebkitTextOrientation:
-        // FIXME: For now just support sideways, sideways-right, upright and vertical-right.
-        if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueUpright)
-            validPrimitive = true;
-        break;
-
-    case CSSPropertyWebkitLineBoxContain:
-        if (id == CSSValueNone)
-            validPrimitive = true;
-        else
-            return parseLineBoxContain(important);
-        break;
-    case CSSPropertyWebkitFontFeatureSettings:
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            return parseFontFeatureSettings(important);
-        break;
-
-    case CSSPropertyFontVariantLigatures:
-        if (id == CSSValueNormal)
-            validPrimitive = true;
-        else
-            return parseFontVariantLigatures(important);
-        break;
-    case CSSPropertyWebkitClipPath:
-        if (id == CSSValueNone) {
-            validPrimitive = true;
-        } else if (value->unit == CSSParserValue::Function) {
-            parsedValue = parseBasicShape();
-        } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
-            parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
-            addProperty(propId, parsedValue.release(), important);
-            return true;
-        }
-        break;
-    case CSSPropertyShapeInside:
-    case CSSPropertyShapeOutside:
-        parsedValue = parseShapeProperty(propId);
-        break;
-    case CSSPropertyShapeMargin:
-    case CSSPropertyShapePadding:
-        validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FLength | FNonNeg));
-        break;
-    case CSSPropertyShapeImageThreshold:
-        validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FNumber));
-        break;
-
-    case CSSPropertyTouchAction:
-        // auto | none | [pan-x || pan-y]
-        return parseTouchAction(important);
-
-    case CSSPropertyAlignSelf:
-        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-        return parseItemPositionOverflowPosition(propId, important);
-
-    case CSSPropertyAlignItems:
-        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-        return parseItemPositionOverflowPosition(propId, important);
-
-    case CSSPropertyBorderBottomStyle:
-    case CSSPropertyBorderCollapse:
-    case CSSPropertyBorderLeftStyle:
-    case CSSPropertyBorderRightStyle:
-    case CSSPropertyBorderTopStyle:
-    case CSSPropertyBoxSizing:
-    case CSSPropertyCaptionSide:
-    case CSSPropertyClear:
-    case CSSPropertyDirection:
-    case CSSPropertyDisplay:
-    case CSSPropertyEmptyCells:
-    case CSSPropertyFloat:
-    case CSSPropertyFontStyle:
-    case CSSPropertyImageRendering:
-    case CSSPropertyListStylePosition:
-    case CSSPropertyListStyleType:
-    case CSSPropertyObjectFit:
-    case CSSPropertyOutlineStyle:
-    case CSSPropertyOverflowWrap:
-    case CSSPropertyOverflowX:
-    case CSSPropertyOverflowY:
-    case CSSPropertyPageBreakAfter:
-    case CSSPropertyPageBreakBefore:
-    case CSSPropertyPageBreakInside:
-    case CSSPropertyPointerEvents:
-    case CSSPropertyPosition:
-    case CSSPropertyResize:
-    case CSSPropertySpeak:
-    case CSSPropertyTableLayout:
-    case CSSPropertyTextAlignLast:
-    case CSSPropertyTextJustify:
-    case CSSPropertyTextLineThroughMode:
-    case CSSPropertyTextLineThroughStyle:
-    case CSSPropertyTextOverflow:
-    case CSSPropertyTextOverlineMode:
-    case CSSPropertyTextOverlineStyle:
-    case CSSPropertyTextRendering:
-    case CSSPropertyTextTransform:
-    case CSSPropertyTextUnderlineMode:
-    case CSSPropertyTextUnderlineStyle:
-    case CSSPropertyTouchActionDelay:
-    case CSSPropertyVisibility:
-    case CSSPropertyWebkitAppearance:
-    case CSSPropertyWebkitBackfaceVisibility:
-    case CSSPropertyWebkitBorderAfterStyle:
-    case CSSPropertyWebkitBorderBeforeStyle:
-    case CSSPropertyWebkitBorderEndStyle:
-    case CSSPropertyWebkitBorderFit:
-    case CSSPropertyWebkitBorderStartStyle:
-    case CSSPropertyWebkitBoxAlign:
-    case CSSPropertyWebkitBoxDecorationBreak:
-    case CSSPropertyWebkitBoxDirection:
-    case CSSPropertyWebkitBoxLines:
-    case CSSPropertyWebkitBoxOrient:
-    case CSSPropertyWebkitBoxPack:
-    case CSSPropertyInternalCallback:
-    case CSSPropertyWebkitColumnBreakAfter:
-    case CSSPropertyWebkitColumnBreakBefore:
-    case CSSPropertyWebkitColumnBreakInside:
-    case CSSPropertyColumnFill:
-    case CSSPropertyWebkitColumnRuleStyle:
-    case CSSPropertyAlignContent:
-    case CSSPropertyFlexDirection:
-    case CSSPropertyFlexWrap:
-    case CSSPropertyJustifyContent:
-    case CSSPropertyFontKerning:
-    case CSSPropertyWebkitFontSmoothing:
-    case CSSPropertyGridAutoFlow:
-    case CSSPropertyWebkitLineBreak:
-    case CSSPropertyWebkitMarginAfterCollapse:
-    case CSSPropertyWebkitMarginBeforeCollapse:
-    case CSSPropertyWebkitMarginBottomCollapse:
-    case CSSPropertyWebkitMarginTopCollapse:
-    case CSSPropertyInternalMarqueeDirection:
-    case CSSPropertyInternalMarqueeStyle:
-    case CSSPropertyWebkitPrintColorAdjust:
-    case CSSPropertyWebkitRtlOrdering:
-    case CSSPropertyWebkitRubyPosition:
-    case CSSPropertyWebkitTextCombine:
-    case CSSPropertyWebkitTextEmphasisPosition:
-    case CSSPropertyWebkitTextSecurity:
-    case CSSPropertyWebkitTransformStyle:
-    case CSSPropertyWebkitUserDrag:
-    case CSSPropertyWebkitUserModify:
-    case CSSPropertyWebkitUserSelect:
-    case CSSPropertyWebkitWrapFlow:
-    case CSSPropertyWebkitWrapThrough:
-    case CSSPropertyWebkitWritingMode:
-    case CSSPropertyWhiteSpace:
-    case CSSPropertyWordBreak:
-    case CSSPropertyWordWrap:
-    case CSSPropertyMixBlendMode:
-    case CSSPropertyIsolation:
-        // These properties should be handled before in isValidKeywordPropertyAndValue().
-        ASSERT_NOT_REACHED();
-        return false;
-    // Properties below are validated inside parseViewportProperty, because we
-    // check for parser state. We need to invalidate if someone adds them outside
-    // a @viewport rule.
-    case CSSPropertyMaxZoom:
-    case CSSPropertyMinZoom:
-    case CSSPropertyOrientation:
-    case CSSPropertyUserZoom:
-        validPrimitive = false;
-        break;
-    default:
-        return parseSVGValue(propId, important);
-    }
-
-    if (validPrimitive) {
-        parsedValue = parseValidPrimitive(id, value);
-        m_valueList->next();
-    }
-    ASSERT(!m_parsedCalculation);
-    if (parsedValue) {
-        if (!m_valueList->current() || inShorthand()) {
-            addProperty(propId, parsedValue.release(), important);
-            return true;
-        }
-    }
-    return false;
-}
-
-void BisonCSSParser::addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
-{
-    if (lval) {
-        if (lval->isBaseValueList())
-            toCSSValueList(lval.get())->append(rval);
-        else {
-            PassRefPtr<CSSValue> oldlVal(lval.release());
-            PassRefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-            list->append(oldlVal);
-            list->append(rval);
-            lval = list;
-        }
-    }
-    else
-        lval = rval;
-}
-
-static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtr<CSSValue>& cssValue)
-{
-    if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox
-        || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) {
-        cssValue = cssValuePool().createIdentifierValue(parserValue->id);
-        return true;
-    }
-    return false;
-}
-
-bool BisonCSSParser::useLegacyBackgroundSizeShorthandBehavior() const
-{
-    return m_context.useLegacyBackgroundSizeShorthandBehavior();
-}
-
-const int cMaxFillProperties = 9;
-
-bool BisonCSSParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important)
-{
-    ASSERT(numProperties <= cMaxFillProperties);
-    if (numProperties > cMaxFillProperties)
-        return false;
-
-    ShorthandScope scope(this, propId);
-
-    bool parsedProperty[cMaxFillProperties] = { false };
-    RefPtr<CSSValue> values[cMaxFillProperties];
-    RefPtr<CSSValue> clipValue;
-    RefPtr<CSSValue> positionYValue;
-    RefPtr<CSSValue> repeatYValue;
-    bool foundClip = false;
-    int i;
-    bool foundPositionCSSProperty = false;
-
-    while (m_valueList->current()) {
-        CSSParserValue* val = m_valueList->current();
-        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
-            // We hit the end.  Fill in all remaining values with the initial value.
-            m_valueList->next();
-            for (i = 0; i < numProperties; ++i) {
-                if (properties[i] == CSSPropertyBackgroundColor && parsedProperty[i])
-                    // Color is not allowed except as the last item in a list for backgrounds.
-                    // Reject the entire property.
-                    return false;
-
-                if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) {
-                    addFillValue(values[i], cssValuePool().createImplicitInitialValue());
-                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                        addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
-                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
-                        addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
-                    if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) {
-                        // If background-origin wasn't present, then reset background-clip also.
-                        addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
-                    }
-                }
-                parsedProperty[i] = false;
-            }
-            if (!m_valueList->current())
-                break;
-        }
-
-        bool sizeCSSPropertyExpected = false;
-        if (isForwardSlashOperator(val) && foundPositionCSSProperty) {
-            sizeCSSPropertyExpected = true;
-            m_valueList->next();
-        }
-
-        foundPositionCSSProperty = false;
-        bool found = false;
-        for (i = 0; !found && i < numProperties; ++i) {
-
-            if (sizeCSSPropertyExpected && (properties[i] != CSSPropertyBackgroundSize && properties[i] != CSSPropertyWebkitMaskSize))
-                continue;
-            if (!sizeCSSPropertyExpected && (properties[i] == CSSPropertyBackgroundSize || properties[i] == CSSPropertyWebkitMaskSize))
-                continue;
-
-            if (!parsedProperty[i]) {
-                RefPtr<CSSValue> val1;
-                RefPtr<CSSValue> val2;
-                CSSPropertyID propId1, propId2;
-                CSSParserValue* parserValue = m_valueList->current();
-                // parseFillProperty() may modify m_implicitShorthand, so we MUST reset it
-                // before EACH return below.
-                if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
-                    parsedProperty[i] = found = true;
-                    addFillValue(values[i], val1.release());
-                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                        addFillValue(positionYValue, val2.release());
-                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
-                        addFillValue(repeatYValue, val2.release());
-                    if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
-                        // Reparse the value as a clip, and see if we succeed.
-                        if (parseBackgroundClip(parserValue, val1))
-                            addFillValue(clipValue, val1.release()); // The property parsed successfully.
-                        else
-                            addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
-                    }
-                    if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) {
-                        // Update clipValue
-                        addFillValue(clipValue, val1.release());
-                        foundClip = true;
-                    }
-                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                        foundPositionCSSProperty = true;
-                }
-            }
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found) {
-            m_implicitShorthand = false;
-            return false;
-        }
-    }
-
-    // Now add all of the properties we found.
-    for (i = 0; i < numProperties; i++) {
-        // Fill in any remaining properties with the initial value.
-        if (!parsedProperty[i]) {
-            addFillValue(values[i], cssValuePool().createImplicitInitialValue());
-            if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
-                addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
-            if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
-                addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
-            if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
-                // If background-origin wasn't present, then reset background-clip also.
-                addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
-            }
-        }
-        if (properties[i] == CSSPropertyBackgroundPosition) {
-            addProperty(CSSPropertyBackgroundPositionX, values[i].release(), important);
-            // it's OK to call positionYValue.release() since we only see CSSPropertyBackgroundPosition once
-            addProperty(CSSPropertyBackgroundPositionY, positionYValue.release(), important);
-        } else if (properties[i] == CSSPropertyWebkitMaskPosition) {
-            addProperty(CSSPropertyWebkitMaskPositionX, values[i].release(), important);
-            // it's OK to call positionYValue.release() since we only see CSSPropertyWebkitMaskPosition once
-            addProperty(CSSPropertyWebkitMaskPositionY, positionYValue.release(), important);
-        } else if (properties[i] == CSSPropertyBackgroundRepeat) {
-            addProperty(CSSPropertyBackgroundRepeatX, values[i].release(), important);
-            // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
-            addProperty(CSSPropertyBackgroundRepeatY, repeatYValue.release(), important);
-        } else if (properties[i] == CSSPropertyWebkitMaskRepeat) {
-            addProperty(CSSPropertyWebkitMaskRepeatX, values[i].release(), important);
-            // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
-            addProperty(CSSPropertyWebkitMaskRepeatY, repeatYValue.release(), important);
-        } else if ((properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) && !foundClip)
-            // Value is already set while updating origin
-            continue;
-        else if (properties[i] == CSSPropertyBackgroundSize && !parsedProperty[i] && useLegacyBackgroundSizeShorthandBehavior())
-            continue;
-        else
-            addProperty(properties[i], values[i].release(), important);
-
-        // Add in clip values when we hit the corresponding origin property.
-        if (properties[i] == CSSPropertyBackgroundOrigin && !foundClip)
-            addProperty(CSSPropertyBackgroundClip, clipValue.release(), important);
-        else if (properties[i] == CSSPropertyWebkitMaskOrigin && !foundClip)
-            addProperty(CSSPropertyWebkitMaskClip, clipValue.release(), important);
-    }
-
-    m_implicitShorthand = false;
-    return true;
-}
-
-void BisonCSSParser::addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval)
-{
-    if (lval) {
-        if (lval->isValueList())
-            toCSSValueList(lval.get())->append(rval);
-        else {
-            PassRefPtr<CSSValue> oldVal(lval.release());
-            PassRefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-            list->append(oldVal);
-            list->append(rval);
-            lval = list;
-        }
-    }
-    else
-        lval = rval;
-}
-
-bool BisonCSSParser::parseAnimationShorthand(CSSPropertyID propId, bool important)
-{
-    const StylePropertyShorthand& animationProperties = parsingShorthandForProperty(propId);
-    const unsigned numProperties = 8;
-
-    // The list of properties in the shorthand should be the same
-    // length as the list with animation name in last position, even though they are
-    // in a different order.
-    ASSERT(numProperties == animationProperties.length());
-    ASSERT(numProperties == shorthandForProperty(propId).length());
-
-    ShorthandScope scope(this, propId);
-
-    bool parsedProperty[numProperties] = { false };
-    AnimationParseContext context;
-    RefPtr<CSSValue> values[numProperties];
-
-    unsigned i;
-    while (m_valueList->current()) {
-        CSSParserValue* val = m_valueList->current();
-        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
-            // We hit the end.  Fill in all remaining values with the initial value.
-            m_valueList->next();
-            for (i = 0; i < numProperties; ++i) {
-                if (!parsedProperty[i])
-                    addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
-                parsedProperty[i] = false;
-            }
-            if (!m_valueList->current())
-                break;
-            context.commitFirstAnimation();
-        }
-
-        bool found = false;
-        for (i = 0; i < numProperties; ++i) {
-            if (!parsedProperty[i]) {
-                RefPtr<CSSValue> val;
-                if (parseAnimationProperty(animationProperties.properties()[i], val, context)) {
-                    parsedProperty[i] = found = true;
-                    addAnimationValue(values[i], val.release());
-                    break;
-                }
-            }
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found)
-            return false;
-    }
-
-    for (i = 0; i < numProperties; ++i) {
-        // If we didn't find the property, set an intial value.
-        if (!parsedProperty[i])
-            addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
-
-        addProperty(animationProperties.properties()[i], values[i].release(), important);
-    }
-
-    return true;
-}
-
-bool BisonCSSParser::parseTransitionShorthand(CSSPropertyID propId, bool important)
-{
-    const unsigned numProperties = 4;
-    const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
-    ASSERT(numProperties == shorthand.length());
-
-    ShorthandScope scope(this, propId);
-
-    bool parsedProperty[numProperties] = { false };
-    AnimationParseContext context;
-    RefPtr<CSSValue> values[numProperties];
-
-    unsigned i;
-    while (m_valueList->current()) {
-        CSSParserValue* val = m_valueList->current();
-        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
-            // We hit the end. Fill in all remaining values with the initial value.
-            m_valueList->next();
-            for (i = 0; i < numProperties; ++i) {
-                if (!parsedProperty[i])
-                    addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
-                parsedProperty[i] = false;
-            }
-            if (!m_valueList->current())
-                break;
-            context.commitFirstAnimation();
-        }
-
-        bool found = false;
-        for (i = 0; !found && i < numProperties; ++i) {
-            if (!parsedProperty[i]) {
-                RefPtr<CSSValue> val;
-                if (parseAnimationProperty(shorthand.properties()[i], val, context)) {
-                    parsedProperty[i] = found = true;
-                    addAnimationValue(values[i], val.release());
-                }
-
-                // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid.
-                if (!context.animationPropertyKeywordAllowed() && context.hasCommittedFirstAnimation())
-                    return false;
-            }
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found)
-            return false;
-    }
-
-    // Fill in any remaining properties with the initial value.
-    for (i = 0; i < numProperties; ++i) {
-        if (!parsedProperty[i])
-            addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
-    }
-
-    // Now add all of the properties we found.
-    for (i = 0; i < numProperties; i++)
-        addPropertyWithPrefixingVariant(shorthand.properties()[i], values[i].release(), important);
-
-    return true;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseColumnWidth()
-{
-    CSSParserValue* value = m_valueList->current();
-    // Always parse lengths in strict mode here, since it would be ambiguous otherwise when used in
-    // the 'columns' shorthand property.
-    if (value->id == CSSValueAuto
-        || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && value->fValue)) {
-        RefPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
-        m_valueList->next();
-        return parsedValue;
-    }
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseColumnCount()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueAuto
-        || (!value->id && validUnit(value, FPositiveInteger, HTMLQuirksMode))) {
-        RefPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
-        m_valueList->next();
-        return parsedValue;
-    }
-    return 0;
-}
-
-bool BisonCSSParser::parseColumnsShorthand(bool important)
-{
-    RefPtr <CSSValue> columnWidth;
-    RefPtr <CSSValue> columnCount;
-    bool hasPendingExplicitAuto = false;
-
-    for (unsigned propertiesParsed = 0; CSSParserValue* value = m_valueList->current(); propertiesParsed++) {
-        if (propertiesParsed >= 2)
-            return false; // Too many values for this shorthand. Invalid declaration.
-        if (!propertiesParsed && value->id == CSSValueAuto) {
-            // 'auto' is a valid value for any of the two longhands, and at this point we
-            // don't know which one(s) it is meant for. We need to see if there are other
-            // values first.
-            m_valueList->next();
-            hasPendingExplicitAuto = true;
-        } else {
-            if (!columnWidth) {
-                if ((columnWidth = parseColumnWidth()))
-                    continue;
-            }
-            if (!columnCount) {
-                if ((columnCount = parseColumnCount()))
-                    continue;
-            }
-            // If we didn't find at least one match, this is an
-            // invalid shorthand and we have to ignore it.
-            return false;
-        }
-    }
-    if (hasPendingExplicitAuto) {
-        // Time to assign the previously skipped 'auto' value to a property. If both properties are
-        // unassigned at this point (i.e. 'columns:auto'), it doesn't matter that much which one we
-        // set (although it does make a slight difference to web-inspector). The one we don't set
-        // here will get an implicit 'auto' value further down.
-        if (!columnWidth) {
-            columnWidth = cssValuePool().createIdentifierValue(CSSValueAuto);
-        } else {
-            ASSERT(!columnCount);
-            columnCount = cssValuePool().createIdentifierValue(CSSValueAuto);
-        }
-    }
-    ASSERT(columnCount || columnWidth);
-
-    // Any unassigned property at this point will become implicit 'auto'.
-    if (columnWidth)
-        addProperty(CSSPropertyWebkitColumnWidth, columnWidth, important);
-    else
-        addProperty(CSSPropertyWebkitColumnWidth, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
-    if (columnCount)
-        addProperty(CSSPropertyWebkitColumnCount, columnCount, important);
-    else
-        addProperty(CSSPropertyWebkitColumnCount, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
-    return true;
-}
-
-bool BisonCSSParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthand& shorthand, bool important)
-{
-    // We try to match as many properties as possible
-    // We set up an array of booleans to mark which property has been found,
-    // and we try to search for properties until it makes no longer any sense.
-    ShorthandScope scope(this, propId);
-
-    bool found = false;
-    unsigned propertiesParsed = 0;
-    bool propertyFound[6] = { false, false, false, false, false, false }; // 6 is enough size.
-
-    while (m_valueList->current()) {
-        found = false;
-        for (unsigned propIndex = 0; !found && propIndex < shorthand.length(); ++propIndex) {
-            if (!propertyFound[propIndex] && parseValue(shorthand.properties()[propIndex], important)) {
-                propertyFound[propIndex] = found = true;
-                propertiesParsed++;
-            }
-        }
-
-        // if we didn't find at least one match, this is an
-        // invalid shorthand and we have to ignore it
-        if (!found)
-            return false;
-    }
-
-    if (propertiesParsed == shorthand.length())
-        return true;
-
-    // Fill in any remaining properties with the initial value.
-    ImplicitScope implicitScope(this, PropertyImplicit);
-    const StylePropertyShorthand* const* const propertiesForInitialization = shorthand.propertiesForInitialization();
-    for (unsigned i = 0; i < shorthand.length(); ++i) {
-        if (propertyFound[i])
-            continue;
-
-        if (propertiesForInitialization) {
-            const StylePropertyShorthand& initProperties = *(propertiesForInitialization[i]);
-            for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex)
-                addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important);
-        } else
-            addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important);
-    }
-
-    return true;
-}
-
-bool BisonCSSParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properties,  bool important)
-{
-    /* From the CSS 2 specs, 8.3
-     * If there is only one value, it applies to all sides. If there are two values, the top and
-     * bottom margins are set to the first value and the right and left margins are set to the second.
-     * If there are three values, the top is set to the first value, the left and right are set to the
-     * second, and the bottom is set to the third. If there are four values, they apply to the top,
-     * right, bottom, and left, respectively.
-     */
-
-    int num = inShorthand() ? 1 : m_valueList->size();
-
-    ShorthandScope scope(this, propId);
-
-    // the order is top, right, bottom, left
-    switch (num) {
-        case 1: {
-            if (!parseValue(properties[0], important))
-                return false;
-            CSSValue* value = m_parsedProperties.last().value();
-            ImplicitScope implicitScope(this, PropertyImplicit);
-            addProperty(properties[1], value, important);
-            addProperty(properties[2], value, important);
-            addProperty(properties[3], value, important);
-            break;
-        }
-        case 2: {
-            if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
-                return false;
-            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
-            ImplicitScope implicitScope(this, PropertyImplicit);
-            addProperty(properties[2], value, important);
-            value = m_parsedProperties[m_parsedProperties.size() - 2].value();
-            addProperty(properties[3], value, important);
-            break;
-        }
-        case 3: {
-            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
-                return false;
-            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
-            ImplicitScope implicitScope(this, PropertyImplicit);
-            addProperty(properties[3], value, important);
-            break;
-        }
-        case 4: {
-            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
-                !parseValue(properties[2], important) || !parseValue(properties[3], important))
-                return false;
-            break;
-        }
-        default: {
-            return false;
-        }
-    }
-
-    return true;
-}
-
-// auto | <identifier>
-bool BisonCSSParser::parsePage(CSSPropertyID propId, bool important)
-{
-    ASSERT(propId == CSSPropertyPage);
-
-    if (m_valueList->size() != 1)
-        return false;
-
-    CSSParserValue* value = m_valueList->current();
-    if (!value)
-        return false;
-
-    if (value->id == CSSValueAuto) {
-        addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
-        return true;
-    } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) {
-        addProperty(propId, createPrimitiveStringValue(value), important);
-        return true;
-    }
-    return false;
-}
-
-// <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
-bool BisonCSSParser::parseSize(CSSPropertyID propId, bool important)
-{
-    ASSERT(propId == CSSPropertySize);
-
-    if (m_valueList->size() > 2)
-        return false;
-
-    CSSParserValue* value = m_valueList->current();
-    if (!value)
-        return false;
-
-    RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
-
-    // First parameter.
-    SizeParameterType paramType = parseSizeParameter(parsedValues.get(), value, None);
-    if (paramType == None)
-        return false;
-
-    // Second parameter, if any.
-    value = m_valueList->next();
-    if (value) {
-        paramType = parseSizeParameter(parsedValues.get(), value, paramType);
-        if (paramType == None)
-            return false;
-    }
-
-    addProperty(propId, parsedValues.release(), important);
-    return true;
-}
-
-BisonCSSParser::SizeParameterType BisonCSSParser::parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType)
-{
-    switch (value->id) {
-    case CSSValueAuto:
-        if (prevParamType == None) {
-            parsedValues->append(cssValuePool().createIdentifierValue(value->id));
-            return Auto;
-        }
-        return None;
-    case CSSValueLandscape:
-    case CSSValuePortrait:
-        if (prevParamType == None || prevParamType == PageSize) {
-            parsedValues->append(cssValuePool().createIdentifierValue(value->id));
-            return Orientation;
-        }
-        return None;
-    case CSSValueA3:
-    case CSSValueA4:
-    case CSSValueA5:
-    case CSSValueB4:
-    case CSSValueB5:
-    case CSSValueLedger:
-    case CSSValueLegal:
-    case CSSValueLetter:
-        if (prevParamType == None || prevParamType == Orientation) {
-            // Normalize to Page Size then Orientation order by prepending.
-            // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (StyleResolver::applyPageSizeProperty).
-            parsedValues->prepend(cssValuePool().createIdentifierValue(value->id));
-            return PageSize;
-        }
-        return None;
-    case 0:
-        if (validUnit(value, FLength | FNonNeg) && (prevParamType == None || prevParamType == Length)) {
-            parsedValues->append(createPrimitiveNumericValue(value));
-            return Length;
-        }
-        return None;
-    default:
-        return None;
-    }
-}
-
-// [ <string> <string> ]+ | inherit | none
-// inherit and none are handled in parseValue.
-bool BisonCSSParser::parseQuotes(CSSPropertyID propId, bool important)
-{
-    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
-    while (CSSParserValue* val = m_valueList->current()) {
-        RefPtr<CSSValue> parsedValue;
-        if (val->unit == CSSPrimitiveValue::CSS_STRING)
-            parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
-        else
-            break;
-        values->append(parsedValue.release());
-        m_valueList->next();
-    }
-    if (values->length()) {
-        addProperty(propId, values.release(), important);
-        m_valueList->next();
-        return true;
-    }
-    return false;
-}
-
-// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
-// in CSS 2.1 this got somewhat reduced:
-// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
-bool BisonCSSParser::parseContent(CSSPropertyID propId, bool important)
-{
-    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
-
-    while (CSSParserValue* val = m_valueList->current()) {
-        RefPtr<CSSValue> parsedValue;
-        if (val->unit == CSSPrimitiveValue::CSS_URI) {
-            // url
-            parsedValue = CSSImageValue::create(completeURL(val->string));
-        } else if (val->unit == CSSParserValue::Function) {
-            // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
-            CSSParserValueList* args = val->function->args.get();
-            if (!args)
-                return false;
-            if (equalIgnoringCase(val->function->name, "attr(")) {
-                parsedValue = parseAttr(args);
-                if (!parsedValue)
-                    return false;
-            } else if (equalIgnoringCase(val->function->name, "counter(")) {
-                parsedValue = parseCounterContent(args, false);
-                if (!parsedValue)
-                    return false;
-            } else if (equalIgnoringCase(val->function->name, "counters(")) {
-                parsedValue = parseCounterContent(args, true);
-                if (!parsedValue)
-                    return false;
-            } else if (equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
-                parsedValue = parseImageSet(m_valueList.get());
-                if (!parsedValue)
-                    return false;
-            } else if (isGeneratedImageValue(val)) {
-                if (!parseGeneratedImage(m_valueList.get(), parsedValue))
-                    return false;
-            } else
-                return false;
-        } else if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
-            // open-quote
-            // close-quote
-            // no-open-quote
-            // no-close-quote
-            // inherit
-            // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
-            // none
-            // normal
-            switch (val->id) {
-            case CSSValueOpenQuote:
-            case CSSValueCloseQuote:
-            case CSSValueNoOpenQuote:
-            case CSSValueNoCloseQuote:
-            case CSSValueNone:
-            case CSSValueNormal:
-                parsedValue = cssValuePool().createIdentifierValue(val->id);
-            default:
-                break;
-            }
-        } else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
-            parsedValue = createPrimitiveStringValue(val);
-        }
-        if (!parsedValue)
-            break;
-        values->append(parsedValue.release());
-        m_valueList->next();
-    }
-
-    if (values->length()) {
-        addProperty(propId, values.release(), important);
-        m_valueList->next();
-        return true;
-    }
-
-    return false;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAttr(CSSParserValueList* args)
-{
-    if (args->size() != 1)
-        return 0;
-
-    CSSParserValue* a = args->current();
-
-    if (a->unit != CSSPrimitiveValue::CSS_IDENT)
-        return 0;
-
-    String attrName = a->string;
-    // CSS allows identifiers with "-" at the start, like "-webkit-mask-image".
-    // But HTML attribute names can't have those characters, and we should not
-    // even parse them inside attr().
-    if (attrName[0] == '-')
-        return 0;
-
-    if (m_context.isHTMLDocument())
-        attrName = attrName.lower();
-
-    return cssValuePool().createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseBackgroundColor()
-{
-    CSSValueID id = m_valueList->current()->id;
-    if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
-        (id >= CSSValueGrey && id < CSSValueWebkitText && inQuirksMode()))
-        return cssValuePool().createIdentifierValue(id);
-    return parseColor();
-}
-
-bool BisonCSSParser::parseFillImage(CSSParserValueList* valueList, RefPtr<CSSValue>& value)
-{
-    if (valueList->current()->id == CSSValueNone) {
-        value = cssValuePool().createIdentifierValue(CSSValueNone);
-        return true;
-    }
-    if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
-        value = CSSImageValue::create(completeURL(valueList->current()->string));
-        return true;
-    }
-
-    if (isGeneratedImageValue(valueList->current()))
-        return parseGeneratedImage(valueList, value);
-
-    if (valueList->current()->unit == CSSParserValue::Function && equalIgnoringCase(valueList->current()->function->name, "-webkit-image-set(")) {
-        value = parseImageSet(m_valueList.get());
-        if (value)
-            return true;
-    }
-
-    return false;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseFillPositionX(CSSParserValueList* valueList)
-{
-    int id = valueList->current()->id;
-    if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
-        int percent = 0;
-        if (id == CSSValueRight)
-            percent = 100;
-        else if (id == CSSValueCenter)
-            percent = 50;
-        return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
-    }
-    if (validUnit(valueList->current(), FPercent | FLength))
-        return createPrimitiveNumericValue(valueList->current());
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseFillPositionY(CSSParserValueList* valueList)
-{
-    int id = valueList->current()->id;
-    if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
-        int percent = 0;
-        if (id == CSSValueBottom)
-            percent = 100;
-        else if (id == CSSValueCenter)
-            percent = 50;
-        return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
-    }
-    if (validUnit(valueList->current(), FPercent | FLength))
-        return createPrimitiveNumericValue(valueList->current());
-    return 0;
-}
-
-PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::parseFillPositionComponent(CSSParserValueList* valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode parsingMode)
-{
-    CSSValueID id = valueList->current()->id;
-    if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
-        int percent = 0;
-        if (id == CSSValueLeft || id == CSSValueRight) {
-            if (cumulativeFlags & XFillPosition)
-                return 0;
-            cumulativeFlags |= XFillPosition;
-            individualFlag = XFillPosition;
-            if (id == CSSValueRight)
-                percent = 100;
-        }
-        else if (id == CSSValueTop || id == CSSValueBottom) {
-            if (cumulativeFlags & YFillPosition)
-                return 0;
-            cumulativeFlags |= YFillPosition;
-            individualFlag = YFillPosition;
-            if (id == CSSValueBottom)
-                percent = 100;
-        } else if (id == CSSValueCenter) {
-            // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
-            percent = 50;
-            cumulativeFlags |= AmbiguousFillPosition;
-            individualFlag = AmbiguousFillPosition;
-        }
-
-        if (parsingMode == ResolveValuesAsKeyword)
-            return cssValuePool().createIdentifierValue(id);
-
-        return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
-    }
-    if (validUnit(valueList->current(), FPercent | FLength)) {
-        if (!cumulativeFlags) {
-            cumulativeFlags |= XFillPosition;
-            individualFlag = XFillPosition;
-        } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
-            cumulativeFlags |= YFillPosition;
-            individualFlag = YFillPosition;
-        } else {
-            if (m_parsedCalculation)
-                m_parsedCalculation.release();
-            return 0;
-        }
-        return createPrimitiveNumericValue(valueList->current());
-    }
-    return 0;
-}
-
-static bool isValueConflictingWithCurrentEdge(int value1, int value2)
-{
-    if ((value1 == CSSValueLeft || value1 == CSSValueRight) && (value2 == CSSValueLeft || value2 == CSSValueRight))
-        return true;
-
-    if ((value1 == CSSValueTop || value1 == CSSValueBottom) && (value2 == CSSValueTop || value2 == CSSValueBottom))
-        return true;
-
-    return false;
-}
-
-static bool isFillPositionKeyword(CSSValueID value)
-{
-    return value == CSSValueLeft || value == CSSValueTop || value == CSSValueBottom || value == CSSValueRight || value == CSSValueCenter;
-}
-
-void BisonCSSParser::parse4ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2)
-{
-    // [ left | right ] [ <percentage] | <length> ] && [ top | bottom ] [ <percentage> | <length> ]
-    // In the case of 4 values <position> requires the second value to be a length or a percentage.
-    if (isFillPositionKeyword(parsedValue2->getValueID()))
-        return;
-
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value3Flag = InvalidFillPosition;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
-    if (!value3)
-        return;
-
-    CSSValueID ident1 = parsedValue1->getValueID();
-    CSSValueID ident3 = value3->getValueID();
-
-    if (ident1 == CSSValueCenter)
-        return;
-
-    if (!isFillPositionKeyword(ident3) || ident3 == CSSValueCenter)
-        return;
-
-    // We need to check if the values are not conflicting, e.g. they are not on the same edge. It is
-    // needed as the second call to parseFillPositionComponent was on purpose not checking it. In the
-    // case of two values top 20px is invalid but in the case of 4 values it becomes valid.
-    if (isValueConflictingWithCurrentEdge(ident1, ident3))
-        return;
-
-    valueList->next();
-
-    cumulativeFlags = 0;
-    FillPositionFlag value4Flag = InvalidFillPosition;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> value4 = parseFillPositionComponent(valueList, cumulativeFlags, value4Flag, ResolveValuesAsKeyword);
-    if (!value4)
-        return;
-
-    // 4th value must be a length or a percentage.
-    if (isFillPositionKeyword(value4->getValueID()))
-        return;
-
-    value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
-    value2 = createPrimitiveValuePair(value3, value4);
-
-    if (ident1 == CSSValueTop || ident1 == CSSValueBottom)
-        value1.swap(value2);
-
-    valueList->next();
-}
-void BisonCSSParser::parse3ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2)
-{
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value3Flag = InvalidFillPosition;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
-
-    // value3 is not an expected value, we return.
-    if (!value3)
-        return;
-
-    valueList->next();
-
-    bool swapNeeded = false;
-    CSSValueID ident1 = parsedValue1->getValueID();
-    CSSValueID ident2 = parsedValue2->getValueID();
-    CSSValueID ident3 = value3->getValueID();
-
-    CSSValueID firstPositionKeyword;
-    CSSValueID secondPositionKeyword;
-
-    if (ident1 == CSSValueCenter) {
-        // <position> requires the first 'center' to be followed by a keyword.
-        if (!isFillPositionKeyword(ident2))
-            return;
-
-        // If 'center' is the first keyword then the last one needs to be a length.
-        if (isFillPositionKeyword(ident3))
-            return;
-
-        firstPositionKeyword = CSSValueLeft;
-        if (ident2 == CSSValueLeft || ident2 == CSSValueRight) {
-            firstPositionKeyword = CSSValueTop;
-            swapNeeded = true;
-        }
-        value1 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(firstPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
-        value2 = createPrimitiveValuePair(parsedValue2, value3);
-    } else if (ident3 == CSSValueCenter) {
-        if (isFillPositionKeyword(ident2))
-            return;
-
-        secondPositionKeyword = CSSValueTop;
-        if (ident1 == CSSValueTop || ident1 == CSSValueBottom) {
-            secondPositionKeyword = CSSValueLeft;
-            swapNeeded = true;
-        }
-        value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
-        value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
-    } else {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> firstPositionValue;
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> secondPositionValue;
-
-        if (isFillPositionKeyword(ident2)) {
-            // To match CSS grammar, we should only accept: [ center | left | right | bottom | top ] [ left | right | top | bottom ] [ <percentage> | <length> ].
-            ASSERT(ident2 != CSSValueCenter);
-
-            if (isFillPositionKeyword(ident3))
-                return;
-
-            secondPositionValue = value3;
-            secondPositionKeyword = ident2;
-            firstPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
-        } else {
-            // Per CSS, we should only accept: [ right | left | top | bottom ] [ <percentage> | <length> ] [ center | left | right | bottom | top ].
-            if (!isFillPositionKeyword(ident3))
-                return;
-
-            firstPositionValue = parsedValue2;
-            secondPositionKeyword = ident3;
-            secondPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
-        }
-
-        if (isValueConflictingWithCurrentEdge(ident1, secondPositionKeyword))
-            return;
-
-        value1 = createPrimitiveValuePair(parsedValue1, firstPositionValue);
-        value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), secondPositionValue);
-    }
-
-    if (ident1 == CSSValueTop || ident1 == CSSValueBottom || swapNeeded)
-        value1.swap(value2);
-
-#ifndef NDEBUG
-    CSSPrimitiveValue* first = toCSSPrimitiveValue(value1.get());
-    CSSPrimitiveValue* second = toCSSPrimitiveValue(value2.get());
-    ident1 = first->getPairValue()->first()->getValueID();
-    ident2 = second->getPairValue()->first()->getValueID();
-    ASSERT(ident1 == CSSValueLeft || ident1 == CSSValueRight);
-    ASSERT(ident2 == CSSValueBottom || ident2 == CSSValueTop);
-#endif
-}
-
-inline bool BisonCSSParser::isPotentialPositionValue(CSSParserValue* value)
-{
-    return isFillPositionKeyword(value->id) || validUnit(value, FPercent | FLength, ReleaseParsedCalcValue);
-}
-
-void BisonCSSParser::parseFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
-{
-    unsigned numberOfValues = 0;
-    for (unsigned i = valueList->currentIndex(); i < valueList->size(); ++i, ++numberOfValues) {
-        CSSParserValue* current = valueList->valueAt(i);
-        if (isComma(current) || !current || isForwardSlashOperator(current) || !isPotentialPositionValue(current))
-            break;
-    }
-
-    if (numberOfValues > 4)
-        return;
-
-    // If we are parsing two values, we can safely call the CSS 2.1 parsing function and return.
-    if (numberOfValues <= 2) {
-        parse2ValuesFillPosition(valueList, value1, value2);
-        return;
-    }
-
-    ASSERT(numberOfValues > 2 && numberOfValues <= 4);
-
-    CSSParserValue* value = valueList->current();
-
-    // <position> requires the first value to be a background keyword.
-    if (!isFillPositionKeyword(value->id))
-        return;
-
-    // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value1Flag = InvalidFillPosition;
-    FillPositionFlag value2Flag = InvalidFillPosition;
-    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag, ResolveValuesAsKeyword);
-    if (!value1)
-        return;
-
-    valueList->next();
-
-    // In case we are parsing more than two values, relax the check inside of parseFillPositionComponent. top 20px is
-    // a valid start for <position>.
-    cumulativeFlags = AmbiguousFillPosition;
-    value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag, ResolveValuesAsKeyword);
-    if (value2)
-        valueList->next();
-    else {
-        value1.clear();
-        return;
-    }
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1 = toCSSPrimitiveValue(value1.get());
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2 = toCSSPrimitiveValue(value2.get());
-
-    value1.clear();
-    value2.clear();
-
-    // Per CSS3 syntax, <position> can't have 'center' as its second keyword as we have more arguments to follow.
-    if (parsedValue2->getValueID() == CSSValueCenter)
-        return;
-
-    if (numberOfValues == 3)
-        parse3ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
-    else
-        parse4ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
-}
-
-void BisonCSSParser::parse2ValuesFillPosition(CSSParserValueList* valueList, RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
-{
-    CSSParserValue* value = valueList->current();
-
-    // Parse the first value.  We're just making sure that it is one of the valid keywords or a percentage/length.
-    unsigned cumulativeFlags = 0;
-    FillPositionFlag value1Flag = InvalidFillPosition;
-    FillPositionFlag value2Flag = InvalidFillPosition;
-    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
-    if (!value1)
-        return;
-
-    // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
-    // can assume that any other values belong to the rest of the shorthand).  If we're not parsing a shorthand, though, the
-    // value was explicitly specified for our property.
-    value = valueList->next();
-
-    // First check for the comma.  If so, we are finished parsing this value or value pair.
-    if (isComma(value))
-        value = 0;
-
-    if (value) {
-        value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
-        if (value2)
-            valueList->next();
-        else {
-            if (!inShorthand()) {
-                value1.clear();
-                return;
-            }
-        }
-    }
-
-    if (!value2)
-        // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position
-        // is simply 50%. This is our default.
-        // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
-        // For left/right/center, the default of 50% in the y is still correct.
-        value2 = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
-
-    if (value1Flag == YFillPosition || value2Flag == XFillPosition)
-        value1.swap(value2);
-}
-
-void BisonCSSParser::parseFillRepeat(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2)
-{
-    CSSValueID id = m_valueList->current()->id;
-    if (id == CSSValueRepeatX) {
-        m_implicitShorthand = true;
-        value1 = cssValuePool().createIdentifierValue(CSSValueRepeat);
-        value2 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
-        m_valueList->next();
-        return;
-    }
-    if (id == CSSValueRepeatY) {
-        m_implicitShorthand = true;
-        value1 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
-        value2 = cssValuePool().createIdentifierValue(CSSValueRepeat);
-        m_valueList->next();
-        return;
-    }
-    if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
-        value1 = cssValuePool().createIdentifierValue(id);
-    else {
-        value1 = 0;
-        return;
-    }
-
-    CSSParserValue* value = m_valueList->next();
-
-    // Parse the second value if one is available
-    if (value && !isComma(value)) {
-        id = value->id;
-        if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) {
-            value2 = cssValuePool().createIdentifierValue(id);
-            m_valueList->next();
-            return;
-        }
-    }
-
-    // If only one value was specified, value2 is the same as value1.
-    m_implicitShorthand = true;
-    value2 = cssValuePool().createIdentifierValue(toCSSPrimitiveValue(value1.get())->getValueID());
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseFillSize(CSSPropertyID propId, bool& allowComma)
-{
-    allowComma = true;
-    CSSParserValue* value = m_valueList->current();
-
-    if (value->id == CSSValueContain || value->id == CSSValueCover)
-        return cssValuePool().createIdentifierValue(value->id);
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1;
-
-    if (value->id == CSSValueAuto)
-        parsedValue1 = cssValuePool().createIdentifierValue(CSSValueAuto);
-    else {
-        if (!validUnit(value, FLength | FPercent))
-            return 0;
-        parsedValue1 = createPrimitiveNumericValue(value);
-    }
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2;
-    if ((value = m_valueList->next())) {
-        if (value->unit == CSSParserValue::Operator && value->iValue == ',')
-            allowComma = false;
-        else if (value->id != CSSValueAuto) {
-            if (!validUnit(value, FLength | FPercent)) {
-                if (!inShorthand())
-                    return 0;
-                // We need to rewind the value list, so that when it is advanced we'll end up back at this value.
-                m_valueList->previous();
-            } else
-                parsedValue2 = createPrimitiveNumericValue(value);
-        }
-    } else if (!parsedValue2 && propId == CSSPropertyWebkitBackgroundSize) {
-        // For backwards compatibility we set the second value to the first if it is omitted.
-        // We only need to do this for -webkit-background-size. It should be safe to let masks match
-        // the real property.
-        parsedValue2 = parsedValue1;
-    }
-
-    if (!parsedValue2)
-        return parsedValue1;
-    return createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release());
-}
-
-bool BisonCSSParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,
-                                  RefPtr<CSSValue>& retValue1, RefPtr<CSSValue>& retValue2)
-{
-    RefPtrWillBeRawPtr<CSSValueList> values;
-    RefPtrWillBeRawPtr<CSSValueList> values2;
-    CSSParserValue* val;
-    RefPtr<CSSValue> value;
-    RefPtr<CSSValue> value2;
-
-    bool allowComma = false;
-
-    retValue1 = retValue2 = 0;
-    propId1 = propId;
-    propId2 = propId;
-    if (propId == CSSPropertyBackgroundPosition) {
-        propId1 = CSSPropertyBackgroundPositionX;
-        propId2 = CSSPropertyBackgroundPositionY;
-    } else if (propId == CSSPropertyWebkitMaskPosition) {
-        propId1 = CSSPropertyWebkitMaskPositionX;
-        propId2 = CSSPropertyWebkitMaskPositionY;
-    } else if (propId == CSSPropertyBackgroundRepeat) {
-        propId1 = CSSPropertyBackgroundRepeatX;
-        propId2 = CSSPropertyBackgroundRepeatY;
-    } else if (propId == CSSPropertyWebkitMaskRepeat) {
-        propId1 = CSSPropertyWebkitMaskRepeatX;
-        propId2 = CSSPropertyWebkitMaskRepeatY;
-    }
-
-    while ((val = m_valueList->current())) {
-        RefPtr<CSSValue> currValue;
-        RefPtr<CSSValue> currValue2;
-
-        if (allowComma) {
-            if (!isComma(val))
-                return false;
-            m_valueList->next();
-            allowComma = false;
-        } else {
-            allowComma = true;
-            switch (propId) {
-                case CSSPropertyBackgroundColor:
-                    currValue = parseBackgroundColor();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyBackgroundAttachment:
-                    if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) {
-                        currValue = cssValuePool().createIdentifierValue(val->id);
-                        m_valueList->next();
-                    }
-                    break;
-                case CSSPropertyBackgroundImage:
-                case CSSPropertyWebkitMaskImage:
-                    if (parseFillImage(m_valueList.get(), currValue))
-                        m_valueList->next();
-                    break;
-                case CSSPropertyWebkitBackgroundClip:
-                case CSSPropertyWebkitBackgroundOrigin:
-                case CSSPropertyWebkitMaskClip:
-                case CSSPropertyWebkitMaskOrigin:
-                    // The first three values here are deprecated and do not apply to the version of the property that has
-                    // the -webkit- prefix removed.
-                    if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent ||
-                        val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox ||
-                        ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) &&
-                         (val->id == CSSValueText || val->id == CSSValueWebkitText))) {
-                        currValue = cssValuePool().createIdentifierValue(val->id);
-                        m_valueList->next();
-                    }
-                    break;
-                case CSSPropertyBackgroundClip:
-                    if (parseBackgroundClip(val, currValue))
-                        m_valueList->next();
-                    break;
-                case CSSPropertyBackgroundOrigin:
-                    if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) {
-                        currValue = cssValuePool().createIdentifierValue(val->id);
-                        m_valueList->next();
-                    }
-                    break;
-                case CSSPropertyBackgroundPosition:
-                case CSSPropertyWebkitMaskPosition:
-                    parseFillPosition(m_valueList.get(), currValue, currValue2);
-                    // parseFillPosition advances the m_valueList pointer.
-                    break;
-                case CSSPropertyBackgroundPositionX:
-                case CSSPropertyWebkitMaskPositionX: {
-                    currValue = parseFillPositionX(m_valueList.get());
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                }
-                case CSSPropertyBackgroundPositionY:
-                case CSSPropertyWebkitMaskPositionY: {
-                    currValue = parseFillPositionY(m_valueList.get());
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                }
-                case CSSPropertyWebkitBackgroundComposite:
-                case CSSPropertyWebkitMaskComposite:
-                    if (val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) {
-                        currValue = cssValuePool().createIdentifierValue(val->id);
-                        m_valueList->next();
-                    }
-                    break;
-                case CSSPropertyBackgroundBlendMode:
-                    if (RuntimeEnabledFeatures::cssCompositingEnabled() && (val->id == CSSValueNormal || val->id == CSSValueMultiply
-                        || val->id == CSSValueScreen || val->id == CSSValueOverlay || val->id == CSSValueDarken
-                        || val->id == CSSValueLighten ||  val->id == CSSValueColorDodge || val->id == CSSValueColorBurn
-                        || val->id == CSSValueHardLight || val->id == CSSValueSoftLight || val->id == CSSValueDifference
-                        || val->id == CSSValueExclusion || val->id == CSSValueHue || val->id == CSSValueSaturation
-                        || val->id == CSSValueColor || val->id == CSSValueLuminosity)) {
-                        currValue = cssValuePool().createIdentifierValue(val->id);
-                        m_valueList->next();
-                    }
-                    break;
-                case CSSPropertyBackgroundRepeat:
-                case CSSPropertyWebkitMaskRepeat:
-                    parseFillRepeat(currValue, currValue2);
-                    // parseFillRepeat advances the m_valueList pointer
-                    break;
-                case CSSPropertyBackgroundSize:
-                case CSSPropertyWebkitBackgroundSize:
-                case CSSPropertyWebkitMaskSize: {
-                    currValue = parseFillSize(propId, allowComma);
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                }
-                case CSSPropertyMaskSourceType: {
-                    if (RuntimeEnabledFeatures::cssMaskSourceTypeEnabled()) {
-                        if (val->id == CSSValueAuto || val->id == CSSValueAlpha || val->id == CSSValueLuminance) {
-                            currValue = cssValuePool().createIdentifierValue(val->id);
-                            m_valueList->next();
-                        } else {
-                            currValue = 0;
-                        }
-                    }
-                    break;
-                }
-                default:
-                    break;
-            }
-            if (!currValue)
-                return false;
-
-            if (value && !values) {
-                values = CSSValueList::createCommaSeparated();
-                values->append(value.release());
-            }
-
-            if (value2 && !values2) {
-                values2 = CSSValueList::createCommaSeparated();
-                values2->append(value2.release());
-            }
-
-            if (values)
-                values->append(currValue.release());
-            else
-                value = currValue.release();
-            if (currValue2) {
-                if (values2)
-                    values2->append(currValue2.release());
-                else
-                    value2 = currValue2.release();
-            }
-        }
-
-        // When parsing any fill shorthand property, we let it handle building up the lists for all
-        // properties.
-        if (inShorthand())
-            break;
-    }
-
-    if (values && values->length()) {
-        retValue1 = values.release();
-        if (values2 && values2->length())
-            retValue2 = values2.release();
-        return true;
-    }
-    if (value) {
-        retValue1 = value.release();
-        retValue2 = value2.release();
-        return true;
-    }
-    return false;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationDelay()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (validUnit(value, FTime))
-        return createPrimitiveNumericValue(value);
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationDirection()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueNormal || value->id == CSSValueAlternate || value->id == CSSValueReverse || value->id == CSSValueAlternateReverse)
-        return cssValuePool().createIdentifierValue(value->id);
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationDuration()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (validUnit(value, FTime | FNonNeg))
-        return createPrimitiveNumericValue(value);
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationFillMode()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth)
-        return cssValuePool().createIdentifierValue(value->id);
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationIterationCount()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueInfinite)
-        return cssValuePool().createIdentifierValue(value->id);
-    if (validUnit(value, FNumber | FNonNeg))
-        return createPrimitiveNumericValue(value);
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationName()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) {
-        if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value, "none"))) {
-            return cssValuePool().createIdentifierValue(CSSValueNone);
-        } else {
-            return createPrimitiveStringValue(value);
-        }
-    }
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationPlayState()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueRunning || value->id == CSSValuePaused)
-        return cssValuePool().createIdentifierValue(value->id);
-    return 0;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationProperty(AnimationParseContext& context)
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->unit != CSSPrimitiveValue::CSS_IDENT)
-        return 0;
-    CSSPropertyID result = cssPropertyID(value->string);
-    if (result)
-        return cssValuePool().createIdentifierValue(result);
-    if (equalIgnoringCase(value, "all")) {
-        context.sawAnimationPropertyKeyword();
-        return cssValuePool().createIdentifierValue(CSSValueAll);
-    }
-    if (equalIgnoringCase(value, "none")) {
-        context.commitAnimationPropertyKeyword();
-        context.sawAnimationPropertyKeyword();
-        return cssValuePool().createIdentifierValue(CSSValueNone);
-    }
-    return 0;
-}
-
-bool BisonCSSParser::parseTransformOriginShorthand(RefPtr<CSSValue>& value1, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
-{
-    parse2ValuesFillPosition(m_valueList.get(), value1, value2);
-
-    // now get z
-    if (m_valueList->current()) {
-        if (validUnit(m_valueList->current(), FLength)) {
-            value3 = createPrimitiveNumericValue(m_valueList->current());
-            m_valueList->next();
-            return true;
-        }
-        return false;
-    }
-    value3 = cssValuePool().createImplicitInitialValue();
-    return true;
-}
-
-bool BisonCSSParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result)
-{
-    CSSParserValue* v = args->current();
-    if (!validUnit(v, FNumber))
-        return false;
-    result = v->fValue;
-    v = args->next();
-    if (!v)
-        // The last number in the function has no comma after it, so we're done.
-        return true;
-    if (!isComma(v))
-        return false;
-    args->next();
-    return true;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseAnimationTimingFunction()
-{
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
-        || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd)
-        return cssValuePool().createIdentifierValue(value->id);
-
-    // We must be a function.
-    if (value->unit != CSSParserValue::Function)
-        return 0;
-
-    CSSParserValueList* args = value->function->args.get();
-
-    if (equalIgnoringCase(value->function->name, "steps(")) {
-        // For steps, 1 or 2 params must be specified (comma-separated)
-        if (!args || (args->size() != 1 && args->size() != 3))
-            return 0;
-
-        // There are two values.
-        int numSteps;
-        bool stepAtStart = false;
-
-        CSSParserValue* v = args->current();
-        if (!validUnit(v, FInteger))
-            return 0;
-        numSteps = clampToInteger(v->fValue);
-        if (numSteps < 1)
-            return 0;
-        v = args->next();
-
-        if (v) {
-            // There is a comma so we need to parse the second value
-            if (!isComma(v))
-                return 0;
-            v = args->next();
-            if (v->id != CSSValueStart && v->id != CSSValueEnd)
-                return 0;
-            stepAtStart = v->id == CSSValueStart;
-        }
-
-        return CSSStepsTimingFunctionValue::create(numSteps, stepAtStart);
-    }
-
-    if (equalIgnoringCase(value->function->name, "cubic-bezier(")) {
-        // For cubic bezier, 4 values must be specified.
-        if (!args || args->size() != 7)
-            return 0;
-
-        // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range.
-        double x1, y1, x2, y2;
-
-        if (!parseCubicBezierTimingFunctionValue(args, x1))
-            return 0;
-        if (x1 < 0 || x1 > 1)
-            return 0;
-        if (!parseCubicBezierTimingFunctionValue(args, y1))
-            return 0;
-        if (!parseCubicBezierTimingFunctionValue(args, x2))
-            return 0;
-        if (x2 < 0 || x2 > 1)
-            return 0;
-        if (!parseCubicBezierTimingFunctionValue(args, y2))
-            return 0;
-
-        return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2);
-    }
-
-    return 0;
-}
-
-bool BisonCSSParser::parseAnimationProperty(CSSPropertyID propId, RefPtr<CSSValue>& result, AnimationParseContext& context)
-{
-    RefPtrWillBeRawPtr<CSSValueList> values;
-    CSSParserValue* val;
-    RefPtr<CSSValue> value;
-    bool allowComma = false;
-
-    result = 0;
-
-    while ((val = m_valueList->current())) {
-        RefPtr<CSSValue> currValue;
-        if (allowComma) {
-            if (!isComma(val))
-                return false;
-            m_valueList->next();
-            allowComma = false;
-        }
-        else {
-            switch (propId) {
-                case CSSPropertyAnimationDelay:
-                case CSSPropertyWebkitAnimationDelay:
-                case CSSPropertyTransitionDelay:
-                case CSSPropertyWebkitTransitionDelay:
-                    currValue = parseAnimationDelay();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyAnimationDirection:
-                case CSSPropertyWebkitAnimationDirection:
-                    currValue = parseAnimationDirection();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyAnimationDuration:
-                case CSSPropertyWebkitAnimationDuration:
-                case CSSPropertyTransitionDuration:
-                case CSSPropertyWebkitTransitionDuration:
-                    currValue = parseAnimationDuration();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyAnimationFillMode:
-                case CSSPropertyWebkitAnimationFillMode:
-                    currValue = parseAnimationFillMode();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyAnimationIterationCount:
-                case CSSPropertyWebkitAnimationIterationCount:
-                    currValue = parseAnimationIterationCount();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyAnimationName:
-                case CSSPropertyWebkitAnimationName:
-                    currValue = parseAnimationName();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyAnimationPlayState:
-                case CSSPropertyWebkitAnimationPlayState:
-                    currValue = parseAnimationPlayState();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyTransitionProperty:
-                case CSSPropertyWebkitTransitionProperty:
-                    currValue = parseAnimationProperty(context);
-                    if (value && !context.animationPropertyKeywordAllowed())
-                        return false;
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                case CSSPropertyAnimationTimingFunction:
-                case CSSPropertyWebkitAnimationTimingFunction:
-                case CSSPropertyTransitionTimingFunction:
-                case CSSPropertyWebkitTransitionTimingFunction:
-                    currValue = parseAnimationTimingFunction();
-                    if (currValue)
-                        m_valueList->next();
-                    break;
-                default:
-                    ASSERT_NOT_REACHED();
-                    return false;
-            }
-
-            if (!currValue)
-                return false;
-
-            if (value && !values) {
-                values = CSSValueList::createCommaSeparated();
-                values->append(value.release());
-            }
-
-            if (values)
-                values->append(currValue.release());
-            else
-                value = currValue.release();
-
-            allowComma = true;
-        }
-
-        // When parsing the 'transition' shorthand property, we let it handle building up the lists for all
-        // properties.
-        if (inShorthand())
-            break;
-    }
-
-    if (values && values->length()) {
-        result = values.release();
-        return true;
-    }
-    if (value) {
-        result = value.release();
-        return true;
-    }
-    return false;
-}
-
-// The function parses [ <integer> || <string> ] in <grid-line> (which can be stand alone or with 'span').
-bool BisonCSSParser::parseIntegerOrStringFromGridPosition(RefPtrWillBeRawPtr<CSSPrimitiveValue>& numericValue, RefPtrWillBeRawPtr<CSSPrimitiveValue>& gridLineName)
-{
-    CSSParserValue* value = m_valueList->current();
-    if (validUnit(value, FInteger) && value->fValue) {
-        numericValue = createPrimitiveNumericValue(value);
-        value = m_valueList->next();
-        if (value && value->unit == CSSPrimitiveValue::CSS_STRING) {
-            gridLineName = createPrimitiveStringValue(m_valueList->current());
-            m_valueList->next();
-        }
-        return true;
-    }
-
-    if (value->unit == CSSPrimitiveValue::CSS_STRING) {
-        gridLineName = createPrimitiveStringValue(m_valueList->current());
-        value = m_valueList->next();
-        if (value && validUnit(value, FInteger) && value->fValue) {
-            numericValue = createPrimitiveNumericValue(value);
-            m_valueList->next();
-        }
-        return true;
-    }
-
-    return false;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseGridPosition()
-{
-    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueAuto) {
-        m_valueList->next();
-        return cssValuePool().createIdentifierValue(CSSValueAuto);
-    }
-
-    if (value->id != CSSValueSpan && value->unit == CSSPrimitiveValue::CSS_IDENT) {
-        m_valueList->next();
-        return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING);
-    }
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> numericValue;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> gridLineName;
-    bool hasSeenSpanKeyword = false;
-
-    if (parseIntegerOrStringFromGridPosition(numericValue, gridLineName)) {
-        value = m_valueList->current();
-        if (value && value->id == CSSValueSpan) {
-            hasSeenSpanKeyword = true;
-            m_valueList->next();
-        }
-    } else if (value->id == CSSValueSpan) {
-        hasSeenSpanKeyword = true;
-        if (m_valueList->next())
-            parseIntegerOrStringFromGridPosition(numericValue, gridLineName);
-    }
-
-    // Check that we have consumed all the value list. For shorthands, the parser will pass
-    // the whole value list (including the opposite position).
-    if (m_valueList->current() && !isForwardSlashOperator(m_valueList->current()))
-        return 0;
-
-    // If we didn't parse anything, this is not a valid grid position.
-    if (!hasSeenSpanKeyword && !gridLineName && !numericValue)
-        return 0;
-
-    // Negative numbers are not allowed for span (but are for <integer>).
-    if (hasSeenSpanKeyword && numericValue && numericValue->getIntValue() < 0)
-        return 0;
-
-    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
-    if (hasSeenSpanKeyword)
-        values->append(cssValuePool().createIdentifierValue(CSSValueSpan));
-    if (numericValue)
-        values->append(numericValue.release());
-    if (gridLineName)
-        values->append(gridLineName.release());
-    ASSERT(values->length());
-    return values.release();
-}
-
-static PassRefPtr<CSSValue> gridMissingGridPositionValue(CSSValue* value)
-{
-    if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->isString())
-        return value;
-
-    return cssValuePool().createIdentifierValue(CSSValueAuto);
-}
-
-bool BisonCSSParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important)
-{
-    ShorthandScope scope(this, shorthandId);
-    const StylePropertyShorthand& shorthand = shorthandForProperty(shorthandId);
-    ASSERT(shorthand.length() == 2);
-
-    RefPtr<CSSValue> startValue = parseGridPosition();
-    if (!startValue)
-        return false;
-
-    RefPtr<CSSValue> endValue;
-    if (m_valueList->current()) {
-        if (!isForwardSlashOperator(m_valueList->current()))
-            return false;
-
-        if (!m_valueList->next())
-            return false;
-
-        endValue = parseGridPosition();
-        if (!endValue || m_valueList->current())
-            return false;
-    } else {
-        endValue = gridMissingGridPositionValue(startValue.get());
-    }
-
-    addProperty(shorthand.properties()[0], startValue, important);
-    addProperty(shorthand.properties()[1], endValue, important);
-    return true;
-}
-
-bool BisonCSSParser::parseGridAreaShorthand(bool important)
-{
-    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
-    ShorthandScope scope(this, CSSPropertyGridArea);
-    const StylePropertyShorthand& shorthand = gridAreaShorthand();
-    ASSERT_UNUSED(shorthand, shorthand.length() == 4);
-
-    RefPtr<CSSValue> rowStartValue = parseGridPosition();
-    if (!rowStartValue)
-        return false;
-
-    RefPtr<CSSValue> columnStartValue;
-    if (!parseSingleGridAreaLonghand(columnStartValue))
-        return false;
-
-    RefPtr<CSSValue> rowEndValue;
-    if (!parseSingleGridAreaLonghand(rowEndValue))
-        return false;
-
-    RefPtr<CSSValue> columnEndValue;
-    if (!parseSingleGridAreaLonghand(columnEndValue))
-        return false;
-
-    if (!columnStartValue)
-        columnStartValue = gridMissingGridPositionValue(rowStartValue.get());
-
-    if (!rowEndValue)
-        rowEndValue = gridMissingGridPositionValue(rowStartValue.get());
-
-    if (!columnEndValue)
-        columnEndValue = gridMissingGridPositionValue(columnStartValue.get());
-
-    addProperty(CSSPropertyGridRowStart, rowStartValue, important);
-    addProperty(CSSPropertyGridColumnStart, columnStartValue, important);
-    addProperty(CSSPropertyGridRowEnd, rowEndValue, important);
-    addProperty(CSSPropertyGridColumnEnd, columnEndValue, important);
-    return true;
-}
-
-bool BisonCSSParser::parseSingleGridAreaLonghand(RefPtr<CSSValue>& property)
-{
-    if (!m_valueList->current())
-        return true;
-
-    if (!isForwardSlashOperator(m_valueList->current()))
-        return false;
-
-    if (!m_valueList->next())
-        return false;
-
-    property = parseGridPosition();
-    return true;
-}
-
-void BisonCSSParser::parseGridLineNames(CSSParserValueList* parserValueList, CSSValueList& valueList)
-{
-    ASSERT(parserValueList->current() && parserValueList->current()->unit == CSSParserValue::ValueList);
-
-    CSSParserValueList* identList = parserValueList->current()->valueList;
-    if (!identList->size()) {
-        parserValueList->next();
-        return;
-    }
-
-    RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
-    while (CSSParserValue* identValue = identList->current()) {
-        ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT);
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> lineName = createPrimitiveStringValue(identValue);
-        lineNames->append(lineName.release());
-        identList->next();
-    }
-    valueList.append(lineNames.release());
-
-    parserValueList->next();
-}
-
-bool BisonCSSParser::parseGridTrackList(CSSPropertyID propId, bool important)
-{
-    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
-    CSSParserValue* value = m_valueList->current();
-    if (value->id == CSSValueNone) {
-        if (m_valueList->next())
-            return false;
-
-        addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
-        return true;
-    }
-
-    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
-    // Handle leading  <ident>*.
-    value = m_valueList->current();
-    if (value && value->unit == CSSParserValue::ValueList)
-        parseGridLineNames(m_valueList.get(), *values);
-
-    bool seenTrackSizeOrRepeatFunction = false;
-    while (CSSParserValue* currentValue = m_valueList->current()) {
-        if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "repeat(")) {
-            if (!parseGridTrackRepeatFunction(*values))
-                return false;
-            seenTrackSizeOrRepeatFunction = true;
-        } else {
-            RefPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
-            if (!value)
-                return false;
-            values->append(value);
-            seenTrackSizeOrRepeatFunction = true;
-        }
-        // This will handle the trailing <ident>* in the grammar.
-        value = m_valueList->current();
-        if (value && value->unit == CSSParserValue::ValueList)
-            parseGridLineNames(m_valueList.get(), *values);
-    }
-
-    // We should have found a <track-size> or else it is not a valid <track-list>
-    if (!seenTrackSizeOrRepeatFunction)
-        return false;
-
-    addProperty(propId, values.release(), important);
-    return true;
-}
-
-bool BisonCSSParser::parseGridTrackRepeatFunction(CSSValueList& list)
-{
-    CSSParserValueList* arguments = m_valueList->current()->function->args.get();
-    if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1)))
-        return false;
-
-    ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0);
-    size_t repetitions = arguments->valueAt(0)->fValue;
-    RefPtrWillBeRawPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated();
-    arguments->next(); // Skip the repetition count.
-    arguments->next(); // Skip the comma.
-
-    // Handle leading <ident>*.
-    CSSParserValue* currentValue = arguments->current();
-    if (currentValue && currentValue->unit == CSSParserValue::ValueList)
-        parseGridLineNames(arguments, *repeatedValues);
-
-    while (arguments->current()) {
-        RefPtr<CSSValue> trackSize = parseGridTrackSize(*arguments);
-        if (!trackSize)
-            return false;
-
-        repeatedValues->append(trackSize);
-
-        // This takes care of any trailing <ident>* in the grammar.
-        currentValue = arguments->current();
-        if (currentValue && currentValue->unit == CSSParserValue::ValueList)
-            parseGridLineNames(arguments, *repeatedValues);
-    }
-
-    for (size_t i = 0; i < repetitions; ++i) {
-        for (size_t j = 0; j < repeatedValues->length(); ++j)
-            list.append(repeatedValues->itemWithoutBoundsCheck(j));
-    }
-
-    // parseGridTrackSize iterated over the repeat arguments, move to the next value.
-    m_valueList->next();
-    return true;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseGridTrackSize(CSSParserValueList& inputList)
-{
-    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
-
-    CSSParserValue* currentValue = inputList.current();
-    inputList.next();
-
-    if (currentValue->id == CSSValueAuto)
-        return cssValuePool().createIdentifierValue(CSSValueAuto);
-
-    if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "minmax(")) {
-        // The spec defines the following grammar: minmax( <track-breadth> , <track-breadth> )
-        CSSParserValueList* arguments = currentValue->function->args.get();
-        if (!arguments || arguments->size() != 3 || !isComma(arguments->valueAt(1)))
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> minTrackBreadth = parseGridBreadth(arguments->valueAt(0));
-        if (!minTrackBreadth)
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> maxTrackBreadth = parseGridBreadth(arguments->valueAt(2));
-        if (!maxTrackBreadth)
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSValueList> parsedArguments = CSSValueList::createCommaSeparated();
-        parsedArguments->append(minTrackBreadth);
-        parsedArguments->append(maxTrackBreadth);
-        return CSSFunctionValue::create("minmax(", parsedArguments);
-    }
-
-    return parseGridBreadth(currentValue);
-}
-
-PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::parseGridBreadth(CSSParserValue* currentValue)
-{
-    if (currentValue->id == CSSValueMinContent || currentValue->id == CSSValueMaxContent)
-        return cssValuePool().createIdentifierValue(currentValue->id);
-
-    if (currentValue->unit == CSSPrimitiveValue::CSS_FR) {
-        double flexValue = currentValue->fValue;
-
-        // Fractional unit is a non-negative dimension.
-        if (flexValue <= 0)
-            return 0;
-
-        return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
-    }
-
-    if (!validUnit(currentValue, FNonNeg | FLength | FPercent))
-        return 0;
-
-    return createPrimitiveNumericValue(currentValue);
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseGridTemplateAreas()
-{
-    NamedGridAreaMap gridAreaMap;
-    size_t rowCount = 0;
-    size_t columnCount = 0;
-
-    while (CSSParserValue* currentValue = m_valueList->current()) {
-        if (currentValue->unit != CSSPrimitiveValue::CSS_STRING)
-            return 0;
-
-        String gridRowNames = currentValue->string;
-        if (!gridRowNames.length())
-            return 0;
-
-        Vector<String> columnNames;
-        gridRowNames.split(' ', columnNames);
-
-        if (!columnCount) {
-            columnCount = columnNames.size();
-            ASSERT(columnCount);
-        } else if (columnCount != columnNames.size()) {
-            // The declaration is invalid is all the rows don't have the number of columns.
-            return 0;
-        }
-
-        for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
-            const String& gridAreaName = columnNames[currentCol];
-
-            // Unamed areas are always valid (we consider them to be 1x1).
-            if (gridAreaName == ".")
-                continue;
-
-            // We handle several grid areas with the same name at once to simplify the validation code.
-            size_t lookAheadCol;
-            for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++lookAheadCol) {
-                if (columnNames[lookAheadCol + 1] != gridAreaName)
-                    break;
-            }
-
-            NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
-            if (gridAreaIt == gridAreaMap.end()) {
-                gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
-            } else {
-                GridCoordinate& gridCoordinate = gridAreaIt->value;
-
-                // The following checks test that the grid area is a single filled-in rectangle.
-                // 1. The new row is adjacent to the previously parsed row.
-                if (rowCount != gridCoordinate.rows.initialPositionIndex + 1)
-                    return 0;
-
-                // 2. The new area starts at the same position as the previously parsed area.
-                if (currentCol != gridCoordinate.columns.initialPositionIndex)
-                    return 0;
-
-                // 3. The new area ends at the same position as the previously parsed area.
-                if (lookAheadCol != gridCoordinate.columns.finalPositionIndex)
-                    return 0;
-
-                ++gridCoordinate.rows.finalPositionIndex;
-            }
-            currentCol = lookAheadCol;
-        }
-
-        ++rowCount;
-        m_valueList->next();
-    }
-
-    if (!rowCount || !columnCount)
-        return 0;
-
-    return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseCounterContent(CSSParserValueList* args, bool counters)
-{
-    unsigned numArgs = args->size();
-    if (counters && numArgs != 3 && numArgs != 5)
-        return 0;
-    if (!counters && numArgs != 1 && numArgs != 3)
-        return 0;
-
-    CSSParserValue* i = args->current();
-    if (i->unit != CSSPrimitiveValue::CSS_IDENT)
-        return 0;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> identifier = createPrimitiveStringValue(i);
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> separator;
-    if (!counters)
-        separator = cssValuePool().createValue(String(), CSSPrimitiveValue::CSS_STRING);
-    else {
-        i = args->next();
-        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
-            return 0;
-
-        i = args->next();
-        if (i->unit != CSSPrimitiveValue::CSS_STRING)
-            return 0;
-
-        separator = createPrimitiveStringValue(i);
-    }
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle;
-    i = args->next();
-    if (!i) // Make the list style default decimal
-        listStyle = cssValuePool().createIdentifierValue(CSSValueDecimal);
-    else {
-        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
-            return 0;
-
-        i = args->next();
-        if (i->unit != CSSPrimitiveValue::CSS_IDENT)
-            return 0;
-
-        CSSValueID listStyleID = CSSValueInvalid;
-        if (i->id == CSSValueNone || (i->id >= CSSValueDisc && i->id <= CSSValueKatakanaIroha))
-            listStyleID = i->id;
-        else
-            return 0;
-
-        listStyle = cssValuePool().createIdentifierValue(listStyleID);
-    }
-
-    return cssValuePool().createValue(Counter::create(identifier.release(), listStyle.release(), separator.release()));
-}
-
-bool BisonCSSParser::parseClipShape(CSSPropertyID propId, bool important)
-{
-    CSSParserValue* value = m_valueList->current();
-    CSSParserValueList* args = value->function->args.get();
-
-    if (!equalIgnoringCase(value->function->name, "rect(") || !args)
-        return false;
-
-    // rect(t, r, b, l) || rect(t r b l)
-    if (args->size() != 4 && args->size() != 7)
-        return false;
-    RefPtr<Rect> rect = Rect::create();
-    bool valid = true;
-    int i = 0;
-    CSSParserValue* a = args->current();
-    while (a) {
-        valid = a->id == CSSValueAuto || validUnit(a, FLength);
-        if (!valid)
-            break;
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ?
-            cssValuePool().createIdentifierValue(CSSValueAuto) :
-            createPrimitiveNumericValue(a);
-        if (i == 0)
-            rect->setTop(length);
-        else if (i == 1)
-            rect->setRight(length);
-        else if (i == 2)
-            rect->setBottom(length);
-        else
-            rect->setLeft(length);
-        a = args->next();
-        if (a && args->size() == 7) {
-            if (a->unit == CSSParserValue::Operator && a->iValue == ',') {
-                a = args->next();
-            } else {
-                valid = false;
-                break;
-            }
-        }
-        i++;
-    }
-    if (valid) {
-        addProperty(propId, cssValuePool().createValue(rect.release()), important);
-        m_valueList->next();
-        return true;
-    }
-    return false;
-}
-
-static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4])
-{
-    if (radii[3])
-        return;
-    if (!radii[2]) {
-        if (!radii[1])
-            radii[1] = radii[0];
-        radii[2] = radii[0];
-    }
-    radii[3] = radii[1];
-}
-
-// FIXME: This should be refactored with CSSParser::parseBorderRadius.
-// CSSParser::parseBorderRadius contains support for some legacy radius construction.
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseInsetRoundedCorners(PassRefPtr<CSSBasicShapeInset> shape, CSSParserValueList* args)
-{
-    CSSParserValue* argument = args->next();
-
-    if (!argument)
-        return 0;
-
-    CSSParserValueList radiusArguments;
-    while (argument) {
-        radiusArguments.addValue(*argument);
-        argument = args->next();
-    }
-
-    unsigned num = radiusArguments.size();
-    if (!num || num > 9)
-        return 0;
-
-    // FIXME: Refactor completeBorderRadii and the array
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[2][4];
-
-    unsigned indexAfterSlash = 0;
-    for (unsigned i = 0; i < num; ++i) {
-        CSSParserValue* value = radiusArguments.valueAt(i);
-        if (value->unit == CSSParserValue::Operator) {
-            if (value->iValue != '/')
-                return 0;
-
-            if (!i || indexAfterSlash || i + 1 == num)
-                return 0;
-
-            indexAfterSlash = i + 1;
-            completeBorderRadii(radii[0]);
-            continue;
-        }
-
-        if (i - indexAfterSlash >= 4)
-            return 0;
-
-        if (!validUnit(value, FLength | FPercent | FNonNeg))
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
-
-        if (!indexAfterSlash)
-            radii[0][i] = radius;
-        else
-            radii[1][i - indexAfterSlash] = radius.release();
-    }
-
-    if (!indexAfterSlash) {
-        completeBorderRadii(radii[0]);
-        for (unsigned i = 0; i < 4; ++i)
-            radii[1][i] = radii[0][i];
-    } else {
-        completeBorderRadii(radii[1]);
-    }
-    shape->setTopLeftRadius(createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()));
-    shape->setTopRightRadius(createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()));
-    shape->setBottomRightRadius(createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()));
-    shape->setBottomLeftRadius(createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()));
-
-    return shape;
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseBasicShapeInset(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    RefPtr<CSSBasicShapeInset> shape = CSSBasicShapeInset::create();
-
-    CSSParserValue* argument = args->current();
-    WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> > widthArguments;
-    bool hasRoundedInset = false;
-
-    while (argument) {
-        if (argument->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(argument->string, "round")) {
-            hasRoundedInset = true;
-            break;
-        }
-
-        Units unitFlags = FLength | FPercent;
-        if (!validUnit(argument, unitFlags) || widthArguments.size() > 4)
-            return 0;
-
-        widthArguments.append(createPrimitiveNumericValue(argument));
-        argument = args->next();
-    }
-
-    switch (widthArguments.size()) {
-    case 1: {
-        shape->updateShapeSize1Value(widthArguments[0].get());
-        break;
-    }
-    case 2: {
-        shape->updateShapeSize2Values(widthArguments[0].get(), widthArguments[1].get());
-        break;
-        }
-    case 3: {
-        shape->updateShapeSize3Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get());
-        break;
-    }
-    case 4: {
-        shape->updateShapeSize4Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get(), widthArguments[3].get());
-        break;
-    }
-    default:
-        return 0;
-    }
-
-    if (hasRoundedInset)
-        return parseInsetRoundedCorners(shape, args);
-    return shape;
-}
-
-static bool isItemPositionKeyword(CSSValueID id)
-{
-    return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
-        || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart
-        || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight;
-}
-
-bool BisonCSSParser::parseItemPositionOverflowPosition(CSSPropertyID propId, bool important)
-{
-    // auto | baseline | stretch | [<item-position> && <overflow-position>? ]
-    // <item-position> = center | start | end | self-start | self-end | flex-start | flex-end | left | right;
-    // <overflow-position> = true | safe
-
-    CSSParserValue* value = m_valueList->current();
-
-    if (value->id == CSSValueAuto || value->id == CSSValueBaseline || value->id == CSSValueStretch) {
-        if (m_valueList->next())
-            return false;
-
-        addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
-        return true;
-    }
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> position = 0;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> overflowAlignmentKeyword = 0;
-    if (isItemPositionKeyword(value->id)) {
-        position = cssValuePool().createIdentifierValue(value->id);
-        value = m_valueList->next();
-        if (value) {
-            if (value->id == CSSValueTrue || value->id == CSSValueSafe)
-                overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
-            else
-                return false;
-        }
-    } else if (value->id == CSSValueTrue || value->id == CSSValueSafe) {
-        overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
-        value = m_valueList->next();
-        if (value) {
-            if (isItemPositionKeyword(value->id))
-                position = cssValuePool().createIdentifierValue(value->id);
-            else
-                return false;
-        }
-    } else {
-        return false;
-    }
-
-    if (m_valueList->next())
-        return false;
-
-    ASSERT(position);
-    if (overflowAlignmentKeyword)
-        addProperty(propId, createPrimitiveValuePair(position, overflowAlignmentKeyword), important);
-    else
-        addProperty(propId, position.release(), important);
-
-    return true;
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseBasicShapeRectangle(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    // rect(x, y, width, height, [[rx], ry])
-    if (args->size() != 7 && args->size() != 9 && args->size() != 11)
-        return 0;
-
-    RefPtr<CSSBasicShapeRectangle> shape = CSSBasicShapeRectangle::create();
-
-    unsigned argumentNumber = 0;
-    CSSParserValue* argument = args->current();
-    while (argument) {
-        Units unitFlags = FLength | FPercent;
-        if (argumentNumber > 1) {
-            // Arguments width, height, rx, and ry cannot be negative.
-            unitFlags = unitFlags | FNonNeg;
-        }
-        if (!validUnit(argument, unitFlags))
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
-        ASSERT(argumentNumber < 6);
-        switch (argumentNumber) {
-        case 0:
-            shape->setX(length);
-            break;
-        case 1:
-            shape->setY(length);
-            break;
-        case 2:
-            shape->setWidth(length);
-            break;
-        case 3:
-            shape->setHeight(length);
-            break;
-        case 4:
-            shape->setRadiusX(length);
-            break;
-        case 5:
-            shape->setRadiusY(length);
-            break;
-        }
-        argument = args->next();
-        if (argument) {
-            if (!isComma(argument))
-                return 0;
-
-            argument = args->next();
-        }
-        argumentNumber++;
-    }
-
-    if (argumentNumber < 4)
-        return 0;
-    return shape;
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseBasicShapeInsetRectangle(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    // inset-rectangle(top, right, bottom, left, [[rx], ry])
-    if (args->size() != 7 && args->size() != 9 && args->size() != 11)
-        return 0;
-
-    RefPtr<CSSBasicShapeInsetRectangle> shape = CSSBasicShapeInsetRectangle::create();
-
-    unsigned argumentNumber = 0;
-    CSSParserValue* argument = args->current();
-    while (argument) {
-        Units unitFlags = FLength | FPercent | FNonNeg;
-        if (!validUnit(argument, unitFlags))
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
-        ASSERT(argumentNumber < 6);
-        switch (argumentNumber) {
-        case 0:
-            shape->setTop(length);
-            break;
-        case 1:
-            shape->setRight(length);
-            break;
-        case 2:
-            shape->setBottom(length);
-            break;
-        case 3:
-            shape->setLeft(length);
-            break;
-        case 4:
-            shape->setRadiusX(length);
-            break;
-        case 5:
-            shape->setRadiusY(length);
-            break;
-        }
-        argument = args->next();
-        if (argument) {
-            if (!isComma(argument))
-                return 0;
-
-            argument = args->next();
-        }
-        argumentNumber++;
-    }
-
-    if (argumentNumber < 4)
-        return 0;
-    return shape;
-}
-
-PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::parseShapeRadius(CSSParserValue* value)
-{
-    if (value->id == CSSValueClosestSide || value->id == CSSValueFarthestSide)
-        return cssValuePool().createIdentifierValue(value->id);
-
-    if (!validUnit(value, FLength | FPercent | FNonNeg))
-        return 0;
-
-    return createPrimitiveNumericValue(value);
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseBasicShapeCircle(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    // circle(radius)
-    // circle(radius at <position>
-    // circle(at <position>)
-    // where position defines centerX and centerY using a CSS <position> data type.
-    RefPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create();
-
-    for (CSSParserValue* argument = args->current(); argument; argument = args->next()) {
-        // The call to parseFillPosition below should consume all of the
-        // arguments except the first two. Thus, and index greater than one
-        // indicates an invalid production.
-        if (args->currentIndex() > 1)
-            return 0;
-
-        if (!args->currentIndex() && argument->id != CSSValueAt) {
-            if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
-                shape->setRadius(radius);
-                continue;
-            }
-
-            return 0;
-        }
-
-        if (argument->id == CSSValueAt) {
-            RefPtr<CSSValue> centerX;
-            RefPtr<CSSValue> centerY;
-            args->next(); // set list to start of position center
-            parseFillPosition(args, centerX, centerY);
-            if (centerX && centerY) {
-                ASSERT(centerX->isPrimitiveValue());
-                ASSERT(centerY->isPrimitiveValue());
-                shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
-                shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
-            } else {
-                return 0;
-            }
-        } else {
-            return 0;
-        }
-    }
-
-    return shape;
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseDeprecatedBasicShapeCircle(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    // circle(centerX, centerY, radius)
-    if (args->size() != 5)
-        return 0;
-
-    RefPtr<CSSDeprecatedBasicShapeCircle> shape = CSSDeprecatedBasicShapeCircle::create();
-
-    unsigned argumentNumber = 0;
-    CSSParserValue* argument = args->current();
-    while (argument) {
-        Units unitFlags = FLength | FPercent;
-        if (argumentNumber == 2) {
-            // Argument radius cannot be negative.
-            unitFlags = unitFlags | FNonNeg;
-        }
-
-        if (!validUnit(argument, unitFlags))
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
-        ASSERT(argumentNumber < 3);
-        switch (argumentNumber) {
-        case 0:
-            shape->setCenterX(length);
-            break;
-        case 1:
-            shape->setCenterY(length);
-            break;
-        case 2:
-            shape->setRadius(length);
-            break;
-        }
-
-        argument = args->next();
-        if (argument) {
-            if (!isComma(argument))
-                return 0;
-            argument = args->next();
-        }
-        argumentNumber++;
-    }
-
-    if (argumentNumber < 3)
-        return 0;
-    return shape;
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseBasicShapeEllipse(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    // ellipse(radiusX)
-    // ellipse(radiusX at <position>
-    // ellipse(radiusX radiusY)
-    // ellipse(radiusX radiusY at <position>
-    // ellipse(at <position>)
-    // where position defines centerX and centerY using a CSS <position> data type.
-    RefPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create();
-
-    for (CSSParserValue* argument = args->current(); argument; argument = args->next()) {
-        // The call to parseFillPosition below should consume all of the
-        // arguments except the first three. Thus, an index greater than two
-        // indicates an invalid production.
-        if (args->currentIndex() > 2)
-            return 0;
-
-        if (args->currentIndex() < 2 && argument->id != CSSValueAt) {
-            if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
-                if (!shape->radiusX())
-                    shape->setRadiusX(radius);
-                else
-                    shape->setRadiusY(radius);
-                continue;
-            }
-
-            return 0;
-        }
-
-        if (argument->id != CSSValueAt)
-            return 0;
-        RefPtr<CSSValue> centerX;
-        RefPtr<CSSValue> centerY;
-        args->next(); // set list to start of position center
-        parseFillPosition(args, centerX, centerY);
-        if (!centerX || !centerY)
-            return 0;
-
-        ASSERT(centerX->isPrimitiveValue());
-        ASSERT(centerY->isPrimitiveValue());
-        shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
-        shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
-    }
-
-    return shape;
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseDeprecatedBasicShapeEllipse(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    // ellipse(centerX, centerY, radiusX, radiusY)
-    if (args->size() != 7)
-        return 0;
-
-    RefPtr<CSSDeprecatedBasicShapeEllipse> shape = CSSDeprecatedBasicShapeEllipse::create();
-    unsigned argumentNumber = 0;
-    CSSParserValue* argument = args->current();
-    while (argument) {
-        Units unitFlags = FLength | FPercent;
-        if (argumentNumber > 1) {
-            // Arguments radiusX and radiusY cannot be negative.
-            unitFlags = unitFlags | FNonNeg;
-        }
-        if (!validUnit(argument, unitFlags))
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
-        ASSERT(argumentNumber < 4);
-        switch (argumentNumber) {
-        case 0:
-            shape->setCenterX(length);
-            break;
-        case 1:
-            shape->setCenterY(length);
-            break;
-        case 2:
-            shape->setRadiusX(length);
-            break;
-        case 3:
-            shape->setRadiusY(length);
-            break;
-        }
-
-        argument = args->next();
-        if (argument) {
-            if (!isComma(argument))
-                return 0;
-            argument = args->next();
-        }
-        argumentNumber++;
-    }
-
-    if (argumentNumber < 4)
-        return 0;
-    return shape;
-}
-
-PassRefPtr<CSSBasicShape> BisonCSSParser::parseBasicShapePolygon(CSSParserValueList* args)
-{
-    ASSERT(args);
-
-    unsigned size = args->size();
-    if (!size)
-        return 0;
-
-    RefPtr<CSSBasicShapePolygon> shape = CSSBasicShapePolygon::create();
-
-    CSSParserValue* argument = args->current();
-    if (argument->id == CSSValueEvenodd || argument->id == CSSValueNonzero) {
-        shape->setWindRule(argument->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
-
-        if (!isComma(args->next()))
-            return 0;
-
-        argument = args->next();
-        size -= 2;
-    }
-
-    // <length> <length>, ... <length> <length> -> each pair has 3 elements except the last one
-    if (!size || (size % 3) - 2)
-        return 0;
-
-    CSSParserValue* argumentX = argument;
-    while (argumentX) {
-        if (!validUnit(argumentX, FLength | FPercent))
-            return 0;
-
-        CSSParserValue* argumentY = args->next();
-        if (!argumentY || !validUnit(argumentY, FLength | FPercent))
-            return 0;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> xLength = createPrimitiveNumericValue(argumentX);
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> yLength = createPrimitiveNumericValue(argumentY);
-
-        shape->appendPoint(xLength.release(), yLength.release());
-
-        CSSParserValue* commaOrNull = args->next();
-        if (!commaOrNull)
-            argumentX = 0;
-        else if (!isComma(commaOrNull))
-            return 0;
-        else
-            argumentX = args->next();
-    }
-
-    return shape;
-}
-
-static bool isBoxValue(CSSValueID valueId)
-{
-    switch (valueId) {
-    case CSSValueContentBox:
-    case CSSValuePaddingBox:
-    case CSSValueBorderBox:
-    case CSSValueMarginBox:
-        return true;
-    default:
-        break;
-    }
-
-    return false;
-}
-
-// FIXME This function is temporary to allow for an orderly transition between
-// the new CSS Shapes circle and ellipse syntax. It will be removed when the
-// old syntax is removed.
-static bool isDeprecatedBasicShape(CSSParserValueList* args)
-{
-    for (unsigned i = args->currentIndex(); i < args->size(); ++i) {
-        CSSParserValue* value = args->valueAt(i);
-        if (isComma(value))
-            return true;
-    }
-
-    return false;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseShapeProperty(CSSPropertyID propId)
-{
-    if (!RuntimeEnabledFeatures::cssShapesEnabled())
-        return 0;
-
-    CSSParserValue* value = m_valueList->current();
-    CSSValueID valueId = value->id;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> boxValue;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue;
-
-    if (valueId == CSSValueNone
-        || (valueId == CSSValueOutsideShape && propId == CSSPropertyShapeInside)) {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> keywordValue = parseValidPrimitive(valueId, value);
-        m_valueList->next();
-        return keywordValue.release();
-    }
-
-    RefPtr<CSSValue> imageValue;
-    if (valueId != CSSValueNone && parseFillImage(m_valueList.get(), imageValue)) {
-        m_valueList->next();
-        return imageValue.release();
-    }
-
-    if (value->unit == CSSParserValue::Function) {
-        shapeValue = parseBasicShape();
-        if (!shapeValue)
-            return 0;
-    } else if (isBoxValue(valueId)) {
-        boxValue = parseValidPrimitive(valueId, value);
-        m_valueList->next();
-    } else {
-        return 0;
-    }
-
-    ASSERT(shapeValue || boxValue);
-    value = m_valueList->current();
-
-    if (value) {
-        valueId = value->id;
-        if (boxValue && value->unit == CSSParserValue::Function) {
-            shapeValue = parseBasicShape();
-            if (!shapeValue)
-                return 0;
-        } else if (shapeValue && isBoxValue(valueId)) {
-            boxValue = parseValidPrimitive(valueId, value);
-            m_valueList->next();
-        } else {
-            return 0;
-        }
-
-        ASSERT(shapeValue && boxValue);
-        shapeValue->getShapeValue()->setLayoutBox(boxValue.release());
-    }
-
-    if (shapeValue)
-        return shapeValue.release();
-    return boxValue.release();
-}
-
-PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::parseBasicShape()
-{
-    CSSParserValue* value = m_valueList->current();
-    ASSERT(value->unit == CSSParserValue::Function);
-    CSSParserValueList* args = value->function->args.get();
-
-    if (!args)
-        return 0;
-
-    RefPtr<CSSBasicShape> shape;
-    if (equalIgnoringCase(value->function->name, "rectangle("))
-        shape = parseBasicShapeRectangle(args);
-    else if (equalIgnoringCase(value->function->name, "circle("))
-        if (isDeprecatedBasicShape(args))
-            shape = parseDeprecatedBasicShapeCircle(args);
-        else
-            shape = parseBasicShapeCircle(args);
-    else if (equalIgnoringCase(value->function->name, "ellipse("))
-        if (isDeprecatedBasicShape(args))
-            shape = parseDeprecatedBasicShapeEllipse(args);
-        else
-            shape = parseBasicShapeEllipse(args);
-    else if (equalIgnoringCase(value->function->name, "polygon("))
-        shape = parseBasicShapePolygon(args);
-    else if (equalIgnoringCase(value->function->name, "inset-rectangle("))
-        shape = parseBasicShapeInsetRectangle(args);
-    else if (equalIgnoringCase(value->function->name, "inset("))
-        shape = parseBasicShapeInset(args);
-
-    if (!shape)
-        return 0;
-
-    m_valueList->next();
-    return cssValuePool().createValue(shape.release());
-}
-
-// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
-bool BisonCSSParser::parseFont(bool important)
-{
-    // Let's check if there is an inherit or initial somewhere in the shorthand.
-    for (unsigned i = 0; i < m_valueList->size(); ++i) {
-        if (m_valueList->valueAt(i)->id == CSSValueInherit || m_valueList->valueAt(i)->id == CSSValueInitial)
-            return false;
-    }
-
-    ShorthandScope scope(this, CSSPropertyFont);
-    // Optional font-style, font-variant and font-weight.
-    bool fontStyleParsed = false;
-    bool fontVariantParsed = false;
-    bool fontWeightParsed = false;
-    CSSParserValue* value;
-    while ((value = m_valueList->current())) {
-        if (!fontStyleParsed && isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value->id, m_context)) {
-            addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(value->id), important);
-            fontStyleParsed = true;
-        } else if (!fontVariantParsed && (value->id == CSSValueNormal || value->id == CSSValueSmallCaps)) {
-            // Font variant in the shorthand is particular, it only accepts normal or small-caps.
-            addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(value->id), important);
-            fontVariantParsed = true;
-        } else if (!fontWeightParsed && parseFontWeight(important))
-            fontWeightParsed = true;
-        else
-            break;
-        m_valueList->next();
-    }
-
-    if (!value)
-        return false;
-
-    if (!fontStyleParsed)
-        addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
-    if (!fontVariantParsed)
-        addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
-    if (!fontWeightParsed)
-        addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
-
-    // Now a font size _must_ come.
-    // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
-    if (!parseFontSize(important))
-        return false;
-
-    value = m_valueList->current();
-    if (!value)
-        return false;
-
-    if (isForwardSlashOperator(value)) {
-        // The line-height property.
-        value = m_valueList->next();
-        if (!value)
-            return false;
-        if (!parseLineHeight(important))
-            return false;
-    } else
-        addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
-
-    // Font family must come now.
-    RefPtr<CSSValue> parsedFamilyValue = parseFontFamily();
-    if (!parsedFamilyValue)
-        return false;
-
-    addProperty(CSSPropertyFontFamily, parsedFamilyValue.release(), important);
-
-    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires that
-    // "font-stretch", "font-size-adjust", and "font-kerning" be reset to their initial values
-    // but we don't seem to support them at the moment. They should also be added here once implemented.
-    if (m_valueList->current())
-        return false;
-
-    return true;
-}
-
-class FontFamilyValueBuilder {
-public:
-    FontFamilyValueBuilder(CSSValueList* list)
-        : m_list(list)
-    {
-    }
-
-    void add(const CSSParserString& string)
-    {
-        if (!m_builder.isEmpty())
-            m_builder.append(' ');
-
-        if (string.is8Bit()) {
-            m_builder.append(string.characters8(), string.length());
-            return;
-        }
-
-        m_builder.append(string.characters16(), string.length());
-    }
-
-    void commit()
-    {
-        if (m_builder.isEmpty())
-            return;
-        m_list->append(cssValuePool().createFontFamilyValue(m_builder.toString()));
-        m_builder.clear();
-    }
-
-private:
-    StringBuilder m_builder;
-    CSSValueList* m_list;
-};
-
-PassRefPtrWillBeRawPtr<CSSValueList> BisonCSSParser::parseFontFamily()
-{
-    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-    CSSParserValue* value = m_valueList->current();
-
-    FontFamilyValueBuilder familyBuilder(list.get());
-    bool inFamily = false;
-
-    while (value) {
-        CSSParserValue* nextValue = m_valueList->next();
-        bool nextValBreaksFont = !nextValue ||
-                                 (nextValue->unit == CSSParserValue::Operator && nextValue->iValue == ',');
-        bool nextValIsFontName = nextValue &&
-            ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) ||
-            (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT));
-
-        bool valueIsKeyword = value->id == CSSValueInitial || value->id == CSSValueInherit || value->id == CSSValueDefault;
-        if (valueIsKeyword && !inFamily) {
-            if (nextValBreaksFont)
-                value = m_valueList->next();
-            else if (nextValIsFontName)
-                value = nextValue;
-            continue;
-        }
-
-        if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) {
-            if (inFamily)
-                familyBuilder.add(value->string);
-            else if (nextValBreaksFont || !nextValIsFontName)
-                list->append(cssValuePool().createIdentifierValue(value->id));
-            else {
-                familyBuilder.commit();
-                familyBuilder.add(value->string);
-                inFamily = true;
-            }
-        } else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
-            // Strings never share in a family name.
-            inFamily = false;
-            familyBuilder.commit();
-            list->append(cssValuePool().createFontFamilyValue(value->string));
-        } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
-            if (inFamily)
-                familyBuilder.add(value->string);
-            else if (nextValBreaksFont || !nextValIsFontName)
-                list->append(cssValuePool().createFontFamilyValue(value->string));
-            else {
-                familyBuilder.commit();
-                familyBuilder.add(value->string);
-                inFamily = true;
-            }
-        } else {
-            break;
-        }
-
-        if (!nextValue)
-            break;
-
-        if (nextValBreaksFont) {
-            value = m_valueList->next();
-            familyBuilder.commit();
-            inFamily = false;
-        }
-        else if (nextValIsFontName)
-            value = nextValue;
-        else
-            break;
-    }
-    familyBuilder.commit();
-
-    if (!list->length())
-        list = 0;
-    return list.release();
-}
-
-bool BisonCSSParser::parseLineHeight(bool important)
-{
-    CSSParserValue* value = m_valueList->current();
-    CSSValueID id = value->id;
-    bool validPrimitive = false;
-    // normal | <number> | <length> | <percentage> | inherit
-    if (id == CSSValueNormal)
-        validPrimitive = true;
-    else
-        validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg));
-    if (validPrimitive && (!m_valueList->next() || inShorthand()))
-        addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, value), important);
-    return validPrimitive;
-}
-
-bool BisonCSSParser::parseFontSize(bool important)
-{
-    CSSParserValue* value = m_valueList->current();
-    CSSValueID id = value->id;
-    bool validPrimitive = false;
-    // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
-    if (id >= CSSValueXxSmall && id <= CSSValueLarger)
-        validPrimitive = true;
-    else
-        validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
-    if (validPrimitive && (!m_valueList->next() || inShorthand()))
-        addProperty(CSSPropertyFontSize, parseValidPrimitive(id, value), important);
-    return validPrimitive;
-}
-
-bool BisonCSSParser::parseFontVariant(bool important)
-{
-    RefPtrWillBeRawPtr<CSSValueList> values;
-    if (m_valueList->size() > 1)
-        values = CSSValueList::createCommaSeparated();
-    CSSParserValue* val;
-    bool expectComma = false;
-    while ((val = m_valueList->current())) {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue;
-        if (!expectComma) {
-            expectComma = true;
-            if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps)
-                parsedValue = cssValuePool().createIdentifierValue(val->id);
-            else if (val->id == CSSValueAll && !values) {
-                // 'all' is only allowed in @font-face and with no other values. Make a value list to
-                // indicate that we are in the @font-face case.
-                values = CSSValueList::createCommaSeparated();
-                parsedValue = cssValuePool().createIdentifierValue(val->id);
-            }
-        } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
-            expectComma = false;
-            m_valueList->next();
-            continue;
-        }
-
-        if (!parsedValue)
-            return false;
-
-        m_valueList->next();
-
-        if (values)
-            values->append(parsedValue.release());
-        else {
-            addProperty(CSSPropertyFontVariant, parsedValue.release(), important);
-            return true;
-        }
-    }
-
-    if (values && values->length()) {
-        m_hasFontFaceOnlyValues = true;
-        addProperty(CSSPropertyFontVariant, values.release(), important);
-        return true;
-    }
-
-    return false;
-}
-
-bool BisonCSSParser::parseFontWeight(bool important)
-{
-    CSSParserValue* value = m_valueList->current();
-    if ((value->id >= CSSValueNormal) && (value->id <= CSSValue900)) {
-        addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important);
-        return true;
-    }
-    if (validUnit(value, FInteger | FNonNeg, HTMLQuirksMode)) {
-        int weight = static_cast<int>(value->fValue);
-        if (!(weight % 100) && weight >= 100 && weight <= 900) {
-            addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue100 + weight / 100 - 1)), important);
-            return true;
-        }
-    }
-    return false;
-}
-
-bool BisonCSSParser::parseFontFaceSrcURI(CSSValueList* valueList)
-{
-    RefPtrWillBeRawPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create(completeURL(m_valueList->current()->string)));
-
-    CSSParserValue* value = m_valueList->next();
-    if (!value) {
-        valueList->append(uriValue.release());
-        return true;
-    }
-    if (value->unit == CSSParserValue::Operator && value->iValue == ',') {
-        m_valueList->next();
-        valueList->append(uriValue.release());
-        return true;
-    }
-
-    if (value->unit != CSSParserValue::Function || !equalIgnoringCase(value->function->name, "format("))
-        return false;
-
-    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format() contains a comma-separated list of strings,
-    // but CSSFontFaceSrcValue stores only one format. Allowing one format for now.
-    CSSParserValueList* args = value->function->args.get();
-    if (!args || args->size() != 1 || (args->current()->unit != CSSPrimitiveValue::CSS_STRING && args->current()->unit != CSSPrimitiveValue::CSS_IDENT))
-        return false;
-    uriValue->setFormat(args->current()->string);
-    valueList->append(uriValue.release());
-    value = m_valueList->next();
-    if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
-        m_valueList->next();
-    return true;
-}
-
-bool BisonCSSParser::parseFontFaceSrcLocal(CSSValueList* valueList)
-{
-    CSSParserValueList* args = m_valueList->current()->function->args.get();
-    if (!args || !args->size())
-        return false;
-
-    if (args->size() == 1 && args->current()->unit == CSSPrimitiveValue::CSS_STRING)
-        valueList->append(CSSFontFaceSrcValue::createLocal(args->current()->string));
-    else if (args->current()->unit == CSSPrimitiveValue::CSS_IDENT) {
-        StringBuilder builder;
-        for (CSSParserValue* localValue = args->current(); localValue; localValue = args->next()) {
-            if (localValue->unit != CSSPrimitiveValue::CSS_IDENT)
-                return false;
-            if (!builder.isEmpty())
-                builder.append(' ');
-            builder.append(localValue->string);
-        }
-        valueList->append(CSSFontFaceSrcValue::createLocal(builder.toString()));
-    } else
-        return false;
-
-    if (CSSParserValue* value = m_valueList->next()) {
-        if (value->unit == CSSParserValue::Operator && value->iValue == ',')
-            m_valueList->next();
-    }
-    return true;
-}
-
-bool BisonCSSParser::parseFontFaceSrc()
-{
-    RefPtrWillBeRawPtr<CSSValueList> values(CSSValueList::createCommaSeparated());
-
-    while (CSSParserValue* value = m_valueList->current()) {
-        if (value->unit == CSSPrimitiveValue::CSS_URI) {
-            if (!parseFontFaceSrcURI(values.get()))
-                return false;
-        } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "local(")) {
-            if (!parseFontFaceSrcLocal(values.get()))
-                return false;
-        } else
-            return false;
-    }
-    if (!values->length())
-        return false;
-
-    addProperty(CSSPropertySrc, values.release(), m_important);
-    m_valueList->next();
-    return true;
-}
-
-bool BisonCSSParser::parseFontFaceUnicodeRange()
-{
-    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
-    bool failed = false;
-    bool operatorExpected = false;
-    for (; m_valueList->current(); m_valueList->next(), operatorExpected = !operatorExpected) {
-        if (operatorExpected) {
-            if (m_valueList->current()->unit == CSSParserValue::Operator && m_valueList->current()->iValue == ',')
-                continue;
-            failed = true;
-            break;
-        }
-        if (m_valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
-            failed = true;
-            break;
-        }
-
-        String rangeString = m_valueList->current()->string;
-        UChar32 from = 0;
-        UChar32 to = 0;
-        unsigned length = rangeString.length();
-
-        if (length < 3) {
-            failed = true;
-            break;
-        }
-
-        unsigned i = 2;
-        while (i < length) {
-            UChar c = rangeString[i];
-            if (c == '-' || c == '?')
-                break;
-            from *= 16;
-            if (c >= '0' && c <= '9')
-                from += c - '0';
-            else if (c >= 'A' && c <= 'F')
-                from += 10 + c - 'A';
-            else if (c >= 'a' && c <= 'f')
-                from += 10 + c - 'a';
-            else {
-                failed = true;
-                break;
-            }
-            i++;
-        }
-        if (failed)
-            break;
-
-        if (i == length)
-            to = from;
-        else if (rangeString[i] == '?') {
-            unsigned span = 1;
-            while (i < length && rangeString[i] == '?') {
-                span *= 16;
-                from *= 16;
-                i++;
-            }
-            if (i < length)
-                failed = true;
-            to = from + span - 1;
-        } else {
-            if (length < i + 2) {
-                failed = true;
-                break;
-            }
-            i++;
-            while (i < length) {
-                UChar c = rangeString[i];
-                to *= 16;
-                if (c >= '0' && c <= '9')
-                    to += c - '0';
-                else if (c >= 'A' && c <= 'F')
-                    to += 10 + c - 'A';
-                else if (c >= 'a' && c <= 'f')
-                    to += 10 + c - 'a';
-                else {
-                    failed = true;
-                    break;
-                }
-                i++;
-            }
-            if (failed)
-                break;
-        }
-        if (from <= to)
-            values->append(CSSUnicodeRangeValue::create(from, to));
-    }
-    if (failed || !values->length())
-        return false;
-    addProperty(CSSPropertyUnicodeRange, values.release(), m_important);
-    return true;
-}
-
-// Returns the number of characters which form a valid double
-// and are terminated by the given terminator character
-template <typename CharacterType>
-static int checkForValidDouble(const CharacterType* string, const CharacterType* end, const char terminator)
-{
-    int length = end - string;
-    if (length < 1)
-        return 0;
-
-    bool decimalMarkSeen = false;
-    int processedLength = 0;
-
-    for (int i = 0; i < length; ++i) {
-        if (string[i] == terminator) {
-            processedLength = i;
-            break;
-        }
-        if (!isASCIIDigit(string[i])) {
-            if (!decimalMarkSeen && string[i] == '.')
-                decimalMarkSeen = true;
-            else
-                return 0;
-        }
-    }
-
-    if (decimalMarkSeen && processedLength == 1)
-        return 0;
-
-    return processedLength;
-}
-
-// Returns the number of characters consumed for parsing a valid double
-// terminated by the given terminator character
-template <typename CharacterType>
-static int parseDouble(const CharacterType* string, const CharacterType* end, const char terminator, double& value)
-{
-    int length = checkForValidDouble(string, end, terminator);
-    if (!length)
-        return 0;
-
-    int position = 0;
-    double localValue = 0;
-
-    // The consumed characters here are guaranteed to be
-    // ASCII digits with or without a decimal mark
-    for (; position < length; ++position) {
-        if (string[position] == '.')
-            break;
-        localValue = localValue * 10 + string[position] - '0';
-    }
-
-    if (++position == length) {
-        value = localValue;
-        return length;
-    }
-
-    double fraction = 0;
-    double scale = 1;
-
-    while (position < length && scale < MAX_SCALE) {
-        fraction = fraction * 10 + string[position++] - '0';
-        scale *= 10;
-    }
-
-    value = localValue + fraction / scale;
-    return length;
-}
-
-template <typename CharacterType>
-static bool parseColorIntOrPercentage(const CharacterType*& string, const CharacterType* end, const char terminator, CSSPrimitiveValue::UnitTypes& expect, int& value)
-{
-    const CharacterType* current = string;
-    double localValue = 0;
-    bool negative = false;
-    while (current != end && isHTMLSpace<CharacterType>(*current))
-        current++;
-    if (current != end && *current == '-') {
-        negative = true;
-        current++;
-    }
-    if (current == end || !isASCIIDigit(*current))
-        return false;
-    while (current != end && isASCIIDigit(*current)) {
-        double newValue = localValue * 10 + *current++ - '0';
-        if (newValue >= 255) {
-            // Clamp values at 255.
-            localValue = 255;
-            while (current != end && isASCIIDigit(*current))
-                ++current;
-            break;
-        }
-        localValue = newValue;
-    }
-
-    if (current == end)
-        return false;
-
-    if (expect == CSSPrimitiveValue::CSS_NUMBER && (*current == '.' || *current == '%'))
-        return false;
-
-    if (*current == '.') {
-        // We already parsed the integral part, try to parse
-        // the fraction part of the percentage value.
-        double percentage = 0;
-        int numCharactersParsed = parseDouble(current, end, '%', percentage);
-        if (!numCharactersParsed)
-            return false;
-        current += numCharactersParsed;
-        if (*current != '%')
-            return false;
-        localValue += percentage;
-    }
-
-    if (expect == CSSPrimitiveValue::CSS_PERCENTAGE && *current != '%')
-        return false;
-
-    if (*current == '%') {
-        expect = CSSPrimitiveValue::CSS_PERCENTAGE;
-        localValue = localValue / 100.0 * 256.0;
-        // Clamp values at 255 for percentages over 100%
-        if (localValue > 255)
-            localValue = 255;
-        current++;
-    } else
-        expect = CSSPrimitiveValue::CSS_NUMBER;
-
-    while (current != end && isHTMLSpace<CharacterType>(*current))
-        current++;
-    if (current == end || *current++ != terminator)
-        return false;
-    // Clamp negative values at zero.
-    value = negative ? 0 : static_cast<int>(localValue);
-    string = current;
-    return true;
-}
-
-template <typename CharacterType>
-static inline bool isTenthAlpha(const CharacterType* string, const int length)
-{
-    // "0.X"
-    if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2]))
-        return true;
-
-    // ".X"
-    if (length == 2 && string[0] == '.' && isASCIIDigit(string[1]))
-        return true;
-
-    return false;
-}
-
-template <typename CharacterType>
-static inline bool parseAlphaValue(const CharacterType*& string, const CharacterType* end, const char terminator, int& value)
-{
-    while (string != end && isHTMLSpace<CharacterType>(*string))
-        string++;
-
-    bool negative = false;
-
-    if (string != end && *string == '-') {
-        negative = true;
-        string++;
-    }
-
-    value = 0;
-
-    int length = end - string;
-    if (length < 2)
-        return false;
-
-    if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
-        return false;
-
-    if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
-        if (checkForValidDouble(string, end, terminator)) {
-            value = negative ? 0 : 255;
-            string = end;
-            return true;
-        }
-        return false;
-    }
-
-    if (length == 2 && string[0] != '.') {
-        value = !negative && string[0] == '1' ? 255 : 0;
-        string = end;
-        return true;
-    }
-
-    if (isTenthAlpha(string, length - 1)) {
-        static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
-        value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
-        string = end;
-        return true;
-    }
-
-    double alpha = 0;
-    if (!parseDouble(string, end, terminator, alpha))
-        return false;
-    value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
-    string = end;
-    return true;
-}
-
-template <typename CharacterType>
-static inline bool mightBeRGBA(const CharacterType* characters, unsigned length)
-{
-    if (length < 5)
-        return false;
-    return characters[4] == '('
-        && isASCIIAlphaCaselessEqual(characters[0], 'r')
-        && isASCIIAlphaCaselessEqual(characters[1], 'g')
-        && isASCIIAlphaCaselessEqual(characters[2], 'b')
-        && isASCIIAlphaCaselessEqual(characters[3], 'a');
-}
-
-template <typename CharacterType>
-static inline bool mightBeRGB(const CharacterType* characters, unsigned length)
-{
-    if (length < 4)
-        return false;
-    return characters[3] == '('
-        && isASCIIAlphaCaselessEqual(characters[0], 'r')
-        && isASCIIAlphaCaselessEqual(characters[1], 'g')
-        && isASCIIAlphaCaselessEqual(characters[2], 'b');
-}
-
-template <typename CharacterType>
-static inline bool fastParseColorInternal(RGBA32& rgb, const CharacterType* characters, unsigned length , bool strict)
-{
-    CSSPrimitiveValue::UnitTypes expect = CSSPrimitiveValue::CSS_UNKNOWN;
-
-    if (!strict && length >= 3) {
-        if (characters[0] == '#') {
-            if (Color::parseHexColor(characters + 1, length - 1, rgb))
-                return true;
-        } else {
-            if (Color::parseHexColor(characters, length, rgb))
-                return true;
-        }
-    }
-
-    // Try rgba() syntax.
-    if (mightBeRGBA(characters, length)) {
-        const CharacterType* current = characters + 5;
-        const CharacterType* end = characters + length;
-        int red;
-        int green;
-        int blue;
-        int alpha;
-
-        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
-            return false;
-        if (!parseAlphaValue(current, end, ')', alpha))
-            return false;
-        if (current != end)
-            return false;
-        rgb = makeRGBA(red, green, blue, alpha);
-        return true;
-    }
-
-    // Try rgb() syntax.
-    if (mightBeRGB(characters, length)) {
-        const CharacterType* current = characters + 4;
-        const CharacterType* end = characters + length;
-        int red;
-        int green;
-        int blue;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
-            return false;
-        if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
-            return false;
-        if (current != end)
-            return false;
-        rgb = makeRGB(red, green, blue);
-        return true;
-    }
-
-    return false;
-}
-
-template<typename StringType>
-bool BisonCSSParser::fastParseColor(RGBA32& rgb, const StringType& name, bool strict)
-{
-    unsigned length = name.length();
-    bool parseResult;
-
-    if (!length)
-        return false;
-
-    if (name.is8Bit())
-        parseResult = fastParseColorInternal(rgb, name.characters8(), length, strict);
-    else
-        parseResult = fastParseColorInternal(rgb, name.characters16(), length, strict);
-
-    if (parseResult)
-        return true;
-
-    // Try named colors.
-    Color tc;
-    if (!tc.setNamedColor(name))
-        return false;
-    rgb = tc.rgb();
-    return true;
-}
-
-inline double BisonCSSParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
-{
-    const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
-    if (releaseCalc == ReleaseParsedCalcValue)
-        m_parsedCalculation.release();
-    return result;
-}
-
-bool BisonCSSParser::isCalculation(CSSParserValue* value)
-{
-    return (value->unit == CSSParserValue::Function)
-        && (equalIgnoringCase(value->function->name, "calc(")
-            || equalIgnoringCase(value->function->name, "-webkit-calc(")
-            || equalIgnoringCase(value->function->name, "-webkit-min(")
-            || equalIgnoringCase(value->function->name, "-webkit-max("));
-}
-
-inline int BisonCSSParser::colorIntFromValue(CSSParserValue* v)
-{
-    bool isPercent;
-
-    if (m_parsedCalculation)
-        isPercent = m_parsedCalculation->category() == CalcPercent;
-    else
-        isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
-
-    const double value = parsedDouble(v, ReleaseParsedCalcValue);
-
-    if (value <= 0.0)
-        return 0;
-
-    if (isPercent) {
-        if (value >= 100.0)
-            return 255;
-        return static_cast<int>(value * 256.0 / 100.0);
-    }
-
-    if (value >= 255.0)
-        return 255;
-
-    return static_cast<int>(value);
-}
-
-bool BisonCSSParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
-{
-    CSSParserValueList* args = value->function->args.get();
-    CSSParserValue* v = args->current();
-    Units unitType = FUnknown;
-    // Get the first value and its type
-    if (validUnit(v, FInteger, HTMLStandardMode))
-        unitType = FInteger;
-    else if (validUnit(v, FPercent, HTMLStandardMode))
-        unitType = FPercent;
-    else
-        return false;
-
-    colorArray[0] = colorIntFromValue(v);
-    for (int i = 1; i < 3; i++) {
-        v = args->next();
-        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
-            return false;
-        v = args->next();
-        if (!validUnit(v, unitType, HTMLStandardMode))
-            return false;
-        colorArray[i] = colorIntFromValue(v);
-    }
-    if (parseAlpha) {
-        v = args->next();
-        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
-            return false;
-        v = args->next();
-        if (!validUnit(v, FNumber, HTMLStandardMode))
-            return false;
-        const double value = parsedDouble(v, ReleaseParsedCalcValue);
-        // Convert the floating pointer number of alpha to an integer in the range [0, 256),
-        // with an equal distribution across all 256 values.
-        colorArray[3] = static_cast<int>(max(0.0, min(1.0, value)) * nextafter(256.0, 0.0));
-    }
-    return true;
-}
-
-// The CSS3 specification defines the format of a HSL color as
-// hsl(<number>, <percent>, <percent>)
-// and with alpha, the format is
-// hsla(<number>, <percent>, <percent>, <number>)
-// The first value, HUE, is in an angle with a value between 0 and 360
-bool BisonCSSParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bool parseAlpha)
-{
-    CSSParserValueList* args = value->function->args.get();
-    CSSParserValue* v = args->current();
-    // Get the first value
-    if (!validUnit(v, FNumber, HTMLStandardMode))
-        return false;
-    // normalize the Hue value and change it to be between 0 and 1.0
-    colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0;
-    for (int i = 1; i < 3; i++) {
-        v = args->next();
-        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
-            return false;
-        v = args->next();
-        if (!validUnit(v, FPercent, HTMLStandardMode))
-            return false;
-        colorArray[i] = max(0.0, min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
-    }
-    if (parseAlpha) {
-        v = args->next();
-        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
-            return false;
-        v = args->next();
-        if (!validUnit(v, FNumber, HTMLStandardMode))
-            return false;
-        colorArray[3] = max(0.0, min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
-    }
-    return true;
-}
-
-PassRefPtrWillBeRawPtr<CSSPrimitiveValue> BisonCSSParser::parseColor(CSSParserValue* value)
-{
-    RGBA32 c = Color::transparent;
-    if (!parseColorFromValue(value ? value : m_valueList->current(), c))
-        return 0;
-    return cssValuePool().createColorValue(c);
-}
-
-bool BisonCSSParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
-{
-    if (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_NUMBER
-        && value->fValue >= 0. && value->fValue < 1000000.) {
-        String str = String::format("%06d", static_cast<int>((value->fValue+.5)));
-        // FIXME: This should be strict parsing for SVG as well.
-        if (!fastParseColor(c, str, !inQuirksMode()))
-            return false;
-    } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR ||
-                value->unit == CSSPrimitiveValue::CSS_IDENT ||
-                (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) {
-        if (!fastParseColor(c, value->string, !inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_IDENT))
-            return false;
-    } else if (value->unit == CSSParserValue::Function &&
-                value->function->args != 0 &&
-                value->function->args->size() == 5 /* rgb + two commas */ &&
-                equalIgnoringCase(value->function->name, "rgb(")) {
-        int colorValues[3];
-        if (!parseColorParameters(value, colorValues, false))
-            return false;
-        c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
-    } else {
-        if (value->unit == CSSParserValue::Function &&
-                value->function->args != 0 &&
-                value->function->args->size() == 7 /* rgba + three commas */ &&
-                equalIgnoringCase(value->function->name, "rgba(")) {
-            int colorValues[4];
-            if (!parseColorParameters(value, colorValues, true))
-                return false;
-            c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
-        } else if (value->unit == CSSParserValue::Function &&
-                    value->function->args != 0 &&
-                    value->function->args->size() == 5 /* hsl + two commas */ &&
-                    equalIgnoringCase(value->function->name, "hsl(")) {
-            double colorValues[3];
-            if (!parseHSLParameters(value, colorValues, false))
-                return false;
-            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
-        } else if (value->unit == CSSParserValue::Function &&
-                    value->function->args != 0 &&
-                    value->function->args->size() == 7 /* hsla + three commas */ &&
-                    equalIgnoringCase(value->function->name, "hsla(")) {
-            double colorValues[4];
-            if (!parseHSLParameters(value, colorValues, true))
-                return false;
-            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
-        } else
-            return false;
-    }
-
-    return true;
-}
-
-// This class tracks parsing state for shadow values.  If it goes out of scope (e.g., due to an early return)
-// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
-struct ShadowParseContext {
-    DISALLOW_ALLOCATION();
-public:
-    ShadowParseContext(CSSPropertyID prop, BisonCSSParser* parser)
-        : property(prop)
-        , m_parser(parser)
-        , allowX(true)
-        , allowY(false)
-        , allowBlur(false)
-        , allowSpread(false)
-        , allowColor(true)
-        , allowStyle(prop == CSSPropertyWebkitBoxShadow || prop == CSSPropertyBoxShadow)
-        , allowBreak(true)
-    {
-    }
-
-    bool allowLength() { return allowX || allowY || allowBlur || allowSpread; }
-
-    void commitValue()
-    {
-        // Handle the ,, case gracefully by doing nothing.
-        if (x || y || blur || spread || color || style) {
-            if (!values)
-                values = CSSValueList::createCommaSeparated();
-
-            // Construct the current shadow value and add it to the list.
-            values->append(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
-        }
-
-        // Now reset for the next shadow value.
-        x = 0;
-        y = 0;
-        blur = 0;
-        spread = 0;
-        style = 0;
-        color = 0;
-
-        allowX = true;
-        allowColor = true;
-        allowBreak = true;
-        allowY = false;
-        allowBlur = false;
-        allowSpread = false;
-        allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-    }
-
-    void commitLength(CSSParserValue* v)
-    {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
-
-        if (allowX) {
-            x = val.release();
-            allowX = false;
-            allowY = true;
-            allowColor = false;
-            allowStyle = false;
-            allowBreak = false;
-        } else if (allowY) {
-            y = val.release();
-            allowY = false;
-            allowBlur = true;
-            allowColor = true;
-            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-            allowBreak = true;
-        } else if (allowBlur) {
-            blur = val.release();
-            allowBlur = false;
-            allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-        } else if (allowSpread) {
-            spread = val.release();
-            allowSpread = false;
-        }
-    }
-
-    void commitColor(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val)
-    {
-        color = val;
-        allowColor = false;
-        if (allowX) {
-            allowStyle = false;
-            allowBreak = false;
-        } else {
-            allowBlur = false;
-            allowSpread = false;
-            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
-        }
-    }
-
-    void commitStyle(CSSParserValue* v)
-    {
-        style = cssValuePool().createIdentifierValue(v->id);
-        allowStyle = false;
-        if (allowX)
-            allowBreak = false;
-        else {
-            allowBlur = false;
-            allowSpread = false;
-            allowColor = false;
-        }
-    }
-
-    CSSPropertyID property;
-    BisonCSSParser* m_parser;
-
-    RefPtrWillBeRawPtr<CSSValueList> values;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> x;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> y;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> blur;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> spread;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> style;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> color;
-
-    bool allowX;
-    bool allowY;
-    bool allowBlur;
-    bool allowSpread;
-    bool allowColor;
-    bool allowStyle; // inset or not.
-    bool allowBreak;
-};
-
-PassRefPtrWillBeRawPtr<CSSValueList> BisonCSSParser::parseShadow(CSSParserValueList* valueList, CSSPropertyID propId)
-{
-    ShadowParseContext context(propId, this);
-    CSSParserValue* val;
-    while ((val = valueList->current())) {
-        // Check for a comma break first.
-        if (val->unit == CSSParserValue::Operator) {
-            if (val->iValue != ',' || !context.allowBreak)
-                // Other operators aren't legal or we aren't done with the current shadow
-                // value.  Treat as invalid.
-                return 0;
-            // The value is good.  Commit it.
-            context.commitValue();
-        } else if (validUnit(val, FLength, HTMLStandardMode)) {
-            // We required a length and didn't get one. Invalid.
-            if (!context.allowLength())
-                return 0;
-
-            // Blur radius must be non-negative.
-            if (context.allowBlur && !validUnit(val, FLength | FNonNeg, HTMLStandardMode))
-                return 0;
-
-            // A length is allowed here.  Construct the value and add it.
-            context.commitLength(val);
-        } else if (val->id == CSSValueInset) {
-            if (!context.allowStyle)
-                return 0;
-
-            context.commitStyle(val);
-        } else {
-            // The only other type of value that's ok is a color value.
-            RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedColor;
-            bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu
-                            || (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && inQuirksMode())
-                            || val->id == CSSValueCurrentcolor);
-            if (isColor) {
-                if (!context.allowColor)
-                    return 0;
-                parsedColor = cssValuePool().createIdentifierValue(val->id);
-            }
-
-            if (!parsedColor)
-                // It's not built-in. Try to parse it as a color.
-                parsedColor = parseColor(val);
-
-            if (!parsedColor || !context.allowColor)
-                return 0; // This value is not a color or length and is invalid or
-                          // it is a color, but a color isn't allowed at this point.
-
-            context.commitColor(parsedColor.release());
-        }
-
-        valueList->next();
-    }
-
-    if (context.allowBreak) {
-        context.commitValue();
-        if (context.values && context.values->length())
-            return context.values.release();
-    }
-
-    return 0;
-}
-
-bool BisonCSSParser::parseReflect(CSSPropertyID propId, bool important)
-{
-    // box-reflect: <direction> <offset> <mask>
-
-    // Direction comes first.
-    CSSParserValue* val = m_valueList->current();
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> direction;
-    switch (val->id) {
-    case CSSValueAbove:
-    case CSSValueBelow:
-    case CSSValueLeft:
-    case CSSValueRight:
-        direction = cssValuePool().createIdentifierValue(val->id);
-        break;
-    default:
-        return false;
-    }
-
-    // The offset comes next.
-    val = m_valueList->next();
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> offset;
-    if (!val)
-        offset = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
-    else {
-        if (!validUnit(val, FLength | FPercent))
-            return false;
-        offset = createPrimitiveNumericValue(val);
-    }
-
-    // Now for the mask.
-    RefPtr<CSSValue> mask;
-    val = m_valueList->next();
-    if (val) {
-        mask = parseBorderImage(propId);
-        if (!mask)
-            return false;
-    }
-
-    RefPtrWillBeRawPtr<CSSReflectValue> reflectValue = CSSReflectValue::create(direction.release(), offset.release(), mask.release());
-    addProperty(propId, reflectValue.release(), important);
-    m_valueList->next();
-    return true;
-}
-
-bool BisonCSSParser::parseFlex(CSSParserValueList* args, bool important)
-{
-    if (!args || !args->size() || args->size() > 3)
-        return false;
-    static const double unsetValue = -1;
-    double flexGrow = unsetValue;
-    double flexShrink = unsetValue;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> flexBasis;
-
-    while (CSSParserValue* arg = args->current()) {
-        if (validUnit(arg, FNumber | FNonNeg)) {
-            if (flexGrow == unsetValue)
-                flexGrow = arg->fValue;
-            else if (flexShrink == unsetValue)
-                flexShrink = arg->fValue;
-            else if (!arg->fValue) {
-                // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set.
-                flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
-            } else {
-                // We only allow 3 numbers without units if the last value is 0. E.g., flex:1 1 1 is invalid.
-                return false;
-            }
-        } else if (!flexBasis && (arg->id == CSSValueAuto || validUnit(arg, FLength | FPercent | FNonNeg)))
-            flexBasis = parseValidPrimitive(arg->id, arg);
-        else {
-            // Not a valid arg for flex.
-            return false;
-        }
-        args->next();
-    }
-
-    if (flexGrow == unsetValue)
-        flexGrow = 1;
-    if (flexShrink == unsetValue)
-        flexShrink = 1;
-    if (!flexBasis)
-        flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
-
-    addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important);
-    addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important);
-    addProperty(CSSPropertyFlexBasis, flexBasis, important);
-    return true;
-}
-
-bool BisonCSSParser::parseObjectPosition(bool important)
-{
-    RefPtr<CSSValue> xValue;
-    RefPtr<CSSValue> yValue;
-    parseFillPosition(m_valueList.get(), xValue, yValue);
-    if (!xValue || !yValue)
-        return false;
-    addProperty(
-        CSSPropertyObjectPosition,
-        createPrimitiveValuePair(toCSSPrimitiveValue(xValue.get()), toCSSPrimitiveValue(yValue.get()), Pair::KeepIdenticalValues),
-        important);
-    return true;
-}
-
-struct BorderImageParseContext {
-    DISALLOW_ALLOCATION();
-public:
-    BorderImageParseContext()
-    : m_canAdvance(false)
-    , m_allowCommit(true)
-    , m_allowImage(true)
-    , m_allowImageSlice(true)
-    , m_allowRepeat(true)
-    , m_allowForwardSlashOperator(false)
-    , m_requireWidth(false)
-    , m_requireOutset(false)
-    {}
-
-    bool canAdvance() const { return m_canAdvance; }
-    void setCanAdvance(bool canAdvance) { m_canAdvance = canAdvance; }
-
-    bool allowCommit() const { return m_allowCommit; }
-    bool allowImage() const { return m_allowImage; }
-    bool allowImageSlice() const { return m_allowImageSlice; }
-    bool allowRepeat() const { return m_allowRepeat; }
-    bool allowForwardSlashOperator() const { return m_allowForwardSlashOperator; }
-
-    bool requireWidth() const { return m_requireWidth; }
-    bool requireOutset() const { return m_requireOutset; }
-
-    void commitImage(PassRefPtr<CSSValue> image)
-    {
-        m_image = image;
-        m_canAdvance = true;
-        m_allowCommit = true;
-        m_allowImage = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
-        m_allowImageSlice = !m_imageSlice;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitImageSlice(PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> slice)
-    {
-        m_imageSlice = slice;
-        m_canAdvance = true;
-        m_allowCommit = m_allowForwardSlashOperator = true;
-        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
-        m_allowImage = !m_image;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitForwardSlashOperator()
-    {
-        m_canAdvance = true;
-        m_allowCommit = m_allowImage = m_allowImageSlice = m_allowRepeat = m_allowForwardSlashOperator = false;
-        if (!m_borderSlice) {
-            m_requireWidth = true;
-            m_requireOutset = false;
-        } else {
-            m_requireOutset = true;
-            m_requireWidth = false;
-        }
-    }
-    void commitBorderWidth(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> slice)
-    {
-        m_borderSlice = slice;
-        m_canAdvance = true;
-        m_allowCommit = m_allowForwardSlashOperator = true;
-        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
-        m_allowImage = !m_image;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitBorderOutset(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> outset)
-    {
-        m_outset = outset;
-        m_canAdvance = true;
-        m_allowCommit = true;
-        m_allowImageSlice = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
-        m_allowImage = !m_image;
-        m_allowRepeat = !m_repeat;
-    }
-    void commitRepeat(PassRefPtr<CSSValue> repeat)
-    {
-        m_repeat = repeat;
-        m_canAdvance = true;
-        m_allowCommit = true;
-        m_allowRepeat = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
-        m_allowImageSlice = !m_imageSlice;
-        m_allowImage = !m_image;
-    }
-
-    PassRefPtr<CSSValue> commitCSSValue()
-    {
-        return createBorderImageValue(m_image, m_imageSlice, m_borderSlice, m_outset, m_repeat);
-    }
-
-    void commitMaskBoxImage(BisonCSSParser* parser, bool important)
-    {
-        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSource, parser, m_image, important);
-        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSlice, parser, m_imageSlice, important);
-        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageWidth, parser, m_borderSlice, important);
-        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageOutset, parser, m_outset, important);
-        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageRepeat, parser, m_repeat, important);
-    }
-
-    void commitBorderImage(BisonCSSParser* parser, bool important)
-    {
-        commitBorderImageProperty(CSSPropertyBorderImageSource, parser, m_image, important);
-        commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important);
-        commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice, important);
-        commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset, important);
-        commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important);
-    }
-
-    void commitBorderImageProperty(CSSPropertyID propId, BisonCSSParser* parser, PassRefPtr<CSSValue> value, bool important)
-    {
-        if (value)
-            parser->addProperty(propId, value, important);
-        else
-            parser->addProperty(propId, cssValuePool().createImplicitInitialValue(), important, true);
-    }
-
-    bool m_canAdvance;
-
-    bool m_allowCommit;
-    bool m_allowImage;
-    bool m_allowImageSlice;
-    bool m_allowRepeat;
-    bool m_allowForwardSlashOperator;
-
-    bool m_requireWidth;
-    bool m_requireOutset;
-
-    RefPtr<CSSValue> m_image;
-    RefPtrWillBeRawPtr<CSSBorderImageSliceValue> m_imageSlice;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_borderSlice;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_outset;
-
-    RefPtr<CSSValue> m_repeat;
-};
-
-static bool buildBorderImageParseContext(BisonCSSParser& parser, CSSPropertyID propId, BorderImageParseContext& context)
-{
-    ShorthandScope scope(&parser, propId);
-    while (CSSParserValue* val = parser.m_valueList->current()) {
-        context.setCanAdvance(false);
-
-        if (!context.canAdvance() && context.allowForwardSlashOperator() && isForwardSlashOperator(val))
-            context.commitForwardSlashOperator();
-
-        if (!context.canAdvance() && context.allowImage()) {
-            if (val->unit == CSSPrimitiveValue::CSS_URI) {
-                context.commitImage(CSSImageValue::create(parser.m_context.completeURL(val->string)));
-            } else if (isGeneratedImageValue(val)) {
-                RefPtr<CSSValue> value;
-                if (parser.parseGeneratedImage(parser.m_valueList.get(), value))
-                    context.commitImage(value.release());
-                else
-                    return false;
-            } else if (val->unit == CSSParserValue::Function && equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
-                RefPtr<CSSValue> value = parser.parseImageSet(parser.m_valueList.get());
-                if (value)
-                    context.commitImage(value.release());
-                else
-                    return false;
-            } else if (val->id == CSSValueNone)
-                context.commitImage(cssValuePool().createIdentifierValue(CSSValueNone));
-        }
-
-        if (!context.canAdvance() && context.allowImageSlice()) {
-            RefPtrWillBeRawPtr<CSSBorderImageSliceValue> imageSlice;
-            if (parser.parseBorderImageSlice(propId, imageSlice))
-                context.commitImageSlice(imageSlice.release());
-        }
-
-        if (!context.canAdvance() && context.allowRepeat()) {
-            RefPtr<CSSValue> repeat;
-            if (parser.parseBorderImageRepeat(repeat))
-                context.commitRepeat(repeat.release());
-        }
-
-        if (!context.canAdvance() && context.requireWidth()) {
-            RefPtrWillBeRawPtr<CSSPrimitiveValue> borderSlice;
-            if (parser.parseBorderImageWidth(borderSlice))
-                context.commitBorderWidth(borderSlice.release());
-        }
-
-        if (!context.canAdvance() && context.requireOutset()) {
-            RefPtrWillBeRawPtr<CSSPrimitiveValue> borderOutset;
-            if (parser.parseBorderImageOutset(borderOutset))
-                context.commitBorderOutset(borderOutset.release());
-        }
-
-        if (!context.canAdvance())
-            return false;
-
-        parser.m_valueList->next();
-    }
-
-    return context.allowCommit();
-}
-
-bool BisonCSSParser::parseBorderImageShorthand(CSSPropertyID propId, bool important)
-{
-    BorderImageParseContext context;
-    if (buildBorderImageParseContext(*this, propId, context)) {
-        switch (propId) {
-        case CSSPropertyWebkitMaskBoxImage:
-            context.commitMaskBoxImage(this, important);
-            return true;
-        case CSSPropertyBorderImage:
-            context.commitBorderImage(this, important);
-            return true;
-        default:
-            ASSERT_NOT_REACHED();
-            return false;
-        }
-    }
-    return false;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseBorderImage(CSSPropertyID propId)
-{
-    BorderImageParseContext context;
-    if (buildBorderImageParseContext(*this, propId, context)) {
-        return context.commitCSSValue();
-    }
-    return 0;
-}
-
-static bool isBorderImageRepeatKeyword(int id)
-{
-    return id == CSSValueStretch || id == CSSValueRepeat || id == CSSValueSpace || id == CSSValueRound;
-}
-
-bool BisonCSSParser::parseBorderImageRepeat(RefPtr<CSSValue>& result)
-{
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> firstValue;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> secondValue;
-    CSSParserValue* val = m_valueList->current();
-    if (!val)
-        return false;
-    if (isBorderImageRepeatKeyword(val->id))
-        firstValue = cssValuePool().createIdentifierValue(val->id);
-    else
-        return false;
-
-    val = m_valueList->next();
-    if (val) {
-        if (isBorderImageRepeatKeyword(val->id))
-            secondValue = cssValuePool().createIdentifierValue(val->id);
-        else if (!inShorthand()) {
-            // If we're not parsing a shorthand then we are invalid.
-            return false;
-        } else {
-            // We need to rewind the value list, so that when its advanced we'll
-            // end up back at this value.
-            m_valueList->previous();
-            secondValue = firstValue;
-        }
-    } else
-        secondValue = firstValue;
-
-    result = createPrimitiveValuePair(firstValue, secondValue);
-    return true;
-}
-
-class BorderImageSliceParseContext {
-    DISALLOW_ALLOCATION();
-public:
-    BorderImageSliceParseContext(BisonCSSParser* parser)
-    : m_parser(parser)
-    , m_allowNumber(true)
-    , m_allowFill(true)
-    , m_allowFinalCommit(false)
-    , m_fill(false)
-    { }
-
-    bool allowNumber() const { return m_allowNumber; }
-    bool allowFill() const { return m_allowFill; }
-    bool allowFinalCommit() const { return m_allowFinalCommit; }
-    CSSPrimitiveValue* top() const { return m_top.get(); }
-
-    void commitNumber(CSSParserValue* v)
-    {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
-        if (!m_top)
-            m_top = val;
-        else if (!m_right)
-            m_right = val;
-        else if (!m_bottom)
-            m_bottom = val;
-        else {
-            ASSERT(!m_left);
-            m_left = val;
-        }
-
-        m_allowNumber = !m_left;
-        m_allowFinalCommit = true;
-    }
-
-    void commitFill() { m_fill = true; m_allowFill = false; m_allowNumber = !m_top; }
-
-    PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> commitBorderImageSlice()
-    {
-        // We need to clone and repeat values for any omissions.
-        ASSERT(m_top);
-        if (!m_right) {
-            m_right = m_top;
-            m_bottom = m_top;
-            m_left = m_top;
-        }
-        if (!m_bottom) {
-            m_bottom = m_top;
-            m_left = m_right;
-        }
-        if (!m_left)
-            m_left = m_right;
-
-        // Now build a rect value to hold all four of our primitive values.
-        RefPtr<Quad> quad = Quad::create();
-        quad->setTop(m_top);
-        quad->setRight(m_right);
-        quad->setBottom(m_bottom);
-        quad->setLeft(m_left);
-
-        // Make our new border image value now.
-        return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), m_fill);
-    }
-
-private:
-    BisonCSSParser* m_parser;
-
-    bool m_allowNumber;
-    bool m_allowFill;
-    bool m_allowFinalCommit;
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_top;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_right;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_bottom;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_left;
-
-    bool m_fill;
-};
-
-bool BisonCSSParser::parseBorderImageSlice(CSSPropertyID propId, RefPtrWillBeRawPtr<CSSBorderImageSliceValue>& result)
-{
-    BorderImageSliceParseContext context(this);
-    CSSParserValue* val;
-    while ((val = m_valueList->current())) {
-        // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
-        if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, HTMLStandardMode)) {
-            context.commitNumber(val);
-        } else if (context.allowFill() && val->id == CSSValueFill)
-            context.commitFill();
-        else if (!inShorthand()) {
-            // If we're not parsing a shorthand then we are invalid.
-            return false;
-        } else {
-            if (context.allowFinalCommit()) {
-                // We're going to successfully parse, but we don't want to consume this token.
-                m_valueList->previous();
-            }
-            break;
-        }
-        m_valueList->next();
-    }
-
-    if (context.allowFinalCommit()) {
-        // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-box-image and -webkit-box-reflect have to do a fill by default.
-        // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image? Probably just have to leave them filling...
-        if (propId == CSSPropertyWebkitBorderImage || propId == CSSPropertyWebkitMaskBoxImage || propId == CSSPropertyWebkitBoxReflect)
-            context.commitFill();
-
-        // Need to fully commit as a single value.
-        result = context.commitBorderImageSlice();
-        return true;
-    }
-
-    return false;
-}
-
-class BorderImageQuadParseContext {
-public:
-    BorderImageQuadParseContext(BisonCSSParser* parser)
-    : m_parser(parser)
-    , m_allowNumber(true)
-    , m_allowFinalCommit(false)
-    { }
-
-    bool allowNumber() const { return m_allowNumber; }
-    bool allowFinalCommit() const { return m_allowFinalCommit; }
-    CSSPrimitiveValue* top() const { return m_top.get(); }
-
-    void commitNumber(CSSParserValue* v)
-    {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> val;
-        if (v->id == CSSValueAuto)
-            val = cssValuePool().createIdentifierValue(v->id);
-        else
-            val = m_parser->createPrimitiveNumericValue(v);
-
-        if (!m_top)
-            m_top = val;
-        else if (!m_right)
-            m_right = val;
-        else if (!m_bottom)
-            m_bottom = val;
-        else {
-            ASSERT(!m_left);
-            m_left = val;
-        }
-
-        m_allowNumber = !m_left;
-        m_allowFinalCommit = true;
-    }
-
-    void setAllowFinalCommit() { m_allowFinalCommit = true; }
-    void setTop(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_top = val; }
-
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> commitBorderImageQuad()
-    {
-        // We need to clone and repeat values for any omissions.
-        ASSERT(m_top);
-        if (!m_right) {
-            m_right = m_top;
-            m_bottom = m_top;
-            m_left = m_top;
-        }
-        if (!m_bottom) {
-            m_bottom = m_top;
-            m_left = m_right;
-        }
-        if (!m_left)
-            m_left = m_right;
-
-        // Now build a quad value to hold all four of our primitive values.
-        RefPtr<Quad> quad = Quad::create();
-        quad->setTop(m_top);
-        quad->setRight(m_right);
-        quad->setBottom(m_bottom);
-        quad->setLeft(m_left);
-
-        // Make our new value now.
-        return cssValuePool().createValue(quad.release());
-    }
-
-private:
-    BisonCSSParser* m_parser;
-
-    bool m_allowNumber;
-    bool m_allowFinalCommit;
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_top;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_right;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_bottom;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_left;
-};
-
-bool BisonCSSParser::parseBorderImageQuad(Units validUnits, RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
-{
-    BorderImageQuadParseContext context(this);
-    CSSParserValue* val;
-    while ((val = m_valueList->current())) {
-        if (context.allowNumber() && (validUnit(val, validUnits, HTMLStandardMode) || val->id == CSSValueAuto)) {
-            context.commitNumber(val);
-        } else if (!inShorthand()) {
-            // If we're not parsing a shorthand then we are invalid.
-            return false;
-        } else {
-            if (context.allowFinalCommit())
-                m_valueList->previous(); // The shorthand loop will advance back to this point.
-            break;
-        }
-        m_valueList->next();
-    }
-
-    if (context.allowFinalCommit()) {
-        // Need to fully commit as a single value.
-        result = context.commitBorderImageQuad();
-        return true;
-    }
-    return false;
-}
-
-bool BisonCSSParser::parseBorderImageWidth(RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
-{
-    return parseBorderImageQuad(FLength | FNumber | FNonNeg | FPercent, result);
-}
-
-bool BisonCSSParser::parseBorderImageOutset(RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
-{
-    return parseBorderImageQuad(FLength | FNumber | FNonNeg, result);
-}
-
-bool BisonCSSParser::parseBorderRadius(CSSPropertyID propId, bool important)
-{
-    unsigned num = m_valueList->size();
-    if (num > 9)
-        return false;
-
-    ShorthandScope scope(this, propId);
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[2][4];
-
-    unsigned indexAfterSlash = 0;
-    for (unsigned i = 0; i < num; ++i) {
-        CSSParserValue* value = m_valueList->valueAt(i);
-        if (value->unit == CSSParserValue::Operator) {
-            if (value->iValue != '/')
-                return false;
-
-            if (!i || indexAfterSlash || i + 1 == num || num > i + 5)
-                return false;
-
-            indexAfterSlash = i + 1;
-            completeBorderRadii(radii[0]);
-            continue;
-        }
-
-        if (i - indexAfterSlash >= 4)
-            return false;
-
-        if (!validUnit(value, FLength | FPercent | FNonNeg))
-            return false;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
-
-        if (!indexAfterSlash) {
-            radii[0][i] = radius;
-
-            // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
-            if (num == 2 && propId == CSSPropertyWebkitBorderRadius) {
-                indexAfterSlash = 1;
-                completeBorderRadii(radii[0]);
-            }
-        } else
-            radii[1][i - indexAfterSlash] = radius.release();
-    }
-
-    if (!indexAfterSlash) {
-        completeBorderRadii(radii[0]);
-        for (unsigned i = 0; i < 4; ++i)
-            radii[1][i] = radii[0][i];
-    } else
-        completeBorderRadii(radii[1]);
-
-    ImplicitScope implicitScope(this, PropertyImplicit);
-    addProperty(CSSPropertyBorderTopLeftRadius, createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()), important);
-    addProperty(CSSPropertyBorderTopRightRadius, createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()), important);
-    addProperty(CSSPropertyBorderBottomRightRadius, createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()), important);
-    addProperty(CSSPropertyBorderBottomLeftRadius, createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()), important);
-    return true;
-}
-
-bool BisonCSSParser::parseAspectRatio(bool important)
-{
-    unsigned num = m_valueList->size();
-    if (num == 1 && m_valueList->valueAt(0)->id == CSSValueNone) {
-        addProperty(CSSPropertyWebkitAspectRatio, cssValuePool().createIdentifierValue(CSSValueNone), important);
-        return true;
-    }
-
-    if (num != 3)
-        return false;
-
-    CSSParserValue* lvalue = m_valueList->valueAt(0);
-    CSSParserValue* op = m_valueList->valueAt(1);
-    CSSParserValue* rvalue = m_valueList->valueAt(2);
-
-    if (!isForwardSlashOperator(op))
-        return false;
-
-    if (!validUnit(lvalue, FNumber | FNonNeg) || !validUnit(rvalue, FNumber | FNonNeg))
-        return false;
-
-    if (!lvalue->fValue || !rvalue->fValue)
-        return false;
-
-    addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalue->fValue), narrowPrecisionToFloat(rvalue->fValue)), important);
-
-    return true;
-}
-
-bool BisonCSSParser::parseCounter(CSSPropertyID propId, int defaultValue, bool important)
-{
-    enum { ID, VAL } state = ID;
-
-    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> counterName;
-
-    while (true) {
-        CSSParserValue* val = m_valueList->current();
-        switch (state) {
-            case ID:
-                if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
-                    counterName = createPrimitiveStringValue(val);
-                    state = VAL;
-                    m_valueList->next();
-                    continue;
-                }
-                break;
-            case VAL: {
-                int i = defaultValue;
-                if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) {
-                    i = clampToInteger(val->fValue);
-                    m_valueList->next();
-                }
-
-                list->append(createPrimitiveValuePair(counterName.release(),
-                    cssValuePool().createValue(i, CSSPrimitiveValue::CSS_NUMBER)));
-                state = ID;
-                continue;
-            }
-        }
-        break;
-    }
-
-    if (list->length() > 0) {
-        addProperty(propId, list.release(), important);
-        return true;
-    }
-
-    return false;
-}
-
-// This should go away once we drop support for -webkit-gradient
-static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal)
-{
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> result;
-    if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
-        if ((equalIgnoringCase(a, "left") && horizontal)
-            || (equalIgnoringCase(a, "top") && !horizontal))
-            result = cssValuePool().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
-        else if ((equalIgnoringCase(a, "right") && horizontal)
-                 || (equalIgnoringCase(a, "bottom") && !horizontal))
-            result = cssValuePool().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
-        else if (equalIgnoringCase(a, "center"))
-            result = cssValuePool().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
-    } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-        result = cssValuePool().createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(a->unit));
-    return result;
-}
-
-static bool parseDeprecatedGradientColorStop(BisonCSSParser* p, CSSParserValue* a, CSSGradientColorStop& stop)
-{
-    if (a->unit != CSSParserValue::Function)
-        return false;
-
-    if (!equalIgnoringCase(a->function->name, "from(") &&
-        !equalIgnoringCase(a->function->name, "to(") &&
-        !equalIgnoringCase(a->function->name, "color-stop("))
-        return false;
-
-    CSSParserValueList* args = a->function->args.get();
-    if (!args)
-        return false;
-
-    if (equalIgnoringCase(a->function->name, "from(")
-        || equalIgnoringCase(a->function->name, "to(")) {
-        // The "from" and "to" stops expect 1 argument.
-        if (args->size() != 1)
-            return false;
-
-        if (equalIgnoringCase(a->function->name, "from("))
-            stop.m_position = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
-        else
-            stop.m_position = cssValuePool().createValue(1, CSSPrimitiveValue::CSS_NUMBER);
-
-        CSSValueID id = args->current()->id;
-        if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
-            stop.m_color = cssValuePool().createIdentifierValue(id);
-        else
-            stop.m_color = p->parseColor(args->current());
-        if (!stop.m_color)
-            return false;
-    }
-
-    // The "color-stop" function expects 3 arguments.
-    if (equalIgnoringCase(a->function->name, "color-stop(")) {
-        if (args->size() != 3)
-            return false;
-
-        CSSParserValue* stopArg = args->current();
-        if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-            stop.m_position = cssValuePool().createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
-        else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
-            stop.m_position = cssValuePool().createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
-        else
-            return false;
-
-        stopArg = args->next();
-        if (stopArg->unit != CSSParserValue::Operator || stopArg->iValue != ',')
-            return false;
-
-        stopArg = args->next();
-        CSSValueID id = stopArg->id;
-        if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
-            stop.m_color = cssValuePool().createIdentifierValue(id);
-        else
-            stop.m_color = p->parseColor(stopArg);
-        if (!stop.m_color)
-            return false;
-    }
-
-    return true;
-}
-
-bool BisonCSSParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient)
-{
-    // Walk the arguments.
-    CSSParserValueList* args = valueList->current()->function->args.get();
-    if (!args || args->size() == 0)
-        return false;
-
-    // The first argument is the gradient type.  It is an identifier.
-    CSSGradientType gradientType;
-    CSSParserValue* a = args->current();
-    if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
-        return false;
-    if (equalIgnoringCase(a, "linear"))
-        gradientType = CSSDeprecatedLinearGradient;
-    else if (equalIgnoringCase(a, "radial"))
-        gradientType = CSSDeprecatedRadialGradient;
-    else
-        return false;
-
-    RefPtr<CSSGradientValue> result;
-    switch (gradientType) {
-    case CSSDeprecatedLinearGradient:
-        result = CSSLinearGradientValue::create(NonRepeating, gradientType);
-        break;
-    case CSSDeprecatedRadialGradient:
-        result = CSSRadialGradientValue::create(NonRepeating, gradientType);
-        break;
-    default:
-        // The rest of the gradient types shouldn't appear here.
-        ASSERT_NOT_REACHED();
-    }
-
-    // Comma.
-    a = args->next();
-    if (!isComma(a))
-        return false;
-
-    // Next comes the starting point for the gradient as an x y pair.  There is no
-    // comma between the x and the y values.
-    // First X.  It can be left, right, number or percent.
-    a = args->next();
-    if (!a)
-        return false;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true);
-    if (!point)
-        return false;
-    result->setFirstX(point.release());
-
-    // First Y.  It can be top, bottom, number or percent.
-    a = args->next();
-    if (!a)
-        return false;
-    point = parseDeprecatedGradientPoint(a, false);
-    if (!point)
-        return false;
-    result->setFirstY(point.release());
-
-    // Comma after the first point.
-    a = args->next();
-    if (!isComma(a))
-        return false;
-
-    // For radial gradients only, we now expect a numeric radius.
-    if (gradientType == CSSDeprecatedRadialGradient) {
-        a = args->next();
-        if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
-            return false;
-        toCSSRadialGradientValue(result.get())->setFirstRadius(createPrimitiveNumericValue(a));
-
-        // Comma after the first radius.
-        a = args->next();
-        if (!isComma(a))
-            return false;
-    }
-
-    // Next is the ending point for the gradient as an x, y pair.
-    // Second X.  It can be left, right, number or percent.
-    a = args->next();
-    if (!a)
-        return false;
-    point = parseDeprecatedGradientPoint(a, true);
-    if (!point)
-        return false;
-    result->setSecondX(point.release());
-
-    // Second Y.  It can be top, bottom, number or percent.
-    a = args->next();
-    if (!a)
-        return false;
-    point = parseDeprecatedGradientPoint(a, false);
-    if (!point)
-        return false;
-    result->setSecondY(point.release());
-
-    // For radial gradients only, we now expect the second radius.
-    if (gradientType == CSSDeprecatedRadialGradient) {
-        // Comma after the second point.
-        a = args->next();
-        if (!isComma(a))
-            return false;
-
-        a = args->next();
-        if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
-            return false;
-        toCSSRadialGradientValue(result.get())->setSecondRadius(createPrimitiveNumericValue(a));
-    }
-
-    // We now will accept any number of stops (0 or more).
-    a = args->next();
-    while (a) {
-        // Look for the comma before the next stop.
-        if (!isComma(a))
-            return false;
-
-        // Now examine the stop itself.
-        a = args->next();
-        if (!a)
-            return false;
-
-        // The function name needs to be one of "from", "to", or "color-stop."
-        CSSGradientColorStop stop;
-        if (!parseDeprecatedGradientColorStop(this, a, stop))
-            return false;
-        result->addStop(stop);
-
-        // Advance
-        a = args->next();
-    }
-
-    gradient = result.release();
-    return true;
-}
-
-static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal)
-{
-    if (a->unit != CSSPrimitiveValue::CSS_IDENT)
-        return 0;
-
-    switch (a->id) {
-        case CSSValueLeft:
-        case CSSValueRight:
-            isHorizontal = true;
-            break;
-        case CSSValueTop:
-        case CSSValueBottom:
-            isHorizontal = false;
-            break;
-        default:
-            return 0;
-    }
-    return cssValuePool().createIdentifierValue(a->id);
-}
-
-static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(BisonCSSParser* p, CSSParserValue* value)
-{
-    CSSValueID id = value->id;
-    if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor)
-        return cssValuePool().createIdentifierValue(id);
-
-    return p->parseColor(value);
-}
-
-bool BisonCSSParser::parseDeprecatedLinearGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
-    RefPtrWillBeRawPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient);
-
-    // Walk the arguments.
-    CSSParserValueList* args = valueList->current()->function->args.get();
-    if (!args || !args->size())
-        return false;
-
-    CSSParserValue* a = args->current();
-    if (!a)
-        return false;
-
-    bool expectComma = false;
-    // Look for angle.
-    if (validUnit(a, FAngle, HTMLStandardMode)) {
-        result->setAngle(createPrimitiveNumericValue(a));
-
-        args->next();
-        expectComma = true;
-    } else {
-        // Look one or two optional keywords that indicate a side or corner.
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> startX, startY;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> location;
-        bool isHorizontal = false;
-        if ((location = valueFromSideKeyword(a, isHorizontal))) {
-            if (isHorizontal)
-                startX = location;
-            else
-                startY = location;
-
-            if ((a = args->next())) {
-                if ((location = valueFromSideKeyword(a, isHorizontal))) {
-                    if (isHorizontal) {
-                        if (startX)
-                            return false;
-                        startX = location;
-                    } else {
-                        if (startY)
-                            return false;
-                        startY = location;
-                    }
-
-                    args->next();
-                }
-            }
-
-            expectComma = true;
-        }
-
-        if (!startX && !startY)
-            startY = cssValuePool().createIdentifierValue(CSSValueTop);
-
-        result->setFirstX(startX.release());
-        result->setFirstY(startY.release());
-    }
-
-    if (!parseGradientColorStops(args, result.get(), expectComma))
-        return false;
-
-    if (!result->stopCount())
-        return false;
-
-    gradient = result.release();
-    return true;
-}
-
-bool BisonCSSParser::parseDeprecatedRadialGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
-    RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient);
-
-    // Walk the arguments.
-    CSSParserValueList* args = valueList->current()->function->args.get();
-    if (!args || !args->size())
-        return false;
-
-    CSSParserValue* a = args->current();
-    if (!a)
-        return false;
-
-    bool expectComma = false;
-
-    // Optional background-position
-    RefPtr<CSSValue> centerX;
-    RefPtr<CSSValue> centerY;
-    // parse2ValuesFillPosition advances the args next pointer.
-    parse2ValuesFillPosition(args, centerX, centerY);
-    a = args->current();
-    if (!a)
-        return false;
-
-    if (centerX || centerY) {
-        // Comma
-        if (!isComma(a))
-            return false;
-
-        a = args->next();
-        if (!a)
-            return false;
-    }
-
-    result->setFirstX(toCSSPrimitiveValue(centerX.get()));
-    result->setSecondX(toCSSPrimitiveValue(centerX.get()));
-    // CSS3 radial gradients always share the same start and end point.
-    result->setFirstY(toCSSPrimitiveValue(centerY.get()));
-    result->setSecondY(toCSSPrimitiveValue(centerY.get()));
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeValue;
-
-    // Optional shape and/or size in any order.
-    for (int i = 0; i < 2; ++i) {
-        if (a->unit != CSSPrimitiveValue::CSS_IDENT)
-            break;
-
-        bool foundValue = false;
-        switch (a->id) {
-        case CSSValueCircle:
-        case CSSValueEllipse:
-            shapeValue = cssValuePool().createIdentifierValue(a->id);
-            foundValue = true;
-            break;
-        case CSSValueClosestSide:
-        case CSSValueClosestCorner:
-        case CSSValueFarthestSide:
-        case CSSValueFarthestCorner:
-        case CSSValueContain:
-        case CSSValueCover:
-            sizeValue = cssValuePool().createIdentifierValue(a->id);
-            foundValue = true;
-            break;
-        default:
-            break;
-        }
-
-        if (foundValue) {
-            a = args->next();
-            if (!a)
-                return false;
-
-            expectComma = true;
-        }
-    }
-
-    result->setShape(shapeValue);
-    result->setSizingBehavior(sizeValue);
-
-    // Or, two lengths or percentages
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize;
-
-    if (!shapeValue && !sizeValue) {
-        if (validUnit(a, FLength | FPercent)) {
-            horizontalSize = createPrimitiveNumericValue(a);
-            a = args->next();
-            if (!a)
-                return false;
-
-            expectComma = true;
-        }
-
-        if (validUnit(a, FLength | FPercent)) {
-            verticalSize = createPrimitiveNumericValue(a);
-
-            a = args->next();
-            if (!a)
-                return false;
-            expectComma = true;
-        }
-    }
-
-    // Must have neither or both.
-    if (!horizontalSize != !verticalSize)
-        return false;
-
-    result->setEndHorizontalSize(horizontalSize);
-    result->setEndVerticalSize(verticalSize);
-
-    if (!parseGradientColorStops(args, result.get(), expectComma))
-        return false;
-
-    gradient = result.release();
-    return true;
-}
-
-bool BisonCSSParser::parseLinearGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
-    RefPtrWillBeRawPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSLinearGradient);
-
-    CSSParserValueList* args = valueList->current()->function->args.get();
-    if (!args || !args->size())
-        return false;
-
-    CSSParserValue* a = args->current();
-    if (!a)
-        return false;
-
-    bool expectComma = false;
-    // Look for angle.
-    if (validUnit(a, FAngle, HTMLStandardMode)) {
-        result->setAngle(createPrimitiveNumericValue(a));
-
-        args->next();
-        expectComma = true;
-    } else if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "to")) {
-        // to [ [left | right] || [top | bottom] ]
-        a = args->next();
-        if (!a)
-            return false;
-
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> endX, endY;
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> location;
-        bool isHorizontal = false;
-
-        location = valueFromSideKeyword(a, isHorizontal);
-        if (!location)
-            return false;
-
-        if (isHorizontal)
-            endX = location;
-        else
-            endY = location;
-
-        a = args->next();
-        if (!a)
-            return false;
-
-        location = valueFromSideKeyword(a, isHorizontal);
-        if (location) {
-            if (isHorizontal) {
-                if (endX)
-                    return false;
-                endX = location;
-            } else {
-                if (endY)
-                    return false;
-                endY = location;
-            }
-
-            args->next();
-        }
-
-        expectComma = true;
-        result->setFirstX(endX.release());
-        result->setFirstY(endY.release());
-    }
-
-    if (!parseGradientColorStops(args, result.get(), expectComma))
-        return false;
-
-    if (!result->stopCount())
-        return false;
-
-    gradient = result.release();
-    return true;
-}
-
-bool BisonCSSParser::parseRadialGradient(CSSParserValueList* valueList, RefPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
-{
-    RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient);
-
-    CSSParserValueList* args = valueList->current()->function->args.get();
-    if (!args || !args->size())
-        return false;
-
-    CSSParserValue* a = args->current();
-    if (!a)
-        return false;
-
-    bool expectComma = false;
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeValue;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize;
-
-    // First part of grammar, the size/shape clause:
-    // [ circle || <length> ] |
-    // [ ellipse || [ <length> | <percentage> ]{2} ] |
-    // [ [ circle | ellipse] || <size-keyword> ]
-    for (int i = 0; i < 3; ++i) {
-        if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
-            bool badIdent = false;
-            switch (a->id) {
-            case CSSValueCircle:
-            case CSSValueEllipse:
-                if (shapeValue)
-                    return false;
-                shapeValue = cssValuePool().createIdentifierValue(a->id);
-                break;
-            case CSSValueClosestSide:
-            case CSSValueClosestCorner:
-            case CSSValueFarthestSide:
-            case CSSValueFarthestCorner:
-                if (sizeValue || horizontalSize)
-                    return false;
-                sizeValue = cssValuePool().createIdentifierValue(a->id);
-                break;
-            default:
-                badIdent = true;
-            }
-
-            if (badIdent)
-                break;
-
-            a = args->next();
-            if (!a)
-                return false;
-        } else if (validUnit(a, FLength | FPercent)) {
-
-            if (sizeValue || horizontalSize)
-                return false;
-            horizontalSize = createPrimitiveNumericValue(a);
-
-            a = args->next();
-            if (!a)
-                return false;
-
-            if (validUnit(a, FLength | FPercent)) {
-                verticalSize = createPrimitiveNumericValue(a);
-                ++i;
-                a = args->next();
-                if (!a)
-                    return false;
-            }
-        } else
-            break;
-    }
-
-    // You can specify size as a keyword or a length/percentage, not both.
-    if (sizeValue && horizontalSize)
-        return false;
-    // Circles must have 0 or 1 lengths.
-    if (shapeValue && shapeValue->getValueID() == CSSValueCircle && verticalSize)
-        return false;
-    // Ellipses must have 0 or 2 length/percentages.
-    if (shapeValue && shapeValue->getValueID() == CSSValueEllipse && horizontalSize && !verticalSize)
-        return false;
-    // If there's only one size, it must be a length.
-    if (!verticalSize && horizontalSize && horizontalSize->isPercentage())
-        return false;
-
-    result->setShape(shapeValue);
-    result->setSizingBehavior(sizeValue);
-    result->setEndHorizontalSize(horizontalSize);
-    result->setEndVerticalSize(verticalSize);
-
-    // Second part of grammar, the center-position clause:
-    // at <position>
-    RefPtr<CSSValue> centerX;
-    RefPtr<CSSValue> centerY;
-    if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "at")) {
-        a = args->next();
-        if (!a)
-            return false;
-
-        parseFillPosition(args, centerX, centerY);
-        if (!(centerX && centerY))
-            return false;
-
-        a = args->current();
-        if (!a)
-            return false;
-        result->setFirstX(toCSSPrimitiveValue(centerX.get()));
-        result->setFirstY(toCSSPrimitiveValue(centerY.get()));
-        // Right now, CSS radial gradients have the same start and end centers.
-        result->setSecondX(toCSSPrimitiveValue(centerX.get()));
-        result->setSecondY(toCSSPrimitiveValue(centerY.get()));
-    }
-
-    if (shapeValue || sizeValue || horizontalSize || centerX || centerY)
-        expectComma = true;
-
-    if (!parseGradientColorStops(args, result.get(), expectComma))
-        return false;
-
-    gradient = result.release();
-    return true;
-}
-
-bool BisonCSSParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradientValue* gradient, bool expectComma)
-{
-    CSSParserValue* a = valueList->current();
-
-    // Now look for color stops.
-    while (a) {
-        // Look for the comma before the next stop.
-        if (expectComma) {
-            if (!isComma(a))
-                return false;
-
-            a = valueList->next();
-            if (!a)
-                return false;
-        }
-
-        // <color-stop> = <color> [ <percentage> | <length> ]?
-        CSSGradientColorStop stop;
-        stop.m_color = parseGradientColorOrKeyword(this, a);
-        if (!stop.m_color)
-            return false;
-
-        a = valueList->next();
-        if (a) {
-            if (validUnit(a, FLength | FPercent)) {
-                stop.m_position = createPrimitiveNumericValue(a);
-                a = valueList->next();
-            }
-        }
-
-        gradient->addStop(stop);
-        expectComma = true;
-    }
-
-    // Must have 2 or more stops to be valid.
-    return gradient->stopCount() >= 2;
-}
-
-bool BisonCSSParser::parseGeneratedImage(CSSParserValueList* valueList, RefPtr<CSSValue>& value)
-{
-    CSSParserValue* val = valueList->current();
-
-    if (val->unit != CSSParserValue::Function)
-        return false;
-
-    if (equalIgnoringCase(val->function->name, "-webkit-gradient(")) {
-        // FIXME: This should send a deprecation message.
-        if (m_context.useCounter())
-            m_context.useCounter()->count(UseCounter::DeprecatedWebKitGradient);
-        return parseDeprecatedGradient(valueList, value);
-    }
-
-    if (equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")) {
-        // FIXME: This should send a deprecation message.
-        if (m_context.useCounter())
-            m_context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradient);
-        return parseDeprecatedLinearGradient(valueList, value, NonRepeating);
-    }
-
-    if (equalIgnoringCase(val->function->name, "linear-gradient("))
-        return parseLinearGradient(valueList, value, NonRepeating);
-
-    if (equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")) {
-        // FIXME: This should send a deprecation message.
-        if (m_context.useCounter())
-            m_context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLinearGradient);
-        return parseDeprecatedLinearGradient(valueList, value, Repeating);
-    }
-
-    if (equalIgnoringCase(val->function->name, "repeating-linear-gradient("))
-        return parseLinearGradient(valueList, value, Repeating);
-
-    if (equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")) {
-        // FIXME: This should send a deprecation message.
-        if (m_context.useCounter())
-            m_context.useCounter()->count(UseCounter::DeprecatedWebKitRadialGradient);
-        return parseDeprecatedRadialGradient(valueList, value, NonRepeating);
-    }
-
-    if (equalIgnoringCase(val->function->name, "radial-gradient("))
-        return parseRadialGradient(valueList, value, NonRepeating);
-
-    if (equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")) {
-        if (m_context.useCounter())
-            m_context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingRadialGradient);
-        return parseDeprecatedRadialGradient(valueList, value, Repeating);
-    }
-
-    if (equalIgnoringCase(val->function->name, "repeating-radial-gradient("))
-        return parseRadialGradient(valueList, value, Repeating);
-
-    if (equalIgnoringCase(val->function->name, "-webkit-canvas("))
-        return parseCanvas(valueList, value);
-
-    if (equalIgnoringCase(val->function->name, "-webkit-cross-fade("))
-        return parseCrossfade(valueList, value);
-
-    return false;
-}
-
-bool BisonCSSParser::parseCrossfade(CSSParserValueList* valueList, RefPtr<CSSValue>& crossfade)
-{
-    // Walk the arguments.
-    CSSParserValueList* args = valueList->current()->function->args.get();
-    if (!args || args->size() != 5)
-        return false;
-    CSSParserValue* a = args->current();
-    RefPtr<CSSValue> fromImageValue;
-    RefPtr<CSSValue> toImageValue;
-
-    // The first argument is the "from" image. It is a fill image.
-    if (!a || !parseFillImage(args, fromImageValue))
-        return false;
-    a = args->next();
-
-    // Skip a comma
-    if (!isComma(a))
-        return false;
-    a = args->next();
-
-    // The second argument is the "to" image. It is a fill image.
-    if (!a || !parseFillImage(args, toImageValue))
-        return false;
-    a = args->next();
-
-    // Skip a comma
-    if (!isComma(a))
-        return false;
-    a = args->next();
-
-    // The third argument is the crossfade value. It is a percentage or a fractional number.
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> percentage;
-    if (!a)
-        return false;
-
-    if (a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
-        percentage = cssValuePool().createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
-    else if (a->unit == CSSPrimitiveValue::CSS_NUMBER)
-        percentage = cssValuePool().createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
-    else
-        return false;
-
-    RefPtrWillBeRawPtr<CSSCrossfadeValue> result = CSSCrossfadeValue::create(fromImageValue, toImageValue);
-    result->setPercentage(percentage);
-
-    crossfade = result;
-
-    return true;
-}
-
-bool BisonCSSParser::parseCanvas(CSSParserValueList* valueList, RefPtr<CSSValue>& canvas)
-{
-    // Walk the arguments.
-    CSSParserValueList* args = valueList->current()->function->args.get();
-    if (!args || args->size() != 1)
-        return false;
-
-    // The first argument is the canvas name.  It is an identifier.
-    CSSParserValue* value = args->current();
-    if (!value || value->unit != CSSPrimitiveValue::CSS_IDENT)
-        return false;
-
-    canvas = CSSCanvasValue::create(value->string);
-    return true;
+    CSSPropertyParser parser(m_valueList, m_context, m_inViewport, m_important, m_parsedProperties, m_hasFontFaceOnlyValues);
+    return parser.parseValue(propId, important);
 }
 
-PassRefPtr<CSSValue> BisonCSSParser::parseImageSet(CSSParserValueList* valueList)
-{
-    CSSParserValue* function = valueList->current();
-
-    if (function->unit != CSSParserValue::Function)
-        return 0;
-
-    CSSParserValueList* functionArgs = valueList->current()->function->args.get();
-    if (!functionArgs || !functionArgs->size() || !functionArgs->current())
-        return 0;
-
-    RefPtrWillBeRawPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create();
-
-    CSSParserValue* arg = functionArgs->current();
-    while (arg) {
-        if (arg->unit != CSSPrimitiveValue::CSS_URI)
-            return 0;
-
-        RefPtr<CSSImageValue> image = CSSImageValue::create(completeURL(arg->string));
-        imageSet->append(image);
-
-        arg = functionArgs->next();
-        if (!arg || arg->unit != CSSPrimitiveValue::CSS_DIMENSION)
-            return 0;
-
-        double imageScaleFactor = 0;
-        const String& string = arg->string;
-        unsigned length = string.length();
-        if (!length)
-            return 0;
-        if (string.is8Bit()) {
-            const LChar* start = string.characters8();
-            parseDouble(start, start + length, 'x', imageScaleFactor);
-        } else {
-            const UChar* start = string.characters16();
-            parseDouble(start, start + length, 'x', imageScaleFactor);
-        }
-        if (imageScaleFactor <= 0)
-            return 0;
-        imageSet->append(cssValuePool().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER));
-
-        // If there are no more arguments, we're done.
-        arg = functionArgs->next();
-        if (!arg)
-            break;
-
-        // If there are more arguments, they should be after a comma.
-        if (!isComma(arg))
-            return 0;
-
-        // Skip the comma and move on to the next argument.
-        arg = functionArgs->next();
-    }
-
-    return imageSet.release();
-}
 
 class TransformOperationInfo {
 public:
@@ -8371,7 +1285,7 @@
         : m_type(CSSTransformValue::UnknownTransformOperation)
         , m_argCount(1)
         , m_allowSingleArgument(false)
-        , m_unit(BisonCSSParser::FUnknown)
+        , m_unit(CSSPropertyParser::FUnknown)
     {
         const UChar* characters;
         unsigned nameLength = name.length();
@@ -8389,97 +1303,97 @@
 
         SWITCH(characters, nameLength) {
             CASE("skew(") {
-                m_unit = BisonCSSParser::FAngle;
+                m_unit = CSSPropertyParser::FAngle;
                 m_type = CSSTransformValue::SkewTransformOperation;
                 m_allowSingleArgument = true;
                 m_argCount = 3;
             }
             CASE("scale(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::ScaleTransformOperation;
                 m_allowSingleArgument = true;
                 m_argCount = 3;
             }
             CASE("skewx(") {
-                m_unit = BisonCSSParser::FAngle;
+                m_unit = CSSPropertyParser::FAngle;
                 m_type = CSSTransformValue::SkewXTransformOperation;
             }
             CASE("skewy(") {
-                m_unit = BisonCSSParser::FAngle;
+                m_unit = CSSPropertyParser::FAngle;
                 m_type = CSSTransformValue::SkewYTransformOperation;
             }
             CASE("matrix(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::MatrixTransformOperation;
                 m_argCount = 11;
             }
             CASE("rotate(") {
-                m_unit = BisonCSSParser::FAngle;
+                m_unit = CSSPropertyParser::FAngle;
                 m_type = CSSTransformValue::RotateTransformOperation;
             }
             CASE("scalex(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::ScaleXTransformOperation;
             }
             CASE("scaley(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::ScaleYTransformOperation;
             }
             CASE("scalez(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::ScaleZTransformOperation;
             }
             CASE("scale3d(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::Scale3DTransformOperation;
                 m_argCount = 5;
             }
             CASE("rotatex(") {
-                m_unit = BisonCSSParser::FAngle;
+                m_unit = CSSPropertyParser::FAngle;
                 m_type = CSSTransformValue::RotateXTransformOperation;
             }
             CASE("rotatey(") {
-                m_unit = BisonCSSParser::FAngle;
+                m_unit = CSSPropertyParser::FAngle;
                 m_type = CSSTransformValue::RotateYTransformOperation;
             }
             CASE("rotatez(") {
-                m_unit = BisonCSSParser::FAngle;
+                m_unit = CSSPropertyParser::FAngle;
                 m_type = CSSTransformValue::RotateZTransformOperation;
             }
             CASE("matrix3d(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::Matrix3DTransformOperation;
                 m_argCount = 31;
             }
             CASE("rotate3d(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::Rotate3DTransformOperation;
                 m_argCount = 7;
             }
             CASE("translate(") {
-                m_unit = BisonCSSParser::FLength | BisonCSSParser::FPercent;
+                m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
                 m_type = CSSTransformValue::TranslateTransformOperation;
                 m_allowSingleArgument = true;
                 m_argCount = 3;
             }
             CASE("translatex(") {
-                m_unit = BisonCSSParser::FLength | BisonCSSParser::FPercent;
+                m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
                 m_type = CSSTransformValue::TranslateXTransformOperation;
             }
             CASE("translatey(") {
-                m_unit = BisonCSSParser::FLength | BisonCSSParser::FPercent;
+                m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
                 m_type = CSSTransformValue::TranslateYTransformOperation;
             }
             CASE("translatez(") {
-                m_unit = BisonCSSParser::FLength | BisonCSSParser::FPercent;
+                m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
                 m_type = CSSTransformValue::TranslateZTransformOperation;
             }
             CASE("perspective(") {
-                m_unit = BisonCSSParser::FNumber;
+                m_unit = CSSPropertyParser::FNumber;
                 m_type = CSSTransformValue::PerspectiveTransformOperation;
             }
             CASE("translate3d(") {
-                m_unit = BisonCSSParser::FLength | BisonCSSParser::FPercent;
+                m_unit = CSSPropertyParser::FLength | CSSPropertyParser::FPercent;
                 m_type = CSSTransformValue::Translate3DTransformOperation;
                 m_argCount = 5;
             }
@@ -8488,7 +1402,7 @@
 
     CSSTransformValue::TransformOperationType type() const { return m_type; }
     unsigned argCount() const { return m_argCount; }
-    BisonCSSParser::Units unit() const { return m_unit; }
+    CSSPropertyParser::Units unit() const { return m_unit; }
 
     bool unknown() const { return m_type == CSSTransformValue::UnknownTransformOperation; }
     bool hasCorrectArgCount(unsigned argCount) { return m_argCount == argCount || (m_allowSingleArgument && argCount == 1); }
@@ -8497,19 +1411,19 @@
     CSSTransformValue::TransformOperationType m_type;
     unsigned m_argCount;
     bool m_allowSingleArgument;
-    BisonCSSParser::Units m_unit;
+    CSSPropertyParser::Units m_unit;
 };
 
-PassRefPtrWillBeRawPtr<CSSValueList> BisonCSSParser::parseTransform()
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseTransform()
 {
     if (!m_valueList)
-        return 0;
+        return nullptr;
 
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
     for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        RefPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
+        RefPtrWillBeRawPtr<CSSValue> parsedTransformValue = parseTransformValue(value);
         if (!parsedTransformValue)
-            return 0;
+            return nullptr;
 
         list->append(parsedTransformValue.release());
     }
@@ -8517,23 +1431,23 @@
     return list.release();
 }
 
-PassRefPtr<CSSValue> BisonCSSParser::parseTransformValue(CSSParserValue *value)
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTransformValue(CSSParserValue *value)
 {
     if (value->unit != CSSParserValue::Function || !value->function)
-        return 0;
+        return nullptr;
 
     // Every primitive requires at least one argument.
     CSSParserValueList* args = value->function->args.get();
     if (!args)
-        return 0;
+        return nullptr;
 
     // See if the specified primitive is one we understand.
     TransformOperationInfo info(value->function->name);
     if (info.unknown())
-        return 0;
+        return nullptr;
 
     if (!info.hasCorrectArgCount(args->size()))
-        return 0;
+        return nullptr;
 
     // The transform is a list of functional primitives that specify transform operations.
     // We collect a list of CSSTransformValues, where each value specifies a single operation.
@@ -8545,26 +1459,27 @@
     CSSParserValue* a = args->current();
     unsigned argNumber = 0;
     while (a) {
-        BisonCSSParser::Units unit = info.unit();
+        CSSPropertyParser::Units unit = info.unit();
 
         if (info.type() == CSSTransformValue::Rotate3DTransformOperation && argNumber == 3) {
             // 4th param of rotate3d() is an angle rather than a bare number, validate it as such
             if (!validUnit(a, FAngle, HTMLStandardMode))
-                return 0;
+                return nullptr;
         } else if (info.type() == CSSTransformValue::Translate3DTransformOperation && argNumber == 2) {
             // 3rd param of translate3d() cannot be a percentage
             if (!validUnit(a, FLength, HTMLStandardMode))
-                return 0;
+                return nullptr;
         } else if (info.type() == CSSTransformValue::TranslateZTransformOperation && !argNumber) {
             // 1st param of translateZ() cannot be a percentage
             if (!validUnit(a, FLength, HTMLStandardMode))
-                return 0;
+                return nullptr;
         } else if (info.type() == CSSTransformValue::PerspectiveTransformOperation && !argNumber) {
             // 1st param of perspective() must be a non-negative number (deprecated) or length.
             if (!validUnit(a, FNumber | FLength | FNonNeg, HTMLStandardMode))
-                return 0;
-        } else if (!validUnit(a, unit, HTMLStandardMode))
-            return 0;
+                return nullptr;
+        } else if (!validUnit(a, unit, HTMLStandardMode)) {
+            return nullptr;
+        }
 
         // Add the value to the current transform operation.
         transformValue->append(createPrimitiveNumericValue(a));
@@ -8573,7 +1488,7 @@
         if (!a)
             break;
         if (a->unit != CSSParserValue::Operator || a->iValue != ',')
-            return 0;
+            return nullptr;
         a = args->next();
 
         argNumber++;
@@ -8582,640 +1497,6 @@
     return transformValue.release();
 }
 
-bool BisonCSSParser::isBlendMode(CSSValueID valueID)
-{
-    return (valueID >= CSSValueMultiply && valueID <= CSSValueLuminosity)
-        || valueID == CSSValueNormal
-        || valueID == CSSValueOverlay;
-}
-
-bool BisonCSSParser::isCompositeOperator(CSSValueID valueID)
-{
-    // FIXME: Add CSSValueDestination and CSSValueLighter when the Compositing spec updates.
-    return valueID >= CSSValueClear && valueID <= CSSValueXor;
-}
-
-static void filterInfoForName(const CSSParserString& name, CSSFilterValue::FilterOperationType& filterType, unsigned& maximumArgumentCount)
-{
-    if (equalIgnoringCase(name, "grayscale("))
-        filterType = CSSFilterValue::GrayscaleFilterOperation;
-    else if (equalIgnoringCase(name, "sepia("))
-        filterType = CSSFilterValue::SepiaFilterOperation;
-    else if (equalIgnoringCase(name, "saturate("))
-        filterType = CSSFilterValue::SaturateFilterOperation;
-    else if (equalIgnoringCase(name, "hue-rotate("))
-        filterType = CSSFilterValue::HueRotateFilterOperation;
-    else if (equalIgnoringCase(name, "invert("))
-        filterType = CSSFilterValue::InvertFilterOperation;
-    else if (equalIgnoringCase(name, "opacity("))
-        filterType = CSSFilterValue::OpacityFilterOperation;
-    else if (equalIgnoringCase(name, "brightness("))
-        filterType = CSSFilterValue::BrightnessFilterOperation;
-    else if (equalIgnoringCase(name, "contrast("))
-        filterType = CSSFilterValue::ContrastFilterOperation;
-    else if (equalIgnoringCase(name, "blur("))
-        filterType = CSSFilterValue::BlurFilterOperation;
-    else if (equalIgnoringCase(name, "drop-shadow(")) {
-        filterType = CSSFilterValue::DropShadowFilterOperation;
-        maximumArgumentCount = 4;  // x-offset, y-offset, blur-radius, color -- spread and inset style not allowed.
-    }
-}
-
-PassRefPtrWillBeRawPtr<CSSFilterValue> BisonCSSParser::parseBuiltinFilterArguments(CSSParserValueList* args, CSSFilterValue::FilterOperationType filterType)
-{
-    RefPtrWillBeRawPtr<CSSFilterValue> filterValue = CSSFilterValue::create(filterType);
-    ASSERT(args);
-
-    switch (filterType) {
-    case CSSFilterValue::GrayscaleFilterOperation:
-    case CSSFilterValue::SepiaFilterOperation:
-    case CSSFilterValue::SaturateFilterOperation:
-    case CSSFilterValue::InvertFilterOperation:
-    case CSSFilterValue::OpacityFilterOperation:
-    case CSSFilterValue::ContrastFilterOperation: {
-        // One optional argument, 0-1 or 0%-100%, if missing use 100%.
-        if (args->size() > 1)
-            return 0;
-
-        if (args->size()) {
-            CSSParserValue* value = args->current();
-            if (!validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode))
-                return 0;
-
-            double amount = value->fValue;
-
-            // Saturate and Contrast allow values over 100%.
-            if (filterType != CSSFilterValue::SaturateFilterOperation
-                && filterType != CSSFilterValue::ContrastFilterOperation) {
-                double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
-                if (amount > maxAllowed)
-                    return 0;
-            }
-
-            filterValue->append(cssValuePool().createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
-        }
-        break;
-    }
-    case CSSFilterValue::BrightnessFilterOperation: {
-        // One optional argument, if missing use 100%.
-        if (args->size() > 1)
-            return 0;
-
-        if (args->size()) {
-            CSSParserValue* value = args->current();
-            if (!validUnit(value, FNumber | FPercent, HTMLStandardMode))
-                return 0;
-
-            filterValue->append(cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
-        }
-        break;
-    }
-    case CSSFilterValue::HueRotateFilterOperation: {
-        // hue-rotate() takes one optional angle.
-        if (args->size() > 1)
-            return 0;
-
-        if (args->size()) {
-            CSSParserValue* argument = args->current();
-            if (!validUnit(argument, FAngle, HTMLStandardMode))
-                return 0;
-
-            filterValue->append(createPrimitiveNumericValue(argument));
-        }
-        break;
-    }
-    case CSSFilterValue::BlurFilterOperation: {
-        // Blur takes a single length. Zero parameters are allowed.
-        if (args->size() > 1)
-            return 0;
-
-        if (args->size()) {
-            CSSParserValue* argument = args->current();
-            if (!validUnit(argument, FLength | FNonNeg, HTMLStandardMode))
-                return 0;
-
-            filterValue->append(createPrimitiveNumericValue(argument));
-        }
-        break;
-    }
-    case CSSFilterValue::DropShadowFilterOperation: {
-        // drop-shadow() takes a single shadow.
-        RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(args, CSSPropertyWebkitFilter);
-        if (!shadowValueList || shadowValueList->length() != 1)
-            return 0;
-
-        filterValue->append((shadowValueList.release())->itemWithoutBoundsCheck(0));
-        break;
-    }
-    default:
-        ASSERT_NOT_REACHED();
-    }
-    return filterValue.release();
-}
-
-PassRefPtrWillBeRawPtr<CSSValueList> BisonCSSParser::parseFilter()
-{
-    if (!m_valueList)
-        return 0;
-
-    // The filter is a list of functional primitives that specify individual operations.
-    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        if (value->unit != CSSPrimitiveValue::CSS_URI && (value->unit != CSSParserValue::Function || !value->function))
-            return 0;
-
-        CSSFilterValue::FilterOperationType filterType = CSSFilterValue::UnknownFilterOperation;
-
-        // See if the specified primitive is one we understand.
-        if (value->unit == CSSPrimitiveValue::CSS_URI) {
-            RefPtrWillBeRawPtr<CSSFilterValue> referenceFilterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
-            list->append(referenceFilterValue);
-            referenceFilterValue->append(CSSSVGDocumentValue::create(value->string));
-        } else {
-            const CSSParserString name = value->function->name;
-            unsigned maximumArgumentCount = 1;
-
-            filterInfoForName(name, filterType, maximumArgumentCount);
-
-            if (filterType == CSSFilterValue::UnknownFilterOperation)
-                return 0;
-
-            CSSParserValueList* args = value->function->args.get();
-            if (!args)
-                return 0;
-
-            RefPtrWillBeRawPtr<CSSFilterValue> filterValue = parseBuiltinFilterArguments(args, filterType);
-            if (!filterValue)
-                return 0;
-
-            list->append(filterValue);
-        }
-    }
-
-    return list.release();
-}
-
-bool BisonCSSParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2, RefPtr<CSSValue>& value3)
-{
-    propId1 = propId;
-    propId2 = propId;
-    propId3 = propId;
-    if (propId == CSSPropertyWebkitTransformOrigin) {
-        propId1 = CSSPropertyWebkitTransformOriginX;
-        propId2 = CSSPropertyWebkitTransformOriginY;
-        propId3 = CSSPropertyWebkitTransformOriginZ;
-    }
-
-    switch (propId) {
-        case CSSPropertyWebkitTransformOrigin:
-            if (!parseTransformOriginShorthand(value, value2, value3))
-                return false;
-            // parseTransformOriginShorthand advances the m_valueList pointer
-            break;
-        case CSSPropertyWebkitTransformOriginX: {
-            value = parseFillPositionX(m_valueList.get());
-            if (value)
-                m_valueList->next();
-            break;
-        }
-        case CSSPropertyWebkitTransformOriginY: {
-            value = parseFillPositionY(m_valueList.get());
-            if (value)
-                m_valueList->next();
-            break;
-        }
-        case CSSPropertyWebkitTransformOriginZ: {
-            if (validUnit(m_valueList->current(), FLength))
-                value = createPrimitiveNumericValue(m_valueList->current());
-            if (value)
-                m_valueList->next();
-            break;
-        }
-        default:
-            ASSERT_NOT_REACHED();
-            return false;
-    }
-
-    return value;
-}
-
-bool BisonCSSParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>& value, RefPtr<CSSValue>& value2)
-{
-    propId1 = propId;
-    propId2 = propId;
-    if (propId == CSSPropertyWebkitPerspectiveOrigin) {
-        propId1 = CSSPropertyWebkitPerspectiveOriginX;
-        propId2 = CSSPropertyWebkitPerspectiveOriginY;
-    }
-
-    switch (propId) {
-        case CSSPropertyWebkitPerspectiveOrigin:
-            if (m_valueList->size() > 2)
-                return false;
-            parse2ValuesFillPosition(m_valueList.get(), value, value2);
-            break;
-        case CSSPropertyWebkitPerspectiveOriginX: {
-            value = parseFillPositionX(m_valueList.get());
-            if (value)
-                m_valueList->next();
-            break;
-        }
-        case CSSPropertyWebkitPerspectiveOriginY: {
-            value = parseFillPositionY(m_valueList.get());
-            if (value)
-                m_valueList->next();
-            break;
-        }
-        default:
-            ASSERT_NOT_REACHED();
-            return false;
-    }
-
-    return value;
-}
-
-bool BisonCSSParser::parseTouchAction(bool important)
-{
-    if (!RuntimeEnabledFeatures::cssTouchActionEnabled())
-        return false;
-
-    CSSParserValue* value = m_valueList->current();
-    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    if (m_valueList->size() == 1 && value && (value->id == CSSValueAuto || value->id == CSSValueNone)) {
-        list->append(cssValuePool().createIdentifierValue(value->id));
-        addProperty(CSSPropertyTouchAction, list.release(), important);
-        m_valueList->next();
-        return true;
-    }
-
-    bool isValid = true;
-    while (isValid && value) {
-        switch (value->id) {
-        case CSSValuePanX:
-        case CSSValuePanY: {
-            RefPtr<CSSValue> panValue = cssValuePool().createIdentifierValue(value->id);
-            if (list->hasValue(panValue.get())) {
-                isValid = false;
-                break;
-            }
-            list->append(panValue.release());
-            break;
-        }
-        default:
-            isValid = false;
-            break;
-        }
-        if (isValid)
-            value = m_valueList->next();
-    }
-
-    if (list->length() && isValid) {
-        addProperty(CSSPropertyTouchAction, list.release(), important);
-        return true;
-    }
-
-    return false;
-}
-
-void BisonCSSParser::addTextDecorationProperty(CSSPropertyID propId, PassRefPtr<CSSValue> value, bool important)
-{
-    // The text-decoration-line property takes priority over text-decoration, unless the latter has important priority set.
-    if (propId == CSSPropertyTextDecoration && !important && !inShorthand()) {
-        for (unsigned i = 0; i < m_parsedProperties.size(); ++i) {
-            if (m_parsedProperties[i].id() == CSSPropertyTextDecorationLine)
-                return;
-        }
-    }
-    addProperty(propId, value, important);
-}
-
-bool BisonCSSParser::parseTextDecoration(CSSPropertyID propId, bool important)
-{
-    if (propId == CSSPropertyTextDecorationLine
-        && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
-        return false;
-
-    CSSParserValue* value = m_valueList->current();
-    if (value && value->id == CSSValueNone) {
-        addTextDecorationProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important);
-        m_valueList->next();
-        return true;
-    }
-
-    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-    bool isValid = true;
-    while (isValid && value) {
-        switch (value->id) {
-        case CSSValueUnderline:
-        case CSSValueOverline:
-        case CSSValueLineThrough:
-        case CSSValueBlink:
-            list->append(cssValuePool().createIdentifierValue(value->id));
-            break;
-        default:
-            isValid = false;
-            break;
-        }
-        if (isValid)
-            value = m_valueList->next();
-    }
-
-    // Values are either valid or in shorthand scope.
-    if (list->length() && (isValid || inShorthand())) {
-        addTextDecorationProperty(propId, list.release(), important);
-        return true;
-    }
-
-    return false;
-}
-
-bool BisonCSSParser::parseTextUnderlinePosition(bool important)
-{
-    // The text-underline-position property has syntax "auto | [ under || [ left | right ] ]".
-    // However, values 'left' and 'right' are not implemented yet, so we will parse syntax
-    // "auto | under" for now.
-    CSSParserValue* value = m_valueList->current();
-    switch (value->id) {
-    case CSSValueAuto:
-    case CSSValueUnder:
-        if (m_valueList->next())
-            return false;
-        addProperty(CSSPropertyTextUnderlinePosition, cssValuePool().createIdentifierValue(value->id), important);
-        return true;
-    default:
-        return false;
-    }
-}
-
-bool BisonCSSParser::parseTextEmphasisStyle(bool important)
-{
-    unsigned valueListSize = m_valueList->size();
-
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> fill;
-    RefPtrWillBeRawPtr<CSSPrimitiveValue> shape;
-
-    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        if (value->unit == CSSPrimitiveValue::CSS_STRING) {
-            if (fill || shape || (valueListSize != 1 && !inShorthand()))
-                return false;
-            addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(value), important);
-            m_valueList->next();
-            return true;
-        }
-
-        if (value->id == CSSValueNone) {
-            if (fill || shape || (valueListSize != 1 && !inShorthand()))
-                return false;
-            addProperty(CSSPropertyWebkitTextEmphasisStyle, cssValuePool().createIdentifierValue(CSSValueNone), important);
-            m_valueList->next();
-            return true;
-        }
-
-        if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
-            if (fill)
-                return false;
-            fill = cssValuePool().createIdentifierValue(value->id);
-        } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
-            if (shape)
-                return false;
-            shape = cssValuePool().createIdentifierValue(value->id);
-        } else if (!inShorthand())
-            return false;
-        else
-            break;
-    }
-
-    if (fill && shape) {
-        RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
-        parsedValues->append(fill.release());
-        parsedValues->append(shape.release());
-        addProperty(CSSPropertyWebkitTextEmphasisStyle, parsedValues.release(), important);
-        return true;
-    }
-    if (fill) {
-        addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.release(), important);
-        return true;
-    }
-    if (shape) {
-        addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.release(), important);
-        return true;
-    }
-
-    return false;
-}
-
-PassRefPtr<CSSValue> BisonCSSParser::parseTextIndent()
-{
-    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
-
-    // <length> | <percentage> | inherit
-    if (m_valueList->size() == 1) {
-        CSSParserValue* value = m_valueList->current();
-        if (!value->id && validUnit(value, FLength | FPercent)) {
-            list->append(createPrimitiveNumericValue(value));
-            m_valueList->next();
-            return list.release();
-        }
-    }
-
-    if (!RuntimeEnabledFeatures::css3TextEnabled())
-        return 0;
-
-    // The case where text-indent has only <length>(or <percentage>) value
-    // is handled above if statement even though css3TextEnabled() returns true.
-
-    // [ [ <length> | <percentage> ] && each-line ] | inherit
-    if (m_valueList->size() != 2)
-        return 0;
-
-    CSSParserValue* firstValue = m_valueList->current();
-    CSSParserValue* secondValue = m_valueList->next();
-    CSSParserValue* lengthOrPercentageValue = 0;
-
-    // [ <length> | <percentage> ] each-line
-    if (validUnit(firstValue, FLength | FPercent) && secondValue->id == CSSValueEachLine)
-        lengthOrPercentageValue = firstValue;
-    // each-line [ <length> | <percentage> ]
-    else if (firstValue->id == CSSValueEachLine && validUnit(secondValue, FLength | FPercent))
-        lengthOrPercentageValue = secondValue;
-
-    if (lengthOrPercentageValue) {
-        list->append(createPrimitiveNumericValue(lengthOrPercentageValue));
-        list->append(cssValuePool().createIdentifierValue(CSSValueEachLine));
-        m_valueList->next();
-        return list.release();
-    }
-
-    return 0;
-}
-
-bool BisonCSSParser::parseLineBoxContain(bool important)
-{
-    LineBoxContain lineBoxContain = LineBoxContainNone;
-
-    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        if (value->id == CSSValueBlock) {
-            if (lineBoxContain & LineBoxContainBlock)
-                return false;
-            lineBoxContain |= LineBoxContainBlock;
-        } else if (value->id == CSSValueInline) {
-            if (lineBoxContain & LineBoxContainInline)
-                return false;
-            lineBoxContain |= LineBoxContainInline;
-        } else if (value->id == CSSValueFont) {
-            if (lineBoxContain & LineBoxContainFont)
-                return false;
-            lineBoxContain |= LineBoxContainFont;
-        } else if (value->id == CSSValueGlyphs) {
-            if (lineBoxContain & LineBoxContainGlyphs)
-                return false;
-            lineBoxContain |= LineBoxContainGlyphs;
-        } else if (value->id == CSSValueReplaced) {
-            if (lineBoxContain & LineBoxContainReplaced)
-                return false;
-            lineBoxContain |= LineBoxContainReplaced;
-        } else if (value->id == CSSValueInlineBox) {
-            if (lineBoxContain & LineBoxContainInlineBox)
-                return false;
-            lineBoxContain |= LineBoxContainInlineBox;
-        } else
-            return false;
-    }
-
-    if (!lineBoxContain)
-        return false;
-
-    addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
-    return true;
-}
-
-bool BisonCSSParser::parseFontFeatureTag(CSSValueList* settings)
-{
-    // Feature tag name consists of 4-letter characters.
-    static const unsigned tagNameLength = 4;
-
-    CSSParserValue* value = m_valueList->current();
-    // Feature tag name comes first
-    if (value->unit != CSSPrimitiveValue::CSS_STRING)
-        return false;
-    if (value->string.length() != tagNameLength)
-        return false;
-    for (unsigned i = 0; i < tagNameLength; ++i) {
-        // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification.
-        UChar character = value->string[i];
-        if (character < 0x20 || character > 0x7E)
-            return false;
-    }
-
-    AtomicString tag = value->string;
-    int tagValue = 1;
-    // Feature tag values could follow: <integer> | on | off
-    value = m_valueList->next();
-    if (value) {
-        if (value->unit == CSSPrimitiveValue::CSS_NUMBER && value->isInt && value->fValue >= 0) {
-            tagValue = clampToInteger(value->fValue);
-            if (tagValue < 0)
-                return false;
-            m_valueList->next();
-        } else if (value->id == CSSValueOn || value->id == CSSValueOff) {
-            tagValue = value->id == CSSValueOn;
-            m_valueList->next();
-        }
-    }
-    settings->append(CSSFontFeatureValue::create(tag, tagValue));
-    return true;
-}
-
-bool BisonCSSParser::parseFontFeatureSettings(bool important)
-{
-    if (m_valueList->size() == 1 && m_valueList->current()->id == CSSValueNormal) {
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> normalValue = cssValuePool().createIdentifierValue(CSSValueNormal);
-        m_valueList->next();
-        addProperty(CSSPropertyWebkitFontFeatureSettings, normalValue.release(), important);
-        return true;
-    }
-
-    RefPtrWillBeRawPtr<CSSValueList> settings = CSSValueList::createCommaSeparated();
-    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        if (!parseFontFeatureTag(settings.get()))
-            return false;
-
-        // If the list isn't parsed fully, the current value should be comma.
-        value = m_valueList->current();
-        if (value && !isComma(value))
-            return false;
-    }
-    if (settings->length()) {
-        addProperty(CSSPropertyWebkitFontFeatureSettings, settings.release(), important);
-        return true;
-    }
-    return false;
-}
-
-bool BisonCSSParser::parseFontVariantLigatures(bool important)
-{
-    RefPtrWillBeRawPtr<CSSValueList> ligatureValues = CSSValueList::createSpaceSeparated();
-    bool sawCommonLigaturesValue = false;
-    bool sawDiscretionaryLigaturesValue = false;
-    bool sawHistoricalLigaturesValue = false;
-
-    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
-        if (value->unit != CSSPrimitiveValue::CSS_IDENT)
-            return false;
-
-        switch (value->id) {
-        case CSSValueNoCommonLigatures:
-        case CSSValueCommonLigatures:
-            if (sawCommonLigaturesValue)
-                return false;
-            sawCommonLigaturesValue = true;
-            ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
-            break;
-        case CSSValueNoDiscretionaryLigatures:
-        case CSSValueDiscretionaryLigatures:
-            if (sawDiscretionaryLigaturesValue)
-                return false;
-            sawDiscretionaryLigaturesValue = true;
-            ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
-            break;
-        case CSSValueNoHistoricalLigatures:
-        case CSSValueHistoricalLigatures:
-            if (sawHistoricalLigaturesValue)
-                return false;
-            sawHistoricalLigaturesValue = true;
-            ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
-            break;
-        default:
-            return false;
-        }
-    }
-
-    if (!ligatureValues->length())
-        return false;
-
-    addProperty(CSSPropertyFontVariantLigatures, ligatureValues.release(), important);
-    return true;
-}
-
-bool BisonCSSParser::parseCalculation(CSSParserValue* value, ValueRange range)
-{
-    ASSERT(isCalculation(value));
-
-    CSSParserValueList* args = value->function->args.get();
-    if (!args || !args->size())
-        return false;
-
-    ASSERT(!m_parsedCalculation);
-    m_parsedCalculation = CSSCalcValue::create(value->function->name, args, range);
-
-    if (!m_parsedCalculation)
-        return false;
-
-    return true;
-}
-
-#define END_TOKEN 0
-
 void BisonCSSParser::ensureLineEndings()
 {
     if (!m_lineEndings)
@@ -9321,31 +1602,31 @@
     return m_floatingMediaQueryExp.get();
 }
 
-PassOwnPtr<MediaQueryExp> BisonCSSParser::sinkFloatingMediaQueryExp(MediaQueryExp* expression)
+PassOwnPtrWillBeRawPtr<MediaQueryExp> BisonCSSParser::sinkFloatingMediaQueryExp(MediaQueryExp* expression)
 {
     ASSERT_UNUSED(expression, expression == m_floatingMediaQueryExp);
     return m_floatingMediaQueryExp.release();
 }
 
-Vector<OwnPtr<MediaQueryExp> >* BisonCSSParser::createFloatingMediaQueryExpList()
+WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* BisonCSSParser::createFloatingMediaQueryExpList()
 {
-    m_floatingMediaQueryExpList = adoptPtr(new Vector<OwnPtr<MediaQueryExp> >);
+    m_floatingMediaQueryExpList = adoptPtrWillBeNoop(new WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >);
     return m_floatingMediaQueryExpList.get();
 }
 
-PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > BisonCSSParser::sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >* list)
+PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > BisonCSSParser::sinkFloatingMediaQueryExpList(WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* list)
 {
     ASSERT_UNUSED(list, list == m_floatingMediaQueryExpList);
     return m_floatingMediaQueryExpList.release();
 }
 
-MediaQuery* BisonCSSParser::createFloatingMediaQuery(MediaQuery::Restrictor restrictor, const AtomicString& mediaType, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
+MediaQuery* BisonCSSParser::createFloatingMediaQuery(MediaQuery::Restrictor restrictor, const AtomicString& mediaType, PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > expressions)
 {
-    m_floatingMediaQuery = adoptPtr(new MediaQuery(restrictor, mediaType, expressions));
+    m_floatingMediaQuery = adoptPtrWillBeNoop(new MediaQuery(restrictor, mediaType, expressions));
     return m_floatingMediaQuery.get();
 }
 
-MediaQuery* BisonCSSParser::createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > expressions)
+MediaQuery* BisonCSSParser::createFloatingMediaQuery(PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > expressions)
 {
     return createFloatingMediaQuery(MediaQuery::None, AtomicString("all", AtomicString::ConstructFromLiteral), expressions);
 }
@@ -9355,7 +1636,7 @@
     return createFloatingMediaQuery(MediaQuery::Not, AtomicString("all", AtomicString::ConstructFromLiteral), sinkFloatingMediaQueryExpList(createFloatingMediaQueryExpList()));
 }
 
-PassOwnPtr<MediaQuery> BisonCSSParser::sinkFloatingMediaQuery(MediaQuery* query)
+PassOwnPtrWillBeRawPtr<MediaQuery> BisonCSSParser::sinkFloatingMediaQuery(MediaQuery* query)
 {
     ASSERT_UNUSED(query, query == m_floatingMediaQuery);
     return m_floatingMediaQuery.release();
@@ -9375,7 +1656,7 @@
 
 MediaQuerySet* BisonCSSParser::createMediaQuerySet()
 {
-    RefPtr<MediaQuerySet> queries = MediaQuerySet::create();
+    RefPtrWillBeRawPtr<MediaQuerySet> queries = MediaQuerySet::create();
     MediaQuerySet* result = queries.get();
     m_parsedMediaQuerySets.append(queries.release());
     return result;
@@ -9385,7 +1666,7 @@
 {
     if (!media || !m_allowImportRules)
         return 0;
-    RefPtr<StyleRuleImport> rule = StyleRuleImport::create(url, media);
+    RefPtrWillBeRawPtr<StyleRuleImport> rule = StyleRuleImport::create(url, media);
     StyleRuleImport* result = rule.get();
     m_parsedRules.append(rule.release());
     return result;
@@ -9394,12 +1675,12 @@
 StyleRuleBase* BisonCSSParser::createMediaRule(MediaQuerySet* media, RuleList* rules)
 {
     m_allowImportRules = m_allowNamespaceDeclarations = false;
-    RefPtr<StyleRuleMedia> rule;
+    RefPtrWillBeRawPtr<StyleRuleMedia> rule;
     if (rules) {
-        rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create(), *rules);
+        rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create().get(), *rules);
     } else {
         RuleList emptyRules;
-        rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create(), emptyRules);
+        rule = StyleRuleMedia::create(media ? media : MediaQuerySet::create().get(), emptyRules);
     }
     StyleRuleMedia* result = rule.get();
     m_parsedRules.append(rule.release());
@@ -9411,7 +1692,7 @@
     m_allowImportRules = m_allowNamespaceDeclarations = false;
 
     RefPtr<CSSRuleSourceData> data = popSupportsRuleData();
-    RefPtr<StyleRuleSupports> rule;
+    RefPtrWillBeRawPtr<StyleRuleSupports> rule;
     String conditionText;
     unsigned conditionOffset = data->ruleHeaderRange.start + 9;
     unsigned conditionLength = data->ruleHeaderRange.length() - 9;
@@ -9464,7 +1745,7 @@
 
 BisonCSSParser::RuleList* BisonCSSParser::createRuleList()
 {
-    OwnPtr<RuleList> list = adoptPtr(new RuleList);
+    OwnPtrWillBeRawPtr<RuleList> list = adoptPtrWillBeNoop(new RuleList);
     RuleList* listPtr = list.get();
 
     m_parsedRuleLists.append(list.release());
@@ -9559,7 +1840,7 @@
 {
     OwnPtr<Vector<RefPtr<StyleKeyframe> > > keyframes = popKeyframes;
     m_allowImportRules = m_allowNamespaceDeclarations = false;
-    RefPtr<StyleRuleKeyframes> rule = StyleRuleKeyframes::create();
+    RefPtrWillBeRawPtr<StyleRuleKeyframes> rule = StyleRuleKeyframes::create();
     for (size_t i = 0; i < keyframes->size(); ++i)
         rule->parserAppendKeyframe(keyframes->at(i));
     rule->setName(name);
@@ -9574,7 +1855,7 @@
     StyleRule* result = 0;
     if (selectors) {
         m_allowImportRules = m_allowNamespaceDeclarations = false;
-        RefPtr<StyleRule> rule = StyleRule::create();
+        RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create();
         rule->parserAdoptSelectorVector(*selectors);
         if (m_hasFontFaceOnlyValues)
             deleteFontFaceOnlyValues();
@@ -9602,7 +1883,7 @@
             return 0;
         }
     }
-    RefPtr<StyleRuleFontFace> rule = StyleRuleFontFace::create();
+    RefPtrWillBeRawPtr<StyleRuleFontFace> rule = StyleRuleFontFace::create();
     rule->setProperties(createStylePropertySet());
     clearProperties();
     StyleRuleFontFace* result = rule.get();
@@ -9653,9 +1934,6 @@
     if (specifiers->needsCrossingTreeScopeBoundary())
         return rewriteSpecifiersWithElementNameForCustomPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule);
 
-    if (specifiers->isContentPseudoElement())
-        return rewriteSpecifiersWithElementNameForContentPseudoElement(tag, elementName, specifiers, tagIsForNamespaceRule);
-
     if (tag == anyQName())
         return specifiers;
     if (!(specifiers->pseudoType() == CSSSelector::PseudoCue))
@@ -9696,7 +1974,7 @@
     CSSParserSelector* history = specifiers;
     while (history->tagHistory()) {
         history = history->tagHistory();
-        if (history->isContentPseudoElement() || history->relationIsAffectedByPseudoContent())
+        if (history->relationIsAffectedByPseudoContent())
             last = history;
     }
 
@@ -9749,19 +2027,11 @@
         newSpecifier->appendTagHistory(CSSSelector::ShadowPseudo, sinkFloatingSelector(specifiers));
         return newSpecifier;
     }
-    if (newSpecifier->isContentPseudoElement()) {
-        newSpecifier->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(specifiers));
-        return newSpecifier;
-    }
     if (specifiers->needsCrossingTreeScopeBoundary()) {
         // Specifiers for unknown pseudo element go right behind it in the chain.
         specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::ShadowPseudo);
         return specifiers;
     }
-    if (specifiers->isContentPseudoElement()) {
-        specifiers->insertTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier), CSSSelector::SubSelector);
-        return specifiers;
-    }
     specifiers->appendTagHistory(CSSSelector::SubSelector, sinkFloatingSelector(newSpecifier));
     return specifiers;
 }
@@ -9772,7 +2042,7 @@
     m_allowImportRules = m_allowNamespaceDeclarations = false;
     StyleRulePage* pageRule = 0;
     if (pageSelector) {
-        RefPtr<StyleRulePage> rule = StyleRulePage::create();
+        RefPtrWillBeRawPtr<StyleRulePage> rule = StyleRulePage::create();
         Vector<OwnPtr<CSSParserSelector> > selectorVector;
         selectorVector.append(pageSelector);
         rule->parserAdoptSelectorVector(selectorVector);
@@ -9930,7 +2200,7 @@
 
     m_allowImportRules = m_allowNamespaceDeclarations = false;
 
-    RefPtr<StyleRuleViewport> rule = StyleRuleViewport::create();
+    RefPtrWillBeRawPtr<StyleRuleViewport> rule = StyleRuleViewport::create();
 
     rule->setProperties(createStylePropertySet());
     clearProperties();
@@ -9941,165 +2211,4 @@
     return result;
 }
 
-bool BisonCSSParser::parseViewportProperty(CSSPropertyID propId, bool important)
-{
-    ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
-
-    CSSParserValue* value = m_valueList->current();
-    if (!value)
-        return false;
-
-    CSSValueID id = value->id;
-    bool validPrimitive = false;
-
-    switch (propId) {
-    case CSSPropertyMinWidth: // auto | extend-to-zoom | <length> | <percentage>
-    case CSSPropertyMaxWidth:
-    case CSSPropertyMinHeight:
-    case CSSPropertyMaxHeight:
-        if (id == CSSValueAuto || id == CSSValueInternalExtendToZoom)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
-        break;
-    case CSSPropertyWidth: // shorthand
-        return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
-    case CSSPropertyHeight:
-        return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
-    case CSSPropertyMinZoom: // auto | <number> | <percentage>
-    case CSSPropertyMaxZoom:
-    case CSSPropertyZoom:
-        if (id == CSSValueAuto)
-            validPrimitive = true;
-        else
-            validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg));
-        break;
-    case CSSPropertyUserZoom: // zoom | fixed
-        if (id == CSSValueZoom || id == CSSValueFixed)
-            validPrimitive = true;
-        break;
-    case CSSPropertyOrientation: // auto | portrait | landscape
-        if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
-            validPrimitive = true;
-    default:
-        break;
-    }
-
-    RefPtr<CSSValue> parsedValue;
-    if (validPrimitive) {
-        parsedValue = parseValidPrimitive(id, value);
-        m_valueList->next();
-    }
-
-    if (parsedValue) {
-        if (!m_valueList->current() || inShorthand()) {
-            addProperty(propId, parsedValue.release(), important);
-            return true;
-        }
-    }
-
-    return false;
-}
-
-bool BisonCSSParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
-{
-    ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
-    unsigned numValues = m_valueList->size();
-
-    if (numValues > 2)
-        return false;
-
-    ShorthandScope scope(this, propId);
-
-    if (!parseViewportProperty(first, important))
-        return false;
-
-    // If just one value is supplied, the second value
-    // is implicitly initialized with the first value.
-    if (numValues == 1)
-        m_valueList->previous();
-
-    return parseViewportProperty(second, important);
-}
-
-template <typename CharacterType>
-static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
-{
-    char buffer[maxCSSPropertyNameLength + 1]; // 1 for null character
-
-    for (unsigned i = 0; i != length; ++i) {
-        CharacterType c = propertyName[i];
-        if (c == 0 || c >= 0x7F)
-            return CSSPropertyInvalid; // illegal character
-        buffer[i] = toASCIILower(c);
-    }
-    buffer[length] = '\0';
-
-    const char* name = buffer;
-    const Property* hashTableEntry = findProperty(name, length);
-    return hashTableEntry ? static_cast<CSSPropertyID>(hashTableEntry->id) : CSSPropertyInvalid;
-}
-
-CSSPropertyID cssPropertyID(const String& string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return CSSPropertyInvalid;
-    if (length > maxCSSPropertyNameLength)
-        return CSSPropertyInvalid;
-
-    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
-}
-
-CSSPropertyID cssPropertyID(const CSSParserString& string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return CSSPropertyInvalid;
-    if (length > maxCSSPropertyNameLength)
-        return CSSPropertyInvalid;
-
-    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
-}
-
-template <typename CharacterType>
-static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned length)
-{
-    char buffer[maxCSSValueKeywordLength + 1]; // 1 for null character
-
-    for (unsigned i = 0; i != length; ++i) {
-        CharacterType c = valueKeyword[i];
-        if (c == 0 || c >= 0x7F)
-            return CSSValueInvalid; // illegal character
-        buffer[i] = WTF::toASCIILower(c);
-    }
-    buffer[length] = '\0';
-
-    const Value* hashTableEntry = findValue(buffer, length);
-    return hashTableEntry ? static_cast<CSSValueID>(hashTableEntry->id) : CSSValueInvalid;
-}
-
-CSSValueID cssValueKeywordID(const CSSParserString& string)
-{
-    unsigned length = string.length();
-    if (!length)
-        return CSSValueInvalid;
-    if (length > maxCSSValueKeywordLength)
-        return CSSValueInvalid;
-
-    return string.is8Bit() ? cssValueKeywordID(string.characters8(), length) : cssValueKeywordID(string.characters16(), length);
-}
-
-bool isValidNthToken(const CSSParserString& token)
-{
-    // The tokenizer checks for the construct of an+b.
-    // However, since the {ident} rule precedes the {nth} rule, some of those
-    // tokens are identified as string literal. Furthermore we need to accept
-    // "odd" and "even" which does not match to an+b.
-    return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
-        || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
-}
-
 }
diff --git a/Source/core/css/parser/BisonCSSParser.h b/Source/core/css/parser/BisonCSSParser.h
index 1a32e94..0a3ec60 100644
--- a/Source/core/css/parser/BisonCSSParser.h
+++ b/Source/core/css/parser/BisonCSSParser.h
@@ -37,6 +37,7 @@
 #include "core/css/MediaQuery.h"
 #include "core/css/StylePropertySet.h"
 #include "core/css/parser/CSSParserObserver.h"
+#include "core/css/parser/CSSPropertyParser.h"
 #include "platform/graphics/Color.h"
 #include "wtf/HashSet.h"
 #include "wtf/OwnPtr.h"
@@ -81,207 +82,30 @@
 
 public:
     BisonCSSParser(const CSSParserContext&);
-
     ~BisonCSSParser();
 
+    void rollbackLastProperties(int num);
+    void setCurrentProperty(CSSPropertyID);
+
     void parseSheet(StyleSheetContents*, const String&, const TextPosition& startPosition = TextPosition::minimumPosition(), CSSParserObserver* = 0, bool = false);
-    PassRefPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
+    PassRefPtrWillBeRawPtr<StyleRuleBase> parseRule(StyleSheetContents*, const String&);
     PassRefPtr<StyleKeyframe> parseKeyframeRule(StyleSheetContents*, const String&);
     bool parseSupportsCondition(const String&);
     static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, CSSParserMode, StyleSheetContents*);
     static bool parseColor(RGBA32& color, const String&, bool strict = false);
-    static bool parseSystemColor(RGBA32& color, const String&, Document*);
+    static bool parseSystemColor(RGBA32& color, const String&);
     static PassRefPtrWillBeRawPtr<CSSValueList> parseFontFaceValue(const AtomicString&);
-    static PassRefPtr<CSSValue> parseAnimationTimingFunctionValue(const String&);
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseValidPrimitive(CSSValueID ident, CSSParserValue*);
+    static PassRefPtrWillBeRawPtr<CSSValue> parseAnimationTimingFunctionValue(const String&);
     bool parseDeclaration(MutableStylePropertySet*, const String&, CSSParserObserver*, StyleSheetContents* contextStyleSheet);
     static PassRefPtr<ImmutableStylePropertySet> parseInlineStyleDeclaration(const String&, Element*);
-    PassRefPtr<MediaQuerySet> parseMediaQueryList(const String&);
+    PassRefPtrWillBeRawPtr<MediaQuerySet> parseMediaQueryList(const String&);
     PassOwnPtr<Vector<double> > parseKeyframeKeyList(const String&);
 
-    void addPropertyWithPrefixingVariant(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
-    void addProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important, bool implicit = false);
-    void rollbackLastProperties(int num);
-    bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
-    void addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtr<CSSValue>, bool);
-    void setCurrentProperty(CSSPropertyID);
-
-    bool parseValue(CSSPropertyID, bool important);
-    bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important);
-    bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
-    bool parseContent(CSSPropertyID, bool important);
-    bool parseQuotes(CSSPropertyID, bool important);
-
     static bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, const Document&);
 
-    PassRefPtr<CSSValue> parseAttr(CSSParserValueList* args);
-
-    PassRefPtr<CSSValue> parseBackgroundColor();
-
-    bool parseFillImage(CSSParserValueList*, RefPtr<CSSValue>&);
-
-    enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
-    enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseFillPositionComponent(CSSParserValueList*, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
-    PassRefPtr<CSSValue> parseFillPositionX(CSSParserValueList*);
-    PassRefPtr<CSSValue> parseFillPositionY(CSSParserValueList*);
-    void parse2ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-    bool isPotentialPositionValue(CSSParserValue*);
-    void parseFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-    void parse3ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>);
-    void parse4ValuesFillPosition(CSSParserValueList*, RefPtr<CSSValue>&, RefPtr<CSSValue>&, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>);
-
-    void parseFillRepeat(RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-    PassRefPtr<CSSValue> parseFillSize(CSSPropertyID, bool &allowComma);
-
-    bool parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-    bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
-
-    void addFillValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
-
-    void addAnimationValue(RefPtr<CSSValue>& lval, PassRefPtr<CSSValue> rval);
-
-    PassRefPtr<CSSValue> parseAnimationDelay();
-    PassRefPtr<CSSValue> parseAnimationDirection();
-    PassRefPtr<CSSValue> parseAnimationDuration();
-    PassRefPtr<CSSValue> parseAnimationFillMode();
-    PassRefPtr<CSSValue> parseAnimationIterationCount();
-    PassRefPtr<CSSValue> parseAnimationName();
-    PassRefPtr<CSSValue> parseAnimationPlayState();
-    PassRefPtr<CSSValue> parseAnimationProperty(AnimationParseContext&);
-    PassRefPtr<CSSValue> parseAnimationTimingFunction();
-
-    bool parseTransformOriginShorthand(RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-    bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
-    bool parseAnimationProperty(CSSPropertyID, RefPtr<CSSValue>&, AnimationParseContext&);
-    bool parseTransitionShorthand(CSSPropertyID, bool important);
-    bool parseAnimationShorthand(CSSPropertyID, bool important);
-
-    PassRefPtr<CSSValue> parseColumnWidth();
-    PassRefPtr<CSSValue> parseColumnCount();
-    bool parseColumnsShorthand(bool important);
-
-    PassRefPtr<CSSValue> parseGridPosition();
-    bool parseIntegerOrStringFromGridPosition(RefPtrWillBeRawPtr<CSSPrimitiveValue>& numericValue, RefPtrWillBeRawPtr<CSSPrimitiveValue>& gridLineName);
-    bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
-    bool parseGridAreaShorthand(bool important);
-    bool parseSingleGridAreaLonghand(RefPtr<CSSValue>&);
-    bool parseGridTrackList(CSSPropertyID, bool important);
-    bool parseGridTrackRepeatFunction(CSSValueList&);
-    PassRefPtr<CSSValue> parseGridTrackSize(CSSParserValueList& inputList);
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGridBreadth(CSSParserValue*);
-    PassRefPtr<CSSValue> parseGridTemplateAreas();
-    void parseGridLineNames(CSSParserValueList* inputList, CSSValueList&);
-
-    bool parseClipShape(CSSPropertyID, bool important);
-
-    bool parseItemPositionOverflowPosition(CSSPropertyID, bool important);
-
-    PassRefPtr<CSSValue> parseShapeProperty(CSSPropertyID propId);
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseBasicShape();
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseShapeRadius(CSSParserValue*);
-
-    PassRefPtr<CSSBasicShape> parseBasicShapeRectangle(CSSParserValueList* args);
-    PassRefPtr<CSSBasicShape> parseBasicShapeCircle(CSSParserValueList* args);
-    PassRefPtr<CSSBasicShape> parseDeprecatedBasicShapeCircle(CSSParserValueList* args);
-    PassRefPtr<CSSBasicShape> parseBasicShapeEllipse(CSSParserValueList* args);
-    PassRefPtr<CSSBasicShape> parseDeprecatedBasicShapeEllipse(CSSParserValueList*);
-    PassRefPtr<CSSBasicShape> parseBasicShapePolygon(CSSParserValueList* args);
-    PassRefPtr<CSSBasicShape> parseBasicShapeInsetRectangle(CSSParserValueList* args);
-    PassRefPtr<CSSBasicShape> parseBasicShapeInset(CSSParserValueList* args);
-
-    bool parseFont(bool important);
-    PassRefPtrWillBeRawPtr<CSSValueList> parseFontFamily();
-
-    bool parseCounter(CSSPropertyID, int defaultValue, bool important);
-    PassRefPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
-
-    bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
-    bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
-    bool parseColorFromValue(CSSParserValue*, RGBA32&);
+    bool parseValue(CSSPropertyID, bool important);
     void parseSelector(const String&, CSSSelectorList&);
 
-    template<typename StringType>
-    static bool fastParseColor(RGBA32&, const StringType&, bool strict);
-
-    bool parseLineHeight(bool important);
-    bool parseFontSize(bool important);
-    bool parseFontVariant(bool important);
-    bool parseFontWeight(bool important);
-    bool parseFontFaceSrc();
-    bool parseFontFaceUnicodeRange();
-
-    bool parseSVGValue(CSSPropertyID propId, bool important);
-    PassRefPtr<CSSValue> parseSVGPaint();
-    PassRefPtr<CSSValue> parseSVGColor();
-    PassRefPtr<CSSValue> parseSVGStrokeDasharray();
-
-    PassRefPtr<CSSValue> parsePaintOrder() const;
-
-    // CSS3 Parsing Routines (for properties specific to CSS3)
-    PassRefPtrWillBeRawPtr<CSSValueList> parseShadow(CSSParserValueList*, CSSPropertyID);
-    bool parseBorderImageShorthand(CSSPropertyID, bool important);
-    PassRefPtr<CSSValue> parseBorderImage(CSSPropertyID);
-    bool parseBorderImageRepeat(RefPtr<CSSValue>&);
-    bool parseBorderImageSlice(CSSPropertyID, RefPtrWillBeRawPtr<CSSBorderImageSliceValue>&);
-    bool parseBorderImageWidth(RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
-    bool parseBorderImageOutset(RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
-    bool parseBorderRadius(CSSPropertyID, bool important);
-
-    bool parseAspectRatio(bool important);
-
-    bool parseReflect(CSSPropertyID, bool important);
-
-    bool parseFlex(CSSParserValueList* args, bool important);
-
-    bool parseObjectPosition(bool important);
-
-    // Image generators
-    bool parseCanvas(CSSParserValueList*, RefPtr<CSSValue>&);
-
-    bool parseDeprecatedGradient(CSSParserValueList*, RefPtr<CSSValue>&);
-    bool parseDeprecatedLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
-    bool parseDeprecatedRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
-    bool parseLinearGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
-    bool parseRadialGradient(CSSParserValueList*, RefPtr<CSSValue>&, CSSGradientRepeat repeating);
-    bool parseGradientColorStops(CSSParserValueList*, CSSGradientValue*, bool expectComma);
-
-    bool parseCrossfade(CSSParserValueList*, RefPtr<CSSValue>&);
-
-    PassRefPtr<CSSValue> parseImageSet(CSSParserValueList*);
-
-    PassRefPtrWillBeRawPtr<CSSValueList> parseFilter();
-    PassRefPtrWillBeRawPtr<CSSFilterValue> parseBuiltinFilterArguments(CSSParserValueList*, CSSFilterValue::FilterOperationType);
-
-    static bool isBlendMode(CSSValueID);
-    static bool isCompositeOperator(CSSValueID);
-
-    PassRefPtrWillBeRawPtr<CSSValueList> parseTransform();
-    PassRefPtr<CSSValue> parseTransformValue(CSSParserValue*);
-    bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtr<CSSValue>&, RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-    bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,  RefPtr<CSSValue>&, RefPtr<CSSValue>&);
-
-    bool parseTextEmphasisStyle(bool important);
-
-    bool parseTouchAction(bool important);
-
-    void addTextDecorationProperty(CSSPropertyID, PassRefPtr<CSSValue>, bool important);
-    bool parseTextDecoration(CSSPropertyID propId, bool important);
-    bool parseTextUnderlinePosition(bool important);
-
-    PassRefPtr<CSSValue> parseTextIndent();
-
-    bool parseLineBoxContain(bool important);
-    bool parseCalculation(CSSParserValue*, ValueRange);
-
-    bool parseFontFeatureTag(CSSValueList*);
-    bool parseFontFeatureSettings(bool important);
-
-    bool parseFontVariantLigatures(bool important);
-
-    bool parseGeneratedImage(CSSParserValueList*, RefPtr<CSSValue>&);
-
     CSSParserSelector* createFloatingSelector();
     CSSParserSelector* createFloatingSelectorWithTagName(const QualifiedName&);
     PassOwnPtr<CSSParserSelector> sinkFloatingSelector(CSSParserSelector*);
@@ -303,7 +127,7 @@
     StyleKeyframe* createKeyframe(CSSParserValueList*);
     StyleRuleKeyframes* createKeyframesRule(const String&, PassOwnPtr<Vector<RefPtr<StyleKeyframe> > >, bool isPrefixed);
 
-    typedef Vector<RefPtr<StyleRuleBase> > RuleList;
+    typedef WillBeHeapVector<RefPtrWillBeMember<StyleRuleBase> > RuleList;
     StyleRuleBase* createMediaRule(MediaQuerySet*, RuleList*);
     RuleList* createRuleList();
     RuleList* appendRule(RuleList*, StyleRuleBase*);
@@ -321,13 +145,13 @@
     void endDeclarationsForMarginBox();
 
     MediaQueryExp* createFloatingMediaQueryExp(const AtomicString&, CSSParserValueList*);
-    PassOwnPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
-    Vector<OwnPtr<MediaQueryExp> >* createFloatingMediaQueryExpList();
-    PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > > sinkFloatingMediaQueryExpList(Vector<OwnPtr<MediaQueryExp> >*);
-    MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const AtomicString&, PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
-    MediaQuery* createFloatingMediaQuery(PassOwnPtr<Vector<OwnPtr<MediaQueryExp> > >);
+    PassOwnPtrWillBeRawPtr<MediaQueryExp> sinkFloatingMediaQueryExp(MediaQueryExp*);
+    WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >* createFloatingMediaQueryExpList();
+    PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > sinkFloatingMediaQueryExpList(WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> >*);
+    MediaQuery* createFloatingMediaQuery(MediaQuery::Restrictor, const AtomicString&, PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
+    MediaQuery* createFloatingMediaQuery(PassOwnPtrWillBeRawPtr<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > >);
     MediaQuery* createFloatingNotAllQuery();
-    PassOwnPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
+    PassOwnPtrWillBeRawPtr<MediaQuery> sinkFloatingMediaQuery(MediaQuery*);
 
     Vector<RefPtr<StyleKeyframe> >* createFloatingKeyframeVector();
     PassOwnPtr<Vector<RefPtr<StyleKeyframe> > > sinkFloatingKeyframeVector(Vector<RefPtr<StyleKeyframe> >*);
@@ -355,22 +179,17 @@
     bool m_important;
     CSSPropertyID m_id;
     StyleSheetContents* m_styleSheet;
-    RefPtr<StyleRuleBase> m_rule;
+    RefPtrWillBePersistent<StyleRuleBase> m_rule;
     RefPtr<StyleKeyframe> m_keyframe;
-    RefPtr<MediaQuerySet> m_mediaList;
+    RefPtrWillBePersistent<MediaQuerySet> m_mediaList;
     OwnPtr<CSSParserValueList> m_valueList;
     bool m_supportsCondition;
 
-    typedef Vector<CSSProperty, 256> ParsedPropertyVector;
-    ParsedPropertyVector m_parsedProperties;
+    WillBePersistentHeapVector<CSSProperty, 256> m_parsedProperties;
     CSSSelectorList* m_selectorListForParseSelector;
 
     unsigned m_numParsedPropertiesBeforeMarginBox;
 
-    int m_inParseShorthand;
-    CSSPropertyID m_currentShorthand;
-    bool m_implicitShorthand;
-
     bool m_hasFontFaceOnlyValues;
     bool m_hadSyntacticallyValidCSSRule;
     bool m_logErrors;
@@ -405,35 +224,9 @@
     void markViewportRuleBodyEnd() { m_inViewport = false; }
     StyleRuleBase* createViewportRule();
 
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
-    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
-
     CSSParserLocation currentLocation() { return m_tokenizer.currentLocation(); }
 
 private:
-    enum PropertyType {
-        PropertyExplicit,
-        PropertyImplicit
-    };
-
-    class ImplicitScope {
-        WTF_MAKE_NONCOPYABLE(ImplicitScope);
-    public:
-        ImplicitScope(WebCore::BisonCSSParser* parser, PropertyType propertyType)
-            : m_parser(parser)
-        {
-            m_parser->m_implicitShorthand = propertyType == BisonCSSParser::PropertyImplicit;
-        }
-
-        ~ImplicitScope()
-        {
-            m_parser->m_implicitShorthand = false;
-        }
-
-    private:
-        WebCore::BisonCSSParser* m_parser;
-    };
-
     class StyleDeclarationScope {
         WTF_MAKE_NONCOPYABLE(StyleDeclarationScope);
     public:
@@ -462,11 +255,8 @@
 
     void setStyleSheet(StyleSheetContents* styleSheet) { m_styleSheet = styleSheet; }
 
-    bool inQuirksMode() const { return isQuirksModeBehavior(m_context.mode()); }
     bool inViewport() const { return m_inViewport; }
 
-    KURL completeURL(const String& url) const;
-
     void recheckAtKeyword(const UChar* str, int len);
 
     template<unsigned prefixLength, unsigned suffixLength>
@@ -475,32 +265,12 @@
         setupParser(prefix, prefixLength - 1, string, suffix, suffixLength - 1);
     }
     void setupParser(const char* prefix, unsigned prefixLength, const String&, const char* suffix, unsigned suffixLength);
-    bool inShorthand() const { return m_inParseShorthand; }
-
-    bool validWidthOrHeight(CSSParserValue*);
 
     void deleteFontFaceOnlyValues();
 
     bool parseValue(MutableStylePropertySet*, CSSPropertyID, const String&, bool important, StyleSheetContents* contextStyleSheet);
     PassRefPtr<ImmutableStylePropertySet> parseDeclaration(const String&, StyleSheetContents* contextStyleSheet);
 
-    PassRefPtr<CSSBasicShape> parseInsetRoundedCorners(PassRefPtr<CSSBasicShapeInset>, CSSParserValueList*);
-
-    enum SizeParameterType {
-        None,
-        Auto,
-        Length,
-        PageSize,
-        Orientation,
-    };
-
-    bool parsePage(CSSPropertyID propId, bool important);
-    bool parseSize(CSSPropertyID propId, bool important);
-    SizeParameterType parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType);
-
-    bool parseFontFaceSrcURI(CSSValueList*);
-    bool parseFontFaceSrcLocal(CSSValueList*);
-
     bool parseColor(const String&);
 
     const String* m_source;
@@ -515,112 +285,45 @@
     bool m_allowImportRules;
     bool m_allowNamespaceDeclarations;
 
-    bool parseViewportProperty(CSSPropertyID propId, bool important);
-    bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
-
     bool m_inViewport;
 
     CSSParserLocation m_locationLabel;
 
-    bool useLegacyBackgroundSizeShorthandBehavior() const;
-
-    Vector<RefPtr<StyleRuleBase> > m_parsedRules;
+    WillBePersistentHeapVector<RefPtrWillBeMember<StyleRuleBase> > m_parsedRules;
     Vector<RefPtr<StyleKeyframe> > m_parsedKeyframes;
-    Vector<RefPtr<MediaQuerySet> > m_parsedMediaQuerySets;
-    Vector<OwnPtr<RuleList> > m_parsedRuleLists;
+    WillBePersistentHeapVector<RefPtrWillBeMember<MediaQuerySet> > m_parsedMediaQuerySets;
+    WillBePersistentHeapVector<OwnPtrWillBeMember<RuleList> > m_parsedRuleLists;
     Vector<CSSParserSelector*> m_floatingSelectors;
     Vector<Vector<OwnPtr<CSSParserSelector> >*> m_floatingSelectorVectors;
     Vector<CSSParserValueList*> m_floatingValueLists;
     Vector<CSSParserFunction*> m_floatingFunctions;
 
-    OwnPtr<MediaQuery> m_floatingMediaQuery;
-    OwnPtr<MediaQueryExp> m_floatingMediaQueryExp;
-    OwnPtr<Vector<OwnPtr<MediaQueryExp> > > m_floatingMediaQueryExpList;
+    OwnPtrWillBePersistent<MediaQuery> m_floatingMediaQuery;
+    OwnPtrWillBePersistent<MediaQueryExp> m_floatingMediaQueryExp;
+    OwnPtrWillBePersistent<WillBeHeapVector<OwnPtrWillBeMember<MediaQueryExp> > > m_floatingMediaQueryExpList;
 
     OwnPtr<Vector<RefPtr<StyleKeyframe> > > m_floatingKeyframeVector;
 
     Vector<OwnPtr<CSSParserSelector> > m_reusableSelectorVector;
 
-    RefPtrWillBePersistent<CSSCalcValue> m_parsedCalculation;
-
     OwnPtr<RuleSourceDataList> m_supportsRuleDataStack;
 
-    // defines units allowed for a certain property, used in parseUnit
-    enum Units {
-        FUnknown = 0x0000,
-        FInteger = 0x0001,
-        FNumber = 0x0002, // Real Numbers
-        FPercent = 0x0004,
-        FLength = 0x0008,
-        FAngle = 0x0010,
-        FTime = 0x0020,
-        FFrequency = 0x0040,
-        FPositiveInteger = 0x0080,
-        FRelative = 0x0100,
-        FResolution = 0x0200,
-        FNonNeg = 0x0400
-    };
-
-    friend inline Units operator|(Units a, Units b)
-    {
-        return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
-    }
-
-    enum ReleaseParsedCalcValueCondition {
-        ReleaseParsedCalcValue,
-        DoNotReleaseParsedCalcValue
-    };
-
     bool isLoggingErrors();
     void logError(const String& message, const CSSParserLocation&);
 
-    bool validCalculationUnit(CSSParserValue*, Units, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
-
-    bool shouldAcceptUnitLessValues(CSSParserValue*, Units, CSSParserMode);
-
-    inline bool validUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue) { return validUnit(value, unitflags, m_context.mode(), releaseCalc); }
-    bool validUnit(CSSParserValue*, Units, CSSParserMode, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
-
-    bool parseBorderImageQuad(Units, RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
-    int colorIntFromValue(CSSParserValue*);
-    double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
-    bool isCalculation(CSSParserValue*);
-
     CSSTokenizer m_tokenizer;
 
     friend class TransformOperationInfo;
     friend class FilterOperationInfo;
 };
 
-CSSPropertyID cssPropertyID(const CSSParserString&);
-CSSPropertyID cssPropertyID(const String&);
-CSSValueID cssValueKeywordID(const CSSParserString&);
-
-class ShorthandScope {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    ShorthandScope(BisonCSSParser* parser, CSSPropertyID propId) : m_parser(parser)
-    {
-        if (!(m_parser->m_inParseShorthand++))
-            m_parser->m_currentShorthand = propId;
-    }
-    ~ShorthandScope()
-    {
-        if (!(--m_parser->m_inParseShorthand))
-            m_parser->m_currentShorthand = CSSPropertyInvalid;
-    }
-
-private:
-    BisonCSSParser* m_parser;
-};
-
-bool isValidNthToken(const CSSParserString&);
-
 inline int cssyylex(void* yylval, BisonCSSParser* parser)
 {
     return parser->m_tokenizer.lex(yylval);
 }
 
+bool isValidNthToken(const CSSParserString&);
+
 } // namespace WebCore
 
 #endif // BisonCSSParser_h
diff --git a/Source/core/css/parser/BisonCSSParserTest.cpp b/Source/core/css/parser/BisonCSSParserTest.cpp
new file mode 100644
index 0000000..ac1b6b9
--- /dev/null
+++ b/Source/core/css/parser/BisonCSSParserTest.cpp
@@ -0,0 +1,67 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/BisonCSSParser.h"
+
+#include "core/css/CSSTimingFunctionValue.h"
+#include "platform/animation/TimingFunction.h"
+
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+TEST(BisonCSSParserTest, ParseAnimationTimingFunctionValue)
+{
+    RefPtr<CSSValue> timingFunctionValue;
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease");
+    EXPECT_EQ(CSSValueEase, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("linear");
+    EXPECT_EQ(CSSValueLinear, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease-in");
+    EXPECT_EQ(CSSValueEaseIn, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease-out");
+    EXPECT_EQ(CSSValueEaseOut, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("ease-in-out");
+    EXPECT_EQ(CSSValueEaseInOut, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("step-start");
+    EXPECT_EQ(CSSValueStepStart, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("step-middle");
+    EXPECT_EQ(CSSValueStepMiddle, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("step-end");
+    EXPECT_EQ(CSSValueStepEnd, toCSSPrimitiveValue(timingFunctionValue.get())->getValueID());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, start)");
+    EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtStart)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, middle)");
+    EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtMiddle)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, end)");
+    EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtEnd)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3, nowhere)");
+    EXPECT_EQ(0, timingFunctionValue.get());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(-3, end)");
+    EXPECT_EQ(0, timingFunctionValue.get());
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("steps(3)");
+    EXPECT_TRUE(CSSStepsTimingFunctionValue::create(3, StepsTimingFunction::StepAtEnd)->equals(toCSSStepsTimingFunctionValue(*timingFunctionValue.get())));
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("cubic-bezier(0.1, 5, 0.23, 0)");
+    EXPECT_TRUE(CSSCubicBezierTimingFunctionValue::create(0.1, 5, 0.23, 0)->equals(toCSSCubicBezierTimingFunctionValue(*timingFunctionValue.get())));
+
+    timingFunctionValue = BisonCSSParser::parseAnimationTimingFunctionValue("cubic-bezier(0.1, 0, 4, 0.4)");
+    EXPECT_EQ(0, timingFunctionValue.get());
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/parser/CSSParserIdioms.h b/Source/core/css/parser/CSSParserIdioms.h
index d0e0b24..4217d0a 100644
--- a/Source/core/css/parser/CSSParserIdioms.h
+++ b/Source/core/css/parser/CSSParserIdioms.h
@@ -36,7 +36,7 @@
 namespace WebCore {
 
 // Space characters as defined by the CSS specification.
-// http://www.w3.org/TR/css3-syntax/
+// http://www.w3.org/TR/css3-syntax/#whitespace
 inline bool isCSSSpace(UChar c)
 {
     return c == ' ' || c == '\t' || c == '\n';
diff --git a/Source/core/css/parser/CSSPropertyParser.cpp b/Source/core/css/parser/CSSPropertyParser.cpp
new file mode 100644
index 0000000..89f3140
--- /dev/null
+++ b/Source/core/css/parser/CSSPropertyParser.cpp
@@ -0,0 +1,8464 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2005 Allan Sandfeld Jensen (kde@carewolf.com)
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Nicholas Shanks <webkit@nickshanks.com>
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2012 Adobe Systems Incorporated. All rights reserved.
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/css/parser/CSSPropertyParser.h"
+#include "RuntimeEnabledFeatures.h"
+#include "core/rendering/RenderTheme.h"
+#include "core/svg/SVGPaint.h"
+// FIXME: Way too many!
+#include "CSSValueKeywords.h"
+#include "RuntimeEnabledFeatures.h"
+#include "StylePropertyShorthand.h"
+#include "core/css/CSSArrayFunctionValue.h"
+#include "core/css/CSSAspectRatioValue.h"
+#include "core/css/CSSBasicShapes.h"
+#include "core/css/CSSBorderImage.h"
+#include "core/css/CSSCanvasValue.h"
+#include "core/css/CSSCrossfadeValue.h"
+#include "core/css/CSSCursorImageValue.h"
+#include "core/css/CSSFontFaceSrcValue.h"
+#include "core/css/CSSFontFeatureValue.h"
+#include "core/css/CSSFunctionValue.h"
+#include "core/css/CSSGradientValue.h"
+#include "core/css/CSSGridLineNamesValue.h"
+#include "core/css/CSSGridTemplateAreasValue.h"
+#include "core/css/CSSImageSetValue.h"
+#include "core/css/CSSImageValue.h"
+#include "core/css/CSSInheritedValue.h"
+#include "core/css/CSSInitialValue.h"
+#include "core/css/CSSKeyframeRule.h"
+#include "core/css/CSSKeyframesRule.h"
+#include "core/css/CSSLineBoxContainValue.h"
+#include "core/css/CSSParserValues.h"
+#include "core/css/CSSPrimitiveValue.h"
+#include "core/css/CSSPropertySourceData.h"
+#include "core/css/CSSReflectValue.h"
+#include "core/css/CSSSVGDocumentValue.h"
+#include "core/css/CSSSelector.h"
+#include "core/css/CSSShadowValue.h"
+#include "core/css/CSSTimingFunctionValue.h"
+#include "core/css/CSSTransformValue.h"
+#include "core/css/CSSUnicodeRangeValue.h"
+#include "core/css/CSSValueList.h"
+#include "core/css/CSSValuePool.h"
+#include "core/css/Counter.h"
+#include "core/css/HashTools.h"
+#include "core/css/Pair.h"
+#include "core/css/Rect.h"
+#include "core/css/parser/CSSParserIdioms.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/rendering/RenderTheme.h"
+#include "core/svg/SVGParserUtilities.h"
+#include "platform/FloatConversion.h"
+#include "wtf/BitArray.h"
+#include "wtf/HexNumber.h"
+#include "wtf/text/StringBuffer.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringImpl.h"
+#include "wtf/text/TextEncoding.h"
+#include <limits.h>
+
+using namespace std;
+
+namespace WebCore {
+
+static const double MAX_SCALE = 1000000;
+
+template <unsigned N>
+static bool equal(const CSSParserString& a, const char (&b)[N])
+{
+    unsigned length = N - 1; // Ignore the trailing null character
+    if (a.length() != length)
+        return false;
+
+    return a.is8Bit() ? WTF::equal(a.characters8(), reinterpret_cast<const LChar*>(b), length) : WTF::equal(a.characters16(), reinterpret_cast<const LChar*>(b), length);
+}
+
+template <unsigned N>
+static bool equalIgnoringCase(const CSSParserString& a, const char (&b)[N])
+{
+    unsigned length = N - 1; // Ignore the trailing null character
+    if (a.length() != length)
+        return false;
+
+    return a.is8Bit() ? WTF::equalIgnoringCase(b, a.characters8(), length) : WTF::equalIgnoringCase(b, a.characters16(), length);
+}
+
+template <unsigned N>
+static bool equalIgnoringCase(CSSParserValue* value, const char (&b)[N])
+{
+    ASSERT(value->unit == CSSPrimitiveValue::CSS_IDENT || value->unit == CSSPrimitiveValue::CSS_STRING);
+    return equalIgnoringCase(value->string, b);
+}
+
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveValuePair(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> first, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> second, Pair::IdenticalValuesPolicy identicalValuesPolicy = Pair::DropIdenticalValues)
+{
+    return cssValuePool().createValue(Pair::create(first, second, identicalValuesPolicy));
+}
+
+class AnimationParseContext {
+public:
+    AnimationParseContext()
+        : m_animationPropertyKeywordAllowed(true)
+        , m_firstAnimationCommitted(false)
+        , m_hasSeenAnimationPropertyKeyword(false)
+    {
+    }
+
+    void commitFirstAnimation()
+    {
+        m_firstAnimationCommitted = true;
+    }
+
+    bool hasCommittedFirstAnimation() const
+    {
+        return m_firstAnimationCommitted;
+    }
+
+    void commitAnimationPropertyKeyword()
+    {
+        m_animationPropertyKeywordAllowed = false;
+    }
+
+    bool animationPropertyKeywordAllowed() const
+    {
+        return m_animationPropertyKeywordAllowed;
+    }
+
+    bool hasSeenAnimationPropertyKeyword() const
+    {
+        return m_hasSeenAnimationPropertyKeyword;
+    }
+
+    void sawAnimationPropertyKeyword()
+    {
+        m_hasSeenAnimationPropertyKeyword = true;
+    }
+
+private:
+    bool m_animationPropertyKeywordAllowed;
+    bool m_firstAnimationCommitted;
+    bool m_hasSeenAnimationPropertyKeyword;
+};
+
+CSSPropertyParser::CSSPropertyParser(OwnPtr<CSSParserValueList>& valueList,
+    const CSSParserContext& context, bool inViewport, bool savedImportant,
+    WillBeHeapVector<CSSProperty, 256>& parsedProperties, bool& hasFontFaceOnlyValues)
+    : m_valueList(valueList)
+    , m_context(context)
+    , m_inViewport(inViewport)
+    , m_important(savedImportant) // See comment in header, should be removed.
+    , m_parsedProperties(parsedProperties)
+    , m_hasFontFaceOnlyValues(hasFontFaceOnlyValues)
+    , m_inParseShorthand(0)
+    , m_currentShorthand(CSSPropertyInvalid)
+    , m_implicitShorthand(false)
+{
+}
+
+CSSPropertyParser::~CSSPropertyParser()
+{
+}
+
+void CSSPropertyParser::addPropertyWithPrefixingVariant(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> value, bool important, bool implicit)
+{
+    RefPtrWillBeRawPtr<CSSValue> val = value.get();
+    addProperty(propId, value, important, implicit);
+
+    CSSPropertyID prefixingVariant = prefixingVariantForPropertyId(propId);
+    if (prefixingVariant == propId)
+        return;
+
+    if (m_currentShorthand) {
+        // We can't use ShorthandScope here as we can already be inside one (e.g we are parsing CSSTransition).
+        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
+        addProperty(prefixingVariant, val.release(), important, implicit);
+        m_currentShorthand = prefixingVariantForPropertyId(m_currentShorthand);
+    } else {
+        addProperty(prefixingVariant, val.release(), important, implicit);
+    }
+}
+
+void CSSPropertyParser::addProperty(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> value, bool important, bool implicit)
+{
+    // This property doesn't belong to a shorthand.
+    if (!m_currentShorthand) {
+        m_parsedProperties.append(CSSProperty(propId, value, important, false, CSSPropertyInvalid, m_implicitShorthand || implicit));
+        return;
+    }
+
+    Vector<StylePropertyShorthand, 4> shorthands;
+    getMatchingShorthandsForLonghand(propId, &shorthands);
+    // The longhand does not belong to multiple shorthands.
+    if (shorthands.size() == 1)
+        m_parsedProperties.append(CSSProperty(propId, value, important, true, CSSPropertyInvalid, m_implicitShorthand || implicit));
+    else
+        m_parsedProperties.append(CSSProperty(propId, value, important, true, indexOfShorthandForLonghand(m_currentShorthand, shorthands), m_implicitShorthand || implicit));
+}
+
+void CSSPropertyParser::rollbackLastProperties(int num)
+{
+    ASSERT(num >= 0);
+    ASSERT(m_parsedProperties.size() >= static_cast<unsigned>(num));
+    m_parsedProperties.shrink(m_parsedProperties.size() - num);
+}
+
+KURL CSSPropertyParser::completeURL(const String& url) const
+{
+    return m_context.completeURL(url);
+}
+
+bool CSSPropertyParser::validCalculationUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc)
+{
+    bool mustBeNonNegative = unitflags & FNonNeg;
+
+    if (!parseCalculation(value, mustBeNonNegative ? ValueRangeNonNegative : ValueRangeAll))
+        return false;
+
+    bool b = false;
+    switch (m_parsedCalculation->category()) {
+    case CalcLength:
+        b = (unitflags & FLength);
+        break;
+    case CalcPercent:
+        b = (unitflags & FPercent);
+        if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
+            b = false;
+        break;
+    case CalcNumber:
+        b = (unitflags & FNumber);
+        if (!b && (unitflags & FInteger) && m_parsedCalculation->isInt())
+            b = true;
+        if (b && mustBeNonNegative && m_parsedCalculation->isNegative())
+            b = false;
+        break;
+    case CalcPercentLength:
+        b = (unitflags & FPercent) && (unitflags & FLength);
+        break;
+    case CalcPercentNumber:
+        b = (unitflags & FPercent) && (unitflags & FNumber);
+        break;
+    case CalcOther:
+        break;
+    }
+    if (!b || releaseCalc == ReleaseParsedCalcValue)
+        m_parsedCalculation.release();
+    return b;
+}
+
+inline bool CSSPropertyParser::shouldAcceptUnitLessValues(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode)
+{
+    // Quirks mode and presentation attributes accept unit less values.
+    return (unitflags & (FLength | FAngle | FTime)) && (!value->fValue || isUnitLessLengthParsingEnabledForMode(cssParserMode));
+}
+
+bool CSSPropertyParser::validUnit(CSSParserValue* value, Units unitflags, CSSParserMode cssParserMode, ReleaseParsedCalcValueCondition releaseCalc)
+{
+    if (isCalculation(value))
+        return validCalculationUnit(value, unitflags, releaseCalc);
+
+    bool b = false;
+    switch (value->unit) {
+    case CSSPrimitiveValue::CSS_NUMBER:
+        b = (unitflags & FNumber);
+        if (!b && shouldAcceptUnitLessValues(value, unitflags, cssParserMode)) {
+            value->unit = (unitflags & FLength) ? CSSPrimitiveValue::CSS_PX :
+                          ((unitflags & FAngle) ? CSSPrimitiveValue::CSS_DEG : CSSPrimitiveValue::CSS_MS);
+            b = true;
+        }
+        if (!b && (unitflags & FInteger) && value->isInt)
+            b = true;
+        if (!b && (unitflags & FPositiveInteger) && value->isInt && value->fValue > 0)
+            b = true;
+        break;
+    case CSSPrimitiveValue::CSS_PERCENTAGE:
+        b = (unitflags & FPercent);
+        break;
+    case CSSParserValue::Q_EMS:
+    case CSSPrimitiveValue::CSS_EMS:
+    case CSSPrimitiveValue::CSS_REMS:
+    case CSSPrimitiveValue::CSS_CHS:
+    case CSSPrimitiveValue::CSS_EXS:
+    case CSSPrimitiveValue::CSS_PX:
+    case CSSPrimitiveValue::CSS_CM:
+    case CSSPrimitiveValue::CSS_MM:
+    case CSSPrimitiveValue::CSS_IN:
+    case CSSPrimitiveValue::CSS_PT:
+    case CSSPrimitiveValue::CSS_PC:
+    case CSSPrimitiveValue::CSS_VW:
+    case CSSPrimitiveValue::CSS_VH:
+    case CSSPrimitiveValue::CSS_VMIN:
+    case CSSPrimitiveValue::CSS_VMAX:
+        b = (unitflags & FLength);
+        break;
+    case CSSPrimitiveValue::CSS_MS:
+    case CSSPrimitiveValue::CSS_S:
+        b = (unitflags & FTime);
+        break;
+    case CSSPrimitiveValue::CSS_DEG:
+    case CSSPrimitiveValue::CSS_RAD:
+    case CSSPrimitiveValue::CSS_GRAD:
+    case CSSPrimitiveValue::CSS_TURN:
+        b = (unitflags & FAngle);
+        break;
+    case CSSPrimitiveValue::CSS_DPPX:
+    case CSSPrimitiveValue::CSS_DPI:
+    case CSSPrimitiveValue::CSS_DPCM:
+        b = (unitflags & FResolution);
+        break;
+    case CSSPrimitiveValue::CSS_HZ:
+    case CSSPrimitiveValue::CSS_KHZ:
+    case CSSPrimitiveValue::CSS_DIMENSION:
+    default:
+        break;
+    }
+    if (b && unitflags & FNonNeg && value->fValue < 0)
+        b = false;
+    return b;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveNumericValue(CSSParserValue* value)
+{
+    if (m_parsedCalculation) {
+        ASSERT(isCalculation(value));
+        return CSSPrimitiveValue::create(m_parsedCalculation.release());
+    }
+
+    ASSERT((value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+        || (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
+        || (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
+        || (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM));
+    return cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit));
+}
+
+inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::createPrimitiveStringValue(CSSParserValue* value)
+{
+    ASSERT(value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT);
+    return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING);
+}
+
+static inline bool isComma(CSSParserValue* value)
+{
+    return value && value->unit == CSSParserValue::Operator && value->iValue == ',';
+}
+
+static inline bool isForwardSlashOperator(CSSParserValue* value)
+{
+    ASSERT(value);
+    return value->unit == CSSParserValue::Operator && value->iValue == '/';
+}
+
+static bool isGeneratedImageValue(CSSParserValue* val)
+{
+    if (val->unit != CSSParserValue::Function)
+        return false;
+
+    return equalIgnoringCase(val->function->name, "-webkit-gradient(")
+        || equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")
+        || equalIgnoringCase(val->function->name, "linear-gradient(")
+        || equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")
+        || equalIgnoringCase(val->function->name, "repeating-linear-gradient(")
+        || equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")
+        || equalIgnoringCase(val->function->name, "radial-gradient(")
+        || equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")
+        || equalIgnoringCase(val->function->name, "repeating-radial-gradient(")
+        || equalIgnoringCase(val->function->name, "-webkit-canvas(")
+        || equalIgnoringCase(val->function->name, "-webkit-cross-fade(");
+}
+
+bool CSSPropertyParser::validWidthOrHeight(CSSParserValue* value)
+{
+    int id = value->id;
+    if (id == CSSValueIntrinsic || id == CSSValueMinIntrinsic || id == CSSValueWebkitMinContent || id == CSSValueWebkitMaxContent || id == CSSValueWebkitFillAvailable || id == CSSValueWebkitFitContent)
+        return true;
+    return !id && validUnit(value, FLength | FPercent | FNonNeg);
+}
+
+inline PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseValidPrimitive(CSSValueID identifier, CSSParserValue* value)
+{
+    if (identifier)
+        return cssValuePool().createIdentifierValue(identifier);
+    if (value->unit == CSSPrimitiveValue::CSS_STRING)
+        return createPrimitiveStringValue(value);
+    if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+        return createPrimitiveNumericValue(value);
+    if (value->unit >= CSSPrimitiveValue::CSS_TURN && value->unit <= CSSPrimitiveValue::CSS_CHS)
+        return createPrimitiveNumericValue(value);
+    if (value->unit >= CSSPrimitiveValue::CSS_VW && value->unit <= CSSPrimitiveValue::CSS_VMAX)
+        return createPrimitiveNumericValue(value);
+    if (value->unit >= CSSPrimitiveValue::CSS_DPPX && value->unit <= CSSPrimitiveValue::CSS_DPCM)
+        return createPrimitiveNumericValue(value);
+    if (value->unit >= CSSParserValue::Q_EMS)
+        return CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+    if (isCalculation(value))
+        return CSSPrimitiveValue::create(m_parsedCalculation.release());
+
+    return nullptr;
+}
+
+void CSSPropertyParser::addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> prpValue, bool important)
+{
+    const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
+    unsigned shorthandLength = shorthand.length();
+    if (!shorthandLength) {
+        addProperty(propId, prpValue, important);
+        return;
+    }
+
+    RefPtrWillBeRawPtr<CSSValue> value = prpValue;
+    ShorthandScope scope(this, propId);
+    const CSSPropertyID* longhands = shorthand.properties();
+    for (unsigned i = 0; i < shorthandLength; ++i)
+        addProperty(longhands[i], value, important);
+}
+
+bool CSSPropertyParser::parseValue(CSSPropertyID propId, bool important)
+{
+    if (!isInternalPropertyAndValueParsingEnabledForMode(m_context.mode()) && isInternalProperty(propId))
+        return false;
+
+    // We don't count the UA style sheet in our statistics.
+    if (m_context.useCounter())
+        m_context.useCounter()->count(m_context, propId);
+
+    if (!m_valueList)
+        return false;
+
+    CSSParserValue* value = m_valueList->current();
+
+    if (!value)
+        return false;
+
+    if (inViewport()) {
+        // Allow @viewport rules from UA stylesheets even if the feature is disabled.
+        if (!RuntimeEnabledFeatures::cssViewportEnabled() && !isUASheetBehavior(m_context.mode()))
+            return false;
+
+        return parseViewportProperty(propId, important);
+    }
+
+    // Note: m_parsedCalculation is used to pass the calc value to validUnit and then cleared at the end of this function.
+    // FIXME: This is to avoid having to pass parsedCalc to all validUnit callers.
+    ASSERT(!m_parsedCalculation);
+
+    CSSValueID id = value->id;
+
+    int num = inShorthand() ? 1 : m_valueList->size();
+
+    if (id == CSSValueInherit) {
+        if (num != 1)
+            return false;
+        addExpandedPropertyForValue(propId, cssValuePool().createInheritedValue(), important);
+        return true;
+    }
+    else if (id == CSSValueInitial) {
+        if (num != 1)
+            return false;
+        addExpandedPropertyForValue(propId, cssValuePool().createExplicitInitialValue(), important);
+        return true;
+    }
+
+    if (isKeywordPropertyID(propId)) {
+        if (!isValidKeywordPropertyAndValue(propId, id, m_context))
+            return false;
+        if (m_valueList->next() && !inShorthand())
+            return false;
+        addProperty(propId, cssValuePool().createIdentifierValue(id), important);
+        return true;
+    }
+
+    bool validPrimitive = false;
+    RefPtrWillBeRawPtr<CSSValue> parsedValue;
+
+    switch (propId) {
+    case CSSPropertySize:                 // <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
+        return parseSize(propId, important);
+
+    case CSSPropertyQuotes:               // [<string> <string>]+ | none | inherit
+        if (id)
+            validPrimitive = true;
+        else
+            return parseQuotes(propId, important);
+        break;
+    case CSSPropertyUnicodeBidi: // normal | embed | bidi-override | isolate | isolate-override | plaintext | inherit
+        if (id == CSSValueNormal
+            || id == CSSValueEmbed
+            || id == CSSValueBidiOverride
+            || id == CSSValueWebkitIsolate
+            || id == CSSValueWebkitIsolateOverride
+            || id == CSSValueWebkitPlaintext)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyContent:              // [ <string> | <uri> | <counter> | attr(X) | open-quote |
+        // close-quote | no-open-quote | no-close-quote ]+ | inherit
+        return parseContent(propId, important);
+
+    case CSSPropertyClip:                 // <shape> | auto | inherit
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else if (value->unit == CSSParserValue::Function)
+            return parseClipShape(propId, important);
+        break;
+
+    /* Start of supported CSS properties with validation. This is needed for parseShorthand to work
+     * correctly and allows optimization in WebCore::applyRule(..)
+     */
+    case CSSPropertyOverflow: {
+        ShorthandScope scope(this, propId);
+        if (num != 1 || !parseValue(CSSPropertyOverflowY, important))
+            return false;
+
+        RefPtrWillBeRawPtr<CSSValue> overflowXValue;
+
+        // FIXME: -webkit-paged-x or -webkit-paged-y only apply to overflow-y. If this value has been
+        // set using the shorthand, then for now overflow-x will default to auto, but once we implement
+        // pagination controls, it should default to hidden. If the overflow-y value is anything but
+        // paged-x or paged-y, then overflow-x and overflow-y should have the same value.
+        if (id == CSSValueWebkitPagedX || id == CSSValueWebkitPagedY)
+            overflowXValue = cssValuePool().createIdentifierValue(CSSValueAuto);
+        else
+            overflowXValue = m_parsedProperties.last().value();
+        addProperty(CSSPropertyOverflowX, overflowXValue.release(), important);
+        return true;
+    }
+
+    case CSSPropertyTextAlign:
+        // left | right | center | justify | -webkit-left | -webkit-right | -webkit-center | -webkit-match-parent
+        // | start | end | <string> | inherit | -webkit-auto (converted to start)
+        if ((id >= CSSValueWebkitAuto && id <= CSSValueWebkitMatchParent) || id == CSSValueStart || id == CSSValueEnd
+            || value->unit == CSSPrimitiveValue::CSS_STRING)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyFontWeight:  { // normal | bold | bolder | lighter | 100 | 200 | 300 | 400 | 500 | 600 | 700 | 800 | 900 | inherit
+        if (m_valueList->size() != 1)
+            return false;
+        return parseFontWeight(important);
+    }
+    case CSSPropertyBorderSpacing: {
+        if (num == 1) {
+            ShorthandScope scope(this, CSSPropertyBorderSpacing);
+            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important))
+                return false;
+            CSSValue* value = m_parsedProperties.last().value();
+            addProperty(CSSPropertyWebkitBorderVerticalSpacing, value, important);
+            return true;
+        }
+        else if (num == 2) {
+            ShorthandScope scope(this, CSSPropertyBorderSpacing);
+            if (!parseValue(CSSPropertyWebkitBorderHorizontalSpacing, important) || !parseValue(CSSPropertyWebkitBorderVerticalSpacing, important))
+                return false;
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyWebkitBorderHorizontalSpacing:
+    case CSSPropertyWebkitBorderVerticalSpacing:
+        validPrimitive = validUnit(value, FLength | FNonNeg);
+        break;
+    case CSSPropertyOutlineColor:        // <color> | invert | inherit
+        // Outline color has "invert" as additional keyword.
+        // Also, we want to allow the special focus color even in HTML Standard parsing mode.
+        if (id == CSSValueInvert || id == CSSValueWebkitFocusRingColor) {
+            validPrimitive = true;
+            break;
+        }
+        /* nobreak */
+    case CSSPropertyBackgroundColor: // <color> | inherit
+    case CSSPropertyBorderTopColor: // <color> | inherit
+    case CSSPropertyBorderRightColor:
+    case CSSPropertyBorderBottomColor:
+    case CSSPropertyBorderLeftColor:
+    case CSSPropertyWebkitBorderStartColor:
+    case CSSPropertyWebkitBorderEndColor:
+    case CSSPropertyWebkitBorderBeforeColor:
+    case CSSPropertyWebkitBorderAfterColor:
+    case CSSPropertyColor: // <color> | inherit
+    case CSSPropertyTextDecorationColor: // CSS3 text decoration colors
+    case CSSPropertyTextLineThroughColor:
+    case CSSPropertyTextUnderlineColor:
+    case CSSPropertyTextOverlineColor:
+    case CSSPropertyWebkitColumnRuleColor:
+    case CSSPropertyWebkitTextEmphasisColor:
+    case CSSPropertyWebkitTextFillColor:
+    case CSSPropertyWebkitTextStrokeColor:
+        if (propId == CSSPropertyTextDecorationColor
+            && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+            return false;
+
+        if ((id >= CSSValueAqua && id <= CSSValueWebkitText) || id == CSSValueMenu) {
+            validPrimitive = isValueAllowedInMode(id, m_context.mode());
+        } else {
+            parsedValue = parseColor();
+            if (parsedValue)
+                m_valueList->next();
+        }
+        break;
+
+    case CSSPropertyCursor: {
+        // Grammar defined by CSS3 UI and modified by CSS4 images:
+        // [ [<image> [<x> <y>]?,]*
+        // [ auto | crosshair | default | pointer | progress | move | e-resize | ne-resize |
+        // nw-resize | n-resize | se-resize | sw-resize | s-resize | w-resize | ew-resize |
+        // ns-resize | nesw-resize | nwse-resize | col-resize | row-resize | text | wait | help |
+        // vertical-text | cell | context-menu | alias | copy | no-drop | not-allowed | -webkit-zoom-in
+        // -webkit-zoom-out | all-scroll | -webkit-grab | -webkit-grabbing ] ] | inherit
+        RefPtrWillBeRawPtr<CSSValueList> list;
+        while (value) {
+            RefPtrWillBeRawPtr<CSSValue> image = nullptr;
+            if (value->unit == CSSPrimitiveValue::CSS_URI) {
+                String uri = value->string;
+                if (!uri.isNull())
+                    image = CSSImageValue::create(uri, completeURL(uri));
+            } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
+                image = parseImageSet(m_valueList.get());
+                if (!image)
+                    break;
+            } else
+                break;
+
+            Vector<int> coords;
+            value = m_valueList->next();
+            while (value && value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+                coords.append(int(value->fValue));
+                value = m_valueList->next();
+            }
+            bool hasHotSpot = false;
+            IntPoint hotSpot(-1, -1);
+            int nrcoords = coords.size();
+            if (nrcoords > 0 && nrcoords != 2)
+                return false;
+            if (nrcoords == 2) {
+                hasHotSpot = true;
+                hotSpot = IntPoint(coords[0], coords[1]);
+            }
+
+            if (!list)
+                list = CSSValueList::createCommaSeparated();
+
+            if (image)
+                list->append(CSSCursorImageValue::create(image, hasHotSpot, hotSpot));
+
+            if (!value || !(value->unit == CSSParserValue::Operator && value->iValue == ','))
+                return false;
+            value = m_valueList->next(); // comma
+        }
+        if (list) {
+            if (!value)
+                return false;
+            if (inQuirksMode() && value->id == CSSValueHand) // MSIE 5 compatibility :/
+                list->append(cssValuePool().createIdentifierValue(CSSValuePointer));
+            else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)
+                list->append(cssValuePool().createIdentifierValue(value->id));
+            m_valueList->next();
+            parsedValue = list.release();
+            break;
+        } else if (value) {
+            id = value->id;
+            if (inQuirksMode() && value->id == CSSValueHand) { // MSIE 5 compatibility :/
+                id = CSSValuePointer;
+                validPrimitive = true;
+            } else if ((value->id >= CSSValueAuto && value->id <= CSSValueWebkitGrabbing) || value->id == CSSValueCopy || value->id == CSSValueNone)
+                validPrimitive = true;
+        } else {
+            ASSERT_NOT_REACHED();
+            return false;
+        }
+        break;
+    }
+
+    case CSSPropertyBackgroundBlendMode:
+    case CSSPropertyBackgroundAttachment:
+    case CSSPropertyBackgroundClip:
+    case CSSPropertyWebkitBackgroundClip:
+    case CSSPropertyWebkitBackgroundComposite:
+    case CSSPropertyBackgroundImage:
+    case CSSPropertyBackgroundOrigin:
+    case CSSPropertyMaskSourceType:
+    case CSSPropertyWebkitBackgroundOrigin:
+    case CSSPropertyBackgroundPosition:
+    case CSSPropertyBackgroundPositionX:
+    case CSSPropertyBackgroundPositionY:
+    case CSSPropertyBackgroundSize:
+    case CSSPropertyWebkitBackgroundSize:
+    case CSSPropertyBackgroundRepeat:
+    case CSSPropertyBackgroundRepeatX:
+    case CSSPropertyBackgroundRepeatY:
+    case CSSPropertyWebkitMaskClip:
+    case CSSPropertyWebkitMaskComposite:
+    case CSSPropertyWebkitMaskImage:
+    case CSSPropertyWebkitMaskOrigin:
+    case CSSPropertyWebkitMaskPosition:
+    case CSSPropertyWebkitMaskPositionX:
+    case CSSPropertyWebkitMaskPositionY:
+    case CSSPropertyWebkitMaskSize:
+    case CSSPropertyWebkitMaskRepeat:
+    case CSSPropertyWebkitMaskRepeatX:
+    case CSSPropertyWebkitMaskRepeatY:
+    {
+        RefPtrWillBeRawPtr<CSSValue> val1;
+        RefPtrWillBeRawPtr<CSSValue> val2;
+        CSSPropertyID propId1, propId2;
+        bool result = false;
+        if (parseFillProperty(propId, propId1, propId2, val1, val2)) {
+            OwnPtr<ShorthandScope> shorthandScope;
+            if (propId == CSSPropertyBackgroundPosition ||
+                propId == CSSPropertyBackgroundRepeat ||
+                propId == CSSPropertyWebkitMaskPosition ||
+                propId == CSSPropertyWebkitMaskRepeat) {
+                shorthandScope = adoptPtr(new ShorthandScope(this, propId));
+            }
+            addProperty(propId1, val1.release(), important);
+            if (val2)
+                addProperty(propId2, val2.release(), important);
+            result = true;
+        }
+        m_implicitShorthand = false;
+        return result;
+    }
+    case CSSPropertyObjectPosition:
+        return RuntimeEnabledFeatures::objectFitPositionEnabled() && parseObjectPosition(important);
+    case CSSPropertyListStyleImage:     // <uri> | none | inherit
+    case CSSPropertyBorderImageSource:
+    case CSSPropertyWebkitMaskBoxImageSource:
+        if (id == CSSValueNone) {
+            parsedValue = cssValuePool().createIdentifierValue(CSSValueNone);
+            m_valueList->next();
+        } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+            parsedValue = CSSImageValue::create(value->string, completeURL(value->string));
+            m_valueList->next();
+        } else if (isGeneratedImageValue(value)) {
+            if (parseGeneratedImage(m_valueList.get(), parsedValue))
+                m_valueList->next();
+            else
+                return false;
+        }
+        else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "-webkit-image-set(")) {
+            parsedValue = parseImageSet(m_valueList.get());
+            if (!parsedValue)
+                return false;
+            m_valueList->next();
+        }
+        break;
+
+    case CSSPropertyWebkitTextStrokeWidth:
+    case CSSPropertyOutlineWidth:        // <border-width> | inherit
+    case CSSPropertyBorderTopWidth:     //// <border-width> | inherit
+    case CSSPropertyBorderRightWidth:   //   Which is defined as
+    case CSSPropertyBorderBottomWidth:  //   thin | medium | thick | <length>
+    case CSSPropertyBorderLeftWidth:
+    case CSSPropertyWebkitBorderStartWidth:
+    case CSSPropertyWebkitBorderEndWidth:
+    case CSSPropertyWebkitBorderBeforeWidth:
+    case CSSPropertyWebkitBorderAfterWidth:
+    case CSSPropertyWebkitColumnRuleWidth:
+        if (id == CSSValueThin || id == CSSValueMedium || id == CSSValueThick)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FLength | FNonNeg);
+        break;
+
+    case CSSPropertyLetterSpacing:       // normal | <length> | inherit
+    case CSSPropertyWordSpacing:         // normal | <length> | inherit
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FLength);
+        break;
+
+    case CSSPropertyTextIndent:
+        parsedValue = parseTextIndent();
+        break;
+
+    case CSSPropertyPaddingTop:          //// <padding-width> | inherit
+    case CSSPropertyPaddingRight:        //   Which is defined as
+    case CSSPropertyPaddingBottom:       //   <length> | <percentage>
+    case CSSPropertyPaddingLeft:         ////
+    case CSSPropertyWebkitPaddingStart:
+    case CSSPropertyWebkitPaddingEnd:
+    case CSSPropertyWebkitPaddingBefore:
+    case CSSPropertyWebkitPaddingAfter:
+        validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+        break;
+
+    case CSSPropertyMaxWidth:
+    case CSSPropertyWebkitMaxLogicalWidth:
+    case CSSPropertyMaxHeight:
+    case CSSPropertyWebkitMaxLogicalHeight:
+        validPrimitive = (id == CSSValueNone || validWidthOrHeight(value));
+        break;
+
+    case CSSPropertyMinWidth:
+    case CSSPropertyWebkitMinLogicalWidth:
+    case CSSPropertyMinHeight:
+    case CSSPropertyWebkitMinLogicalHeight:
+        validPrimitive = validWidthOrHeight(value);
+        break;
+
+    case CSSPropertyWidth:
+    case CSSPropertyWebkitLogicalWidth:
+    case CSSPropertyHeight:
+    case CSSPropertyWebkitLogicalHeight:
+        validPrimitive = (id == CSSValueAuto || validWidthOrHeight(value));
+        break;
+
+    case CSSPropertyFontSize:
+        return parseFontSize(important);
+
+    case CSSPropertyFontVariant:         // normal | small-caps | inherit
+        return parseFontVariant(important);
+
+    case CSSPropertyVerticalAlign:
+        // baseline | sub | super | top | text-top | middle | bottom | text-bottom |
+        // <percentage> | <length> | inherit
+
+        if (id >= CSSValueBaseline && id <= CSSValueWebkitBaselineMiddle)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FLength | FPercent));
+        break;
+
+    case CSSPropertyBottom:               // <length> | <percentage> | auto | inherit
+    case CSSPropertyLeft:                 // <length> | <percentage> | auto | inherit
+    case CSSPropertyRight:                // <length> | <percentage> | auto | inherit
+    case CSSPropertyTop:                  // <length> | <percentage> | auto | inherit
+    case CSSPropertyMarginTop:           //// <margin-width> | inherit
+    case CSSPropertyMarginRight:         //   Which is defined as
+    case CSSPropertyMarginBottom:        //   <length> | <percentage> | auto | inherit
+    case CSSPropertyMarginLeft:          ////
+    case CSSPropertyWebkitMarginStart:
+    case CSSPropertyWebkitMarginEnd:
+    case CSSPropertyWebkitMarginBefore:
+    case CSSPropertyWebkitMarginAfter:
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FLength | FPercent));
+        break;
+
+    case CSSPropertyOrphans: // <integer> | inherit | auto (We've added support for auto for backwards compatibility)
+    case CSSPropertyWidows: // <integer> | inherit | auto (Ditto)
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FPositiveInteger, HTMLQuirksMode));
+        break;
+
+    case CSSPropertyZIndex: // auto | <integer> | inherit
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FInteger, HTMLQuirksMode));
+        break;
+
+    case CSSPropertyLineHeight:
+        return parseLineHeight(important);
+    case CSSPropertyCounterIncrement:    // [ <identifier> <integer>? ]+ | none | inherit
+        if (id != CSSValueNone)
+            return parseCounter(propId, 1, important);
+        validPrimitive = true;
+        break;
+    case CSSPropertyCounterReset:        // [ <identifier> <integer>? ]+ | none | inherit
+        if (id != CSSValueNone)
+            return parseCounter(propId, 0, important);
+        validPrimitive = true;
+        break;
+    case CSSPropertyFontFamily:
+        // [[ <family-name> | <generic-family> ],]* [<family-name> | <generic-family>] | inherit
+    {
+        parsedValue = parseFontFamily();
+        break;
+    }
+
+    case CSSPropertyTextDecoration:
+        // Fall through 'text-decoration-line' parsing if CSS 3 Text Decoration
+        // is disabled to match CSS 2.1 rules for parsing 'text-decoration'.
+        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()) {
+            // [ <text-decoration-line> || <text-decoration-style> || <text-decoration-color> ] | inherit
+            return parseShorthand(CSSPropertyTextDecoration, textDecorationShorthand(), important);
+        }
+    case CSSPropertyWebkitTextDecorationsInEffect:
+    case CSSPropertyTextDecorationLine:
+        // none | [ underline || overline || line-through || blink ] | inherit
+        return parseTextDecoration(propId, important);
+
+    case CSSPropertyTextDecorationStyle:
+        // solid | double | dotted | dashed | wavy
+        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled()
+            && (id == CSSValueSolid || id == CSSValueDouble || id == CSSValueDotted || id == CSSValueDashed || id == CSSValueWavy))
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyTextUnderlinePosition:
+        // auto | under | inherit
+        if (RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+            return parseTextUnderlinePosition(important);
+        return false;
+
+    case CSSPropertyZoom:          // normal | reset | document | <number> | <percentage> | inherit
+        if (id == CSSValueNormal || id == CSSValueReset || id == CSSValueDocument)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode));
+        break;
+
+    case CSSPropertySrc: // Only used within @font-face and @-webkit-filter, so cannot use inherit | initial or be !important. This is a list of urls or local references.
+        return parseFontFaceSrc();
+
+    case CSSPropertyUnicodeRange:
+        return parseFontFaceUnicodeRange();
+
+    /* CSS3 properties */
+
+    case CSSPropertyBorderImage:
+    case CSSPropertyWebkitMaskBoxImage:
+        return parseBorderImageShorthand(propId, important);
+    case CSSPropertyWebkitBorderImage: {
+        if (RefPtrWillBeRawPtr<CSSValue> result = parseBorderImage(propId)) {
+            addProperty(propId, result, important);
+            return true;
+        }
+        return false;
+    }
+
+    case CSSPropertyBorderImageOutset:
+    case CSSPropertyWebkitMaskBoxImageOutset: {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> result;
+        if (parseBorderImageOutset(result)) {
+            addProperty(propId, result, important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderImageRepeat:
+    case CSSPropertyWebkitMaskBoxImageRepeat: {
+        RefPtrWillBeRawPtr<CSSValue> result;
+        if (parseBorderImageRepeat(result)) {
+            addProperty(propId, result, important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderImageSlice:
+    case CSSPropertyWebkitMaskBoxImageSlice: {
+        RefPtrWillBeRawPtr<CSSBorderImageSliceValue> result;
+        if (parseBorderImageSlice(propId, result)) {
+            addProperty(propId, result, important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderImageWidth:
+    case CSSPropertyWebkitMaskBoxImageWidth: {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> result;
+        if (parseBorderImageWidth(result)) {
+            addProperty(propId, result, important);
+            return true;
+        }
+        break;
+    }
+    case CSSPropertyBorderTopRightRadius:
+    case CSSPropertyBorderTopLeftRadius:
+    case CSSPropertyBorderBottomLeftRadius:
+    case CSSPropertyBorderBottomRightRadius: {
+        if (num != 1 && num != 2)
+            return false;
+        validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
+        if (!validPrimitive)
+            return false;
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1 = createPrimitiveNumericValue(value);
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2;
+        if (num == 2) {
+            value = m_valueList->next();
+            validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
+            if (!validPrimitive)
+                return false;
+            parsedValue2 = createPrimitiveNumericValue(value);
+        } else
+            parsedValue2 = parsedValue1;
+
+        addProperty(propId, createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release()), important);
+        return true;
+    }
+    case CSSPropertyTabSize:
+        validPrimitive = validUnit(value, FInteger | FNonNeg);
+        break;
+    case CSSPropertyWebkitAspectRatio:
+        return parseAspectRatio(important);
+    case CSSPropertyBorderRadius:
+    case CSSPropertyWebkitBorderRadius:
+        return parseBorderRadius(propId, important);
+    case CSSPropertyOutlineOffset:
+        validPrimitive = validUnit(value, FLength);
+        break;
+    case CSSPropertyTextShadow: // CSS2 property, dropped in CSS2.1, back in CSS3, so treat as CSS3
+    case CSSPropertyBoxShadow:
+    case CSSPropertyWebkitBoxShadow:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(m_valueList.get(), propId);
+            if (shadowValueList) {
+                addProperty(propId, shadowValueList.release(), important);
+                m_valueList->next();
+                return true;
+            }
+            return false;
+        }
+        break;
+    case CSSPropertyWebkitBoxReflect:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else
+            return parseReflect(propId, important);
+        break;
+    case CSSPropertyOpacity:
+        validPrimitive = validUnit(value, FNumber);
+        break;
+    case CSSPropertyWebkitBoxFlex:
+        validPrimitive = validUnit(value, FNumber);
+        break;
+    case CSSPropertyWebkitBoxFlexGroup:
+        validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode);
+        break;
+    case CSSPropertyWebkitBoxOrdinalGroup:
+        validPrimitive = validUnit(value, FInteger | FNonNeg, HTMLStandardMode) && value->fValue;
+        break;
+    case CSSPropertyWebkitFilter:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            RefPtrWillBeRawPtr<CSSValue> val = parseFilter();
+            if (val) {
+                addProperty(propId, val, important);
+                return true;
+            }
+            return false;
+        }
+        break;
+    case CSSPropertyFlex: {
+        ShorthandScope scope(this, propId);
+        if (id == CSSValueNone) {
+            addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
+            addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER), important);
+            addProperty(CSSPropertyFlexBasis, cssValuePool().createIdentifierValue(CSSValueAuto), important);
+            return true;
+        }
+        return parseFlex(m_valueList.get(), important);
+    }
+    case CSSPropertyFlexBasis:
+        // FIXME: Support intrinsic dimensions too.
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+        break;
+    case CSSPropertyFlexGrow:
+    case CSSPropertyFlexShrink:
+        validPrimitive = validUnit(value, FNumber | FNonNeg);
+        break;
+    case CSSPropertyOrder:
+        validPrimitive = validUnit(value, FInteger, HTMLStandardMode);
+        break;
+    case CSSPropertyInternalMarqueeIncrement:
+        if (id == CSSValueSmall || id == CSSValueLarge || id == CSSValueMedium)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FLength | FPercent);
+        break;
+    case CSSPropertyInternalMarqueeRepetition:
+        if (id == CSSValueInfinite)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FInteger | FNonNeg);
+        break;
+    case CSSPropertyInternalMarqueeSpeed:
+        if (id == CSSValueNormal || id == CSSValueSlow || id == CSSValueFast)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FTime | FInteger | FNonNeg);
+        break;
+    case CSSPropertyWebkitTransform:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            RefPtrWillBeRawPtr<CSSValue> transformValue = parseTransform();
+            if (transformValue) {
+                addProperty(propId, transformValue.release(), important);
+                return true;
+            }
+            return false;
+        }
+        break;
+    case CSSPropertyWebkitTransformOrigin:
+    case CSSPropertyWebkitTransformOriginX:
+    case CSSPropertyWebkitTransformOriginY:
+    case CSSPropertyWebkitTransformOriginZ: {
+        RefPtrWillBeRawPtr<CSSValue> val1;
+        RefPtrWillBeRawPtr<CSSValue> val2;
+        RefPtrWillBeRawPtr<CSSValue> val3;
+        CSSPropertyID propId1, propId2, propId3;
+        if (parseTransformOrigin(propId, propId1, propId2, propId3, val1, val2, val3)) {
+            addProperty(propId1, val1.release(), important);
+            if (val2)
+                addProperty(propId2, val2.release(), important);
+            if (val3)
+                addProperty(propId3, val3.release(), important);
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyWebkitPerspective:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else {
+            // Accepting valueless numbers is a quirk of the -webkit prefixed version of the property.
+            if (validUnit(value, FNumber | FLength | FNonNeg)) {
+                RefPtrWillBeRawPtr<CSSValue> val = createPrimitiveNumericValue(value);
+                if (val) {
+                    addProperty(propId, val.release(), important);
+                    return true;
+                }
+                return false;
+            }
+        }
+        break;
+    case CSSPropertyWebkitPerspectiveOrigin:
+    case CSSPropertyWebkitPerspectiveOriginX:
+    case CSSPropertyWebkitPerspectiveOriginY: {
+        RefPtrWillBeRawPtr<CSSValue> val1;
+        RefPtrWillBeRawPtr<CSSValue> val2;
+        CSSPropertyID propId1, propId2;
+        if (parsePerspectiveOrigin(propId, propId1, propId2, val1, val2)) {
+            addProperty(propId1, val1.release(), important);
+            if (val2)
+                addProperty(propId2, val2.release(), important);
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyAnimationDelay:
+    case CSSPropertyAnimationDirection:
+    case CSSPropertyAnimationDuration:
+    case CSSPropertyAnimationFillMode:
+    case CSSPropertyAnimationName:
+    case CSSPropertyAnimationPlayState:
+    case CSSPropertyAnimationIterationCount:
+    case CSSPropertyAnimationTimingFunction:
+        if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
+            break;
+    case CSSPropertyWebkitAnimationDelay:
+    case CSSPropertyWebkitAnimationDirection:
+    case CSSPropertyWebkitAnimationDuration:
+    case CSSPropertyWebkitAnimationFillMode:
+    case CSSPropertyWebkitAnimationName:
+    case CSSPropertyWebkitAnimationPlayState:
+    case CSSPropertyWebkitAnimationIterationCount:
+    case CSSPropertyWebkitAnimationTimingFunction:
+    case CSSPropertyTransitionDelay:
+    case CSSPropertyTransitionDuration:
+    case CSSPropertyTransitionTimingFunction:
+    case CSSPropertyTransitionProperty:
+    case CSSPropertyWebkitTransitionDelay:
+    case CSSPropertyWebkitTransitionDuration:
+    case CSSPropertyWebkitTransitionTimingFunction:
+    case CSSPropertyWebkitTransitionProperty: {
+        RefPtrWillBeRawPtr<CSSValue> val;
+        AnimationParseContext context;
+        if (parseAnimationProperty(propId, val, context)) {
+            addPropertyWithPrefixingVariant(propId, val.release(), important);
+            return true;
+        }
+        return false;
+    }
+
+    case CSSPropertyJustifySelf:
+        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+            return false;
+
+        return parseItemPositionOverflowPosition(propId, important);
+    case CSSPropertyGridAutoColumns:
+    case CSSPropertyGridAutoRows:
+        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridTrackSize(*m_valueList);
+        break;
+
+    case CSSPropertyGridTemplateColumns:
+    case CSSPropertyGridTemplateRows:
+        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+            return false;
+        return parseGridTrackList(propId, important);
+
+    case CSSPropertyGridColumnEnd:
+    case CSSPropertyGridColumnStart:
+    case CSSPropertyGridRowEnd:
+    case CSSPropertyGridRowStart:
+        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridPosition();
+        break;
+
+    case CSSPropertyGridColumn:
+    case CSSPropertyGridRow:
+        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+            return false;
+        return parseGridItemPositionShorthand(propId, important);
+
+    case CSSPropertyGridArea:
+        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+            return false;
+        return parseGridAreaShorthand(important);
+
+    case CSSPropertyGridTemplateAreas:
+        if (!RuntimeEnabledFeatures::cssGridLayoutEnabled())
+            return false;
+        parsedValue = parseGridTemplateAreas();
+        break;
+
+    case CSSPropertyWebkitMarginCollapse: {
+        if (num == 1) {
+            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
+            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important))
+                return false;
+            CSSValue* value = m_parsedProperties.last().value();
+            addProperty(webkitMarginCollapseShorthand().properties()[1], value, important);
+            return true;
+        }
+        else if (num == 2) {
+            ShorthandScope scope(this, CSSPropertyWebkitMarginCollapse);
+            if (!parseValue(webkitMarginCollapseShorthand().properties()[0], important) || !parseValue(webkitMarginCollapseShorthand().properties()[1], important))
+                return false;
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyTextLineThroughWidth:
+    case CSSPropertyTextOverlineWidth:
+    case CSSPropertyTextUnderlineWidth:
+        if (id == CSSValueAuto || id == CSSValueNormal || id == CSSValueThin ||
+            id == CSSValueMedium || id == CSSValueThick)
+            validPrimitive = true;
+        else
+            validPrimitive = !id && validUnit(value, FNumber | FLength | FPercent);
+        break;
+    case CSSPropertyWebkitColumnCount:
+        parsedValue = parseColumnCount();
+        break;
+    case CSSPropertyWebkitColumnGap:         // normal | <length>
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FLength | FNonNeg);
+        break;
+    case CSSPropertyWebkitColumnAxis:
+        if (id == CSSValueHorizontal || id == CSSValueVertical || id == CSSValueAuto)
+            validPrimitive = true;
+        break;
+    case CSSPropertyWebkitColumnProgression:
+        if (id == CSSValueNormal || id == CSSValueReverse)
+            validPrimitive = true;
+        break;
+    case CSSPropertyWebkitColumnSpan: // none | all | 1 (will be dropped in the unprefixed property)
+        if (id == CSSValueAll || id == CSSValueNone)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FNumber | FNonNeg) && value->fValue == 1;
+        break;
+    case CSSPropertyWebkitColumnWidth:         // auto | <length>
+        parsedValue = parseColumnWidth();
+        break;
+    case CSSPropertyWillChange:
+        if (!RuntimeEnabledFeatures::cssWillChangeEnabled())
+            return false;
+        return parseWillChange(important);
+    // End of CSS3 properties
+
+    // Apple specific properties.  These will never be standardized and are purely to
+    // support custom WebKit-based Apple applications.
+    case CSSPropertyWebkitLineClamp:
+        // When specifying number of lines, don't allow 0 as a valid value
+        // When specifying either type of unit, require non-negative integers
+        validPrimitive = (!id && (value->unit == CSSPrimitiveValue::CSS_PERCENTAGE || value->fValue) && validUnit(value, FInteger | FPercent | FNonNeg, HTMLQuirksMode));
+        break;
+
+    case CSSPropertyWebkitFontSizeDelta:           // <length>
+        validPrimitive = validUnit(value, FLength);
+        break;
+
+    case CSSPropertyWebkitHighlight:
+        if (id == CSSValueNone || value->unit == CSSPrimitiveValue::CSS_STRING)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitHyphenateCharacter:
+        if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitLocale:
+        if (id == CSSValueAuto || value->unit == CSSPrimitiveValue::CSS_STRING)
+            validPrimitive = true;
+        break;
+
+    // End Apple-specific properties
+
+    case CSSPropertyWebkitAppRegion:
+        if (id >= CSSValueDrag && id <= CSSValueNoDrag)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitTapHighlightColor:
+        if ((id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu
+            || (id >= CSSValueWebkitFocusRingColor && id < CSSValueWebkitText && inQuirksMode())) {
+            validPrimitive = true;
+        } else {
+            parsedValue = parseColor();
+            if (parsedValue)
+                m_valueList->next();
+        }
+        break;
+
+        /* shorthand properties */
+    case CSSPropertyBackground: {
+        // Position must come before color in this array because a plain old "0" is a legal color
+        // in quirks mode but it's usually the X coordinate of a position.
+        const CSSPropertyID properties[] = { CSSPropertyBackgroundImage, CSSPropertyBackgroundRepeat,
+                                   CSSPropertyBackgroundAttachment, CSSPropertyBackgroundPosition, CSSPropertyBackgroundOrigin,
+                                   CSSPropertyBackgroundClip, CSSPropertyBackgroundColor, CSSPropertyBackgroundSize };
+        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
+    }
+    case CSSPropertyWebkitMask: {
+        const CSSPropertyID properties[] = { CSSPropertyWebkitMaskImage, CSSPropertyWebkitMaskRepeat,
+            CSSPropertyWebkitMaskPosition, CSSPropertyWebkitMaskOrigin, CSSPropertyWebkitMaskClip, CSSPropertyWebkitMaskSize };
+        return parseFillShorthand(propId, properties, WTF_ARRAY_LENGTH(properties), important);
+    }
+    case CSSPropertyBorder:
+        // [ 'border-width' || 'border-style' || <color> ] | inherit
+    {
+        if (parseShorthand(propId, parsingShorthandForProperty(CSSPropertyBorder), important)) {
+            // The CSS3 Borders and Backgrounds specification says that border also resets border-image. It's as
+            // though a value of none was specified for the image.
+            addExpandedPropertyForValue(CSSPropertyBorderImage, cssValuePool().createImplicitInitialValue(), important);
+            return true;
+        }
+        return false;
+    }
+    case CSSPropertyBorderTop:
+        // [ 'border-top-width' || 'border-style' || <color> ] | inherit
+        return parseShorthand(propId, borderTopShorthand(), important);
+    case CSSPropertyBorderRight:
+        // [ 'border-right-width' || 'border-style' || <color> ] | inherit
+        return parseShorthand(propId, borderRightShorthand(), important);
+    case CSSPropertyBorderBottom:
+        // [ 'border-bottom-width' || 'border-style' || <color> ] | inherit
+        return parseShorthand(propId, borderBottomShorthand(), important);
+    case CSSPropertyBorderLeft:
+        // [ 'border-left-width' || 'border-style' || <color> ] | inherit
+        return parseShorthand(propId, borderLeftShorthand(), important);
+    case CSSPropertyWebkitBorderStart:
+        return parseShorthand(propId, webkitBorderStartShorthand(), important);
+    case CSSPropertyWebkitBorderEnd:
+        return parseShorthand(propId, webkitBorderEndShorthand(), important);
+    case CSSPropertyWebkitBorderBefore:
+        return parseShorthand(propId, webkitBorderBeforeShorthand(), important);
+    case CSSPropertyWebkitBorderAfter:
+        return parseShorthand(propId, webkitBorderAfterShorthand(), important);
+    case CSSPropertyOutline:
+        // [ 'outline-color' || 'outline-style' || 'outline-width' ] | inherit
+        return parseShorthand(propId, outlineShorthand(), important);
+    case CSSPropertyBorderColor:
+        // <color>{1,4} | inherit
+        return parse4Values(propId, borderColorShorthand().properties(), important);
+    case CSSPropertyBorderWidth:
+        // <border-width>{1,4} | inherit
+        return parse4Values(propId, borderWidthShorthand().properties(), important);
+    case CSSPropertyBorderStyle:
+        // <border-style>{1,4} | inherit
+        return parse4Values(propId, borderStyleShorthand().properties(), important);
+    case CSSPropertyMargin:
+        // <margin-width>{1,4} | inherit
+        return parse4Values(propId, marginShorthand().properties(), important);
+    case CSSPropertyPadding:
+        // <padding-width>{1,4} | inherit
+        return parse4Values(propId, paddingShorthand().properties(), important);
+    case CSSPropertyFlexFlow:
+        return parseShorthand(propId, flexFlowShorthand(), important);
+    case CSSPropertyFont:
+        // [ [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]?
+        // 'font-family' ] | caption | icon | menu | message-box | small-caption | status-bar | inherit
+        if (id >= CSSValueCaption && id <= CSSValueStatusBar)
+            validPrimitive = true;
+        else
+            return parseFont(important);
+        break;
+    case CSSPropertyListStyle:
+        return parseShorthand(propId, listStyleShorthand(), important);
+    case CSSPropertyWebkitColumns:
+        return parseColumnsShorthand(important);
+    case CSSPropertyWebkitColumnRule:
+        return parseShorthand(propId, webkitColumnRuleShorthand(), important);
+    case CSSPropertyWebkitTextStroke:
+        return parseShorthand(propId, webkitTextStrokeShorthand(), important);
+    case CSSPropertyAnimation:
+        if (!RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
+            break;
+    case CSSPropertyWebkitAnimation:
+        return parseAnimationShorthand(propId, important);
+    case CSSPropertyTransition:
+    case CSSPropertyWebkitTransition:
+        return parseTransitionShorthand(propId, important);
+    case CSSPropertyInvalid:
+        return false;
+    case CSSPropertyPage:
+        return parsePage(propId, important);
+    case CSSPropertyFontStretch:
+        return false;
+    // CSS Text Layout Module Level 3: Vertical writing support
+    case CSSPropertyWebkitTextEmphasis:
+        return parseShorthand(propId, webkitTextEmphasisShorthand(), important);
+
+    case CSSPropertyWebkitTextEmphasisStyle:
+        return parseTextEmphasisStyle(important);
+
+    case CSSPropertyWebkitTextOrientation:
+        // FIXME: For now just support sideways, sideways-right, upright and vertical-right.
+        if (id == CSSValueSideways || id == CSSValueSidewaysRight || id == CSSValueVerticalRight || id == CSSValueUpright)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWebkitLineBoxContain:
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else
+            return parseLineBoxContain(important);
+        break;
+    case CSSPropertyWebkitFontFeatureSettings:
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            return parseFontFeatureSettings(important);
+        break;
+
+    case CSSPropertyFontVariantLigatures:
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            return parseFontVariantLigatures(important);
+        break;
+    case CSSPropertyWebkitClipPath:
+        if (id == CSSValueNone) {
+            validPrimitive = true;
+        } else if (value->unit == CSSParserValue::Function) {
+            parsedValue = parseBasicShape();
+        } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+            parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
+            addProperty(propId, parsedValue.release(), important);
+            return true;
+        }
+        break;
+    case CSSPropertyShapeInside:
+    case CSSPropertyShapeOutside:
+        parsedValue = parseShapeProperty(propId);
+        break;
+    case CSSPropertyShapeMargin:
+    case CSSPropertyShapePadding:
+        validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FLength | FNonNeg));
+        break;
+    case CSSPropertyShapeImageThreshold:
+        validPrimitive = (RuntimeEnabledFeatures::cssShapesEnabled() && !id && validUnit(value, FNumber));
+        break;
+
+    case CSSPropertyTouchAction:
+        // auto | none | [pan-x || pan-y] | manipulation
+        return parseTouchAction(important);
+
+    case CSSPropertyAlignSelf:
+        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+        return parseItemPositionOverflowPosition(propId, important);
+
+    case CSSPropertyAlignItems:
+        ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+        return parseItemPositionOverflowPosition(propId, important);
+
+    case CSSPropertyBorderBottomStyle:
+    case CSSPropertyBorderCollapse:
+    case CSSPropertyBorderLeftStyle:
+    case CSSPropertyBorderRightStyle:
+    case CSSPropertyBorderTopStyle:
+    case CSSPropertyBoxSizing:
+    case CSSPropertyCaptionSide:
+    case CSSPropertyClear:
+    case CSSPropertyDirection:
+    case CSSPropertyDisplay:
+    case CSSPropertyEmptyCells:
+    case CSSPropertyFloat:
+    case CSSPropertyFontStyle:
+    case CSSPropertyImageRendering:
+    case CSSPropertyListStylePosition:
+    case CSSPropertyListStyleType:
+    case CSSPropertyObjectFit:
+    case CSSPropertyOutlineStyle:
+    case CSSPropertyOverflowWrap:
+    case CSSPropertyOverflowX:
+    case CSSPropertyOverflowY:
+    case CSSPropertyPageBreakAfter:
+    case CSSPropertyPageBreakBefore:
+    case CSSPropertyPageBreakInside:
+    case CSSPropertyPointerEvents:
+    case CSSPropertyPosition:
+    case CSSPropertyResize:
+    case CSSPropertySpeak:
+    case CSSPropertyTableLayout:
+    case CSSPropertyTextAlignLast:
+    case CSSPropertyTextJustify:
+    case CSSPropertyTextLineThroughMode:
+    case CSSPropertyTextLineThroughStyle:
+    case CSSPropertyTextOverflow:
+    case CSSPropertyTextOverlineMode:
+    case CSSPropertyTextOverlineStyle:
+    case CSSPropertyTextRendering:
+    case CSSPropertyTextTransform:
+    case CSSPropertyTextUnderlineMode:
+    case CSSPropertyTextUnderlineStyle:
+    case CSSPropertyTouchActionDelay:
+    case CSSPropertyVisibility:
+    case CSSPropertyWebkitAppearance:
+    case CSSPropertyWebkitBackfaceVisibility:
+    case CSSPropertyWebkitBorderAfterStyle:
+    case CSSPropertyWebkitBorderBeforeStyle:
+    case CSSPropertyWebkitBorderEndStyle:
+    case CSSPropertyWebkitBorderFit:
+    case CSSPropertyWebkitBorderStartStyle:
+    case CSSPropertyWebkitBoxAlign:
+    case CSSPropertyWebkitBoxDecorationBreak:
+    case CSSPropertyWebkitBoxDirection:
+    case CSSPropertyWebkitBoxLines:
+    case CSSPropertyWebkitBoxOrient:
+    case CSSPropertyWebkitBoxPack:
+    case CSSPropertyInternalCallback:
+    case CSSPropertyWebkitColumnBreakAfter:
+    case CSSPropertyWebkitColumnBreakBefore:
+    case CSSPropertyWebkitColumnBreakInside:
+    case CSSPropertyColumnFill:
+    case CSSPropertyWebkitColumnRuleStyle:
+    case CSSPropertyAlignContent:
+    case CSSPropertyFlexDirection:
+    case CSSPropertyFlexWrap:
+    case CSSPropertyJustifyContent:
+    case CSSPropertyFontKerning:
+    case CSSPropertyWebkitFontSmoothing:
+    case CSSPropertyGridAutoFlow:
+    case CSSPropertyWebkitLineBreak:
+    case CSSPropertyWebkitMarginAfterCollapse:
+    case CSSPropertyWebkitMarginBeforeCollapse:
+    case CSSPropertyWebkitMarginBottomCollapse:
+    case CSSPropertyWebkitMarginTopCollapse:
+    case CSSPropertyInternalMarqueeDirection:
+    case CSSPropertyInternalMarqueeStyle:
+    case CSSPropertyWebkitPrintColorAdjust:
+    case CSSPropertyWebkitRtlOrdering:
+    case CSSPropertyWebkitRubyPosition:
+    case CSSPropertyWebkitTextCombine:
+    case CSSPropertyWebkitTextEmphasisPosition:
+    case CSSPropertyWebkitTextSecurity:
+    case CSSPropertyWebkitTransformStyle:
+    case CSSPropertyWebkitUserDrag:
+    case CSSPropertyWebkitUserModify:
+    case CSSPropertyWebkitUserSelect:
+    case CSSPropertyWebkitWrapFlow:
+    case CSSPropertyWebkitWrapThrough:
+    case CSSPropertyWebkitWritingMode:
+    case CSSPropertyWhiteSpace:
+    case CSSPropertyWordBreak:
+    case CSSPropertyWordWrap:
+    case CSSPropertyMixBlendMode:
+    case CSSPropertyIsolation:
+        // These properties should be handled before in isValidKeywordPropertyAndValue().
+        ASSERT_NOT_REACHED();
+        return false;
+    // Properties below are validated inside parseViewportProperty, because we
+    // check for parser state. We need to invalidate if someone adds them outside
+    // a @viewport rule.
+    case CSSPropertyMaxZoom:
+    case CSSPropertyMinZoom:
+    case CSSPropertyOrientation:
+    case CSSPropertyUserZoom:
+        validPrimitive = false;
+        break;
+    default:
+        return parseSVGValue(propId, important);
+    }
+
+    if (validPrimitive) {
+        parsedValue = parseValidPrimitive(id, value);
+        m_valueList->next();
+    }
+    ASSERT(!m_parsedCalculation);
+    if (parsedValue) {
+        if (!m_valueList->current() || inShorthand()) {
+            addProperty(propId, parsedValue.release(), important);
+            return true;
+        }
+    }
+    return false;
+}
+
+void CSSPropertyParser::addFillValue(RefPtrWillBeRawPtr<CSSValue>& lval, PassRefPtrWillBeRawPtr<CSSValue> rval)
+{
+    if (lval) {
+        if (lval->isBaseValueList())
+            toCSSValueList(lval.get())->append(rval);
+        else {
+            PassRefPtrWillBeRawPtr<CSSValue> oldlVal(lval.release());
+            PassRefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+            list->append(oldlVal);
+            list->append(rval);
+            lval = list;
+        }
+    }
+    else
+        lval = rval;
+}
+
+static bool parseBackgroundClip(CSSParserValue* parserValue, RefPtrWillBeRawPtr<CSSValue>& cssValue)
+{
+    if (parserValue->id == CSSValueBorderBox || parserValue->id == CSSValuePaddingBox
+        || parserValue->id == CSSValueContentBox || parserValue->id == CSSValueWebkitText) {
+        cssValue = cssValuePool().createIdentifierValue(parserValue->id);
+        return true;
+    }
+    return false;
+}
+
+const int cMaxFillProperties = 9;
+
+bool CSSPropertyParser::parseFillShorthand(CSSPropertyID propId, const CSSPropertyID* properties, int numProperties, bool important)
+{
+    ASSERT(numProperties <= cMaxFillProperties);
+    if (numProperties > cMaxFillProperties)
+        return false;
+
+    ShorthandScope scope(this, propId);
+
+    bool parsedProperty[cMaxFillProperties] = { false };
+    RefPtrWillBeRawPtr<CSSValue> values[cMaxFillProperties];
+    RefPtrWillBeRawPtr<CSSValue> clipValue;
+    RefPtrWillBeRawPtr<CSSValue> positionYValue;
+    RefPtrWillBeRawPtr<CSSValue> repeatYValue;
+    bool foundClip = false;
+    int i;
+    bool foundPositionCSSProperty = false;
+
+    while (m_valueList->current()) {
+        CSSParserValue* val = m_valueList->current();
+        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+            // We hit the end.  Fill in all remaining values with the initial value.
+            m_valueList->next();
+            for (i = 0; i < numProperties; ++i) {
+                if (properties[i] == CSSPropertyBackgroundColor && parsedProperty[i])
+                    // Color is not allowed except as the last item in a list for backgrounds.
+                    // Reject the entire property.
+                    return false;
+
+                if (!parsedProperty[i] && properties[i] != CSSPropertyBackgroundColor) {
+                    addFillValue(values[i], cssValuePool().createImplicitInitialValue());
+                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                        addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
+                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+                        addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
+                    if ((properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) && !parsedProperty[i]) {
+                        // If background-origin wasn't present, then reset background-clip also.
+                        addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
+                    }
+                }
+                parsedProperty[i] = false;
+            }
+            if (!m_valueList->current())
+                break;
+        }
+
+        bool sizeCSSPropertyExpected = false;
+        if (isForwardSlashOperator(val) && foundPositionCSSProperty) {
+            sizeCSSPropertyExpected = true;
+            m_valueList->next();
+        }
+
+        foundPositionCSSProperty = false;
+        bool found = false;
+        for (i = 0; !found && i < numProperties; ++i) {
+
+            if (sizeCSSPropertyExpected && (properties[i] != CSSPropertyBackgroundSize && properties[i] != CSSPropertyWebkitMaskSize))
+                continue;
+            if (!sizeCSSPropertyExpected && (properties[i] == CSSPropertyBackgroundSize || properties[i] == CSSPropertyWebkitMaskSize))
+                continue;
+
+            if (!parsedProperty[i]) {
+                RefPtrWillBeRawPtr<CSSValue> val1;
+                RefPtrWillBeRawPtr<CSSValue> val2;
+                CSSPropertyID propId1, propId2;
+                CSSParserValue* parserValue = m_valueList->current();
+                // parseFillProperty() may modify m_implicitShorthand, so we MUST reset it
+                // before EACH return below.
+                if (parseFillProperty(properties[i], propId1, propId2, val1, val2)) {
+                    parsedProperty[i] = found = true;
+                    addFillValue(values[i], val1.release());
+                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                        addFillValue(positionYValue, val2.release());
+                    if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+                        addFillValue(repeatYValue, val2.release());
+                    if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
+                        // Reparse the value as a clip, and see if we succeed.
+                        if (parseBackgroundClip(parserValue, val1))
+                            addFillValue(clipValue, val1.release()); // The property parsed successfully.
+                        else
+                            addFillValue(clipValue, cssValuePool().createImplicitInitialValue()); // Some value was used for origin that is not supported by clip. Just reset clip instead.
+                    }
+                    if (properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) {
+                        // Update clipValue
+                        addFillValue(clipValue, val1.release());
+                        foundClip = true;
+                    }
+                    if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                        foundPositionCSSProperty = true;
+                }
+            }
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found) {
+            m_implicitShorthand = false;
+            return false;
+        }
+    }
+
+    // Now add all of the properties we found.
+    for (i = 0; i < numProperties; i++) {
+        // Fill in any remaining properties with the initial value.
+        if (!parsedProperty[i]) {
+            addFillValue(values[i], cssValuePool().createImplicitInitialValue());
+            if (properties[i] == CSSPropertyBackgroundPosition || properties[i] == CSSPropertyWebkitMaskPosition)
+                addFillValue(positionYValue, cssValuePool().createImplicitInitialValue());
+            if (properties[i] == CSSPropertyBackgroundRepeat || properties[i] == CSSPropertyWebkitMaskRepeat)
+                addFillValue(repeatYValue, cssValuePool().createImplicitInitialValue());
+            if (properties[i] == CSSPropertyBackgroundOrigin || properties[i] == CSSPropertyWebkitMaskOrigin) {
+                // If background-origin wasn't present, then reset background-clip also.
+                addFillValue(clipValue, cssValuePool().createImplicitInitialValue());
+            }
+        }
+        if (properties[i] == CSSPropertyBackgroundPosition) {
+            addProperty(CSSPropertyBackgroundPositionX, values[i].release(), important);
+            // it's OK to call positionYValue.release() since we only see CSSPropertyBackgroundPosition once
+            addProperty(CSSPropertyBackgroundPositionY, positionYValue.release(), important);
+        } else if (properties[i] == CSSPropertyWebkitMaskPosition) {
+            addProperty(CSSPropertyWebkitMaskPositionX, values[i].release(), important);
+            // it's OK to call positionYValue.release() since we only see CSSPropertyWebkitMaskPosition once
+            addProperty(CSSPropertyWebkitMaskPositionY, positionYValue.release(), important);
+        } else if (properties[i] == CSSPropertyBackgroundRepeat) {
+            addProperty(CSSPropertyBackgroundRepeatX, values[i].release(), important);
+            // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
+            addProperty(CSSPropertyBackgroundRepeatY, repeatYValue.release(), important);
+        } else if (properties[i] == CSSPropertyWebkitMaskRepeat) {
+            addProperty(CSSPropertyWebkitMaskRepeatX, values[i].release(), important);
+            // it's OK to call repeatYValue.release() since we only see CSSPropertyBackgroundPosition once
+            addProperty(CSSPropertyWebkitMaskRepeatY, repeatYValue.release(), important);
+        } else if ((properties[i] == CSSPropertyBackgroundClip || properties[i] == CSSPropertyWebkitMaskClip) && !foundClip)
+            // Value is already set while updating origin
+            continue;
+        else if (properties[i] == CSSPropertyBackgroundSize && !parsedProperty[i] && m_context.useLegacyBackgroundSizeShorthandBehavior())
+            continue;
+        else
+            addProperty(properties[i], values[i].release(), important);
+
+        // Add in clip values when we hit the corresponding origin property.
+        if (properties[i] == CSSPropertyBackgroundOrigin && !foundClip)
+            addProperty(CSSPropertyBackgroundClip, clipValue.release(), important);
+        else if (properties[i] == CSSPropertyWebkitMaskOrigin && !foundClip)
+            addProperty(CSSPropertyWebkitMaskClip, clipValue.release(), important);
+    }
+
+    m_implicitShorthand = false;
+    return true;
+}
+
+void CSSPropertyParser::addAnimationValue(RefPtrWillBeRawPtr<CSSValue>& lval, PassRefPtrWillBeRawPtr<CSSValue> rval)
+{
+    if (lval) {
+        if (lval->isValueList())
+            toCSSValueList(lval.get())->append(rval);
+        else {
+            PassRefPtrWillBeRawPtr<CSSValue> oldVal(lval.release());
+            PassRefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+            list->append(oldVal);
+            list->append(rval);
+            lval = list;
+        }
+    }
+    else
+        lval = rval;
+}
+
+bool CSSPropertyParser::parseAnimationShorthand(CSSPropertyID propId, bool important)
+{
+    const StylePropertyShorthand& animationProperties = parsingShorthandForProperty(propId);
+    const unsigned numProperties = 8;
+
+    // The list of properties in the shorthand should be the same
+    // length as the list with animation name in last position, even though they are
+    // in a different order.
+    ASSERT(numProperties == animationProperties.length());
+    ASSERT(numProperties == shorthandForProperty(propId).length());
+
+    ShorthandScope scope(this, propId);
+
+    bool parsedProperty[numProperties] = { false };
+    AnimationParseContext context;
+    RefPtrWillBeRawPtr<CSSValue> values[numProperties];
+
+    unsigned i;
+    while (m_valueList->current()) {
+        CSSParserValue* val = m_valueList->current();
+        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+            // We hit the end.  Fill in all remaining values with the initial value.
+            m_valueList->next();
+            for (i = 0; i < numProperties; ++i) {
+                if (!parsedProperty[i])
+                    addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
+                parsedProperty[i] = false;
+            }
+            if (!m_valueList->current())
+                break;
+            context.commitFirstAnimation();
+        }
+
+        bool found = false;
+        for (i = 0; i < numProperties; ++i) {
+            if (!parsedProperty[i]) {
+                RefPtrWillBeRawPtr<CSSValue> val;
+                if (parseAnimationProperty(animationProperties.properties()[i], val, context)) {
+                    parsedProperty[i] = found = true;
+                    addAnimationValue(values[i], val.release());
+                    break;
+                }
+            }
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found)
+            return false;
+    }
+
+    for (i = 0; i < numProperties; ++i) {
+        // If we didn't find the property, set an intial value.
+        if (!parsedProperty[i])
+            addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
+
+        if (RuntimeEnabledFeatures::cssAnimationUnprefixedEnabled())
+            addPropertyWithPrefixingVariant(animationProperties.properties()[i], values[i].release(), important);
+        else
+            addProperty(animationProperties.properties()[i], values[i].release(), important);
+    }
+
+    return true;
+}
+
+bool CSSPropertyParser::parseTransitionShorthand(CSSPropertyID propId, bool important)
+{
+    const unsigned numProperties = 4;
+    const StylePropertyShorthand& shorthand = shorthandForProperty(propId);
+    ASSERT(numProperties == shorthand.length());
+
+    ShorthandScope scope(this, propId);
+
+    bool parsedProperty[numProperties] = { false };
+    AnimationParseContext context;
+    RefPtrWillBeRawPtr<CSSValue> values[numProperties];
+
+    unsigned i;
+    while (m_valueList->current()) {
+        CSSParserValue* val = m_valueList->current();
+        if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+            // We hit the end. Fill in all remaining values with the initial value.
+            m_valueList->next();
+            for (i = 0; i < numProperties; ++i) {
+                if (!parsedProperty[i])
+                    addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
+                parsedProperty[i] = false;
+            }
+            if (!m_valueList->current())
+                break;
+            context.commitFirstAnimation();
+        }
+
+        bool found = false;
+        for (i = 0; !found && i < numProperties; ++i) {
+            if (!parsedProperty[i]) {
+                RefPtrWillBeRawPtr<CSSValue> val;
+                if (parseAnimationProperty(shorthand.properties()[i], val, context)) {
+                    parsedProperty[i] = found = true;
+                    addAnimationValue(values[i], val.release());
+                }
+
+                // There are more values to process but 'none' or 'all' were already defined as the animation property, the declaration becomes invalid.
+                if (!context.animationPropertyKeywordAllowed() && context.hasCommittedFirstAnimation())
+                    return false;
+            }
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found)
+            return false;
+    }
+
+    // Fill in any remaining properties with the initial value.
+    for (i = 0; i < numProperties; ++i) {
+        if (!parsedProperty[i])
+            addAnimationValue(values[i], cssValuePool().createImplicitInitialValue());
+    }
+
+    // Now add all of the properties we found.
+    for (i = 0; i < numProperties; i++)
+        addPropertyWithPrefixingVariant(shorthand.properties()[i], values[i].release(), important);
+
+    return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseColumnWidth()
+{
+    CSSParserValue* value = m_valueList->current();
+    // Always parse lengths in strict mode here, since it would be ambiguous otherwise when used in
+    // the 'columns' shorthand property.
+    if (value->id == CSSValueAuto
+        || (validUnit(value, FLength | FNonNeg, HTMLStandardMode) && value->fValue)) {
+        RefPtrWillBeRawPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
+        m_valueList->next();
+        return parsedValue;
+    }
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseColumnCount()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueAuto
+        || (!value->id && validUnit(value, FPositiveInteger, HTMLQuirksMode))) {
+        RefPtrWillBeRawPtr<CSSValue> parsedValue = parseValidPrimitive(value->id, value);
+        m_valueList->next();
+        return parsedValue;
+    }
+    return nullptr;
+}
+
+bool CSSPropertyParser::parseColumnsShorthand(bool important)
+{
+    RefPtrWillBeRawPtr<CSSValue> columnWidth;
+    RefPtrWillBeRawPtr<CSSValue> columnCount;
+    bool hasPendingExplicitAuto = false;
+
+    for (unsigned propertiesParsed = 0; CSSParserValue* value = m_valueList->current(); propertiesParsed++) {
+        if (propertiesParsed >= 2)
+            return false; // Too many values for this shorthand. Invalid declaration.
+        if (!propertiesParsed && value->id == CSSValueAuto) {
+            // 'auto' is a valid value for any of the two longhands, and at this point we
+            // don't know which one(s) it is meant for. We need to see if there are other
+            // values first.
+            m_valueList->next();
+            hasPendingExplicitAuto = true;
+        } else {
+            if (!columnWidth) {
+                if ((columnWidth = parseColumnWidth()))
+                    continue;
+            }
+            if (!columnCount) {
+                if ((columnCount = parseColumnCount()))
+                    continue;
+            }
+            // If we didn't find at least one match, this is an
+            // invalid shorthand and we have to ignore it.
+            return false;
+        }
+    }
+    if (hasPendingExplicitAuto) {
+        // Time to assign the previously skipped 'auto' value to a property. If both properties are
+        // unassigned at this point (i.e. 'columns:auto'), it doesn't matter that much which one we
+        // set (although it does make a slight difference to web-inspector). The one we don't set
+        // here will get an implicit 'auto' value further down.
+        if (!columnWidth) {
+            columnWidth = cssValuePool().createIdentifierValue(CSSValueAuto);
+        } else {
+            ASSERT(!columnCount);
+            columnCount = cssValuePool().createIdentifierValue(CSSValueAuto);
+        }
+    }
+    ASSERT(columnCount || columnWidth);
+
+    // Any unassigned property at this point will become implicit 'auto'.
+    if (columnWidth)
+        addProperty(CSSPropertyWebkitColumnWidth, columnWidth, important);
+    else
+        addProperty(CSSPropertyWebkitColumnWidth, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
+    if (columnCount)
+        addProperty(CSSPropertyWebkitColumnCount, columnCount, important);
+    else
+        addProperty(CSSPropertyWebkitColumnCount, cssValuePool().createIdentifierValue(CSSValueAuto), important, true /* implicit */);
+    return true;
+}
+
+bool CSSPropertyParser::parseShorthand(CSSPropertyID propId, const StylePropertyShorthand& shorthand, bool important)
+{
+    // We try to match as many properties as possible
+    // We set up an array of booleans to mark which property has been found,
+    // and we try to search for properties until it makes no longer any sense.
+    ShorthandScope scope(this, propId);
+
+    bool found = false;
+    unsigned propertiesParsed = 0;
+    bool propertyFound[6] = { false, false, false, false, false, false }; // 6 is enough size.
+
+    while (m_valueList->current()) {
+        found = false;
+        for (unsigned propIndex = 0; !found && propIndex < shorthand.length(); ++propIndex) {
+            if (!propertyFound[propIndex] && parseValue(shorthand.properties()[propIndex], important)) {
+                propertyFound[propIndex] = found = true;
+                propertiesParsed++;
+            }
+        }
+
+        // if we didn't find at least one match, this is an
+        // invalid shorthand and we have to ignore it
+        if (!found)
+            return false;
+    }
+
+    if (propertiesParsed == shorthand.length())
+        return true;
+
+    // Fill in any remaining properties with the initial value.
+    ImplicitScope implicitScope(this, PropertyImplicit);
+    const StylePropertyShorthand* const* const propertiesForInitialization = shorthand.propertiesForInitialization();
+    for (unsigned i = 0; i < shorthand.length(); ++i) {
+        if (propertyFound[i])
+            continue;
+
+        if (propertiesForInitialization) {
+            const StylePropertyShorthand& initProperties = *(propertiesForInitialization[i]);
+            for (unsigned propIndex = 0; propIndex < initProperties.length(); ++propIndex)
+                addProperty(initProperties.properties()[propIndex], cssValuePool().createImplicitInitialValue(), important);
+        } else
+            addProperty(shorthand.properties()[i], cssValuePool().createImplicitInitialValue(), important);
+    }
+
+    return true;
+}
+
+bool CSSPropertyParser::parse4Values(CSSPropertyID propId, const CSSPropertyID *properties,  bool important)
+{
+    /* From the CSS 2 specs, 8.3
+     * If there is only one value, it applies to all sides. If there are two values, the top and
+     * bottom margins are set to the first value and the right and left margins are set to the second.
+     * If there are three values, the top is set to the first value, the left and right are set to the
+     * second, and the bottom is set to the third. If there are four values, they apply to the top,
+     * right, bottom, and left, respectively.
+     */
+
+    int num = inShorthand() ? 1 : m_valueList->size();
+
+    ShorthandScope scope(this, propId);
+
+    // the order is top, right, bottom, left
+    switch (num) {
+        case 1: {
+            if (!parseValue(properties[0], important))
+                return false;
+            CSSValue* value = m_parsedProperties.last().value();
+            ImplicitScope implicitScope(this, PropertyImplicit);
+            addProperty(properties[1], value, important);
+            addProperty(properties[2], value, important);
+            addProperty(properties[3], value, important);
+            break;
+        }
+        case 2: {
+            if (!parseValue(properties[0], important) || !parseValue(properties[1], important))
+                return false;
+            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+            ImplicitScope implicitScope(this, PropertyImplicit);
+            addProperty(properties[2], value, important);
+            value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+            addProperty(properties[3], value, important);
+            break;
+        }
+        case 3: {
+            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) || !parseValue(properties[2], important))
+                return false;
+            CSSValue* value = m_parsedProperties[m_parsedProperties.size() - 2].value();
+            ImplicitScope implicitScope(this, PropertyImplicit);
+            addProperty(properties[3], value, important);
+            break;
+        }
+        case 4: {
+            if (!parseValue(properties[0], important) || !parseValue(properties[1], important) ||
+                !parseValue(properties[2], important) || !parseValue(properties[3], important))
+                return false;
+            break;
+        }
+        default: {
+            return false;
+        }
+    }
+
+    return true;
+}
+
+// auto | <identifier>
+bool CSSPropertyParser::parsePage(CSSPropertyID propId, bool important)
+{
+    ASSERT(propId == CSSPropertyPage);
+
+    if (m_valueList->size() != 1)
+        return false;
+
+    CSSParserValue* value = m_valueList->current();
+    if (!value)
+        return false;
+
+    if (value->id == CSSValueAuto) {
+        addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
+        return true;
+    } else if (value->id == 0 && value->unit == CSSPrimitiveValue::CSS_IDENT) {
+        addProperty(propId, createPrimitiveStringValue(value), important);
+        return true;
+    }
+    return false;
+}
+
+// <length>{1,2} | auto | [ <page-size> || [ portrait | landscape] ]
+bool CSSPropertyParser::parseSize(CSSPropertyID propId, bool important)
+{
+    ASSERT(propId == CSSPropertySize);
+
+    if (m_valueList->size() > 2)
+        return false;
+
+    CSSParserValue* value = m_valueList->current();
+    if (!value)
+        return false;
+
+    RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
+
+    // First parameter.
+    SizeParameterType paramType = parseSizeParameter(parsedValues.get(), value, None);
+    if (paramType == None)
+        return false;
+
+    // Second parameter, if any.
+    value = m_valueList->next();
+    if (value) {
+        paramType = parseSizeParameter(parsedValues.get(), value, paramType);
+        if (paramType == None)
+            return false;
+    }
+
+    addProperty(propId, parsedValues.release(), important);
+    return true;
+}
+
+CSSPropertyParser::SizeParameterType CSSPropertyParser::parseSizeParameter(CSSValueList* parsedValues, CSSParserValue* value, SizeParameterType prevParamType)
+{
+    switch (value->id) {
+    case CSSValueAuto:
+        if (prevParamType == None) {
+            parsedValues->append(cssValuePool().createIdentifierValue(value->id));
+            return Auto;
+        }
+        return None;
+    case CSSValueLandscape:
+    case CSSValuePortrait:
+        if (prevParamType == None || prevParamType == PageSize) {
+            parsedValues->append(cssValuePool().createIdentifierValue(value->id));
+            return Orientation;
+        }
+        return None;
+    case CSSValueA3:
+    case CSSValueA4:
+    case CSSValueA5:
+    case CSSValueB4:
+    case CSSValueB5:
+    case CSSValueLedger:
+    case CSSValueLegal:
+    case CSSValueLetter:
+        if (prevParamType == None || prevParamType == Orientation) {
+            // Normalize to Page Size then Orientation order by prepending.
+            // This is not specified by the CSS3 Paged Media specification, but for simpler processing later (StyleResolver::applyPageSizeProperty).
+            parsedValues->prepend(cssValuePool().createIdentifierValue(value->id));
+            return PageSize;
+        }
+        return None;
+    case 0:
+        if (validUnit(value, FLength | FNonNeg) && (prevParamType == None || prevParamType == Length)) {
+            parsedValues->append(createPrimitiveNumericValue(value));
+            return Length;
+        }
+        return None;
+    default:
+        return None;
+    }
+}
+
+// [ <string> <string> ]+ | inherit | none
+// inherit and none are handled in parseValue.
+bool CSSPropertyParser::parseQuotes(CSSPropertyID propId, bool important)
+{
+    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+    while (CSSParserValue* val = m_valueList->current()) {
+        RefPtrWillBeRawPtr<CSSValue> parsedValue;
+        if (val->unit == CSSPrimitiveValue::CSS_STRING)
+            parsedValue = CSSPrimitiveValue::create(val->string, CSSPrimitiveValue::CSS_STRING);
+        else
+            break;
+        values->append(parsedValue.release());
+        m_valueList->next();
+    }
+    if (values->length()) {
+        addProperty(propId, values.release(), important);
+        m_valueList->next();
+        return true;
+    }
+    return false;
+}
+
+// [ <string> | <uri> | <counter> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+// in CSS 2.1 this got somewhat reduced:
+// [ <string> | attr(X) | open-quote | close-quote | no-open-quote | no-close-quote ]+ | inherit
+bool CSSPropertyParser::parseContent(CSSPropertyID propId, bool important)
+{
+    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+
+    while (CSSParserValue* val = m_valueList->current()) {
+        RefPtrWillBeRawPtr<CSSValue> parsedValue;
+        if (val->unit == CSSPrimitiveValue::CSS_URI) {
+            // url
+            parsedValue = CSSImageValue::create(val->string, completeURL(val->string));
+        } else if (val->unit == CSSParserValue::Function) {
+            // attr(X) | counter(X [,Y]) | counters(X, Y, [,Z]) | -webkit-gradient(...)
+            CSSParserValueList* args = val->function->args.get();
+            if (!args)
+                return false;
+            if (equalIgnoringCase(val->function->name, "attr(")) {
+                parsedValue = parseAttr(args);
+                if (!parsedValue)
+                    return false;
+            } else if (equalIgnoringCase(val->function->name, "counter(")) {
+                parsedValue = parseCounterContent(args, false);
+                if (!parsedValue)
+                    return false;
+            } else if (equalIgnoringCase(val->function->name, "counters(")) {
+                parsedValue = parseCounterContent(args, true);
+                if (!parsedValue)
+                    return false;
+            } else if (equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
+                parsedValue = parseImageSet(m_valueList.get());
+                if (!parsedValue)
+                    return false;
+            } else if (isGeneratedImageValue(val)) {
+                if (!parseGeneratedImage(m_valueList.get(), parsedValue))
+                    return false;
+            } else
+                return false;
+        } else if (val->unit == CSSPrimitiveValue::CSS_IDENT) {
+            // open-quote
+            // close-quote
+            // no-open-quote
+            // no-close-quote
+            // inherit
+            // FIXME: These are not yet implemented (http://bugs.webkit.org/show_bug.cgi?id=6503).
+            // none
+            // normal
+            switch (val->id) {
+            case CSSValueOpenQuote:
+            case CSSValueCloseQuote:
+            case CSSValueNoOpenQuote:
+            case CSSValueNoCloseQuote:
+            case CSSValueNone:
+            case CSSValueNormal:
+                parsedValue = cssValuePool().createIdentifierValue(val->id);
+            default:
+                break;
+            }
+        } else if (val->unit == CSSPrimitiveValue::CSS_STRING) {
+            parsedValue = createPrimitiveStringValue(val);
+        }
+        if (!parsedValue)
+            break;
+        values->append(parsedValue.release());
+        m_valueList->next();
+    }
+
+    if (values->length()) {
+        addProperty(propId, values.release(), important);
+        m_valueList->next();
+        return true;
+    }
+
+    return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAttr(CSSParserValueList* args)
+{
+    if (args->size() != 1)
+        return nullptr;
+
+    CSSParserValue* a = args->current();
+
+    if (a->unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+
+    String attrName = a->string;
+    // CSS allows identifiers with "-" at the start, like "-webkit-mask-image".
+    // But HTML attribute names can't have those characters, and we should not
+    // even parse them inside attr().
+    if (attrName[0] == '-')
+        return nullptr;
+
+    if (m_context.isHTMLDocument())
+        attrName = attrName.lower();
+
+    return cssValuePool().createValue(attrName, CSSPrimitiveValue::CSS_ATTR);
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseBackgroundColor()
+{
+    CSSValueID id = m_valueList->current()->id;
+    if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor ||
+        (id >= CSSValueGrey && id < CSSValueWebkitText && inQuirksMode()))
+        return cssValuePool().createIdentifierValue(id);
+    return parseColor();
+}
+
+bool CSSPropertyParser::parseFillImage(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value)
+{
+    if (valueList->current()->id == CSSValueNone) {
+        value = cssValuePool().createIdentifierValue(CSSValueNone);
+        return true;
+    }
+    if (valueList->current()->unit == CSSPrimitiveValue::CSS_URI) {
+        value = CSSImageValue::create(valueList->current()->string, completeURL(valueList->current()->string));
+        return true;
+    }
+
+    if (isGeneratedImageValue(valueList->current()))
+        return parseGeneratedImage(valueList, value);
+
+    if (valueList->current()->unit == CSSParserValue::Function && equalIgnoringCase(valueList->current()->function->name, "-webkit-image-set(")) {
+        value = parseImageSet(m_valueList.get());
+        if (value)
+            return true;
+    }
+
+    return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseFillPositionX(CSSParserValueList* valueList)
+{
+    int id = valueList->current()->id;
+    if (id == CSSValueLeft || id == CSSValueRight || id == CSSValueCenter) {
+        int percent = 0;
+        if (id == CSSValueRight)
+            percent = 100;
+        else if (id == CSSValueCenter)
+            percent = 50;
+        return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+    }
+    if (validUnit(valueList->current(), FPercent | FLength))
+        return createPrimitiveNumericValue(valueList->current());
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseFillPositionY(CSSParserValueList* valueList)
+{
+    int id = valueList->current()->id;
+    if (id == CSSValueTop || id == CSSValueBottom || id == CSSValueCenter) {
+        int percent = 0;
+        if (id == CSSValueBottom)
+            percent = 100;
+        else if (id == CSSValueCenter)
+            percent = 50;
+        return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+    }
+    if (validUnit(valueList->current(), FPercent | FLength))
+        return createPrimitiveNumericValue(valueList->current());
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseFillPositionComponent(CSSParserValueList* valueList, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode parsingMode)
+{
+    CSSValueID id = valueList->current()->id;
+    if (id == CSSValueLeft || id == CSSValueTop || id == CSSValueRight || id == CSSValueBottom || id == CSSValueCenter) {
+        int percent = 0;
+        if (id == CSSValueLeft || id == CSSValueRight) {
+            if (cumulativeFlags & XFillPosition)
+                return nullptr;
+            cumulativeFlags |= XFillPosition;
+            individualFlag = XFillPosition;
+            if (id == CSSValueRight)
+                percent = 100;
+        }
+        else if (id == CSSValueTop || id == CSSValueBottom) {
+            if (cumulativeFlags & YFillPosition)
+                return nullptr;
+            cumulativeFlags |= YFillPosition;
+            individualFlag = YFillPosition;
+            if (id == CSSValueBottom)
+                percent = 100;
+        } else if (id == CSSValueCenter) {
+            // Center is ambiguous, so we're not sure which position we've found yet, an x or a y.
+            percent = 50;
+            cumulativeFlags |= AmbiguousFillPosition;
+            individualFlag = AmbiguousFillPosition;
+        }
+
+        if (parsingMode == ResolveValuesAsKeyword)
+            return cssValuePool().createIdentifierValue(id);
+
+        return cssValuePool().createValue(percent, CSSPrimitiveValue::CSS_PERCENTAGE);
+    }
+    if (validUnit(valueList->current(), FPercent | FLength)) {
+        if (!cumulativeFlags) {
+            cumulativeFlags |= XFillPosition;
+            individualFlag = XFillPosition;
+        } else if (cumulativeFlags & (XFillPosition | AmbiguousFillPosition)) {
+            cumulativeFlags |= YFillPosition;
+            individualFlag = YFillPosition;
+        } else {
+            if (m_parsedCalculation)
+                m_parsedCalculation.release();
+            return nullptr;
+        }
+        return createPrimitiveNumericValue(valueList->current());
+    }
+    return nullptr;
+}
+
+static bool isValueConflictingWithCurrentEdge(int value1, int value2)
+{
+    if ((value1 == CSSValueLeft || value1 == CSSValueRight) && (value2 == CSSValueLeft || value2 == CSSValueRight))
+        return true;
+
+    if ((value1 == CSSValueTop || value1 == CSSValueBottom) && (value2 == CSSValueTop || value2 == CSSValueBottom))
+        return true;
+
+    return false;
+}
+
+static bool isFillPositionKeyword(CSSValueID value)
+{
+    return value == CSSValueLeft || value == CSSValueTop || value == CSSValueBottom || value == CSSValueRight || value == CSSValueCenter;
+}
+
+void CSSPropertyParser::parse4ValuesFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2)
+{
+    // [ left | right ] [ <percentage] | <length> ] && [ top | bottom ] [ <percentage> | <length> ]
+    // In the case of 4 values <position> requires the second value to be a length or a percentage.
+    if (isFillPositionKeyword(parsedValue2->getValueID()))
+        return;
+
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value3Flag = InvalidFillPosition;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
+    if (!value3)
+        return;
+
+    CSSValueID ident1 = parsedValue1->getValueID();
+    CSSValueID ident3 = value3->getValueID();
+
+    if (ident1 == CSSValueCenter)
+        return;
+
+    if (!isFillPositionKeyword(ident3) || ident3 == CSSValueCenter)
+        return;
+
+    // We need to check if the values are not conflicting, e.g. they are not on the same edge. It is
+    // needed as the second call to parseFillPositionComponent was on purpose not checking it. In the
+    // case of two values top 20px is invalid but in the case of 4 values it becomes valid.
+    if (isValueConflictingWithCurrentEdge(ident1, ident3))
+        return;
+
+    valueList->next();
+
+    cumulativeFlags = 0;
+    FillPositionFlag value4Flag = InvalidFillPosition;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> value4 = parseFillPositionComponent(valueList, cumulativeFlags, value4Flag, ResolveValuesAsKeyword);
+    if (!value4)
+        return;
+
+    // 4th value must be a length or a percentage.
+    if (isFillPositionKeyword(value4->getValueID()))
+        return;
+
+    value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
+    value2 = createPrimitiveValuePair(value3, value4);
+
+    if (ident1 == CSSValueTop || ident1 == CSSValueBottom)
+        value1.swap(value2);
+
+    valueList->next();
+}
+void CSSPropertyParser::parse3ValuesFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1, PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2)
+{
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value3Flag = InvalidFillPosition;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> value3 = parseFillPositionComponent(valueList, cumulativeFlags, value3Flag, ResolveValuesAsKeyword);
+
+    // value3 is not an expected value, we return.
+    if (!value3)
+        return;
+
+    valueList->next();
+
+    bool swapNeeded = false;
+    CSSValueID ident1 = parsedValue1->getValueID();
+    CSSValueID ident2 = parsedValue2->getValueID();
+    CSSValueID ident3 = value3->getValueID();
+
+    CSSValueID firstPositionKeyword;
+    CSSValueID secondPositionKeyword;
+
+    if (ident1 == CSSValueCenter) {
+        // <position> requires the first 'center' to be followed by a keyword.
+        if (!isFillPositionKeyword(ident2))
+            return;
+
+        // If 'center' is the first keyword then the last one needs to be a length.
+        if (isFillPositionKeyword(ident3))
+            return;
+
+        firstPositionKeyword = CSSValueLeft;
+        if (ident2 == CSSValueLeft || ident2 == CSSValueRight) {
+            firstPositionKeyword = CSSValueTop;
+            swapNeeded = true;
+        }
+        value1 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(firstPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+        value2 = createPrimitiveValuePair(parsedValue2, value3);
+    } else if (ident3 == CSSValueCenter) {
+        if (isFillPositionKeyword(ident2))
+            return;
+
+        secondPositionKeyword = CSSValueTop;
+        if (ident1 == CSSValueTop || ident1 == CSSValueBottom) {
+            secondPositionKeyword = CSSValueLeft;
+            swapNeeded = true;
+        }
+        value1 = createPrimitiveValuePair(parsedValue1, parsedValue2);
+        value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE));
+    } else {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> firstPositionValue;
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> secondPositionValue;
+
+        if (isFillPositionKeyword(ident2)) {
+            // To match CSS grammar, we should only accept: [ center | left | right | bottom | top ] [ left | right | top | bottom ] [ <percentage> | <length> ].
+            ASSERT(ident2 != CSSValueCenter);
+
+            if (isFillPositionKeyword(ident3))
+                return;
+
+            secondPositionValue = value3;
+            secondPositionKeyword = ident2;
+            firstPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
+        } else {
+            // Per CSS, we should only accept: [ right | left | top | bottom ] [ <percentage> | <length> ] [ center | left | right | bottom | top ].
+            if (!isFillPositionKeyword(ident3))
+                return;
+
+            firstPositionValue = parsedValue2;
+            secondPositionKeyword = ident3;
+            secondPositionValue = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PERCENTAGE);
+        }
+
+        if (isValueConflictingWithCurrentEdge(ident1, secondPositionKeyword))
+            return;
+
+        value1 = createPrimitiveValuePair(parsedValue1, firstPositionValue);
+        value2 = createPrimitiveValuePair(cssValuePool().createIdentifierValue(secondPositionKeyword), secondPositionValue);
+    }
+
+    if (ident1 == CSSValueTop || ident1 == CSSValueBottom || swapNeeded)
+        value1.swap(value2);
+
+#ifndef NDEBUG
+    CSSPrimitiveValue* first = toCSSPrimitiveValue(value1.get());
+    CSSPrimitiveValue* second = toCSSPrimitiveValue(value2.get());
+    ident1 = first->getPairValue()->first()->getValueID();
+    ident2 = second->getPairValue()->first()->getValueID();
+    ASSERT(ident1 == CSSValueLeft || ident1 == CSSValueRight);
+    ASSERT(ident2 == CSSValueBottom || ident2 == CSSValueTop);
+#endif
+}
+
+inline bool CSSPropertyParser::isPotentialPositionValue(CSSParserValue* value)
+{
+    return isFillPositionKeyword(value->id) || validUnit(value, FPercent | FLength, ReleaseParsedCalcValue);
+}
+
+void CSSPropertyParser::parseFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+    unsigned numberOfValues = 0;
+    for (unsigned i = valueList->currentIndex(); i < valueList->size(); ++i, ++numberOfValues) {
+        CSSParserValue* current = valueList->valueAt(i);
+        if (isComma(current) || !current || isForwardSlashOperator(current) || !isPotentialPositionValue(current))
+            break;
+    }
+
+    if (numberOfValues > 4)
+        return;
+
+    // If we are parsing two values, we can safely call the CSS 2.1 parsing function and return.
+    if (numberOfValues <= 2) {
+        parse2ValuesFillPosition(valueList, value1, value2);
+        return;
+    }
+
+    ASSERT(numberOfValues > 2 && numberOfValues <= 4);
+
+    CSSParserValue* value = valueList->current();
+
+    // <position> requires the first value to be a background keyword.
+    if (!isFillPositionKeyword(value->id))
+        return;
+
+    // Parse the first value. We're just making sure that it is one of the valid keywords or a percentage/length.
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value1Flag = InvalidFillPosition;
+    FillPositionFlag value2Flag = InvalidFillPosition;
+    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag, ResolveValuesAsKeyword);
+    if (!value1)
+        return;
+
+    valueList->next();
+
+    // In case we are parsing more than two values, relax the check inside of parseFillPositionComponent. top 20px is
+    // a valid start for <position>.
+    cumulativeFlags = AmbiguousFillPosition;
+    value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag, ResolveValuesAsKeyword);
+    if (value2)
+        valueList->next();
+    else {
+        value1.clear();
+        return;
+    }
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1 = toCSSPrimitiveValue(value1.get());
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2 = toCSSPrimitiveValue(value2.get());
+
+    value1.clear();
+    value2.clear();
+
+    // Per CSS3 syntax, <position> can't have 'center' as its second keyword as we have more arguments to follow.
+    if (parsedValue2->getValueID() == CSSValueCenter)
+        return;
+
+    if (numberOfValues == 3)
+        parse3ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
+    else
+        parse4ValuesFillPosition(valueList, value1, value2, parsedValue1.release(), parsedValue2.release());
+}
+
+void CSSPropertyParser::parse2ValuesFillPosition(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+    // Parse the first value.  We're just making sure that it is one of the valid keywords or a percentage/length.
+    unsigned cumulativeFlags = 0;
+    FillPositionFlag value1Flag = InvalidFillPosition;
+    FillPositionFlag value2Flag = InvalidFillPosition;
+    value1 = parseFillPositionComponent(valueList, cumulativeFlags, value1Flag);
+    if (!value1)
+        return;
+
+    // It only takes one value for background-position to be correctly parsed if it was specified in a shorthand (since we
+    // can assume that any other values belong to the rest of the shorthand).  If we're not parsing a shorthand, though, the
+    // value was explicitly specified for our property.
+    CSSParserValue* value = valueList->next();
+
+    // First check for the comma.  If so, we are finished parsing this value or value pair.
+    if (isComma(value))
+        value = 0;
+
+    if (value) {
+        value2 = parseFillPositionComponent(valueList, cumulativeFlags, value2Flag);
+        if (value2)
+            valueList->next();
+        else {
+            if (!inShorthand()) {
+                value1.clear();
+                return;
+            }
+        }
+    }
+
+    if (!value2)
+        // Only one value was specified. If that value was not a keyword, then it sets the x position, and the y position
+        // is simply 50%. This is our default.
+        // For keywords, the keyword was either an x-keyword (left/right), a y-keyword (top/bottom), or an ambiguous keyword (center).
+        // For left/right/center, the default of 50% in the y is still correct.
+        value2 = cssValuePool().createValue(50, CSSPrimitiveValue::CSS_PERCENTAGE);
+
+    if (value1Flag == YFillPosition || value2Flag == XFillPosition)
+        value1.swap(value2);
+}
+
+void CSSPropertyParser::parseFillRepeat(RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+    CSSValueID id = m_valueList->current()->id;
+    if (id == CSSValueRepeatX) {
+        m_implicitShorthand = true;
+        value1 = cssValuePool().createIdentifierValue(CSSValueRepeat);
+        value2 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
+        m_valueList->next();
+        return;
+    }
+    if (id == CSSValueRepeatY) {
+        m_implicitShorthand = true;
+        value1 = cssValuePool().createIdentifierValue(CSSValueNoRepeat);
+        value2 = cssValuePool().createIdentifierValue(CSSValueRepeat);
+        m_valueList->next();
+        return;
+    }
+    if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace)
+        value1 = cssValuePool().createIdentifierValue(id);
+    else {
+        value1 = nullptr;
+        return;
+    }
+
+    CSSParserValue* value = m_valueList->next();
+
+    // Parse the second value if one is available
+    if (value && !isComma(value)) {
+        id = value->id;
+        if (id == CSSValueRepeat || id == CSSValueNoRepeat || id == CSSValueRound || id == CSSValueSpace) {
+            value2 = cssValuePool().createIdentifierValue(id);
+            m_valueList->next();
+            return;
+        }
+    }
+
+    // If only one value was specified, value2 is the same as value1.
+    m_implicitShorthand = true;
+    value2 = cssValuePool().createIdentifierValue(toCSSPrimitiveValue(value1.get())->getValueID());
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseFillSize(CSSPropertyID propId, bool& allowComma)
+{
+    allowComma = true;
+    CSSParserValue* value = m_valueList->current();
+
+    if (value->id == CSSValueContain || value->id == CSSValueCover)
+        return cssValuePool().createIdentifierValue(value->id);
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue1;
+
+    if (value->id == CSSValueAuto)
+        parsedValue1 = cssValuePool().createIdentifierValue(CSSValueAuto);
+    else {
+        if (!validUnit(value, FLength | FPercent))
+            return nullptr;
+        parsedValue1 = createPrimitiveNumericValue(value);
+    }
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue2;
+    if ((value = m_valueList->next())) {
+        if (value->unit == CSSParserValue::Operator && value->iValue == ',')
+            allowComma = false;
+        else if (value->id != CSSValueAuto) {
+            if (!validUnit(value, FLength | FPercent)) {
+                if (!inShorthand())
+                    return nullptr;
+                // We need to rewind the value list, so that when it is advanced we'll end up back at this value.
+                m_valueList->previous();
+            } else
+                parsedValue2 = createPrimitiveNumericValue(value);
+        }
+    } else if (!parsedValue2 && propId == CSSPropertyWebkitBackgroundSize) {
+        // For backwards compatibility we set the second value to the first if it is omitted.
+        // We only need to do this for -webkit-background-size. It should be safe to let masks match
+        // the real property.
+        parsedValue2 = parsedValue1;
+    }
+
+    if (!parsedValue2)
+        return parsedValue1;
+    return createPrimitiveValuePair(parsedValue1.release(), parsedValue2.release());
+}
+
+bool CSSPropertyParser::parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,
+    RefPtrWillBeRawPtr<CSSValue>& retValue1, RefPtrWillBeRawPtr<CSSValue>& retValue2)
+{
+    RefPtrWillBeRawPtr<CSSValueList> values;
+    RefPtrWillBeRawPtr<CSSValueList> values2;
+    CSSParserValue* val;
+    RefPtrWillBeRawPtr<CSSValue> value;
+    RefPtrWillBeRawPtr<CSSValue> value2;
+
+    bool allowComma = false;
+
+    retValue1 = retValue2 = nullptr;
+    propId1 = propId;
+    propId2 = propId;
+    if (propId == CSSPropertyBackgroundPosition) {
+        propId1 = CSSPropertyBackgroundPositionX;
+        propId2 = CSSPropertyBackgroundPositionY;
+    } else if (propId == CSSPropertyWebkitMaskPosition) {
+        propId1 = CSSPropertyWebkitMaskPositionX;
+        propId2 = CSSPropertyWebkitMaskPositionY;
+    } else if (propId == CSSPropertyBackgroundRepeat) {
+        propId1 = CSSPropertyBackgroundRepeatX;
+        propId2 = CSSPropertyBackgroundRepeatY;
+    } else if (propId == CSSPropertyWebkitMaskRepeat) {
+        propId1 = CSSPropertyWebkitMaskRepeatX;
+        propId2 = CSSPropertyWebkitMaskRepeatY;
+    }
+
+    while ((val = m_valueList->current())) {
+        RefPtrWillBeRawPtr<CSSValue> currValue;
+        RefPtrWillBeRawPtr<CSSValue> currValue2;
+
+        if (allowComma) {
+            if (!isComma(val))
+                return false;
+            m_valueList->next();
+            allowComma = false;
+        } else {
+            allowComma = true;
+            switch (propId) {
+                case CSSPropertyBackgroundColor:
+                    currValue = parseBackgroundColor();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyBackgroundAttachment:
+                    if (val->id == CSSValueScroll || val->id == CSSValueFixed || val->id == CSSValueLocal) {
+                        currValue = cssValuePool().createIdentifierValue(val->id);
+                        m_valueList->next();
+                    }
+                    break;
+                case CSSPropertyBackgroundImage:
+                case CSSPropertyWebkitMaskImage:
+                    if (parseFillImage(m_valueList.get(), currValue))
+                        m_valueList->next();
+                    break;
+                case CSSPropertyWebkitBackgroundClip:
+                case CSSPropertyWebkitBackgroundOrigin:
+                case CSSPropertyWebkitMaskClip:
+                case CSSPropertyWebkitMaskOrigin:
+                    // The first three values here are deprecated and do not apply to the version of the property that has
+                    // the -webkit- prefix removed.
+                    if (val->id == CSSValueBorder || val->id == CSSValuePadding || val->id == CSSValueContent ||
+                        val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox ||
+                        ((propId == CSSPropertyWebkitBackgroundClip || propId == CSSPropertyWebkitMaskClip) &&
+                         (val->id == CSSValueText || val->id == CSSValueWebkitText))) {
+                        currValue = cssValuePool().createIdentifierValue(val->id);
+                        m_valueList->next();
+                    }
+                    break;
+                case CSSPropertyBackgroundClip:
+                    if (parseBackgroundClip(val, currValue))
+                        m_valueList->next();
+                    break;
+                case CSSPropertyBackgroundOrigin:
+                    if (val->id == CSSValueBorderBox || val->id == CSSValuePaddingBox || val->id == CSSValueContentBox) {
+                        currValue = cssValuePool().createIdentifierValue(val->id);
+                        m_valueList->next();
+                    }
+                    break;
+                case CSSPropertyBackgroundPosition:
+                case CSSPropertyWebkitMaskPosition:
+                    parseFillPosition(m_valueList.get(), currValue, currValue2);
+                    // parseFillPosition advances the m_valueList pointer.
+                    break;
+                case CSSPropertyBackgroundPositionX:
+                case CSSPropertyWebkitMaskPositionX: {
+                    currValue = parseFillPositionX(m_valueList.get());
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                }
+                case CSSPropertyBackgroundPositionY:
+                case CSSPropertyWebkitMaskPositionY: {
+                    currValue = parseFillPositionY(m_valueList.get());
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                }
+                case CSSPropertyWebkitBackgroundComposite:
+                case CSSPropertyWebkitMaskComposite:
+                    if (val->id >= CSSValueClear && val->id <= CSSValuePlusLighter) {
+                        currValue = cssValuePool().createIdentifierValue(val->id);
+                        m_valueList->next();
+                    }
+                    break;
+                case CSSPropertyBackgroundBlendMode:
+                    if (val->id == CSSValueNormal || val->id == CSSValueMultiply
+                        || val->id == CSSValueScreen || val->id == CSSValueOverlay || val->id == CSSValueDarken
+                        || val->id == CSSValueLighten ||  val->id == CSSValueColorDodge || val->id == CSSValueColorBurn
+                        || val->id == CSSValueHardLight || val->id == CSSValueSoftLight || val->id == CSSValueDifference
+                        || val->id == CSSValueExclusion || val->id == CSSValueHue || val->id == CSSValueSaturation
+                        || val->id == CSSValueColor || val->id == CSSValueLuminosity) {
+                        currValue = cssValuePool().createIdentifierValue(val->id);
+                        m_valueList->next();
+                    }
+                    break;
+                case CSSPropertyBackgroundRepeat:
+                case CSSPropertyWebkitMaskRepeat:
+                    parseFillRepeat(currValue, currValue2);
+                    // parseFillRepeat advances the m_valueList pointer
+                    break;
+                case CSSPropertyBackgroundSize:
+                case CSSPropertyWebkitBackgroundSize:
+                case CSSPropertyWebkitMaskSize: {
+                    currValue = parseFillSize(propId, allowComma);
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                }
+                case CSSPropertyMaskSourceType: {
+                    if (RuntimeEnabledFeatures::cssMaskSourceTypeEnabled()) {
+                        if (val->id == CSSValueAuto || val->id == CSSValueAlpha || val->id == CSSValueLuminance) {
+                            currValue = cssValuePool().createIdentifierValue(val->id);
+                            m_valueList->next();
+                        } else {
+                            currValue = nullptr;
+                        }
+                    }
+                    break;
+                }
+                default:
+                    break;
+            }
+            if (!currValue)
+                return false;
+
+            if (value && !values) {
+                values = CSSValueList::createCommaSeparated();
+                values->append(value.release());
+            }
+
+            if (value2 && !values2) {
+                values2 = CSSValueList::createCommaSeparated();
+                values2->append(value2.release());
+            }
+
+            if (values)
+                values->append(currValue.release());
+            else
+                value = currValue.release();
+            if (currValue2) {
+                if (values2)
+                    values2->append(currValue2.release());
+                else
+                    value2 = currValue2.release();
+            }
+        }
+
+        // When parsing any fill shorthand property, we let it handle building up the lists for all
+        // properties.
+        if (inShorthand())
+            break;
+    }
+
+    if (values && values->length()) {
+        retValue1 = values.release();
+        if (values2 && values2->length())
+            retValue2 = values2.release();
+        return true;
+    }
+    if (value) {
+        retValue1 = value.release();
+        retValue2 = value2.release();
+        return true;
+    }
+    return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationDelay()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (validUnit(value, FTime))
+        return createPrimitiveNumericValue(value);
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationDirection()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueNormal || value->id == CSSValueAlternate || value->id == CSSValueReverse || value->id == CSSValueAlternateReverse)
+        return cssValuePool().createIdentifierValue(value->id);
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationDuration()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (validUnit(value, FTime | FNonNeg))
+        return createPrimitiveNumericValue(value);
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationFillMode()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueNone || value->id == CSSValueForwards || value->id == CSSValueBackwards || value->id == CSSValueBoth)
+        return cssValuePool().createIdentifierValue(value->id);
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationIterationCount()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueInfinite)
+        return cssValuePool().createIdentifierValue(value->id);
+    if (validUnit(value, FNumber | FNonNeg))
+        return createPrimitiveNumericValue(value);
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationName()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->unit == CSSPrimitiveValue::CSS_STRING || value->unit == CSSPrimitiveValue::CSS_IDENT) {
+        if (value->id == CSSValueNone || (value->unit == CSSPrimitiveValue::CSS_STRING && equalIgnoringCase(value, "none"))) {
+            return cssValuePool().createIdentifierValue(CSSValueNone);
+        } else {
+            return createPrimitiveStringValue(value);
+        }
+    }
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationPlayState()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueRunning || value->id == CSSValuePaused)
+        return cssValuePool().createIdentifierValue(value->id);
+    return nullptr;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationProperty(AnimationParseContext& context)
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+    CSSPropertyID result = cssPropertyID(value->string);
+    if (result)
+        return cssValuePool().createIdentifierValue(result);
+    if (equalIgnoringCase(value, "all")) {
+        context.sawAnimationPropertyKeyword();
+        return cssValuePool().createIdentifierValue(CSSValueAll);
+    }
+    if (equalIgnoringCase(value, "none")) {
+        context.commitAnimationPropertyKeyword();
+        context.sawAnimationPropertyKeyword();
+        return cssValuePool().createIdentifierValue(CSSValueNone);
+    }
+    return nullptr;
+}
+
+bool CSSPropertyParser::parseTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>& value1, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
+{
+    parse2ValuesFillPosition(m_valueList.get(), value1, value2);
+
+    // now get z
+    if (m_valueList->current()) {
+        if (validUnit(m_valueList->current(), FLength)) {
+            value3 = createPrimitiveNumericValue(m_valueList->current());
+            m_valueList->next();
+            return true;
+        }
+        return false;
+    }
+    value3 = cssValuePool().createImplicitInitialValue();
+    return true;
+}
+
+bool CSSPropertyParser::parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result)
+{
+    CSSParserValue* v = args->current();
+    if (!validUnit(v, FNumber))
+        return false;
+    result = v->fValue;
+    v = args->next();
+    if (!v)
+        // The last number in the function has no comma after it, so we're done.
+        return true;
+    if (!isComma(v))
+        return false;
+    args->next();
+    return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseAnimationTimingFunction()
+{
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueEase || value->id == CSSValueLinear || value->id == CSSValueEaseIn || value->id == CSSValueEaseOut
+        || value->id == CSSValueEaseInOut || value->id == CSSValueStepStart || value->id == CSSValueStepEnd
+        || (value->id == CSSValueStepMiddle && RuntimeEnabledFeatures::webAnimationsAPIEnabled()))
+        return cssValuePool().createIdentifierValue(value->id);
+
+    // We must be a function.
+    if (value->unit != CSSParserValue::Function)
+        return nullptr;
+
+    CSSParserValueList* args = value->function->args.get();
+
+    if (equalIgnoringCase(value->function->name, "steps(")) {
+        // For steps, 1 or 2 params must be specified (comma-separated)
+        if (!args || (args->size() != 1 && args->size() != 3))
+            return nullptr;
+
+        // There are two values.
+        int numSteps;
+        StepsTimingFunction::StepAtPosition stepAtPosition = StepsTimingFunction::StepAtEnd;
+
+        CSSParserValue* v = args->current();
+        if (!validUnit(v, FInteger))
+            return nullptr;
+        numSteps = clampToInteger(v->fValue);
+        if (numSteps < 1)
+            return nullptr;
+        v = args->next();
+
+        if (v) {
+            // There is a comma so we need to parse the second value
+            if (!isComma(v))
+                return nullptr;
+            v = args->next();
+            switch (v->id) {
+            case CSSValueMiddle:
+                if (!RuntimeEnabledFeatures::webAnimationsAPIEnabled())
+                    return nullptr;
+                stepAtPosition = StepsTimingFunction::StepAtMiddle;
+                break;
+            case CSSValueStart:
+                stepAtPosition = StepsTimingFunction::StepAtStart;
+                break;
+            case CSSValueEnd:
+                stepAtPosition = StepsTimingFunction::StepAtEnd;
+                break;
+            default:
+                return nullptr;
+            }
+        }
+
+        return CSSStepsTimingFunctionValue::create(numSteps, stepAtPosition);
+    }
+
+    if (equalIgnoringCase(value->function->name, "cubic-bezier(")) {
+        // For cubic bezier, 4 values must be specified.
+        if (!args || args->size() != 7)
+            return nullptr;
+
+        // There are two points specified. The x values must be between 0 and 1 but the y values can exceed this range.
+        double x1, y1, x2, y2;
+
+        if (!parseCubicBezierTimingFunctionValue(args, x1))
+            return nullptr;
+        if (x1 < 0 || x1 > 1)
+            return nullptr;
+        if (!parseCubicBezierTimingFunctionValue(args, y1))
+            return nullptr;
+        if (!parseCubicBezierTimingFunctionValue(args, x2))
+            return nullptr;
+        if (x2 < 0 || x2 > 1)
+            return nullptr;
+        if (!parseCubicBezierTimingFunctionValue(args, y2))
+            return nullptr;
+
+        return CSSCubicBezierTimingFunctionValue::create(x1, y1, x2, y2);
+    }
+
+    return nullptr;
+}
+
+bool CSSPropertyParser::parseAnimationProperty(CSSPropertyID propId, RefPtrWillBeRawPtr<CSSValue>& result, AnimationParseContext& context)
+{
+    RefPtrWillBeRawPtr<CSSValueList> values;
+    CSSParserValue* val;
+    RefPtrWillBeRawPtr<CSSValue> value;
+    bool allowComma = false;
+
+    result = nullptr;
+
+    while ((val = m_valueList->current())) {
+        RefPtrWillBeRawPtr<CSSValue> currValue;
+        if (allowComma) {
+            if (!isComma(val))
+                return false;
+            m_valueList->next();
+            allowComma = false;
+        }
+        else {
+            switch (propId) {
+                case CSSPropertyAnimationDelay:
+                case CSSPropertyWebkitAnimationDelay:
+                case CSSPropertyTransitionDelay:
+                case CSSPropertyWebkitTransitionDelay:
+                    currValue = parseAnimationDelay();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyAnimationDirection:
+                case CSSPropertyWebkitAnimationDirection:
+                    currValue = parseAnimationDirection();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyAnimationDuration:
+                case CSSPropertyWebkitAnimationDuration:
+                case CSSPropertyTransitionDuration:
+                case CSSPropertyWebkitTransitionDuration:
+                    currValue = parseAnimationDuration();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyAnimationFillMode:
+                case CSSPropertyWebkitAnimationFillMode:
+                    currValue = parseAnimationFillMode();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyAnimationIterationCount:
+                case CSSPropertyWebkitAnimationIterationCount:
+                    currValue = parseAnimationIterationCount();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyAnimationName:
+                case CSSPropertyWebkitAnimationName:
+                    currValue = parseAnimationName();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyAnimationPlayState:
+                case CSSPropertyWebkitAnimationPlayState:
+                    currValue = parseAnimationPlayState();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyTransitionProperty:
+                case CSSPropertyWebkitTransitionProperty:
+                    currValue = parseAnimationProperty(context);
+                    if (value && !context.animationPropertyKeywordAllowed())
+                        return false;
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                case CSSPropertyAnimationTimingFunction:
+                case CSSPropertyWebkitAnimationTimingFunction:
+                case CSSPropertyTransitionTimingFunction:
+                case CSSPropertyWebkitTransitionTimingFunction:
+                    currValue = parseAnimationTimingFunction();
+                    if (currValue)
+                        m_valueList->next();
+                    break;
+                default:
+                    ASSERT_NOT_REACHED();
+                    return false;
+            }
+
+            if (!currValue)
+                return false;
+
+            if (value && !values) {
+                values = CSSValueList::createCommaSeparated();
+                values->append(value.release());
+            }
+
+            if (values)
+                values->append(currValue.release());
+            else
+                value = currValue.release();
+
+            allowComma = true;
+        }
+
+        // When parsing the 'transition' shorthand property, we let it handle building up the lists for all
+        // properties.
+        if (inShorthand())
+            break;
+    }
+
+    if (values && values->length()) {
+        result = values.release();
+        return true;
+    }
+    if (value) {
+        result = value.release();
+        return true;
+    }
+    return false;
+}
+
+// The function parses [ <integer> || <string> ] in <grid-line> (which can be stand alone or with 'span').
+bool CSSPropertyParser::parseIntegerOrStringFromGridPosition(RefPtrWillBeRawPtr<CSSPrimitiveValue>& numericValue, RefPtrWillBeRawPtr<CSSPrimitiveValue>& gridLineName)
+{
+    CSSParserValue* value = m_valueList->current();
+    if (validUnit(value, FInteger) && value->fValue) {
+        numericValue = createPrimitiveNumericValue(value);
+        value = m_valueList->next();
+        if (value && value->unit == CSSPrimitiveValue::CSS_STRING) {
+            gridLineName = createPrimitiveStringValue(m_valueList->current());
+            m_valueList->next();
+        }
+        return true;
+    }
+
+    if (value->unit == CSSPrimitiveValue::CSS_STRING) {
+        gridLineName = createPrimitiveStringValue(m_valueList->current());
+        value = m_valueList->next();
+        if (value && validUnit(value, FInteger) && value->fValue) {
+            numericValue = createPrimitiveNumericValue(value);
+            m_valueList->next();
+        }
+        return true;
+    }
+
+    return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridPosition()
+{
+    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueAuto) {
+        m_valueList->next();
+        return cssValuePool().createIdentifierValue(CSSValueAuto);
+    }
+
+    if (value->id != CSSValueSpan && value->unit == CSSPrimitiveValue::CSS_IDENT) {
+        m_valueList->next();
+        return cssValuePool().createValue(value->string, CSSPrimitiveValue::CSS_STRING);
+    }
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> numericValue;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> gridLineName;
+    bool hasSeenSpanKeyword = false;
+
+    if (parseIntegerOrStringFromGridPosition(numericValue, gridLineName)) {
+        value = m_valueList->current();
+        if (value && value->id == CSSValueSpan) {
+            hasSeenSpanKeyword = true;
+            m_valueList->next();
+        }
+    } else if (value->id == CSSValueSpan) {
+        hasSeenSpanKeyword = true;
+        if (m_valueList->next())
+            parseIntegerOrStringFromGridPosition(numericValue, gridLineName);
+    }
+
+    // Check that we have consumed all the value list. For shorthands, the parser will pass
+    // the whole value list (including the opposite position).
+    if (m_valueList->current() && !isForwardSlashOperator(m_valueList->current()))
+        return nullptr;
+
+    // If we didn't parse anything, this is not a valid grid position.
+    if (!hasSeenSpanKeyword && !gridLineName && !numericValue)
+        return nullptr;
+
+    // Negative numbers are not allowed for span (but are for <integer>).
+    if (hasSeenSpanKeyword && numericValue && numericValue->getIntValue() < 0)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
+    if (hasSeenSpanKeyword)
+        values->append(cssValuePool().createIdentifierValue(CSSValueSpan));
+    if (numericValue)
+        values->append(numericValue.release());
+    if (gridLineName)
+        values->append(gridLineName.release());
+    ASSERT(values->length());
+    return values.release();
+}
+
+static PassRefPtrWillBeRawPtr<CSSValue> gridMissingGridPositionValue(CSSValue* value)
+{
+    if (value->isPrimitiveValue() && toCSSPrimitiveValue(value)->isString())
+        return value;
+
+    return cssValuePool().createIdentifierValue(CSSValueAuto);
+}
+
+bool CSSPropertyParser::parseGridItemPositionShorthand(CSSPropertyID shorthandId, bool important)
+{
+    ShorthandScope scope(this, shorthandId);
+    const StylePropertyShorthand& shorthand = shorthandForProperty(shorthandId);
+    ASSERT(shorthand.length() == 2);
+
+    RefPtrWillBeRawPtr<CSSValue> startValue = parseGridPosition();
+    if (!startValue)
+        return false;
+
+    RefPtrWillBeRawPtr<CSSValue> endValue;
+    if (m_valueList->current()) {
+        if (!isForwardSlashOperator(m_valueList->current()))
+            return false;
+
+        if (!m_valueList->next())
+            return false;
+
+        endValue = parseGridPosition();
+        if (!endValue || m_valueList->current())
+            return false;
+    } else {
+        endValue = gridMissingGridPositionValue(startValue.get());
+    }
+
+    addProperty(shorthand.properties()[0], startValue, important);
+    addProperty(shorthand.properties()[1], endValue, important);
+    return true;
+}
+
+bool CSSPropertyParser::parseGridAreaShorthand(bool important)
+{
+    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+    ShorthandScope scope(this, CSSPropertyGridArea);
+    const StylePropertyShorthand& shorthand = gridAreaShorthand();
+    ASSERT_UNUSED(shorthand, shorthand.length() == 4);
+
+    RefPtrWillBeRawPtr<CSSValue> rowStartValue = parseGridPosition();
+    if (!rowStartValue)
+        return false;
+
+    RefPtrWillBeRawPtr<CSSValue> columnStartValue;
+    if (!parseSingleGridAreaLonghand(columnStartValue))
+        return false;
+
+    RefPtrWillBeRawPtr<CSSValue> rowEndValue;
+    if (!parseSingleGridAreaLonghand(rowEndValue))
+        return false;
+
+    RefPtrWillBeRawPtr<CSSValue> columnEndValue;
+    if (!parseSingleGridAreaLonghand(columnEndValue))
+        return false;
+
+    if (!columnStartValue)
+        columnStartValue = gridMissingGridPositionValue(rowStartValue.get());
+
+    if (!rowEndValue)
+        rowEndValue = gridMissingGridPositionValue(rowStartValue.get());
+
+    if (!columnEndValue)
+        columnEndValue = gridMissingGridPositionValue(columnStartValue.get());
+
+    addProperty(CSSPropertyGridRowStart, rowStartValue, important);
+    addProperty(CSSPropertyGridColumnStart, columnStartValue, important);
+    addProperty(CSSPropertyGridRowEnd, rowEndValue, important);
+    addProperty(CSSPropertyGridColumnEnd, columnEndValue, important);
+    return true;
+}
+
+bool CSSPropertyParser::parseSingleGridAreaLonghand(RefPtrWillBeRawPtr<CSSValue>& property)
+{
+    if (!m_valueList->current())
+        return true;
+
+    if (!isForwardSlashOperator(m_valueList->current()))
+        return false;
+
+    if (!m_valueList->next())
+        return false;
+
+    property = parseGridPosition();
+    return true;
+}
+
+void CSSPropertyParser::parseGridLineNames(CSSParserValueList* parserValueList, CSSValueList& valueList)
+{
+    ASSERT(parserValueList->current() && parserValueList->current()->unit == CSSParserValue::ValueList);
+
+    CSSParserValueList* identList = parserValueList->current()->valueList;
+    if (!identList->size()) {
+        parserValueList->next();
+        return;
+    }
+
+    RefPtrWillBeRawPtr<CSSGridLineNamesValue> lineNames = CSSGridLineNamesValue::create();
+    while (CSSParserValue* identValue = identList->current()) {
+        ASSERT(identValue->unit == CSSPrimitiveValue::CSS_IDENT);
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> lineName = createPrimitiveStringValue(identValue);
+        lineNames->append(lineName.release());
+        identList->next();
+    }
+    valueList.append(lineNames.release());
+
+    parserValueList->next();
+}
+
+bool CSSPropertyParser::parseGridTrackList(CSSPropertyID propId, bool important)
+{
+    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+    CSSParserValue* value = m_valueList->current();
+    if (value->id == CSSValueNone) {
+        if (m_valueList->next())
+            return false;
+
+        addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
+        return true;
+    }
+
+    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createSpaceSeparated();
+    // Handle leading  <ident>*.
+    value = m_valueList->current();
+    if (value && value->unit == CSSParserValue::ValueList)
+        parseGridLineNames(m_valueList.get(), *values);
+
+    bool seenTrackSizeOrRepeatFunction = false;
+    while (CSSParserValue* currentValue = m_valueList->current()) {
+        if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "repeat(")) {
+            if (!parseGridTrackRepeatFunction(*values))
+                return false;
+            seenTrackSizeOrRepeatFunction = true;
+        } else {
+            RefPtrWillBeRawPtr<CSSValue> value = parseGridTrackSize(*m_valueList);
+            if (!value)
+                return false;
+            values->append(value);
+            seenTrackSizeOrRepeatFunction = true;
+        }
+        // This will handle the trailing <ident>* in the grammar.
+        value = m_valueList->current();
+        if (value && value->unit == CSSParserValue::ValueList)
+            parseGridLineNames(m_valueList.get(), *values);
+    }
+
+    // We should have found a <track-size> or else it is not a valid <track-list>
+    if (!seenTrackSizeOrRepeatFunction)
+        return false;
+
+    addProperty(propId, values.release(), important);
+    return true;
+}
+
+bool CSSPropertyParser::parseGridTrackRepeatFunction(CSSValueList& list)
+{
+    CSSParserValueList* arguments = m_valueList->current()->function->args.get();
+    if (!arguments || arguments->size() < 3 || !validUnit(arguments->valueAt(0), FPositiveInteger) || !isComma(arguments->valueAt(1)))
+        return false;
+
+    ASSERT_WITH_SECURITY_IMPLICATION(arguments->valueAt(0)->fValue > 0);
+    size_t repetitions = arguments->valueAt(0)->fValue;
+    RefPtrWillBeRawPtr<CSSValueList> repeatedValues = CSSValueList::createSpaceSeparated();
+    arguments->next(); // Skip the repetition count.
+    arguments->next(); // Skip the comma.
+
+    // Handle leading <ident>*.
+    CSSParserValue* currentValue = arguments->current();
+    if (currentValue && currentValue->unit == CSSParserValue::ValueList)
+        parseGridLineNames(arguments, *repeatedValues);
+
+    while (arguments->current()) {
+        RefPtrWillBeRawPtr<CSSValue> trackSize = parseGridTrackSize(*arguments);
+        if (!trackSize)
+            return false;
+
+        repeatedValues->append(trackSize);
+
+        // This takes care of any trailing <ident>* in the grammar.
+        currentValue = arguments->current();
+        if (currentValue && currentValue->unit == CSSParserValue::ValueList)
+            parseGridLineNames(arguments, *repeatedValues);
+    }
+
+    for (size_t i = 0; i < repetitions; ++i) {
+        for (size_t j = 0; j < repeatedValues->length(); ++j)
+            list.append(repeatedValues->itemWithoutBoundsCheck(j));
+    }
+
+    // parseGridTrackSize iterated over the repeat arguments, move to the next value.
+    m_valueList->next();
+    return true;
+}
+
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTrackSize(CSSParserValueList& inputList)
+{
+    ASSERT(RuntimeEnabledFeatures::cssGridLayoutEnabled());
+
+    CSSParserValue* currentValue = inputList.current();
+    inputList.next();
+
+    if (currentValue->id == CSSValueAuto)
+        return cssValuePool().createIdentifierValue(CSSValueAuto);
+
+    if (currentValue->unit == CSSParserValue::Function && equalIgnoringCase(currentValue->function->name, "minmax(")) {
+        // The spec defines the following grammar: minmax( <track-breadth> , <track-breadth> )
+        CSSParserValueList* arguments = currentValue->function->args.get();
+        if (!arguments || arguments->size() != 3 || !isComma(arguments->valueAt(1)))
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> minTrackBreadth = parseGridBreadth(arguments->valueAt(0));
+        if (!minTrackBreadth)
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> maxTrackBreadth = parseGridBreadth(arguments->valueAt(2));
+        if (!maxTrackBreadth)
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSValueList> parsedArguments = CSSValueList::createCommaSeparated();
+        parsedArguments->append(minTrackBreadth);
+        parsedArguments->append(maxTrackBreadth);
+        return CSSFunctionValue::create("minmax(", parsedArguments);
+    }
+
+    return parseGridBreadth(currentValue);
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseGridBreadth(CSSParserValue* currentValue)
+{
+    if (currentValue->id == CSSValueMinContent || currentValue->id == CSSValueMaxContent)
+        return cssValuePool().createIdentifierValue(currentValue->id);
+
+    if (currentValue->unit == CSSPrimitiveValue::CSS_FR) {
+        double flexValue = currentValue->fValue;
+
+        // Fractional unit is a non-negative dimension.
+        if (flexValue <= 0)
+            return nullptr;
+
+        return cssValuePool().createValue(flexValue, CSSPrimitiveValue::CSS_FR);
+    }
+
+    if (!validUnit(currentValue, FNonNeg | FLength | FPercent))
+        return nullptr;
+
+    return createPrimitiveNumericValue(currentValue);
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseGridTemplateAreas()
+{
+    NamedGridAreaMap gridAreaMap;
+    size_t rowCount = 0;
+    size_t columnCount = 0;
+
+    while (CSSParserValue* currentValue = m_valueList->current()) {
+        if (currentValue->unit != CSSPrimitiveValue::CSS_STRING)
+            return nullptr;
+
+        String gridRowNames = currentValue->string;
+        if (!gridRowNames.length())
+            return nullptr;
+
+        Vector<String> columnNames;
+        gridRowNames.split(' ', columnNames);
+
+        if (!columnCount) {
+            columnCount = columnNames.size();
+            ASSERT(columnCount);
+        } else if (columnCount != columnNames.size()) {
+            // The declaration is invalid is all the rows don't have the number of columns.
+            return nullptr;
+        }
+
+        for (size_t currentCol = 0; currentCol < columnCount; ++currentCol) {
+            const String& gridAreaName = columnNames[currentCol];
+
+            // Unamed areas are always valid (we consider them to be 1x1).
+            if (gridAreaName == ".")
+                continue;
+
+            // We handle several grid areas with the same name at once to simplify the validation code.
+            size_t lookAheadCol;
+            for (lookAheadCol = currentCol; lookAheadCol < (columnCount - 1); ++lookAheadCol) {
+                if (columnNames[lookAheadCol + 1] != gridAreaName)
+                    break;
+            }
+
+            NamedGridAreaMap::iterator gridAreaIt = gridAreaMap.find(gridAreaName);
+            if (gridAreaIt == gridAreaMap.end()) {
+                gridAreaMap.add(gridAreaName, GridCoordinate(GridSpan(rowCount, rowCount), GridSpan(currentCol, lookAheadCol)));
+            } else {
+                GridCoordinate& gridCoordinate = gridAreaIt->value;
+
+                // The following checks test that the grid area is a single filled-in rectangle.
+                // 1. The new row is adjacent to the previously parsed row.
+                if (rowCount != gridCoordinate.rows.initialPositionIndex + 1)
+                    return nullptr;
+
+                // 2. The new area starts at the same position as the previously parsed area.
+                if (currentCol != gridCoordinate.columns.initialPositionIndex)
+                    return nullptr;
+
+                // 3. The new area ends at the same position as the previously parsed area.
+                if (lookAheadCol != gridCoordinate.columns.finalPositionIndex)
+                    return nullptr;
+
+                ++gridCoordinate.rows.finalPositionIndex;
+            }
+            currentCol = lookAheadCol;
+        }
+
+        ++rowCount;
+        m_valueList->next();
+    }
+
+    if (!rowCount || !columnCount)
+        return nullptr;
+
+    return CSSGridTemplateAreasValue::create(gridAreaMap, rowCount, columnCount);
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseCounterContent(CSSParserValueList* args, bool counters)
+{
+    unsigned numArgs = args->size();
+    if (counters && numArgs != 3 && numArgs != 5)
+        return nullptr;
+    if (!counters && numArgs != 1 && numArgs != 3)
+        return nullptr;
+
+    CSSParserValue* i = args->current();
+    if (i->unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> identifier = createPrimitiveStringValue(i);
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> separator;
+    if (!counters)
+        separator = cssValuePool().createValue(String(), CSSPrimitiveValue::CSS_STRING);
+    else {
+        i = args->next();
+        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
+            return nullptr;
+
+        i = args->next();
+        if (i->unit != CSSPrimitiveValue::CSS_STRING)
+            return nullptr;
+
+        separator = createPrimitiveStringValue(i);
+    }
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> listStyle;
+    i = args->next();
+    if (!i) // Make the list style default decimal
+        listStyle = cssValuePool().createIdentifierValue(CSSValueDecimal);
+    else {
+        if (i->unit != CSSParserValue::Operator || i->iValue != ',')
+            return nullptr;
+
+        i = args->next();
+        if (i->unit != CSSPrimitiveValue::CSS_IDENT)
+            return nullptr;
+
+        CSSValueID listStyleID = CSSValueInvalid;
+        if (i->id == CSSValueNone || (i->id >= CSSValueDisc && i->id <= CSSValueKatakanaIroha))
+            listStyleID = i->id;
+        else
+            return nullptr;
+
+        listStyle = cssValuePool().createIdentifierValue(listStyleID);
+    }
+
+    return cssValuePool().createValue(Counter::create(identifier.release(), listStyle.release(), separator.release()));
+}
+
+bool CSSPropertyParser::parseClipShape(CSSPropertyID propId, bool important)
+{
+    CSSParserValue* value = m_valueList->current();
+    CSSParserValueList* args = value->function->args.get();
+
+    if (!equalIgnoringCase(value->function->name, "rect(") || !args)
+        return false;
+
+    // rect(t, r, b, l) || rect(t r b l)
+    if (args->size() != 4 && args->size() != 7)
+        return false;
+    RefPtrWillBeRawPtr<Rect> rect = Rect::create();
+    bool valid = true;
+    int i = 0;
+    CSSParserValue* a = args->current();
+    while (a) {
+        valid = a->id == CSSValueAuto || validUnit(a, FLength);
+        if (!valid)
+            break;
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = a->id == CSSValueAuto ?
+            cssValuePool().createIdentifierValue(CSSValueAuto) :
+            createPrimitiveNumericValue(a);
+        if (i == 0)
+            rect->setTop(length);
+        else if (i == 1)
+            rect->setRight(length);
+        else if (i == 2)
+            rect->setBottom(length);
+        else
+            rect->setLeft(length);
+        a = args->next();
+        if (a && args->size() == 7) {
+            if (a->unit == CSSParserValue::Operator && a->iValue == ',') {
+                a = args->next();
+            } else {
+                valid = false;
+                break;
+            }
+        }
+        i++;
+    }
+    if (valid) {
+        addProperty(propId, cssValuePool().createValue(rect.release()), important);
+        m_valueList->next();
+        return true;
+    }
+    return false;
+}
+
+static void completeBorderRadii(RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[4])
+{
+    if (radii[3])
+        return;
+    if (!radii[2]) {
+        if (!radii[1])
+            radii[1] = radii[0];
+        radii[2] = radii[0];
+    }
+    radii[3] = radii[1];
+}
+
+// FIXME: This should be refactored with CSSParser::parseBorderRadius.
+// CSSParser::parseBorderRadius contains support for some legacy radius construction.
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseInsetRoundedCorners(PassRefPtrWillBeRawPtr<CSSBasicShapeInset> shape, CSSParserValueList* args)
+{
+    CSSParserValue* argument = args->next();
+
+    if (!argument)
+        return nullptr;
+
+    CSSParserValueList radiusArguments;
+    while (argument) {
+        radiusArguments.addValue(*argument);
+        argument = args->next();
+    }
+
+    unsigned num = radiusArguments.size();
+    if (!num || num > 9)
+        return nullptr;
+
+    // FIXME: Refactor completeBorderRadii and the array
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[2][4];
+
+    unsigned indexAfterSlash = 0;
+    for (unsigned i = 0; i < num; ++i) {
+        CSSParserValue* value = radiusArguments.valueAt(i);
+        if (value->unit == CSSParserValue::Operator) {
+            if (value->iValue != '/')
+                return nullptr;
+
+            if (!i || indexAfterSlash || i + 1 == num)
+                return nullptr;
+
+            indexAfterSlash = i + 1;
+            completeBorderRadii(radii[0]);
+            continue;
+        }
+
+        if (i - indexAfterSlash >= 4)
+            return nullptr;
+
+        if (!validUnit(value, FLength | FPercent | FNonNeg))
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
+
+        if (!indexAfterSlash)
+            radii[0][i] = radius;
+        else
+            radii[1][i - indexAfterSlash] = radius.release();
+    }
+
+    if (!indexAfterSlash) {
+        completeBorderRadii(radii[0]);
+        for (unsigned i = 0; i < 4; ++i)
+            radii[1][i] = radii[0][i];
+    } else {
+        completeBorderRadii(radii[1]);
+    }
+    shape->setTopLeftRadius(createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()));
+    shape->setTopRightRadius(createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()));
+    shape->setBottomRightRadius(createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()));
+    shape->setBottomLeftRadius(createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()));
+
+    return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeInset(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    RefPtrWillBeRawPtr<CSSBasicShapeInset> shape = CSSBasicShapeInset::create();
+
+    CSSParserValue* argument = args->current();
+    WillBeHeapVector<RefPtrWillBeMember<CSSPrimitiveValue> > widthArguments;
+    bool hasRoundedInset = false;
+
+    while (argument) {
+        if (argument->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(argument->string, "round")) {
+            hasRoundedInset = true;
+            break;
+        }
+
+        Units unitFlags = FLength | FPercent;
+        if (!validUnit(argument, unitFlags) || widthArguments.size() > 4)
+            return nullptr;
+
+        widthArguments.append(createPrimitiveNumericValue(argument));
+        argument = args->next();
+    }
+
+    switch (widthArguments.size()) {
+    case 1: {
+        shape->updateShapeSize1Value(widthArguments[0].get());
+        break;
+    }
+    case 2: {
+        shape->updateShapeSize2Values(widthArguments[0].get(), widthArguments[1].get());
+        break;
+        }
+    case 3: {
+        shape->updateShapeSize3Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get());
+        break;
+    }
+    case 4: {
+        shape->updateShapeSize4Values(widthArguments[0].get(), widthArguments[1].get(), widthArguments[2].get(), widthArguments[3].get());
+        break;
+    }
+    default:
+        return nullptr;
+    }
+
+    if (hasRoundedInset)
+        return parseInsetRoundedCorners(shape, args);
+    return shape;
+}
+
+static bool isItemPositionKeyword(CSSValueID id)
+{
+    return id == CSSValueStart || id == CSSValueEnd || id == CSSValueCenter
+        || id == CSSValueSelfStart || id == CSSValueSelfEnd || id == CSSValueFlexStart
+        || id == CSSValueFlexEnd || id == CSSValueLeft || id == CSSValueRight;
+}
+
+bool CSSPropertyParser::parseItemPositionOverflowPosition(CSSPropertyID propId, bool important)
+{
+    // auto | baseline | stretch | [<item-position> && <overflow-position>? ]
+    // <item-position> = center | start | end | self-start | self-end | flex-start | flex-end | left | right;
+    // <overflow-position> = true | safe
+
+    CSSParserValue* value = m_valueList->current();
+
+    if (value->id == CSSValueAuto || value->id == CSSValueBaseline || value->id == CSSValueStretch) {
+        if (m_valueList->next())
+            return false;
+
+        addProperty(propId, cssValuePool().createIdentifierValue(value->id), important);
+        return true;
+    }
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> position = nullptr;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> overflowAlignmentKeyword = nullptr;
+    if (isItemPositionKeyword(value->id)) {
+        position = cssValuePool().createIdentifierValue(value->id);
+        value = m_valueList->next();
+        if (value) {
+            if (value->id == CSSValueTrue || value->id == CSSValueSafe)
+                overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
+            else
+                return false;
+        }
+    } else if (value->id == CSSValueTrue || value->id == CSSValueSafe) {
+        overflowAlignmentKeyword = cssValuePool().createIdentifierValue(value->id);
+        value = m_valueList->next();
+        if (value) {
+            if (isItemPositionKeyword(value->id))
+                position = cssValuePool().createIdentifierValue(value->id);
+            else
+                return false;
+        }
+    } else {
+        return false;
+    }
+
+    if (m_valueList->next())
+        return false;
+
+    ASSERT(position);
+    if (overflowAlignmentKeyword)
+        addProperty(propId, createPrimitiveValuePair(position, overflowAlignmentKeyword), important);
+    else
+        addProperty(propId, position.release(), important);
+
+    return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeRectangle(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    // rect(x, y, width, height, [[rx], ry])
+    if (args->size() != 7 && args->size() != 9 && args->size() != 11)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSBasicShapeRectangle> shape = CSSBasicShapeRectangle::create();
+
+    unsigned argumentNumber = 0;
+    CSSParserValue* argument = args->current();
+    while (argument) {
+        Units unitFlags = FLength | FPercent;
+        if (argumentNumber > 1) {
+            // Arguments width, height, rx, and ry cannot be negative.
+            unitFlags = unitFlags | FNonNeg;
+        }
+        if (!validUnit(argument, unitFlags))
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
+        ASSERT(argumentNumber < 6);
+        switch (argumentNumber) {
+        case 0:
+            shape->setX(length);
+            break;
+        case 1:
+            shape->setY(length);
+            break;
+        case 2:
+            shape->setWidth(length);
+            break;
+        case 3:
+            shape->setHeight(length);
+            break;
+        case 4:
+            shape->setRadiusX(length);
+            break;
+        case 5:
+            shape->setRadiusY(length);
+            break;
+        }
+        argument = args->next();
+        if (argument) {
+            if (!isComma(argument))
+                return nullptr;
+
+            argument = args->next();
+        }
+        argumentNumber++;
+    }
+
+    if (argumentNumber < 4)
+        return nullptr;
+    return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeInsetRectangle(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    // inset-rectangle(top, right, bottom, left, [[rx], ry])
+    if (args->size() != 7 && args->size() != 9 && args->size() != 11)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSBasicShapeInsetRectangle> shape = CSSBasicShapeInsetRectangle::create();
+
+    unsigned argumentNumber = 0;
+    CSSParserValue* argument = args->current();
+    while (argument) {
+        Units unitFlags = FLength | FPercent | FNonNeg;
+        if (!validUnit(argument, unitFlags))
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
+        ASSERT(argumentNumber < 6);
+        switch (argumentNumber) {
+        case 0:
+            shape->setTop(length);
+            break;
+        case 1:
+            shape->setRight(length);
+            break;
+        case 2:
+            shape->setBottom(length);
+            break;
+        case 3:
+            shape->setLeft(length);
+            break;
+        case 4:
+            shape->setRadiusX(length);
+            break;
+        case 5:
+            shape->setRadiusY(length);
+            break;
+        }
+        argument = args->next();
+        if (argument) {
+            if (!isComma(argument))
+                return nullptr;
+
+            argument = args->next();
+        }
+        argumentNumber++;
+    }
+
+    if (argumentNumber < 4)
+        return nullptr;
+    return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseShapeRadius(CSSParserValue* value)
+{
+    if (value->id == CSSValueClosestSide || value->id == CSSValueFarthestSide)
+        return cssValuePool().createIdentifierValue(value->id);
+
+    if (!validUnit(value, FLength | FPercent | FNonNeg))
+        return nullptr;
+
+    return createPrimitiveNumericValue(value);
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeCircle(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    // circle(radius)
+    // circle(radius at <position>
+    // circle(at <position>)
+    // where position defines centerX and centerY using a CSS <position> data type.
+    RefPtrWillBeRawPtr<CSSBasicShapeCircle> shape = CSSBasicShapeCircle::create();
+
+    for (CSSParserValue* argument = args->current(); argument; argument = args->next()) {
+        // The call to parseFillPosition below should consume all of the
+        // arguments except the first two. Thus, and index greater than one
+        // indicates an invalid production.
+        if (args->currentIndex() > 1)
+            return nullptr;
+
+        if (!args->currentIndex() && argument->id != CSSValueAt) {
+            if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
+                shape->setRadius(radius);
+                continue;
+            }
+
+            return nullptr;
+        }
+
+        if (argument->id == CSSValueAt) {
+            RefPtrWillBeRawPtr<CSSValue> centerX;
+            RefPtrWillBeRawPtr<CSSValue> centerY;
+            args->next(); // set list to start of position center
+            parseFillPosition(args, centerX, centerY);
+            if (centerX && centerY && !args->current()) {
+                ASSERT(centerX->isPrimitiveValue());
+                ASSERT(centerY->isPrimitiveValue());
+                shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
+                shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
+            } else {
+                return nullptr;
+            }
+        } else {
+            return nullptr;
+        }
+    }
+
+    return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseDeprecatedBasicShapeCircle(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    // circle(centerX, centerY, radius)
+    if (args->size() != 5)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSDeprecatedBasicShapeCircle> shape = CSSDeprecatedBasicShapeCircle::create();
+
+    unsigned argumentNumber = 0;
+    CSSParserValue* argument = args->current();
+    while (argument) {
+        Units unitFlags = FLength | FPercent;
+        if (argumentNumber == 2) {
+            // Argument radius cannot be negative.
+            unitFlags = unitFlags | FNonNeg;
+        }
+
+        if (!validUnit(argument, unitFlags))
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
+        ASSERT(argumentNumber < 3);
+        switch (argumentNumber) {
+        case 0:
+            shape->setCenterX(length);
+            break;
+        case 1:
+            shape->setCenterY(length);
+            break;
+        case 2:
+            shape->setRadius(length);
+            break;
+        }
+
+        argument = args->next();
+        if (argument) {
+            if (!isComma(argument))
+                return nullptr;
+            argument = args->next();
+        }
+        argumentNumber++;
+    }
+
+    if (argumentNumber < 3)
+        return nullptr;
+    return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapeEllipse(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    // ellipse(radiusX)
+    // ellipse(radiusX at <position>
+    // ellipse(radiusX radiusY)
+    // ellipse(radiusX radiusY at <position>
+    // ellipse(at <position>)
+    // where position defines centerX and centerY using a CSS <position> data type.
+    RefPtrWillBeRawPtr<CSSBasicShapeEllipse> shape = CSSBasicShapeEllipse::create();
+
+    for (CSSParserValue* argument = args->current(); argument; argument = args->next()) {
+        // The call to parseFillPosition below should consume all of the
+        // arguments except the first three. Thus, an index greater than two
+        // indicates an invalid production.
+        if (args->currentIndex() > 2)
+            return nullptr;
+
+        if (args->currentIndex() < 2 && argument->id != CSSValueAt) {
+            if (RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = parseShapeRadius(argument)) {
+                if (!shape->radiusX())
+                    shape->setRadiusX(radius);
+                else
+                    shape->setRadiusY(radius);
+                continue;
+            }
+
+            return nullptr;
+        }
+
+        if (argument->id != CSSValueAt)
+            return nullptr;
+        RefPtrWillBeRawPtr<CSSValue> centerX;
+        RefPtrWillBeRawPtr<CSSValue> centerY;
+        args->next(); // set list to start of position center
+        parseFillPosition(args, centerX, centerY);
+        if (!centerX || !centerY || args->current())
+            return nullptr;
+
+        ASSERT(centerX->isPrimitiveValue());
+        ASSERT(centerY->isPrimitiveValue());
+        shape->setCenterX(toCSSPrimitiveValue(centerX.get()));
+        shape->setCenterY(toCSSPrimitiveValue(centerY.get()));
+    }
+
+    return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseDeprecatedBasicShapeEllipse(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    // ellipse(centerX, centerY, radiusX, radiusY)
+    if (args->size() != 7)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSDeprecatedBasicShapeEllipse> shape = CSSDeprecatedBasicShapeEllipse::create();
+    unsigned argumentNumber = 0;
+    CSSParserValue* argument = args->current();
+    while (argument) {
+        Units unitFlags = FLength | FPercent;
+        if (argumentNumber > 1) {
+            // Arguments radiusX and radiusY cannot be negative.
+            unitFlags = unitFlags | FNonNeg;
+        }
+        if (!validUnit(argument, unitFlags))
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> length = createPrimitiveNumericValue(argument);
+        ASSERT(argumentNumber < 4);
+        switch (argumentNumber) {
+        case 0:
+            shape->setCenterX(length);
+            break;
+        case 1:
+            shape->setCenterY(length);
+            break;
+        case 2:
+            shape->setRadiusX(length);
+            break;
+        case 3:
+            shape->setRadiusY(length);
+            break;
+        }
+
+        argument = args->next();
+        if (argument) {
+            if (!isComma(argument))
+                return nullptr;
+            argument = args->next();
+        }
+        argumentNumber++;
+    }
+
+    if (argumentNumber < 4)
+        return nullptr;
+    return shape;
+}
+
+PassRefPtrWillBeRawPtr<CSSBasicShape> CSSPropertyParser::parseBasicShapePolygon(CSSParserValueList* args)
+{
+    ASSERT(args);
+
+    unsigned size = args->size();
+    if (!size)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSBasicShapePolygon> shape = CSSBasicShapePolygon::create();
+
+    CSSParserValue* argument = args->current();
+    if (argument->id == CSSValueEvenodd || argument->id == CSSValueNonzero) {
+        shape->setWindRule(argument->id == CSSValueEvenodd ? RULE_EVENODD : RULE_NONZERO);
+
+        if (!isComma(args->next()))
+            return nullptr;
+
+        argument = args->next();
+        size -= 2;
+    }
+
+    // <length> <length>, ... <length> <length> -> each pair has 3 elements except the last one
+    if (!size || (size % 3) - 2)
+        return nullptr;
+
+    CSSParserValue* argumentX = argument;
+    while (argumentX) {
+        if (!validUnit(argumentX, FLength | FPercent))
+            return nullptr;
+
+        CSSParserValue* argumentY = args->next();
+        if (!argumentY || !validUnit(argumentY, FLength | FPercent))
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> xLength = createPrimitiveNumericValue(argumentX);
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> yLength = createPrimitiveNumericValue(argumentY);
+
+        shape->appendPoint(xLength.release(), yLength.release());
+
+        CSSParserValue* commaOrNull = args->next();
+        if (!commaOrNull)
+            argumentX = 0;
+        else if (!isComma(commaOrNull))
+            return nullptr;
+        else
+            argumentX = args->next();
+    }
+
+    return shape;
+}
+
+static bool isBoxValue(CSSValueID valueId)
+{
+    switch (valueId) {
+    case CSSValueContentBox:
+    case CSSValuePaddingBox:
+    case CSSValueBorderBox:
+    case CSSValueMarginBox:
+        return true;
+    default:
+        break;
+    }
+
+    return false;
+}
+
+// FIXME This function is temporary to allow for an orderly transition between
+// the new CSS Shapes circle and ellipse syntax. It will be removed when the
+// old syntax is removed.
+static bool isDeprecatedBasicShape(CSSParserValueList* args)
+{
+    for (unsigned i = args->currentIndex(); i < args->size(); ++i) {
+        CSSParserValue* value = args->valueAt(i);
+        if (isComma(value))
+            return true;
+    }
+
+    return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseShapeProperty(CSSPropertyID propId)
+{
+    if (!RuntimeEnabledFeatures::cssShapesEnabled())
+        return nullptr;
+
+    CSSParserValue* value = m_valueList->current();
+    CSSValueID valueId = value->id;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> boxValue;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue;
+
+    if (valueId == CSSValueNone
+        || (valueId == CSSValueOutsideShape && propId == CSSPropertyShapeInside)) {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> keywordValue = parseValidPrimitive(valueId, value);
+        m_valueList->next();
+        return keywordValue.release();
+    }
+
+    RefPtrWillBeRawPtr<CSSValue> imageValue;
+    if (valueId != CSSValueNone && parseFillImage(m_valueList.get(), imageValue)) {
+        m_valueList->next();
+        return imageValue.release();
+    }
+
+    return parseBasicShapeAndOrBox();
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseBasicShapeAndOrBox()
+{
+    CSSParserValue* value = m_valueList->current();
+
+    bool shapeFound = false;
+    bool boxFound = false;
+    CSSValueID valueId;
+
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    for (unsigned i = 0; i < 2; ++i) {
+        if (!value)
+            break;
+        valueId = value->id;
+        if (value->unit == CSSParserValue::Function && !shapeFound) {
+            // parseBasicShape already asks for the next value list item.
+            RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue = parseBasicShape();
+            if (!shapeValue)
+                return nullptr;
+            list->append(shapeValue.release());
+            shapeFound = true;
+        } else if (isBoxValue(valueId) && !boxFound) {
+            list->append(parseValidPrimitive(valueId, value));
+            boxFound = true;
+            m_valueList->next();
+        } else {
+            return nullptr;
+        }
+
+        value = m_valueList->current();
+    }
+
+    if (m_valueList->current())
+        return nullptr;
+    return list.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseBasicShape()
+{
+    CSSParserValue* value = m_valueList->current();
+    ASSERT(value->unit == CSSParserValue::Function);
+    CSSParserValueList* args = value->function->args.get();
+
+    if (!args)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSBasicShape> shape;
+    if (equalIgnoringCase(value->function->name, "rectangle("))
+        shape = parseBasicShapeRectangle(args);
+    else if (equalIgnoringCase(value->function->name, "circle("))
+        if (isDeprecatedBasicShape(args))
+            shape = parseDeprecatedBasicShapeCircle(args);
+        else
+            shape = parseBasicShapeCircle(args);
+    else if (equalIgnoringCase(value->function->name, "ellipse("))
+        if (isDeprecatedBasicShape(args))
+            shape = parseDeprecatedBasicShapeEllipse(args);
+        else
+            shape = parseBasicShapeEllipse(args);
+    else if (equalIgnoringCase(value->function->name, "polygon("))
+        shape = parseBasicShapePolygon(args);
+    else if (equalIgnoringCase(value->function->name, "inset-rectangle("))
+        shape = parseBasicShapeInsetRectangle(args);
+    else if (equalIgnoringCase(value->function->name, "inset("))
+        shape = parseBasicShapeInset(args);
+
+    if (!shape)
+        return nullptr;
+
+    m_valueList->next();
+
+    return cssValuePool().createValue(shape.release());
+}
+
+// [ 'font-style' || 'font-variant' || 'font-weight' ]? 'font-size' [ / 'line-height' ]? 'font-family'
+bool CSSPropertyParser::parseFont(bool important)
+{
+    // Let's check if there is an inherit or initial somewhere in the shorthand.
+    for (unsigned i = 0; i < m_valueList->size(); ++i) {
+        if (m_valueList->valueAt(i)->id == CSSValueInherit || m_valueList->valueAt(i)->id == CSSValueInitial)
+            return false;
+    }
+
+    ShorthandScope scope(this, CSSPropertyFont);
+    // Optional font-style, font-variant and font-weight.
+    bool fontStyleParsed = false;
+    bool fontVariantParsed = false;
+    bool fontWeightParsed = false;
+    CSSParserValue* value;
+    while ((value = m_valueList->current())) {
+        if (!fontStyleParsed && isValidKeywordPropertyAndValue(CSSPropertyFontStyle, value->id, m_context)) {
+            addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(value->id), important);
+            fontStyleParsed = true;
+        } else if (!fontVariantParsed && (value->id == CSSValueNormal || value->id == CSSValueSmallCaps)) {
+            // Font variant in the shorthand is particular, it only accepts normal or small-caps.
+            addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(value->id), important);
+            fontVariantParsed = true;
+        } else if (!fontWeightParsed && parseFontWeight(important))
+            fontWeightParsed = true;
+        else
+            break;
+        m_valueList->next();
+    }
+
+    if (!value)
+        return false;
+
+    if (!fontStyleParsed)
+        addProperty(CSSPropertyFontStyle, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+    if (!fontVariantParsed)
+        addProperty(CSSPropertyFontVariant, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+    if (!fontWeightParsed)
+        addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+
+    // Now a font size _must_ come.
+    // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
+    if (!parseFontSize(important))
+        return false;
+
+    value = m_valueList->current();
+    if (!value)
+        return false;
+
+    if (isForwardSlashOperator(value)) {
+        // The line-height property.
+        value = m_valueList->next();
+        if (!value)
+            return false;
+        if (!parseLineHeight(important))
+            return false;
+    } else
+        addProperty(CSSPropertyLineHeight, cssValuePool().createIdentifierValue(CSSValueNormal), important, true);
+
+    // Font family must come now.
+    RefPtrWillBeRawPtr<CSSValue> parsedFamilyValue = parseFontFamily();
+    if (!parsedFamilyValue)
+        return false;
+
+    addProperty(CSSPropertyFontFamily, parsedFamilyValue.release(), important);
+
+    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20110324/#font-prop requires that
+    // "font-stretch", "font-size-adjust", and "font-kerning" be reset to their initial values
+    // but we don't seem to support them at the moment. They should also be added here once implemented.
+    if (m_valueList->current())
+        return false;
+
+    return true;
+}
+
+class FontFamilyValueBuilder {
+    DISALLOW_ALLOCATION();
+public:
+    FontFamilyValueBuilder(CSSValueList* list)
+        : m_list(list)
+    {
+    }
+
+    void add(const CSSParserString& string)
+    {
+        if (!m_builder.isEmpty())
+            m_builder.append(' ');
+
+        if (string.is8Bit()) {
+            m_builder.append(string.characters8(), string.length());
+            return;
+        }
+
+        m_builder.append(string.characters16(), string.length());
+    }
+
+    void commit()
+    {
+        if (m_builder.isEmpty())
+            return;
+        m_list->append(cssValuePool().createFontFamilyValue(m_builder.toString()));
+        m_builder.clear();
+    }
+
+private:
+    StringBuilder m_builder;
+    CSSValueList* m_list;
+};
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseFontFamily()
+{
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+    CSSParserValue* value = m_valueList->current();
+
+    FontFamilyValueBuilder familyBuilder(list.get());
+    bool inFamily = false;
+
+    while (value) {
+        CSSParserValue* nextValue = m_valueList->next();
+        bool nextValBreaksFont = !nextValue ||
+                                 (nextValue->unit == CSSParserValue::Operator && nextValue->iValue == ',');
+        bool nextValIsFontName = nextValue &&
+            ((nextValue->id >= CSSValueSerif && nextValue->id <= CSSValueWebkitBody) ||
+            (nextValue->unit == CSSPrimitiveValue::CSS_STRING || nextValue->unit == CSSPrimitiveValue::CSS_IDENT));
+
+        bool valueIsKeyword = value->id == CSSValueInitial || value->id == CSSValueInherit || value->id == CSSValueDefault;
+        if (valueIsKeyword && !inFamily) {
+            if (nextValBreaksFont)
+                value = m_valueList->next();
+            else if (nextValIsFontName)
+                value = nextValue;
+            continue;
+        }
+
+        if (value->id >= CSSValueSerif && value->id <= CSSValueWebkitBody) {
+            if (inFamily)
+                familyBuilder.add(value->string);
+            else if (nextValBreaksFont || !nextValIsFontName)
+                list->append(cssValuePool().createIdentifierValue(value->id));
+            else {
+                familyBuilder.commit();
+                familyBuilder.add(value->string);
+                inFamily = true;
+            }
+        } else if (value->unit == CSSPrimitiveValue::CSS_STRING) {
+            // Strings never share in a family name.
+            inFamily = false;
+            familyBuilder.commit();
+            list->append(cssValuePool().createFontFamilyValue(value->string));
+        } else if (value->unit == CSSPrimitiveValue::CSS_IDENT) {
+            if (inFamily)
+                familyBuilder.add(value->string);
+            else if (nextValBreaksFont || !nextValIsFontName)
+                list->append(cssValuePool().createFontFamilyValue(value->string));
+            else {
+                familyBuilder.commit();
+                familyBuilder.add(value->string);
+                inFamily = true;
+            }
+        } else {
+            break;
+        }
+
+        if (!nextValue)
+            break;
+
+        if (nextValBreaksFont) {
+            value = m_valueList->next();
+            familyBuilder.commit();
+            inFamily = false;
+        }
+        else if (nextValIsFontName)
+            value = nextValue;
+        else
+            break;
+    }
+    familyBuilder.commit();
+
+    if (!list->length())
+        list = nullptr;
+    return list.release();
+}
+
+bool CSSPropertyParser::parseLineHeight(bool important)
+{
+    CSSParserValue* value = m_valueList->current();
+    CSSValueID id = value->id;
+    bool validPrimitive = false;
+    // normal | <number> | <length> | <percentage> | inherit
+    if (id == CSSValueNormal)
+        validPrimitive = true;
+    else
+        validPrimitive = (!id && validUnit(value, FNumber | FLength | FPercent | FNonNeg));
+    if (validPrimitive && (!m_valueList->next() || inShorthand()))
+        addProperty(CSSPropertyLineHeight, parseValidPrimitive(id, value), important);
+    return validPrimitive;
+}
+
+bool CSSPropertyParser::parseFontSize(bool important)
+{
+    CSSParserValue* value = m_valueList->current();
+    CSSValueID id = value->id;
+    bool validPrimitive = false;
+    // <absolute-size> | <relative-size> | <length> | <percentage> | inherit
+    if (id >= CSSValueXxSmall && id <= CSSValueLarger)
+        validPrimitive = true;
+    else
+        validPrimitive = validUnit(value, FLength | FPercent | FNonNeg);
+    if (validPrimitive && (!m_valueList->next() || inShorthand()))
+        addProperty(CSSPropertyFontSize, parseValidPrimitive(id, value), important);
+    return validPrimitive;
+}
+
+bool CSSPropertyParser::parseFontVariant(bool important)
+{
+    RefPtrWillBeRawPtr<CSSValueList> values;
+    if (m_valueList->size() > 1)
+        values = CSSValueList::createCommaSeparated();
+    CSSParserValue* val;
+    bool expectComma = false;
+    while ((val = m_valueList->current())) {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedValue;
+        if (!expectComma) {
+            expectComma = true;
+            if (val->id == CSSValueNormal || val->id == CSSValueSmallCaps)
+                parsedValue = cssValuePool().createIdentifierValue(val->id);
+            else if (val->id == CSSValueAll && !values) {
+                // 'all' is only allowed in @font-face and with no other values. Make a value list to
+                // indicate that we are in the @font-face case.
+                values = CSSValueList::createCommaSeparated();
+                parsedValue = cssValuePool().createIdentifierValue(val->id);
+            }
+        } else if (val->unit == CSSParserValue::Operator && val->iValue == ',') {
+            expectComma = false;
+            m_valueList->next();
+            continue;
+        }
+
+        if (!parsedValue)
+            return false;
+
+        m_valueList->next();
+
+        if (values)
+            values->append(parsedValue.release());
+        else {
+            addProperty(CSSPropertyFontVariant, parsedValue.release(), important);
+            return true;
+        }
+    }
+
+    if (values && values->length()) {
+        m_hasFontFaceOnlyValues = true;
+        addProperty(CSSPropertyFontVariant, values.release(), important);
+        return true;
+    }
+
+    return false;
+}
+
+bool CSSPropertyParser::parseFontWeight(bool important)
+{
+    CSSParserValue* value = m_valueList->current();
+    if ((value->id >= CSSValueNormal) && (value->id <= CSSValue900)) {
+        addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(value->id), important);
+        return true;
+    }
+    if (validUnit(value, FInteger | FNonNeg, HTMLQuirksMode)) {
+        int weight = static_cast<int>(value->fValue);
+        if (!(weight % 100) && weight >= 100 && weight <= 900) {
+            addProperty(CSSPropertyFontWeight, cssValuePool().createIdentifierValue(static_cast<CSSValueID>(CSSValue100 + weight / 100 - 1)), important);
+            return true;
+        }
+    }
+    return false;
+}
+
+bool CSSPropertyParser::parseFontFaceSrcURI(CSSValueList* valueList)
+{
+    RefPtrWillBeRawPtr<CSSFontFaceSrcValue> uriValue(CSSFontFaceSrcValue::create(completeURL(m_valueList->current()->string)));
+
+    CSSParserValue* value = m_valueList->next();
+    if (!value) {
+        valueList->append(uriValue.release());
+        return true;
+    }
+    if (value->unit == CSSParserValue::Operator && value->iValue == ',') {
+        m_valueList->next();
+        valueList->append(uriValue.release());
+        return true;
+    }
+
+    if (value->unit != CSSParserValue::Function || !equalIgnoringCase(value->function->name, "format("))
+        return false;
+
+    // FIXME: http://www.w3.org/TR/2011/WD-css3-fonts-20111004/ says that format() contains a comma-separated list of strings,
+    // but CSSFontFaceSrcValue stores only one format. Allowing one format for now.
+    CSSParserValueList* args = value->function->args.get();
+    if (!args || args->size() != 1 || (args->current()->unit != CSSPrimitiveValue::CSS_STRING && args->current()->unit != CSSPrimitiveValue::CSS_IDENT))
+        return false;
+    uriValue->setFormat(args->current()->string);
+    valueList->append(uriValue.release());
+    value = m_valueList->next();
+    if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
+        m_valueList->next();
+    return true;
+}
+
+bool CSSPropertyParser::parseFontFaceSrcLocal(CSSValueList* valueList)
+{
+    CSSParserValueList* args = m_valueList->current()->function->args.get();
+    if (!args || !args->size())
+        return false;
+
+    if (args->size() == 1 && args->current()->unit == CSSPrimitiveValue::CSS_STRING)
+        valueList->append(CSSFontFaceSrcValue::createLocal(args->current()->string));
+    else if (args->current()->unit == CSSPrimitiveValue::CSS_IDENT) {
+        StringBuilder builder;
+        for (CSSParserValue* localValue = args->current(); localValue; localValue = args->next()) {
+            if (localValue->unit != CSSPrimitiveValue::CSS_IDENT)
+                return false;
+            if (!builder.isEmpty())
+                builder.append(' ');
+            builder.append(localValue->string);
+        }
+        valueList->append(CSSFontFaceSrcValue::createLocal(builder.toString()));
+    } else
+        return false;
+
+    if (CSSParserValue* value = m_valueList->next()) {
+        if (value->unit == CSSParserValue::Operator && value->iValue == ',')
+            m_valueList->next();
+    }
+    return true;
+}
+
+bool CSSPropertyParser::parseFontFaceSrc()
+{
+    RefPtrWillBeRawPtr<CSSValueList> values(CSSValueList::createCommaSeparated());
+
+    while (CSSParserValue* value = m_valueList->current()) {
+        if (value->unit == CSSPrimitiveValue::CSS_URI) {
+            if (!parseFontFaceSrcURI(values.get()))
+                return false;
+        } else if (value->unit == CSSParserValue::Function && equalIgnoringCase(value->function->name, "local(")) {
+            if (!parseFontFaceSrcLocal(values.get()))
+                return false;
+        } else
+            return false;
+    }
+    if (!values->length())
+        return false;
+
+    addProperty(CSSPropertySrc, values.release(), m_important);
+    m_valueList->next();
+    return true;
+}
+
+bool CSSPropertyParser::parseFontFaceUnicodeRange()
+{
+    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+    bool failed = false;
+    bool operatorExpected = false;
+    for (; m_valueList->current(); m_valueList->next(), operatorExpected = !operatorExpected) {
+        if (operatorExpected) {
+            if (m_valueList->current()->unit == CSSParserValue::Operator && m_valueList->current()->iValue == ',')
+                continue;
+            failed = true;
+            break;
+        }
+        if (m_valueList->current()->unit != CSSPrimitiveValue::CSS_UNICODE_RANGE) {
+            failed = true;
+            break;
+        }
+
+        String rangeString = m_valueList->current()->string;
+        UChar32 from = 0;
+        UChar32 to = 0;
+        unsigned length = rangeString.length();
+
+        if (length < 3) {
+            failed = true;
+            break;
+        }
+
+        unsigned i = 2;
+        while (i < length) {
+            UChar c = rangeString[i];
+            if (c == '-' || c == '?')
+                break;
+            from *= 16;
+            if (c >= '0' && c <= '9')
+                from += c - '0';
+            else if (c >= 'A' && c <= 'F')
+                from += 10 + c - 'A';
+            else if (c >= 'a' && c <= 'f')
+                from += 10 + c - 'a';
+            else {
+                failed = true;
+                break;
+            }
+            i++;
+        }
+        if (failed)
+            break;
+
+        if (i == length)
+            to = from;
+        else if (rangeString[i] == '?') {
+            unsigned span = 1;
+            while (i < length && rangeString[i] == '?') {
+                span *= 16;
+                from *= 16;
+                i++;
+            }
+            if (i < length)
+                failed = true;
+            to = from + span - 1;
+        } else {
+            if (length < i + 2) {
+                failed = true;
+                break;
+            }
+            i++;
+            while (i < length) {
+                UChar c = rangeString[i];
+                to *= 16;
+                if (c >= '0' && c <= '9')
+                    to += c - '0';
+                else if (c >= 'A' && c <= 'F')
+                    to += 10 + c - 'A';
+                else if (c >= 'a' && c <= 'f')
+                    to += 10 + c - 'a';
+                else {
+                    failed = true;
+                    break;
+                }
+                i++;
+            }
+            if (failed)
+                break;
+        }
+        if (from <= to)
+            values->append(CSSUnicodeRangeValue::create(from, to));
+    }
+    if (failed || !values->length())
+        return false;
+    addProperty(CSSPropertyUnicodeRange, values.release(), m_important);
+    return true;
+}
+
+// Returns the number of characters which form a valid double
+// and are terminated by the given terminator character
+template <typename CharacterType>
+static int checkForValidDouble(const CharacterType* string, const CharacterType* end, const char terminator)
+{
+    int length = end - string;
+    if (length < 1)
+        return 0;
+
+    bool decimalMarkSeen = false;
+    int processedLength = 0;
+
+    for (int i = 0; i < length; ++i) {
+        if (string[i] == terminator) {
+            processedLength = i;
+            break;
+        }
+        if (!isASCIIDigit(string[i])) {
+            if (!decimalMarkSeen && string[i] == '.')
+                decimalMarkSeen = true;
+            else
+                return 0;
+        }
+    }
+
+    if (decimalMarkSeen && processedLength == 1)
+        return 0;
+
+    return processedLength;
+}
+
+// Returns the number of characters consumed for parsing a valid double
+// terminated by the given terminator character
+template <typename CharacterType>
+static int parseDouble(const CharacterType* string, const CharacterType* end, const char terminator, double& value)
+{
+    int length = checkForValidDouble(string, end, terminator);
+    if (!length)
+        return 0;
+
+    int position = 0;
+    double localValue = 0;
+
+    // The consumed characters here are guaranteed to be
+    // ASCII digits with or without a decimal mark
+    for (; position < length; ++position) {
+        if (string[position] == '.')
+            break;
+        localValue = localValue * 10 + string[position] - '0';
+    }
+
+    if (++position == length) {
+        value = localValue;
+        return length;
+    }
+
+    double fraction = 0;
+    double scale = 1;
+
+    while (position < length && scale < MAX_SCALE) {
+        fraction = fraction * 10 + string[position++] - '0';
+        scale *= 10;
+    }
+
+    value = localValue + fraction / scale;
+    return length;
+}
+
+template <typename CharacterType>
+static bool parseColorIntOrPercentage(const CharacterType*& string, const CharacterType* end, const char terminator, CSSPrimitiveValue::UnitTypes& expect, int& value)
+{
+    const CharacterType* current = string;
+    double localValue = 0;
+    bool negative = false;
+    while (current != end && isHTMLSpace<CharacterType>(*current))
+        current++;
+    if (current != end && *current == '-') {
+        negative = true;
+        current++;
+    }
+    if (current == end || !isASCIIDigit(*current))
+        return false;
+    while (current != end && isASCIIDigit(*current)) {
+        double newValue = localValue * 10 + *current++ - '0';
+        if (newValue >= 255) {
+            // Clamp values at 255.
+            localValue = 255;
+            while (current != end && isASCIIDigit(*current))
+                ++current;
+            break;
+        }
+        localValue = newValue;
+    }
+
+    if (current == end)
+        return false;
+
+    if (expect == CSSPrimitiveValue::CSS_NUMBER && (*current == '.' || *current == '%'))
+        return false;
+
+    if (*current == '.') {
+        // We already parsed the integral part, try to parse
+        // the fraction part of the percentage value.
+        double percentage = 0;
+        int numCharactersParsed = parseDouble(current, end, '%', percentage);
+        if (!numCharactersParsed)
+            return false;
+        current += numCharactersParsed;
+        if (*current != '%')
+            return false;
+        localValue += percentage;
+    }
+
+    if (expect == CSSPrimitiveValue::CSS_PERCENTAGE && *current != '%')
+        return false;
+
+    if (*current == '%') {
+        expect = CSSPrimitiveValue::CSS_PERCENTAGE;
+        localValue = localValue / 100.0 * 256.0;
+        // Clamp values at 255 for percentages over 100%
+        if (localValue > 255)
+            localValue = 255;
+        current++;
+    } else
+        expect = CSSPrimitiveValue::CSS_NUMBER;
+
+    while (current != end && isHTMLSpace<CharacterType>(*current))
+        current++;
+    if (current == end || *current++ != terminator)
+        return false;
+    // Clamp negative values at zero.
+    value = negative ? 0 : static_cast<int>(localValue);
+    string = current;
+    return true;
+}
+
+template <typename CharacterType>
+static inline bool isTenthAlpha(const CharacterType* string, const int length)
+{
+    // "0.X"
+    if (length == 3 && string[0] == '0' && string[1] == '.' && isASCIIDigit(string[2]))
+        return true;
+
+    // ".X"
+    if (length == 2 && string[0] == '.' && isASCIIDigit(string[1]))
+        return true;
+
+    return false;
+}
+
+template <typename CharacterType>
+static inline bool parseAlphaValue(const CharacterType*& string, const CharacterType* end, const char terminator, int& value)
+{
+    while (string != end && isHTMLSpace<CharacterType>(*string))
+        string++;
+
+    bool negative = false;
+
+    if (string != end && *string == '-') {
+        negative = true;
+        string++;
+    }
+
+    value = 0;
+
+    int length = end - string;
+    if (length < 2)
+        return false;
+
+    if (string[length - 1] != terminator || !isASCIIDigit(string[length - 2]))
+        return false;
+
+    if (string[0] != '0' && string[0] != '1' && string[0] != '.') {
+        if (checkForValidDouble(string, end, terminator)) {
+            value = negative ? 0 : 255;
+            string = end;
+            return true;
+        }
+        return false;
+    }
+
+    if (length == 2 && string[0] != '.') {
+        value = !negative && string[0] == '1' ? 255 : 0;
+        string = end;
+        return true;
+    }
+
+    if (isTenthAlpha(string, length - 1)) {
+        static const int tenthAlphaValues[] = { 0, 25, 51, 76, 102, 127, 153, 179, 204, 230 };
+        value = negative ? 0 : tenthAlphaValues[string[length - 2] - '0'];
+        string = end;
+        return true;
+    }
+
+    double alpha = 0;
+    if (!parseDouble(string, end, terminator, alpha))
+        return false;
+    value = negative ? 0 : static_cast<int>(alpha * nextafter(256.0, 0.0));
+    string = end;
+    return true;
+}
+
+template <typename CharacterType>
+static inline bool mightBeRGBA(const CharacterType* characters, unsigned length)
+{
+    if (length < 5)
+        return false;
+    return characters[4] == '('
+        && isASCIIAlphaCaselessEqual(characters[0], 'r')
+        && isASCIIAlphaCaselessEqual(characters[1], 'g')
+        && isASCIIAlphaCaselessEqual(characters[2], 'b')
+        && isASCIIAlphaCaselessEqual(characters[3], 'a');
+}
+
+template <typename CharacterType>
+static inline bool mightBeRGB(const CharacterType* characters, unsigned length)
+{
+    if (length < 4)
+        return false;
+    return characters[3] == '('
+        && isASCIIAlphaCaselessEqual(characters[0], 'r')
+        && isASCIIAlphaCaselessEqual(characters[1], 'g')
+        && isASCIIAlphaCaselessEqual(characters[2], 'b');
+}
+
+template <typename CharacterType>
+static inline bool fastParseColorInternal(RGBA32& rgb, const CharacterType* characters, unsigned length , bool strict)
+{
+    CSSPrimitiveValue::UnitTypes expect = CSSPrimitiveValue::CSS_UNKNOWN;
+
+    if (!strict && length >= 3) {
+        if (characters[0] == '#') {
+            if (Color::parseHexColor(characters + 1, length - 1, rgb))
+                return true;
+        } else {
+            if (Color::parseHexColor(characters, length, rgb))
+                return true;
+        }
+    }
+
+    // Try rgba() syntax.
+    if (mightBeRGBA(characters, length)) {
+        const CharacterType* current = characters + 5;
+        const CharacterType* end = characters + length;
+        int red;
+        int green;
+        int blue;
+        int alpha;
+
+        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, blue))
+            return false;
+        if (!parseAlphaValue(current, end, ')', alpha))
+            return false;
+        if (current != end)
+            return false;
+        rgb = makeRGBA(red, green, blue, alpha);
+        return true;
+    }
+
+    // Try rgb() syntax.
+    if (mightBeRGB(characters, length)) {
+        const CharacterType* current = characters + 4;
+        const CharacterType* end = characters + length;
+        int red;
+        int green;
+        int blue;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, red))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ',', expect, green))
+            return false;
+        if (!parseColorIntOrPercentage(current, end, ')', expect, blue))
+            return false;
+        if (current != end)
+            return false;
+        rgb = makeRGB(red, green, blue);
+        return true;
+    }
+
+    return false;
+}
+
+template<typename StringType>
+bool CSSPropertyParser::fastParseColor(RGBA32& rgb, const StringType& name, bool strict)
+{
+    unsigned length = name.length();
+    bool parseResult;
+
+    if (!length)
+        return false;
+
+    if (name.is8Bit())
+        parseResult = fastParseColorInternal(rgb, name.characters8(), length, strict);
+    else
+        parseResult = fastParseColorInternal(rgb, name.characters16(), length, strict);
+
+    if (parseResult)
+        return true;
+
+    // Try named colors.
+    Color tc;
+    if (!tc.setNamedColor(name))
+        return false;
+    rgb = tc.rgb();
+    return true;
+}
+
+template bool CSSPropertyParser::fastParseColor(RGBA32&, const String&, bool strict);
+
+inline double CSSPropertyParser::parsedDouble(CSSParserValue *v, ReleaseParsedCalcValueCondition releaseCalc)
+{
+    const double result = m_parsedCalculation ? m_parsedCalculation->doubleValue() : v->fValue;
+    if (releaseCalc == ReleaseParsedCalcValue)
+        m_parsedCalculation.release();
+    return result;
+}
+
+bool CSSPropertyParser::isCalculation(CSSParserValue* value)
+{
+    return (value->unit == CSSParserValue::Function)
+        && (equalIgnoringCase(value->function->name, "calc(")
+            || equalIgnoringCase(value->function->name, "-webkit-calc(")
+            || equalIgnoringCase(value->function->name, "-webkit-min(")
+            || equalIgnoringCase(value->function->name, "-webkit-max("));
+}
+
+inline int CSSPropertyParser::colorIntFromValue(CSSParserValue* v)
+{
+    bool isPercent;
+
+    if (m_parsedCalculation)
+        isPercent = m_parsedCalculation->category() == CalcPercent;
+    else
+        isPercent = v->unit == CSSPrimitiveValue::CSS_PERCENTAGE;
+
+    const double value = parsedDouble(v, ReleaseParsedCalcValue);
+
+    if (value <= 0.0)
+        return 0;
+
+    if (isPercent) {
+        if (value >= 100.0)
+            return 255;
+        return static_cast<int>(value * 256.0 / 100.0);
+    }
+
+    if (value >= 255.0)
+        return 255;
+
+    return static_cast<int>(value);
+}
+
+bool CSSPropertyParser::parseColorParameters(CSSParserValue* value, int* colorArray, bool parseAlpha)
+{
+    CSSParserValueList* args = value->function->args.get();
+    CSSParserValue* v = args->current();
+    Units unitType = FUnknown;
+    // Get the first value and its type
+    if (validUnit(v, FInteger, HTMLStandardMode))
+        unitType = FInteger;
+    else if (validUnit(v, FPercent, HTMLStandardMode))
+        unitType = FPercent;
+    else
+        return false;
+
+    colorArray[0] = colorIntFromValue(v);
+    for (int i = 1; i < 3; i++) {
+        v = args->next();
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+            return false;
+        v = args->next();
+        if (!validUnit(v, unitType, HTMLStandardMode))
+            return false;
+        colorArray[i] = colorIntFromValue(v);
+    }
+    if (parseAlpha) {
+        v = args->next();
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+            return false;
+        v = args->next();
+        if (!validUnit(v, FNumber, HTMLStandardMode))
+            return false;
+        const double value = parsedDouble(v, ReleaseParsedCalcValue);
+        // Convert the floating pointer number of alpha to an integer in the range [0, 256),
+        // with an equal distribution across all 256 values.
+        colorArray[3] = static_cast<int>(max(0.0, min(1.0, value)) * nextafter(256.0, 0.0));
+    }
+    return true;
+}
+
+// The CSS3 specification defines the format of a HSL color as
+// hsl(<number>, <percent>, <percent>)
+// and with alpha, the format is
+// hsla(<number>, <percent>, <percent>, <number>)
+// The first value, HUE, is in an angle with a value between 0 and 360
+bool CSSPropertyParser::parseHSLParameters(CSSParserValue* value, double* colorArray, bool parseAlpha)
+{
+    CSSParserValueList* args = value->function->args.get();
+    CSSParserValue* v = args->current();
+    // Get the first value
+    if (!validUnit(v, FNumber, HTMLStandardMode))
+        return false;
+    // normalize the Hue value and change it to be between 0 and 1.0
+    colorArray[0] = (((static_cast<int>(parsedDouble(v, ReleaseParsedCalcValue)) % 360) + 360) % 360) / 360.0;
+    for (int i = 1; i < 3; i++) {
+        v = args->next();
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+            return false;
+        v = args->next();
+        if (!validUnit(v, FPercent, HTMLStandardMode))
+            return false;
+        colorArray[i] = max(0.0, min(100.0, parsedDouble(v, ReleaseParsedCalcValue))) / 100.0; // needs to be value between 0 and 1.0
+    }
+    if (parseAlpha) {
+        v = args->next();
+        if (v->unit != CSSParserValue::Operator && v->iValue != ',')
+            return false;
+        v = args->next();
+        if (!validUnit(v, FNumber, HTMLStandardMode))
+            return false;
+        colorArray[3] = max(0.0, min(1.0, parsedDouble(v, ReleaseParsedCalcValue)));
+    }
+    return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> CSSPropertyParser::parseColor(CSSParserValue* value)
+{
+    RGBA32 c = Color::transparent;
+    if (!parseColorFromValue(value ? value : m_valueList->current(), c))
+        return nullptr;
+    return cssValuePool().createColorValue(c);
+}
+
+bool CSSPropertyParser::parseColorFromValue(CSSParserValue* value, RGBA32& c)
+{
+    if (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_NUMBER
+        && value->fValue >= 0. && value->fValue < 1000000.) {
+        String str = String::format("%06d", static_cast<int>((value->fValue+.5)));
+        // FIXME: This should be strict parsing for SVG as well.
+        if (!fastParseColor(c, str, !inQuirksMode()))
+            return false;
+    } else if (value->unit == CSSPrimitiveValue::CSS_PARSER_HEXCOLOR ||
+                value->unit == CSSPrimitiveValue::CSS_IDENT ||
+                (inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_DIMENSION)) {
+        if (!fastParseColor(c, value->string, !inQuirksMode() && value->unit == CSSPrimitiveValue::CSS_IDENT))
+            return false;
+    } else if (value->unit == CSSParserValue::Function &&
+                value->function->args != 0 &&
+                value->function->args->size() == 5 /* rgb + two commas */ &&
+                equalIgnoringCase(value->function->name, "rgb(")) {
+        int colorValues[3];
+        if (!parseColorParameters(value, colorValues, false))
+            return false;
+        c = makeRGB(colorValues[0], colorValues[1], colorValues[2]);
+    } else {
+        if (value->unit == CSSParserValue::Function &&
+                value->function->args != 0 &&
+                value->function->args->size() == 7 /* rgba + three commas */ &&
+                equalIgnoringCase(value->function->name, "rgba(")) {
+            int colorValues[4];
+            if (!parseColorParameters(value, colorValues, true))
+                return false;
+            c = makeRGBA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+        } else if (value->unit == CSSParserValue::Function &&
+                    value->function->args != 0 &&
+                    value->function->args->size() == 5 /* hsl + two commas */ &&
+                    equalIgnoringCase(value->function->name, "hsl(")) {
+            double colorValues[3];
+            if (!parseHSLParameters(value, colorValues, false))
+                return false;
+            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], 1.0);
+        } else if (value->unit == CSSParserValue::Function &&
+                    value->function->args != 0 &&
+                    value->function->args->size() == 7 /* hsla + three commas */ &&
+                    equalIgnoringCase(value->function->name, "hsla(")) {
+            double colorValues[4];
+            if (!parseHSLParameters(value, colorValues, true))
+                return false;
+            c = makeRGBAFromHSLA(colorValues[0], colorValues[1], colorValues[2], colorValues[3]);
+        } else
+            return false;
+    }
+
+    return true;
+}
+
+// This class tracks parsing state for shadow values.  If it goes out of scope (e.g., due to an early return)
+// without the allowBreak bit being set, then it will clean up all of the objects and destroy them.
+class ShadowParseContext {
+    DISALLOW_ALLOCATION();
+public:
+    ShadowParseContext(CSSPropertyID prop, CSSPropertyParser* parser)
+        : property(prop)
+        , m_parser(parser)
+        , allowX(true)
+        , allowY(false)
+        , allowBlur(false)
+        , allowSpread(false)
+        , allowColor(true)
+        , allowStyle(prop == CSSPropertyWebkitBoxShadow || prop == CSSPropertyBoxShadow)
+        , allowBreak(true)
+    {
+    }
+
+    bool allowLength() { return allowX || allowY || allowBlur || allowSpread; }
+
+    void commitValue()
+    {
+        // Handle the ,, case gracefully by doing nothing.
+        if (x || y || blur || spread || color || style) {
+            if (!values)
+                values = CSSValueList::createCommaSeparated();
+
+            // Construct the current shadow value and add it to the list.
+            values->append(CSSShadowValue::create(x.release(), y.release(), blur.release(), spread.release(), style.release(), color.release()));
+        }
+
+        // Now reset for the next shadow value.
+        x = nullptr;
+        y = nullptr;
+        blur = nullptr;
+        spread = nullptr;
+        style = nullptr;
+        color = nullptr;
+
+        allowX = true;
+        allowColor = true;
+        allowBreak = true;
+        allowY = false;
+        allowBlur = false;
+        allowSpread = false;
+        allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+    }
+
+    void commitLength(CSSParserValue* v)
+    {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
+
+        if (allowX) {
+            x = val.release();
+            allowX = false;
+            allowY = true;
+            allowColor = false;
+            allowStyle = false;
+            allowBreak = false;
+        } else if (allowY) {
+            y = val.release();
+            allowY = false;
+            allowBlur = true;
+            allowColor = true;
+            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+            allowBreak = true;
+        } else if (allowBlur) {
+            blur = val.release();
+            allowBlur = false;
+            allowSpread = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+        } else if (allowSpread) {
+            spread = val.release();
+            allowSpread = false;
+        }
+    }
+
+    void commitColor(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val)
+    {
+        color = val;
+        allowColor = false;
+        if (allowX) {
+            allowStyle = false;
+            allowBreak = false;
+        } else {
+            allowBlur = false;
+            allowSpread = false;
+            allowStyle = property == CSSPropertyWebkitBoxShadow || property == CSSPropertyBoxShadow;
+        }
+    }
+
+    void commitStyle(CSSParserValue* v)
+    {
+        style = cssValuePool().createIdentifierValue(v->id);
+        allowStyle = false;
+        if (allowX)
+            allowBreak = false;
+        else {
+            allowBlur = false;
+            allowSpread = false;
+            allowColor = false;
+        }
+    }
+
+    CSSPropertyID property;
+    CSSPropertyParser* m_parser;
+
+    RefPtrWillBeRawPtr<CSSValueList> values;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> x;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> y;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> blur;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> spread;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> style;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> color;
+
+    bool allowX;
+    bool allowY;
+    bool allowBlur;
+    bool allowSpread;
+    bool allowColor;
+    bool allowStyle; // inset or not.
+    bool allowBreak;
+};
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseShadow(CSSParserValueList* valueList, CSSPropertyID propId)
+{
+    ShadowParseContext context(propId, this);
+    CSSParserValue* val;
+    while ((val = valueList->current())) {
+        // Check for a comma break first.
+        if (val->unit == CSSParserValue::Operator) {
+            if (val->iValue != ',' || !context.allowBreak) {
+                // Other operators aren't legal or we aren't done with the current shadow
+                // value.  Treat as invalid.
+                return nullptr;
+            }
+            // The value is good.  Commit it.
+            context.commitValue();
+        } else if (validUnit(val, FLength, HTMLStandardMode)) {
+            // We required a length and didn't get one. Invalid.
+            if (!context.allowLength())
+                return nullptr;
+
+            // Blur radius must be non-negative.
+            if (context.allowBlur && !validUnit(val, FLength | FNonNeg, HTMLStandardMode))
+                return nullptr;
+
+            // A length is allowed here.  Construct the value and add it.
+            context.commitLength(val);
+        } else if (val->id == CSSValueInset) {
+            if (!context.allowStyle)
+                return nullptr;
+
+            context.commitStyle(val);
+        } else {
+            // The only other type of value that's ok is a color value.
+            RefPtrWillBeRawPtr<CSSPrimitiveValue> parsedColor;
+            bool isColor = ((val->id >= CSSValueAqua && val->id <= CSSValueWindowtext) || val->id == CSSValueMenu
+                            || (val->id >= CSSValueWebkitFocusRingColor && val->id <= CSSValueWebkitText && inQuirksMode())
+                            || val->id == CSSValueCurrentcolor);
+            if (isColor) {
+                if (!context.allowColor)
+                    return nullptr;
+                parsedColor = cssValuePool().createIdentifierValue(val->id);
+            }
+
+            if (!parsedColor)
+                // It's not built-in. Try to parse it as a color.
+                parsedColor = parseColor(val);
+
+            if (!parsedColor || !context.allowColor)
+                return nullptr; // This value is not a color or length and is invalid or
+                          // it is a color, but a color isn't allowed at this point.
+
+            context.commitColor(parsedColor.release());
+        }
+
+        valueList->next();
+    }
+
+    if (context.allowBreak) {
+        context.commitValue();
+        if (context.values && context.values->length())
+            return context.values.release();
+    }
+
+    return nullptr;
+}
+
+bool CSSPropertyParser::parseReflect(CSSPropertyID propId, bool important)
+{
+    // box-reflect: <direction> <offset> <mask>
+
+    // Direction comes first.
+    CSSParserValue* val = m_valueList->current();
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> direction;
+    switch (val->id) {
+    case CSSValueAbove:
+    case CSSValueBelow:
+    case CSSValueLeft:
+    case CSSValueRight:
+        direction = cssValuePool().createIdentifierValue(val->id);
+        break;
+    default:
+        return false;
+    }
+
+    // The offset comes next.
+    val = m_valueList->next();
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> offset;
+    if (!val)
+        offset = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
+    else {
+        if (!validUnit(val, FLength | FPercent))
+            return false;
+        offset = createPrimitiveNumericValue(val);
+    }
+
+    // Now for the mask.
+    RefPtrWillBeRawPtr<CSSValue> mask;
+    val = m_valueList->next();
+    if (val) {
+        mask = parseBorderImage(propId);
+        if (!mask)
+            return false;
+    }
+
+    RefPtrWillBeRawPtr<CSSReflectValue> reflectValue = CSSReflectValue::create(direction.release(), offset.release(), mask.release());
+    addProperty(propId, reflectValue.release(), important);
+    m_valueList->next();
+    return true;
+}
+
+bool CSSPropertyParser::parseFlex(CSSParserValueList* args, bool important)
+{
+    if (!args || !args->size() || args->size() > 3)
+        return false;
+    static const double unsetValue = -1;
+    double flexGrow = unsetValue;
+    double flexShrink = unsetValue;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> flexBasis;
+
+    while (CSSParserValue* arg = args->current()) {
+        if (validUnit(arg, FNumber | FNonNeg)) {
+            if (flexGrow == unsetValue)
+                flexGrow = arg->fValue;
+            else if (flexShrink == unsetValue)
+                flexShrink = arg->fValue;
+            else if (!arg->fValue) {
+                // flex only allows a basis of 0 (sans units) if flex-grow and flex-shrink values have already been set.
+                flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
+            } else {
+                // We only allow 3 numbers without units if the last value is 0. E.g., flex:1 1 1 is invalid.
+                return false;
+            }
+        } else if (!flexBasis && (arg->id == CSSValueAuto || validUnit(arg, FLength | FPercent | FNonNeg)))
+            flexBasis = parseValidPrimitive(arg->id, arg);
+        else {
+            // Not a valid arg for flex.
+            return false;
+        }
+        args->next();
+    }
+
+    if (flexGrow == unsetValue)
+        flexGrow = 1;
+    if (flexShrink == unsetValue)
+        flexShrink = 1;
+    if (!flexBasis)
+        flexBasis = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_PX);
+
+    addProperty(CSSPropertyFlexGrow, cssValuePool().createValue(clampToFloat(flexGrow), CSSPrimitiveValue::CSS_NUMBER), important);
+    addProperty(CSSPropertyFlexShrink, cssValuePool().createValue(clampToFloat(flexShrink), CSSPrimitiveValue::CSS_NUMBER), important);
+    addProperty(CSSPropertyFlexBasis, flexBasis, important);
+    return true;
+}
+
+bool CSSPropertyParser::parseObjectPosition(bool important)
+{
+    RefPtrWillBeRawPtr<CSSValue> xValue;
+    RefPtrWillBeRawPtr<CSSValue> yValue;
+    parseFillPosition(m_valueList.get(), xValue, yValue);
+    if (!xValue || !yValue)
+        return false;
+    addProperty(
+        CSSPropertyObjectPosition,
+        createPrimitiveValuePair(toCSSPrimitiveValue(xValue.get()), toCSSPrimitiveValue(yValue.get()), Pair::KeepIdenticalValues),
+        important);
+    return true;
+}
+
+class BorderImageParseContext {
+    DISALLOW_ALLOCATION();
+public:
+    BorderImageParseContext()
+    : m_canAdvance(false)
+    , m_allowCommit(true)
+    , m_allowImage(true)
+    , m_allowImageSlice(true)
+    , m_allowRepeat(true)
+    , m_allowForwardSlashOperator(false)
+    , m_requireWidth(false)
+    , m_requireOutset(false)
+    {}
+
+    bool canAdvance() const { return m_canAdvance; }
+    void setCanAdvance(bool canAdvance) { m_canAdvance = canAdvance; }
+
+    bool allowCommit() const { return m_allowCommit; }
+    bool allowImage() const { return m_allowImage; }
+    bool allowImageSlice() const { return m_allowImageSlice; }
+    bool allowRepeat() const { return m_allowRepeat; }
+    bool allowForwardSlashOperator() const { return m_allowForwardSlashOperator; }
+
+    bool requireWidth() const { return m_requireWidth; }
+    bool requireOutset() const { return m_requireOutset; }
+
+    void commitImage(PassRefPtrWillBeRawPtr<CSSValue> image)
+    {
+        m_image = image;
+        m_canAdvance = true;
+        m_allowCommit = true;
+        m_allowImage = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+        m_allowImageSlice = !m_imageSlice;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitImageSlice(PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> slice)
+    {
+        m_imageSlice = slice;
+        m_canAdvance = true;
+        m_allowCommit = m_allowForwardSlashOperator = true;
+        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
+        m_allowImage = !m_image;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitForwardSlashOperator()
+    {
+        m_canAdvance = true;
+        m_allowCommit = m_allowImage = m_allowImageSlice = m_allowRepeat = m_allowForwardSlashOperator = false;
+        if (!m_borderSlice) {
+            m_requireWidth = true;
+            m_requireOutset = false;
+        } else {
+            m_requireOutset = true;
+            m_requireWidth = false;
+        }
+    }
+    void commitBorderWidth(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> slice)
+    {
+        m_borderSlice = slice;
+        m_canAdvance = true;
+        m_allowCommit = m_allowForwardSlashOperator = true;
+        m_allowImageSlice = m_requireWidth = m_requireOutset = false;
+        m_allowImage = !m_image;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitBorderOutset(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> outset)
+    {
+        m_outset = outset;
+        m_canAdvance = true;
+        m_allowCommit = true;
+        m_allowImageSlice = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+        m_allowImage = !m_image;
+        m_allowRepeat = !m_repeat;
+    }
+    void commitRepeat(PassRefPtrWillBeRawPtr<CSSValue> repeat)
+    {
+        m_repeat = repeat;
+        m_canAdvance = true;
+        m_allowCommit = true;
+        m_allowRepeat = m_allowForwardSlashOperator = m_requireWidth = m_requireOutset = false;
+        m_allowImageSlice = !m_imageSlice;
+        m_allowImage = !m_image;
+    }
+
+    PassRefPtrWillBeRawPtr<CSSValue> commitCSSValue()
+    {
+        return createBorderImageValue(m_image, m_imageSlice, m_borderSlice, m_outset, m_repeat);
+    }
+
+    void commitMaskBoxImage(CSSPropertyParser* parser, bool important)
+    {
+        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSource, parser, m_image, important);
+        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageSlice, parser, m_imageSlice, important);
+        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageWidth, parser, m_borderSlice, important);
+        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageOutset, parser, m_outset, important);
+        commitBorderImageProperty(CSSPropertyWebkitMaskBoxImageRepeat, parser, m_repeat, important);
+    }
+
+    void commitBorderImage(CSSPropertyParser* parser, bool important)
+    {
+        commitBorderImageProperty(CSSPropertyBorderImageSource, parser, m_image, important);
+        commitBorderImageProperty(CSSPropertyBorderImageSlice, parser, m_imageSlice, important);
+        commitBorderImageProperty(CSSPropertyBorderImageWidth, parser, m_borderSlice, important);
+        commitBorderImageProperty(CSSPropertyBorderImageOutset, parser, m_outset, important);
+        commitBorderImageProperty(CSSPropertyBorderImageRepeat, parser, m_repeat, important);
+    }
+
+    void commitBorderImageProperty(CSSPropertyID propId, CSSPropertyParser* parser, PassRefPtrWillBeRawPtr<CSSValue> value, bool important)
+    {
+        if (value)
+            parser->addProperty(propId, value, important);
+        else
+            parser->addProperty(propId, cssValuePool().createImplicitInitialValue(), important, true);
+    }
+
+    static bool buildFromParser(CSSPropertyParser&, CSSPropertyID, BorderImageParseContext&);
+
+    bool m_canAdvance;
+
+    bool m_allowCommit;
+    bool m_allowImage;
+    bool m_allowImageSlice;
+    bool m_allowRepeat;
+    bool m_allowForwardSlashOperator;
+
+    bool m_requireWidth;
+    bool m_requireOutset;
+
+    RefPtrWillBeRawPtr<CSSValue> m_image;
+    RefPtrWillBeRawPtr<CSSBorderImageSliceValue> m_imageSlice;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_borderSlice;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_outset;
+
+    RefPtrWillBeRawPtr<CSSValue> m_repeat;
+};
+
+bool BorderImageParseContext::buildFromParser(CSSPropertyParser& parser, CSSPropertyID propId, BorderImageParseContext& context)
+{
+    CSSPropertyParser::ShorthandScope scope(&parser, propId);
+    while (CSSParserValue* val = parser.m_valueList->current()) {
+        context.setCanAdvance(false);
+
+        if (!context.canAdvance() && context.allowForwardSlashOperator() && isForwardSlashOperator(val))
+            context.commitForwardSlashOperator();
+
+        if (!context.canAdvance() && context.allowImage()) {
+            if (val->unit == CSSPrimitiveValue::CSS_URI) {
+                context.commitImage(CSSImageValue::create(val->string, parser.m_context.completeURL(val->string)));
+            } else if (isGeneratedImageValue(val)) {
+                RefPtrWillBeRawPtr<CSSValue> value;
+                if (parser.parseGeneratedImage(parser.m_valueList.get(), value))
+                    context.commitImage(value.release());
+                else
+                    return false;
+            } else if (val->unit == CSSParserValue::Function && equalIgnoringCase(val->function->name, "-webkit-image-set(")) {
+                RefPtrWillBeRawPtr<CSSValue> value = parser.parseImageSet(parser.m_valueList.get());
+                if (value)
+                    context.commitImage(value.release());
+                else
+                    return false;
+            } else if (val->id == CSSValueNone)
+                context.commitImage(cssValuePool().createIdentifierValue(CSSValueNone));
+        }
+
+        if (!context.canAdvance() && context.allowImageSlice()) {
+            RefPtrWillBeRawPtr<CSSBorderImageSliceValue> imageSlice;
+            if (parser.parseBorderImageSlice(propId, imageSlice))
+                context.commitImageSlice(imageSlice.release());
+        }
+
+        if (!context.canAdvance() && context.allowRepeat()) {
+            RefPtrWillBeRawPtr<CSSValue> repeat;
+            if (parser.parseBorderImageRepeat(repeat))
+                context.commitRepeat(repeat.release());
+        }
+
+        if (!context.canAdvance() && context.requireWidth()) {
+            RefPtrWillBeRawPtr<CSSPrimitiveValue> borderSlice;
+            if (parser.parseBorderImageWidth(borderSlice))
+                context.commitBorderWidth(borderSlice.release());
+        }
+
+        if (!context.canAdvance() && context.requireOutset()) {
+            RefPtrWillBeRawPtr<CSSPrimitiveValue> borderOutset;
+            if (parser.parseBorderImageOutset(borderOutset))
+                context.commitBorderOutset(borderOutset.release());
+        }
+
+        if (!context.canAdvance())
+            return false;
+
+        parser.m_valueList->next();
+    }
+
+    return context.allowCommit();
+}
+
+bool CSSPropertyParser::parseBorderImageShorthand(CSSPropertyID propId, bool important)
+{
+    BorderImageParseContext context;
+    if (BorderImageParseContext::buildFromParser(*this, propId, context)) {
+        switch (propId) {
+        case CSSPropertyWebkitMaskBoxImage:
+            context.commitMaskBoxImage(this, important);
+            return true;
+        case CSSPropertyBorderImage:
+            context.commitBorderImage(this, important);
+            return true;
+        default:
+            ASSERT_NOT_REACHED();
+            return false;
+        }
+    }
+    return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseBorderImage(CSSPropertyID propId)
+{
+    BorderImageParseContext context;
+    if (BorderImageParseContext::buildFromParser(*this, propId, context)) {
+        return context.commitCSSValue();
+    }
+    return nullptr;
+}
+
+static bool isBorderImageRepeatKeyword(int id)
+{
+    return id == CSSValueStretch || id == CSSValueRepeat || id == CSSValueSpace || id == CSSValueRound;
+}
+
+bool CSSPropertyParser::parseBorderImageRepeat(RefPtrWillBeRawPtr<CSSValue>& result)
+{
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> firstValue;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> secondValue;
+    CSSParserValue* val = m_valueList->current();
+    if (!val)
+        return false;
+    if (isBorderImageRepeatKeyword(val->id))
+        firstValue = cssValuePool().createIdentifierValue(val->id);
+    else
+        return false;
+
+    val = m_valueList->next();
+    if (val) {
+        if (isBorderImageRepeatKeyword(val->id))
+            secondValue = cssValuePool().createIdentifierValue(val->id);
+        else if (!inShorthand()) {
+            // If we're not parsing a shorthand then we are invalid.
+            return false;
+        } else {
+            // We need to rewind the value list, so that when its advanced we'll
+            // end up back at this value.
+            m_valueList->previous();
+            secondValue = firstValue;
+        }
+    } else
+        secondValue = firstValue;
+
+    result = createPrimitiveValuePair(firstValue, secondValue);
+    return true;
+}
+
+class BorderImageSliceParseContext {
+    DISALLOW_ALLOCATION();
+public:
+    BorderImageSliceParseContext(CSSPropertyParser* parser)
+    : m_parser(parser)
+    , m_allowNumber(true)
+    , m_allowFill(true)
+    , m_allowFinalCommit(false)
+    , m_fill(false)
+    { }
+
+    bool allowNumber() const { return m_allowNumber; }
+    bool allowFill() const { return m_allowFill; }
+    bool allowFinalCommit() const { return m_allowFinalCommit; }
+    CSSPrimitiveValue* top() const { return m_top.get(); }
+
+    void commitNumber(CSSParserValue* v)
+    {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> val = m_parser->createPrimitiveNumericValue(v);
+        if (!m_top)
+            m_top = val;
+        else if (!m_right)
+            m_right = val;
+        else if (!m_bottom)
+            m_bottom = val;
+        else {
+            ASSERT(!m_left);
+            m_left = val;
+        }
+
+        m_allowNumber = !m_left;
+        m_allowFinalCommit = true;
+    }
+
+    void commitFill() { m_fill = true; m_allowFill = false; m_allowNumber = !m_top; }
+
+    PassRefPtrWillBeRawPtr<CSSBorderImageSliceValue> commitBorderImageSlice()
+    {
+        // We need to clone and repeat values for any omissions.
+        ASSERT(m_top);
+        if (!m_right) {
+            m_right = m_top;
+            m_bottom = m_top;
+            m_left = m_top;
+        }
+        if (!m_bottom) {
+            m_bottom = m_top;
+            m_left = m_right;
+        }
+        if (!m_left)
+            m_left = m_right;
+
+        // Now build a rect value to hold all four of our primitive values.
+        RefPtrWillBeRawPtr<Quad> quad = Quad::create();
+        quad->setTop(m_top);
+        quad->setRight(m_right);
+        quad->setBottom(m_bottom);
+        quad->setLeft(m_left);
+
+        // Make our new border image value now.
+        return CSSBorderImageSliceValue::create(cssValuePool().createValue(quad.release()), m_fill);
+    }
+
+private:
+    CSSPropertyParser* m_parser;
+
+    bool m_allowNumber;
+    bool m_allowFill;
+    bool m_allowFinalCommit;
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_top;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_right;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_bottom;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_left;
+
+    bool m_fill;
+};
+
+bool CSSPropertyParser::parseBorderImageSlice(CSSPropertyID propId, RefPtrWillBeRawPtr<CSSBorderImageSliceValue>& result)
+{
+    BorderImageSliceParseContext context(this);
+    CSSParserValue* val;
+    while ((val = m_valueList->current())) {
+        // FIXME calc() http://webkit.org/b/16662 : calc is parsed but values are not created yet.
+        if (context.allowNumber() && !isCalculation(val) && validUnit(val, FInteger | FNonNeg | FPercent, HTMLStandardMode)) {
+            context.commitNumber(val);
+        } else if (context.allowFill() && val->id == CSSValueFill)
+            context.commitFill();
+        else if (!inShorthand()) {
+            // If we're not parsing a shorthand then we are invalid.
+            return false;
+        } else {
+            if (context.allowFinalCommit()) {
+                // We're going to successfully parse, but we don't want to consume this token.
+                m_valueList->previous();
+            }
+            break;
+        }
+        m_valueList->next();
+    }
+
+    if (context.allowFinalCommit()) {
+        // FIXME: For backwards compatibility, -webkit-border-image, -webkit-mask-box-image and -webkit-box-reflect have to do a fill by default.
+        // FIXME: What do we do with -webkit-box-reflect and -webkit-mask-box-image? Probably just have to leave them filling...
+        if (propId == CSSPropertyWebkitBorderImage || propId == CSSPropertyWebkitMaskBoxImage || propId == CSSPropertyWebkitBoxReflect)
+            context.commitFill();
+
+        // Need to fully commit as a single value.
+        result = context.commitBorderImageSlice();
+        return true;
+    }
+
+    return false;
+}
+
+class BorderImageQuadParseContext {
+public:
+    BorderImageQuadParseContext(CSSPropertyParser* parser)
+    : m_parser(parser)
+    , m_allowNumber(true)
+    , m_allowFinalCommit(false)
+    { }
+
+    bool allowNumber() const { return m_allowNumber; }
+    bool allowFinalCommit() const { return m_allowFinalCommit; }
+    CSSPrimitiveValue* top() const { return m_top.get(); }
+
+    void commitNumber(CSSParserValue* v)
+    {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> val;
+        if (v->id == CSSValueAuto)
+            val = cssValuePool().createIdentifierValue(v->id);
+        else
+            val = m_parser->createPrimitiveNumericValue(v);
+
+        if (!m_top)
+            m_top = val;
+        else if (!m_right)
+            m_right = val;
+        else if (!m_bottom)
+            m_bottom = val;
+        else {
+            ASSERT(!m_left);
+            m_left = val;
+        }
+
+        m_allowNumber = !m_left;
+        m_allowFinalCommit = true;
+    }
+
+    void setAllowFinalCommit() { m_allowFinalCommit = true; }
+    void setTop(PassRefPtrWillBeRawPtr<CSSPrimitiveValue> val) { m_top = val; }
+
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> commitBorderImageQuad()
+    {
+        // We need to clone and repeat values for any omissions.
+        ASSERT(m_top);
+        if (!m_right) {
+            m_right = m_top;
+            m_bottom = m_top;
+            m_left = m_top;
+        }
+        if (!m_bottom) {
+            m_bottom = m_top;
+            m_left = m_right;
+        }
+        if (!m_left)
+            m_left = m_right;
+
+        // Now build a quad value to hold all four of our primitive values.
+        RefPtrWillBeRawPtr<Quad> quad = Quad::create();
+        quad->setTop(m_top);
+        quad->setRight(m_right);
+        quad->setBottom(m_bottom);
+        quad->setLeft(m_left);
+
+        // Make our new value now.
+        return cssValuePool().createValue(quad.release());
+    }
+
+private:
+    CSSPropertyParser* m_parser;
+
+    bool m_allowNumber;
+    bool m_allowFinalCommit;
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_top;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_right;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_bottom;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> m_left;
+};
+
+bool CSSPropertyParser::parseBorderImageQuad(Units validUnits, RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
+{
+    BorderImageQuadParseContext context(this);
+    CSSParserValue* val;
+    while ((val = m_valueList->current())) {
+        if (context.allowNumber() && (validUnit(val, validUnits, HTMLStandardMode) || val->id == CSSValueAuto)) {
+            context.commitNumber(val);
+        } else if (!inShorthand()) {
+            // If we're not parsing a shorthand then we are invalid.
+            return false;
+        } else {
+            if (context.allowFinalCommit())
+                m_valueList->previous(); // The shorthand loop will advance back to this point.
+            break;
+        }
+        m_valueList->next();
+    }
+
+    if (context.allowFinalCommit()) {
+        // Need to fully commit as a single value.
+        result = context.commitBorderImageQuad();
+        return true;
+    }
+    return false;
+}
+
+bool CSSPropertyParser::parseBorderImageWidth(RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
+{
+    return parseBorderImageQuad(FLength | FNumber | FNonNeg | FPercent, result);
+}
+
+bool CSSPropertyParser::parseBorderImageOutset(RefPtrWillBeRawPtr<CSSPrimitiveValue>& result)
+{
+    return parseBorderImageQuad(FLength | FNumber | FNonNeg, result);
+}
+
+bool CSSPropertyParser::parseBorderRadius(CSSPropertyID propId, bool important)
+{
+    unsigned num = m_valueList->size();
+    if (num > 9)
+        return false;
+
+    ShorthandScope scope(this, propId);
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> radii[2][4];
+
+    unsigned indexAfterSlash = 0;
+    for (unsigned i = 0; i < num; ++i) {
+        CSSParserValue* value = m_valueList->valueAt(i);
+        if (value->unit == CSSParserValue::Operator) {
+            if (value->iValue != '/')
+                return false;
+
+            if (!i || indexAfterSlash || i + 1 == num || num > i + 5)
+                return false;
+
+            indexAfterSlash = i + 1;
+            completeBorderRadii(radii[0]);
+            continue;
+        }
+
+        if (i - indexAfterSlash >= 4)
+            return false;
+
+        if (!validUnit(value, FLength | FPercent | FNonNeg))
+            return false;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> radius = createPrimitiveNumericValue(value);
+
+        if (!indexAfterSlash) {
+            radii[0][i] = radius;
+
+            // Legacy syntax: -webkit-border-radius: l1 l2; is equivalent to border-radius: l1 / l2;
+            if (num == 2 && propId == CSSPropertyWebkitBorderRadius) {
+                indexAfterSlash = 1;
+                completeBorderRadii(radii[0]);
+            }
+        } else
+            radii[1][i - indexAfterSlash] = radius.release();
+    }
+
+    if (!indexAfterSlash) {
+        completeBorderRadii(radii[0]);
+        for (unsigned i = 0; i < 4; ++i)
+            radii[1][i] = radii[0][i];
+    } else
+        completeBorderRadii(radii[1]);
+
+    ImplicitScope implicitScope(this, PropertyImplicit);
+    addProperty(CSSPropertyBorderTopLeftRadius, createPrimitiveValuePair(radii[0][0].release(), radii[1][0].release()), important);
+    addProperty(CSSPropertyBorderTopRightRadius, createPrimitiveValuePair(radii[0][1].release(), radii[1][1].release()), important);
+    addProperty(CSSPropertyBorderBottomRightRadius, createPrimitiveValuePair(radii[0][2].release(), radii[1][2].release()), important);
+    addProperty(CSSPropertyBorderBottomLeftRadius, createPrimitiveValuePair(radii[0][3].release(), radii[1][3].release()), important);
+    return true;
+}
+
+bool CSSPropertyParser::parseAspectRatio(bool important)
+{
+    unsigned num = m_valueList->size();
+    if (num == 1 && m_valueList->valueAt(0)->id == CSSValueNone) {
+        addProperty(CSSPropertyWebkitAspectRatio, cssValuePool().createIdentifierValue(CSSValueNone), important);
+        return true;
+    }
+
+    if (num != 3)
+        return false;
+
+    CSSParserValue* lvalue = m_valueList->valueAt(0);
+    CSSParserValue* op = m_valueList->valueAt(1);
+    CSSParserValue* rvalue = m_valueList->valueAt(2);
+
+    if (!isForwardSlashOperator(op))
+        return false;
+
+    if (!validUnit(lvalue, FNumber | FNonNeg) || !validUnit(rvalue, FNumber | FNonNeg))
+        return false;
+
+    if (!lvalue->fValue || !rvalue->fValue)
+        return false;
+
+    addProperty(CSSPropertyWebkitAspectRatio, CSSAspectRatioValue::create(narrowPrecisionToFloat(lvalue->fValue), narrowPrecisionToFloat(rvalue->fValue)), important);
+
+    return true;
+}
+
+bool CSSPropertyParser::parseCounter(CSSPropertyID propId, int defaultValue, bool important)
+{
+    enum { ID, VAL } state = ID;
+
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> counterName;
+
+    while (true) {
+        CSSParserValue* val = m_valueList->current();
+        switch (state) {
+            case ID:
+                if (val && val->unit == CSSPrimitiveValue::CSS_IDENT) {
+                    counterName = createPrimitiveStringValue(val);
+                    state = VAL;
+                    m_valueList->next();
+                    continue;
+                }
+                break;
+            case VAL: {
+                int i = defaultValue;
+                if (val && val->unit == CSSPrimitiveValue::CSS_NUMBER) {
+                    i = clampToInteger(val->fValue);
+                    m_valueList->next();
+                }
+
+                list->append(createPrimitiveValuePair(counterName.release(),
+                    cssValuePool().createValue(i, CSSPrimitiveValue::CSS_NUMBER)));
+                state = ID;
+                continue;
+            }
+        }
+        break;
+    }
+
+    if (list->length() > 0) {
+        addProperty(propId, list.release(), important);
+        return true;
+    }
+
+    return false;
+}
+
+// This should go away once we drop support for -webkit-gradient
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseDeprecatedGradientPoint(CSSParserValue* a, bool horizontal)
+{
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> result;
+    if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
+        if ((equalIgnoringCase(a, "left") && horizontal)
+            || (equalIgnoringCase(a, "top") && !horizontal))
+            result = cssValuePool().createValue(0., CSSPrimitiveValue::CSS_PERCENTAGE);
+        else if ((equalIgnoringCase(a, "right") && horizontal)
+                 || (equalIgnoringCase(a, "bottom") && !horizontal))
+            result = cssValuePool().createValue(100., CSSPrimitiveValue::CSS_PERCENTAGE);
+        else if (equalIgnoringCase(a, "center"))
+            result = cssValuePool().createValue(50., CSSPrimitiveValue::CSS_PERCENTAGE);
+    } else if (a->unit == CSSPrimitiveValue::CSS_NUMBER || a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+        result = cssValuePool().createValue(a->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(a->unit));
+    return result;
+}
+
+bool parseDeprecatedGradientColorStop(CSSPropertyParser* p, CSSParserValue* a, CSSGradientColorStop& stop)
+{
+    if (a->unit != CSSParserValue::Function)
+        return false;
+
+    if (!equalIgnoringCase(a->function->name, "from(") &&
+        !equalIgnoringCase(a->function->name, "to(") &&
+        !equalIgnoringCase(a->function->name, "color-stop("))
+        return false;
+
+    CSSParserValueList* args = a->function->args.get();
+    if (!args)
+        return false;
+
+    if (equalIgnoringCase(a->function->name, "from(")
+        || equalIgnoringCase(a->function->name, "to(")) {
+        // The "from" and "to" stops expect 1 argument.
+        if (args->size() != 1)
+            return false;
+
+        if (equalIgnoringCase(a->function->name, "from("))
+            stop.m_position = cssValuePool().createValue(0, CSSPrimitiveValue::CSS_NUMBER);
+        else
+            stop.m_position = cssValuePool().createValue(1, CSSPrimitiveValue::CSS_NUMBER);
+
+        CSSValueID id = args->current()->id;
+        if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
+            stop.m_color = cssValuePool().createIdentifierValue(id);
+        else
+            stop.m_color = p->parseColor(args->current());
+        if (!stop.m_color)
+            return false;
+    }
+
+    // The "color-stop" function expects 3 arguments.
+    if (equalIgnoringCase(a->function->name, "color-stop(")) {
+        if (args->size() != 3)
+            return false;
+
+        CSSParserValue* stopArg = args->current();
+        if (stopArg->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+            stop.m_position = cssValuePool().createValue(stopArg->fValue / 100, CSSPrimitiveValue::CSS_NUMBER);
+        else if (stopArg->unit == CSSPrimitiveValue::CSS_NUMBER)
+            stop.m_position = cssValuePool().createValue(stopArg->fValue, CSSPrimitiveValue::CSS_NUMBER);
+        else
+            return false;
+
+        stopArg = args->next();
+        if (stopArg->unit != CSSParserValue::Operator || stopArg->iValue != ',')
+            return false;
+
+        stopArg = args->next();
+        CSSValueID id = stopArg->id;
+        if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu)
+            stop.m_color = cssValuePool().createIdentifierValue(id);
+        else
+            stop.m_color = p->parseColor(stopArg);
+        if (!stop.m_color)
+            return false;
+    }
+
+    return true;
+}
+
+bool CSSPropertyParser::parseDeprecatedGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient)
+{
+    // Walk the arguments.
+    CSSParserValueList* args = valueList->current()->function->args.get();
+    if (!args || args->size() == 0)
+        return false;
+
+    // The first argument is the gradient type.  It is an identifier.
+    CSSGradientType gradientType;
+    CSSParserValue* a = args->current();
+    if (!a || a->unit != CSSPrimitiveValue::CSS_IDENT)
+        return false;
+    if (equalIgnoringCase(a, "linear"))
+        gradientType = CSSDeprecatedLinearGradient;
+    else if (equalIgnoringCase(a, "radial"))
+        gradientType = CSSDeprecatedRadialGradient;
+    else
+        return false;
+
+    RefPtrWillBeRawPtr<CSSGradientValue> result;
+    switch (gradientType) {
+    case CSSDeprecatedLinearGradient:
+        result = CSSLinearGradientValue::create(NonRepeating, gradientType);
+        break;
+    case CSSDeprecatedRadialGradient:
+        result = CSSRadialGradientValue::create(NonRepeating, gradientType);
+        break;
+    default:
+        // The rest of the gradient types shouldn't appear here.
+        ASSERT_NOT_REACHED();
+    }
+
+    // Comma.
+    a = args->next();
+    if (!isComma(a))
+        return false;
+
+    // Next comes the starting point for the gradient as an x y pair.  There is no
+    // comma between the x and the y values.
+    // First X.  It can be left, right, number or percent.
+    a = args->next();
+    if (!a)
+        return false;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> point = parseDeprecatedGradientPoint(a, true);
+    if (!point)
+        return false;
+    result->setFirstX(point.release());
+
+    // First Y.  It can be top, bottom, number or percent.
+    a = args->next();
+    if (!a)
+        return false;
+    point = parseDeprecatedGradientPoint(a, false);
+    if (!point)
+        return false;
+    result->setFirstY(point.release());
+
+    // Comma after the first point.
+    a = args->next();
+    if (!isComma(a))
+        return false;
+
+    // For radial gradients only, we now expect a numeric radius.
+    if (gradientType == CSSDeprecatedRadialGradient) {
+        a = args->next();
+        if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
+            return false;
+        toCSSRadialGradientValue(result.get())->setFirstRadius(createPrimitiveNumericValue(a));
+
+        // Comma after the first radius.
+        a = args->next();
+        if (!isComma(a))
+            return false;
+    }
+
+    // Next is the ending point for the gradient as an x, y pair.
+    // Second X.  It can be left, right, number or percent.
+    a = args->next();
+    if (!a)
+        return false;
+    point = parseDeprecatedGradientPoint(a, true);
+    if (!point)
+        return false;
+    result->setSecondX(point.release());
+
+    // Second Y.  It can be top, bottom, number or percent.
+    a = args->next();
+    if (!a)
+        return false;
+    point = parseDeprecatedGradientPoint(a, false);
+    if (!point)
+        return false;
+    result->setSecondY(point.release());
+
+    // For radial gradients only, we now expect the second radius.
+    if (gradientType == CSSDeprecatedRadialGradient) {
+        // Comma after the second point.
+        a = args->next();
+        if (!isComma(a))
+            return false;
+
+        a = args->next();
+        if (!a || a->unit != CSSPrimitiveValue::CSS_NUMBER)
+            return false;
+        toCSSRadialGradientValue(result.get())->setSecondRadius(createPrimitiveNumericValue(a));
+    }
+
+    // We now will accept any number of stops (0 or more).
+    a = args->next();
+    while (a) {
+        // Look for the comma before the next stop.
+        if (!isComma(a))
+            return false;
+
+        // Now examine the stop itself.
+        a = args->next();
+        if (!a)
+            return false;
+
+        // The function name needs to be one of "from", "to", or "color-stop."
+        CSSGradientColorStop stop;
+        if (!parseDeprecatedGradientColorStop(this, a, stop))
+            return false;
+        result->addStop(stop);
+
+        // Advance
+        a = args->next();
+    }
+
+    gradient = result.release();
+    return true;
+}
+
+static PassRefPtrWillBeRawPtr<CSSPrimitiveValue> valueFromSideKeyword(CSSParserValue* a, bool& isHorizontal)
+{
+    if (a->unit != CSSPrimitiveValue::CSS_IDENT)
+        return nullptr;
+
+    switch (a->id) {
+        case CSSValueLeft:
+        case CSSValueRight:
+            isHorizontal = true;
+            break;
+        case CSSValueTop:
+        case CSSValueBottom:
+            isHorizontal = false;
+            break;
+        default:
+            return nullptr;
+    }
+    return cssValuePool().createIdentifierValue(a->id);
+}
+
+PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSPropertyParser* p, CSSParserValue* value)
+{
+    CSSValueID id = value->id;
+    if (id == CSSValueWebkitText || (id >= CSSValueAqua && id <= CSSValueWindowtext) || id == CSSValueMenu || id == CSSValueCurrentcolor)
+        return cssValuePool().createIdentifierValue(id);
+
+    return p->parseColor(value);
+}
+
+bool CSSPropertyParser::parseDeprecatedLinearGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+    RefPtrWillBeRawPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSPrefixedLinearGradient);
+
+    // Walk the arguments.
+    CSSParserValueList* args = valueList->current()->function->args.get();
+    if (!args || !args->size())
+        return false;
+
+    CSSParserValue* a = args->current();
+    if (!a)
+        return false;
+
+    bool expectComma = false;
+    // Look for angle.
+    if (validUnit(a, FAngle, HTMLStandardMode)) {
+        result->setAngle(createPrimitiveNumericValue(a));
+
+        args->next();
+        expectComma = true;
+    } else {
+        // Look one or two optional keywords that indicate a side or corner.
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> startX, startY;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> location;
+        bool isHorizontal = false;
+        if ((location = valueFromSideKeyword(a, isHorizontal))) {
+            if (isHorizontal)
+                startX = location;
+            else
+                startY = location;
+
+            if ((a = args->next())) {
+                if ((location = valueFromSideKeyword(a, isHorizontal))) {
+                    if (isHorizontal) {
+                        if (startX)
+                            return false;
+                        startX = location;
+                    } else {
+                        if (startY)
+                            return false;
+                        startY = location;
+                    }
+
+                    args->next();
+                }
+            }
+
+            expectComma = true;
+        }
+
+        if (!startX && !startY)
+            startY = cssValuePool().createIdentifierValue(CSSValueTop);
+
+        result->setFirstX(startX.release());
+        result->setFirstY(startY.release());
+    }
+
+    if (!parseGradientColorStops(args, result.get(), expectComma))
+        return false;
+
+    if (!result->stopCount())
+        return false;
+
+    gradient = result.release();
+    return true;
+}
+
+bool CSSPropertyParser::parseDeprecatedRadialGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+    RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSPrefixedRadialGradient);
+
+    // Walk the arguments.
+    CSSParserValueList* args = valueList->current()->function->args.get();
+    if (!args || !args->size())
+        return false;
+
+    CSSParserValue* a = args->current();
+    if (!a)
+        return false;
+
+    bool expectComma = false;
+
+    // Optional background-position
+    RefPtrWillBeRawPtr<CSSValue> centerX;
+    RefPtrWillBeRawPtr<CSSValue> centerY;
+    // parse2ValuesFillPosition advances the args next pointer.
+    parse2ValuesFillPosition(args, centerX, centerY);
+    a = args->current();
+    if (!a)
+        return false;
+
+    if (centerX || centerY) {
+        // Comma
+        if (!isComma(a))
+            return false;
+
+        a = args->next();
+        if (!a)
+            return false;
+    }
+
+    result->setFirstX(toCSSPrimitiveValue(centerX.get()));
+    result->setSecondX(toCSSPrimitiveValue(centerX.get()));
+    // CSS3 radial gradients always share the same start and end point.
+    result->setFirstY(toCSSPrimitiveValue(centerY.get()));
+    result->setSecondY(toCSSPrimitiveValue(centerY.get()));
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeValue;
+
+    // Optional shape and/or size in any order.
+    for (int i = 0; i < 2; ++i) {
+        if (a->unit != CSSPrimitiveValue::CSS_IDENT)
+            break;
+
+        bool foundValue = false;
+        switch (a->id) {
+        case CSSValueCircle:
+        case CSSValueEllipse:
+            shapeValue = cssValuePool().createIdentifierValue(a->id);
+            foundValue = true;
+            break;
+        case CSSValueClosestSide:
+        case CSSValueClosestCorner:
+        case CSSValueFarthestSide:
+        case CSSValueFarthestCorner:
+        case CSSValueContain:
+        case CSSValueCover:
+            sizeValue = cssValuePool().createIdentifierValue(a->id);
+            foundValue = true;
+            break;
+        default:
+            break;
+        }
+
+        if (foundValue) {
+            a = args->next();
+            if (!a)
+                return false;
+
+            expectComma = true;
+        }
+    }
+
+    result->setShape(shapeValue);
+    result->setSizingBehavior(sizeValue);
+
+    // Or, two lengths or percentages
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize;
+
+    if (!shapeValue && !sizeValue) {
+        if (validUnit(a, FLength | FPercent)) {
+            horizontalSize = createPrimitiveNumericValue(a);
+            a = args->next();
+            if (!a)
+                return false;
+
+            expectComma = true;
+        }
+
+        if (validUnit(a, FLength | FPercent)) {
+            verticalSize = createPrimitiveNumericValue(a);
+
+            a = args->next();
+            if (!a)
+                return false;
+            expectComma = true;
+        }
+    }
+
+    // Must have neither or both.
+    if (!horizontalSize != !verticalSize)
+        return false;
+
+    result->setEndHorizontalSize(horizontalSize);
+    result->setEndVerticalSize(verticalSize);
+
+    if (!parseGradientColorStops(args, result.get(), expectComma))
+        return false;
+
+    gradient = result.release();
+    return true;
+}
+
+bool CSSPropertyParser::parseLinearGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+    RefPtrWillBeRawPtr<CSSLinearGradientValue> result = CSSLinearGradientValue::create(repeating, CSSLinearGradient);
+
+    CSSParserValueList* args = valueList->current()->function->args.get();
+    if (!args || !args->size())
+        return false;
+
+    CSSParserValue* a = args->current();
+    if (!a)
+        return false;
+
+    bool expectComma = false;
+    // Look for angle.
+    if (validUnit(a, FAngle, HTMLStandardMode)) {
+        result->setAngle(createPrimitiveNumericValue(a));
+
+        args->next();
+        expectComma = true;
+    } else if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "to")) {
+        // to [ [left | right] || [top | bottom] ]
+        a = args->next();
+        if (!a)
+            return false;
+
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> endX, endY;
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> location;
+        bool isHorizontal = false;
+
+        location = valueFromSideKeyword(a, isHorizontal);
+        if (!location)
+            return false;
+
+        if (isHorizontal)
+            endX = location;
+        else
+            endY = location;
+
+        a = args->next();
+        if (!a)
+            return false;
+
+        location = valueFromSideKeyword(a, isHorizontal);
+        if (location) {
+            if (isHorizontal) {
+                if (endX)
+                    return false;
+                endX = location;
+            } else {
+                if (endY)
+                    return false;
+                endY = location;
+            }
+
+            args->next();
+        }
+
+        expectComma = true;
+        result->setFirstX(endX.release());
+        result->setFirstY(endY.release());
+    }
+
+    if (!parseGradientColorStops(args, result.get(), expectComma))
+        return false;
+
+    if (!result->stopCount())
+        return false;
+
+    gradient = result.release();
+    return true;
+}
+
+bool CSSPropertyParser::parseRadialGradient(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& gradient, CSSGradientRepeat repeating)
+{
+    RefPtrWillBeRawPtr<CSSRadialGradientValue> result = CSSRadialGradientValue::create(repeating, CSSRadialGradient);
+
+    CSSParserValueList* args = valueList->current()->function->args.get();
+    if (!args || !args->size())
+        return false;
+
+    CSSParserValue* a = args->current();
+    if (!a)
+        return false;
+
+    bool expectComma = false;
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> shapeValue;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> sizeValue;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> horizontalSize;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> verticalSize;
+
+    // First part of grammar, the size/shape clause:
+    // [ circle || <length> ] |
+    // [ ellipse || [ <length> | <percentage> ]{2} ] |
+    // [ [ circle | ellipse] || <size-keyword> ]
+    for (int i = 0; i < 3; ++i) {
+        if (a->unit == CSSPrimitiveValue::CSS_IDENT) {
+            bool badIdent = false;
+            switch (a->id) {
+            case CSSValueCircle:
+            case CSSValueEllipse:
+                if (shapeValue)
+                    return false;
+                shapeValue = cssValuePool().createIdentifierValue(a->id);
+                break;
+            case CSSValueClosestSide:
+            case CSSValueClosestCorner:
+            case CSSValueFarthestSide:
+            case CSSValueFarthestCorner:
+                if (sizeValue || horizontalSize)
+                    return false;
+                sizeValue = cssValuePool().createIdentifierValue(a->id);
+                break;
+            default:
+                badIdent = true;
+            }
+
+            if (badIdent)
+                break;
+
+            a = args->next();
+            if (!a)
+                return false;
+        } else if (validUnit(a, FLength | FPercent)) {
+
+            if (sizeValue || horizontalSize)
+                return false;
+            horizontalSize = createPrimitiveNumericValue(a);
+
+            a = args->next();
+            if (!a)
+                return false;
+
+            if (validUnit(a, FLength | FPercent)) {
+                verticalSize = createPrimitiveNumericValue(a);
+                ++i;
+                a = args->next();
+                if (!a)
+                    return false;
+            }
+        } else
+            break;
+    }
+
+    // You can specify size as a keyword or a length/percentage, not both.
+    if (sizeValue && horizontalSize)
+        return false;
+    // Circles must have 0 or 1 lengths.
+    if (shapeValue && shapeValue->getValueID() == CSSValueCircle && verticalSize)
+        return false;
+    // Ellipses must have 0 or 2 length/percentages.
+    if (shapeValue && shapeValue->getValueID() == CSSValueEllipse && horizontalSize && !verticalSize)
+        return false;
+    // If there's only one size, it must be a length.
+    if (!verticalSize && horizontalSize && horizontalSize->isPercentage())
+        return false;
+
+    result->setShape(shapeValue);
+    result->setSizingBehavior(sizeValue);
+    result->setEndHorizontalSize(horizontalSize);
+    result->setEndVerticalSize(verticalSize);
+
+    // Second part of grammar, the center-position clause:
+    // at <position>
+    RefPtrWillBeRawPtr<CSSValue> centerX;
+    RefPtrWillBeRawPtr<CSSValue> centerY;
+    if (a->unit == CSSPrimitiveValue::CSS_IDENT && equalIgnoringCase(a, "at")) {
+        a = args->next();
+        if (!a)
+            return false;
+
+        parseFillPosition(args, centerX, centerY);
+        if (!(centerX && centerY))
+            return false;
+
+        a = args->current();
+        if (!a)
+            return false;
+        result->setFirstX(toCSSPrimitiveValue(centerX.get()));
+        result->setFirstY(toCSSPrimitiveValue(centerY.get()));
+        // Right now, CSS radial gradients have the same start and end centers.
+        result->setSecondX(toCSSPrimitiveValue(centerX.get()));
+        result->setSecondY(toCSSPrimitiveValue(centerY.get()));
+    }
+
+    if (shapeValue || sizeValue || horizontalSize || centerX || centerY)
+        expectComma = true;
+
+    if (!parseGradientColorStops(args, result.get(), expectComma))
+        return false;
+
+    gradient = result.release();
+    return true;
+}
+
+bool CSSPropertyParser::parseGradientColorStops(CSSParserValueList* valueList, CSSGradientValue* gradient, bool expectComma)
+{
+    CSSParserValue* a = valueList->current();
+
+    // Now look for color stops.
+    while (a) {
+        // Look for the comma before the next stop.
+        if (expectComma) {
+            if (!isComma(a))
+                return false;
+
+            a = valueList->next();
+            if (!a)
+                return false;
+        }
+
+        // <color-stop> = <color> [ <percentage> | <length> ]?
+        CSSGradientColorStop stop;
+        stop.m_color = parseGradientColorOrKeyword(this, a);
+        if (!stop.m_color)
+            return false;
+
+        a = valueList->next();
+        if (a) {
+            if (validUnit(a, FLength | FPercent)) {
+                stop.m_position = createPrimitiveNumericValue(a);
+                a = valueList->next();
+            }
+        }
+
+        gradient->addStop(stop);
+        expectComma = true;
+    }
+
+    // Must have 2 or more stops to be valid.
+    return gradient->stopCount() >= 2;
+}
+
+bool CSSPropertyParser::parseGeneratedImage(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& value)
+{
+    CSSParserValue* val = valueList->current();
+
+    if (val->unit != CSSParserValue::Function)
+        return false;
+
+    if (equalIgnoringCase(val->function->name, "-webkit-gradient(")) {
+        // FIXME: This should send a deprecation message.
+        if (m_context.useCounter())
+            m_context.useCounter()->count(UseCounter::DeprecatedWebKitGradient);
+        return parseDeprecatedGradient(valueList, value);
+    }
+
+    if (equalIgnoringCase(val->function->name, "-webkit-linear-gradient(")) {
+        // FIXME: This should send a deprecation message.
+        if (m_context.useCounter())
+            m_context.useCounter()->count(UseCounter::DeprecatedWebKitLinearGradient);
+        return parseDeprecatedLinearGradient(valueList, value, NonRepeating);
+    }
+
+    if (equalIgnoringCase(val->function->name, "linear-gradient("))
+        return parseLinearGradient(valueList, value, NonRepeating);
+
+    if (equalIgnoringCase(val->function->name, "-webkit-repeating-linear-gradient(")) {
+        // FIXME: This should send a deprecation message.
+        if (m_context.useCounter())
+            m_context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingLinearGradient);
+        return parseDeprecatedLinearGradient(valueList, value, Repeating);
+    }
+
+    if (equalIgnoringCase(val->function->name, "repeating-linear-gradient("))
+        return parseLinearGradient(valueList, value, Repeating);
+
+    if (equalIgnoringCase(val->function->name, "-webkit-radial-gradient(")) {
+        // FIXME: This should send a deprecation message.
+        if (m_context.useCounter())
+            m_context.useCounter()->count(UseCounter::DeprecatedWebKitRadialGradient);
+        return parseDeprecatedRadialGradient(valueList, value, NonRepeating);
+    }
+
+    if (equalIgnoringCase(val->function->name, "radial-gradient("))
+        return parseRadialGradient(valueList, value, NonRepeating);
+
+    if (equalIgnoringCase(val->function->name, "-webkit-repeating-radial-gradient(")) {
+        if (m_context.useCounter())
+            m_context.useCounter()->count(UseCounter::DeprecatedWebKitRepeatingRadialGradient);
+        return parseDeprecatedRadialGradient(valueList, value, Repeating);
+    }
+
+    if (equalIgnoringCase(val->function->name, "repeating-radial-gradient("))
+        return parseRadialGradient(valueList, value, Repeating);
+
+    if (equalIgnoringCase(val->function->name, "-webkit-canvas("))
+        return parseCanvas(valueList, value);
+
+    if (equalIgnoringCase(val->function->name, "-webkit-cross-fade("))
+        return parseCrossfade(valueList, value);
+
+    return false;
+}
+
+bool CSSPropertyParser::parseCrossfade(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& crossfade)
+{
+    // Walk the arguments.
+    CSSParserValueList* args = valueList->current()->function->args.get();
+    if (!args || args->size() != 5)
+        return false;
+    CSSParserValue* a = args->current();
+    RefPtrWillBeRawPtr<CSSValue> fromImageValue;
+    RefPtrWillBeRawPtr<CSSValue> toImageValue;
+
+    // The first argument is the "from" image. It is a fill image.
+    if (!a || !parseFillImage(args, fromImageValue))
+        return false;
+    a = args->next();
+
+    // Skip a comma
+    if (!isComma(a))
+        return false;
+    a = args->next();
+
+    // The second argument is the "to" image. It is a fill image.
+    if (!a || !parseFillImage(args, toImageValue))
+        return false;
+    a = args->next();
+
+    // Skip a comma
+    if (!isComma(a))
+        return false;
+    a = args->next();
+
+    // The third argument is the crossfade value. It is a percentage or a fractional number.
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> percentage;
+    if (!a)
+        return false;
+
+    if (a->unit == CSSPrimitiveValue::CSS_PERCENTAGE)
+        percentage = cssValuePool().createValue(clampTo<double>(a->fValue / 100, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+    else if (a->unit == CSSPrimitiveValue::CSS_NUMBER)
+        percentage = cssValuePool().createValue(clampTo<double>(a->fValue, 0, 1), CSSPrimitiveValue::CSS_NUMBER);
+    else
+        return false;
+
+    RefPtrWillBeRawPtr<CSSCrossfadeValue> result = CSSCrossfadeValue::create(fromImageValue, toImageValue);
+    result->setPercentage(percentage);
+
+    crossfade = result;
+
+    return true;
+}
+
+bool CSSPropertyParser::parseCanvas(CSSParserValueList* valueList, RefPtrWillBeRawPtr<CSSValue>& canvas)
+{
+    // Walk the arguments.
+    CSSParserValueList* args = valueList->current()->function->args.get();
+    if (!args || args->size() != 1)
+        return false;
+
+    // The first argument is the canvas name.  It is an identifier.
+    CSSParserValue* value = args->current();
+    if (!value || value->unit != CSSPrimitiveValue::CSS_IDENT)
+        return false;
+
+    canvas = CSSCanvasValue::create(value->string);
+    return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseImageSet(CSSParserValueList* valueList)
+{
+    CSSParserValue* function = valueList->current();
+
+    if (function->unit != CSSParserValue::Function)
+        return nullptr;
+
+    CSSParserValueList* functionArgs = valueList->current()->function->args.get();
+    if (!functionArgs || !functionArgs->size() || !functionArgs->current())
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSImageSetValue> imageSet = CSSImageSetValue::create();
+
+    CSSParserValue* arg = functionArgs->current();
+    while (arg) {
+        if (arg->unit != CSSPrimitiveValue::CSS_URI)
+            return nullptr;
+
+        RefPtrWillBeRawPtr<CSSImageValue> image = CSSImageValue::create(arg->string, completeURL(arg->string));
+        imageSet->append(image);
+
+        arg = functionArgs->next();
+        if (!arg || arg->unit != CSSPrimitiveValue::CSS_DIMENSION)
+            return nullptr;
+
+        double imageScaleFactor = 0;
+        const String& string = arg->string;
+        unsigned length = string.length();
+        if (!length)
+            return nullptr;
+        if (string.is8Bit()) {
+            const LChar* start = string.characters8();
+            parseDouble(start, start + length, 'x', imageScaleFactor);
+        } else {
+            const UChar* start = string.characters16();
+            parseDouble(start, start + length, 'x', imageScaleFactor);
+        }
+        if (imageScaleFactor <= 0)
+            return nullptr;
+        imageSet->append(cssValuePool().createValue(imageScaleFactor, CSSPrimitiveValue::CSS_NUMBER));
+
+        // If there are no more arguments, we're done.
+        arg = functionArgs->next();
+        if (!arg)
+            break;
+
+        // If there are more arguments, they should be after a comma.
+        if (!isComma(arg))
+            return nullptr;
+
+        // Skip the comma and move on to the next argument.
+        arg = functionArgs->next();
+    }
+
+    return imageSet.release();
+}
+
+bool CSSPropertyParser::parseWillChange(bool important)
+{
+    ASSERT(RuntimeEnabledFeatures::cssWillChangeEnabled());
+
+    RefPtrWillBeRawPtr<CSSValueList> values = CSSValueList::createCommaSeparated();
+    if (m_valueList->current()->id == CSSValueAuto) {
+        if (m_valueList->next())
+            return false;
+    }
+
+    CSSParserValue* currentValue;
+    bool expectComma = false;
+
+    // Every comma-separated list of CSS_IDENTs is a valid will-change value,
+    // unless the list includes an explicitly disallowed CSS_IDENT.
+    while ((currentValue = m_valueList->current())) {
+        if (expectComma) {
+            if (!isComma(currentValue))
+                return false;
+            expectComma = false;
+            m_valueList->next();
+            continue;
+        }
+
+        if (currentValue->unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        if (CSSPropertyID property = cssPropertyID(currentValue->string)) {
+            if (property == CSSPropertyWillChange)
+                return false;
+            values->append(cssValuePool().createIdentifierValue(property));
+        } else {
+            switch (currentValue->id) {
+            case CSSValueNone:
+            case CSSValueAll:
+            case CSSValueAuto:
+            case CSSValueDefault:
+            case CSSValueInitial:
+            case CSSValueInherit:
+                return false;
+            case CSSValueContents:
+            case CSSValueScrollPosition:
+                values->append(cssValuePool().createIdentifierValue(currentValue->id));
+                break;
+            default:
+                break;
+            }
+        }
+        expectComma = true;
+        m_valueList->next();
+    }
+
+    addProperty(CSSPropertyWillChange, values.release(), important);
+    return true;
+}
+
+bool CSSPropertyParser::isBlendMode(CSSValueID valueID)
+{
+    return (valueID >= CSSValueMultiply && valueID <= CSSValueLuminosity)
+        || valueID == CSSValueNormal
+        || valueID == CSSValueOverlay;
+}
+
+bool CSSPropertyParser::isCompositeOperator(CSSValueID valueID)
+{
+    // FIXME: Add CSSValueDestination and CSSValueLighter when the Compositing spec updates.
+    return valueID >= CSSValueClear && valueID <= CSSValueXor;
+}
+
+static void filterInfoForName(const CSSParserString& name, CSSFilterValue::FilterOperationType& filterType, unsigned& maximumArgumentCount)
+{
+    if (equalIgnoringCase(name, "grayscale("))
+        filterType = CSSFilterValue::GrayscaleFilterOperation;
+    else if (equalIgnoringCase(name, "sepia("))
+        filterType = CSSFilterValue::SepiaFilterOperation;
+    else if (equalIgnoringCase(name, "saturate("))
+        filterType = CSSFilterValue::SaturateFilterOperation;
+    else if (equalIgnoringCase(name, "hue-rotate("))
+        filterType = CSSFilterValue::HueRotateFilterOperation;
+    else if (equalIgnoringCase(name, "invert("))
+        filterType = CSSFilterValue::InvertFilterOperation;
+    else if (equalIgnoringCase(name, "opacity("))
+        filterType = CSSFilterValue::OpacityFilterOperation;
+    else if (equalIgnoringCase(name, "brightness("))
+        filterType = CSSFilterValue::BrightnessFilterOperation;
+    else if (equalIgnoringCase(name, "contrast("))
+        filterType = CSSFilterValue::ContrastFilterOperation;
+    else if (equalIgnoringCase(name, "blur("))
+        filterType = CSSFilterValue::BlurFilterOperation;
+    else if (equalIgnoringCase(name, "drop-shadow(")) {
+        filterType = CSSFilterValue::DropShadowFilterOperation;
+        maximumArgumentCount = 4;  // x-offset, y-offset, blur-radius, color -- spread and inset style not allowed.
+    }
+}
+
+PassRefPtrWillBeRawPtr<CSSFilterValue> CSSPropertyParser::parseBuiltinFilterArguments(CSSParserValueList* args, CSSFilterValue::FilterOperationType filterType)
+{
+    RefPtrWillBeRawPtr<CSSFilterValue> filterValue = CSSFilterValue::create(filterType);
+    ASSERT(args);
+
+    switch (filterType) {
+    case CSSFilterValue::GrayscaleFilterOperation:
+    case CSSFilterValue::SepiaFilterOperation:
+    case CSSFilterValue::SaturateFilterOperation:
+    case CSSFilterValue::InvertFilterOperation:
+    case CSSFilterValue::OpacityFilterOperation:
+    case CSSFilterValue::ContrastFilterOperation: {
+        // One optional argument, 0-1 or 0%-100%, if missing use 100%.
+        if (args->size() > 1)
+            return nullptr;
+
+        if (args->size()) {
+            CSSParserValue* value = args->current();
+            if (!validUnit(value, FNumber | FPercent | FNonNeg, HTMLStandardMode))
+                return nullptr;
+
+            double amount = value->fValue;
+
+            // Saturate and Contrast allow values over 100%.
+            if (filterType != CSSFilterValue::SaturateFilterOperation
+                && filterType != CSSFilterValue::ContrastFilterOperation) {
+                double maxAllowed = value->unit == CSSPrimitiveValue::CSS_PERCENTAGE ? 100.0 : 1.0;
+                if (amount > maxAllowed)
+                    return nullptr;
+            }
+
+            filterValue->append(cssValuePool().createValue(amount, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
+        }
+        break;
+    }
+    case CSSFilterValue::BrightnessFilterOperation: {
+        // One optional argument, if missing use 100%.
+        if (args->size() > 1)
+            return nullptr;
+
+        if (args->size()) {
+            CSSParserValue* value = args->current();
+            if (!validUnit(value, FNumber | FPercent, HTMLStandardMode))
+                return nullptr;
+
+            filterValue->append(cssValuePool().createValue(value->fValue, static_cast<CSSPrimitiveValue::UnitTypes>(value->unit)));
+        }
+        break;
+    }
+    case CSSFilterValue::HueRotateFilterOperation: {
+        // hue-rotate() takes one optional angle.
+        if (args->size() > 1)
+            return nullptr;
+
+        if (args->size()) {
+            CSSParserValue* argument = args->current();
+            if (!validUnit(argument, FAngle, HTMLStandardMode))
+                return nullptr;
+
+            filterValue->append(createPrimitiveNumericValue(argument));
+        }
+        break;
+    }
+    case CSSFilterValue::BlurFilterOperation: {
+        // Blur takes a single length. Zero parameters are allowed.
+        if (args->size() > 1)
+            return nullptr;
+
+        if (args->size()) {
+            CSSParserValue* argument = args->current();
+            if (!validUnit(argument, FLength | FNonNeg, HTMLStandardMode))
+                return nullptr;
+
+            filterValue->append(createPrimitiveNumericValue(argument));
+        }
+        break;
+    }
+    case CSSFilterValue::DropShadowFilterOperation: {
+        // drop-shadow() takes a single shadow.
+        RefPtrWillBeRawPtr<CSSValueList> shadowValueList = parseShadow(args, CSSPropertyWebkitFilter);
+        if (!shadowValueList || shadowValueList->length() != 1)
+            return nullptr;
+
+        filterValue->append((shadowValueList.release())->itemWithoutBoundsCheck(0));
+        break;
+    }
+    default:
+        ASSERT_NOT_REACHED();
+    }
+    return filterValue.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSValueList> CSSPropertyParser::parseFilter()
+{
+    if (!m_valueList)
+        return nullptr;
+
+    // The filter is a list of functional primitives that specify individual operations.
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+        if (value->unit != CSSPrimitiveValue::CSS_URI && (value->unit != CSSParserValue::Function || !value->function))
+            return nullptr;
+
+        CSSFilterValue::FilterOperationType filterType = CSSFilterValue::UnknownFilterOperation;
+
+        // See if the specified primitive is one we understand.
+        if (value->unit == CSSPrimitiveValue::CSS_URI) {
+            RefPtrWillBeRawPtr<CSSFilterValue> referenceFilterValue = CSSFilterValue::create(CSSFilterValue::ReferenceFilterOperation);
+            list->append(referenceFilterValue);
+            referenceFilterValue->append(CSSSVGDocumentValue::create(value->string));
+        } else {
+            const CSSParserString name = value->function->name;
+            unsigned maximumArgumentCount = 1;
+
+            filterInfoForName(name, filterType, maximumArgumentCount);
+
+            if (filterType == CSSFilterValue::UnknownFilterOperation)
+                return nullptr;
+
+            CSSParserValueList* args = value->function->args.get();
+            if (!args)
+                return nullptr;
+
+            RefPtrWillBeRawPtr<CSSFilterValue> filterValue = parseBuiltinFilterArguments(args, filterType);
+            if (!filterValue)
+                return nullptr;
+
+            list->append(filterValue);
+        }
+    }
+
+    return list.release();
+}
+
+bool CSSPropertyParser::parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2, RefPtrWillBeRawPtr<CSSValue>& value3)
+{
+    propId1 = propId;
+    propId2 = propId;
+    propId3 = propId;
+    if (propId == CSSPropertyWebkitTransformOrigin) {
+        propId1 = CSSPropertyWebkitTransformOriginX;
+        propId2 = CSSPropertyWebkitTransformOriginY;
+        propId3 = CSSPropertyWebkitTransformOriginZ;
+    }
+
+    switch (propId) {
+        case CSSPropertyWebkitTransformOrigin:
+            if (!parseTransformOriginShorthand(value, value2, value3))
+                return false;
+            // parseTransformOriginShorthand advances the m_valueList pointer
+            break;
+        case CSSPropertyWebkitTransformOriginX: {
+            value = parseFillPositionX(m_valueList.get());
+            if (value)
+                m_valueList->next();
+            break;
+        }
+        case CSSPropertyWebkitTransformOriginY: {
+            value = parseFillPositionY(m_valueList.get());
+            if (value)
+                m_valueList->next();
+            break;
+        }
+        case CSSPropertyWebkitTransformOriginZ: {
+            if (validUnit(m_valueList->current(), FLength))
+                value = createPrimitiveNumericValue(m_valueList->current());
+            if (value)
+                m_valueList->next();
+            break;
+        }
+        default:
+            ASSERT_NOT_REACHED();
+            return false;
+    }
+
+    return value;
+}
+
+bool CSSPropertyParser::parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>& value, RefPtrWillBeRawPtr<CSSValue>& value2)
+{
+    propId1 = propId;
+    propId2 = propId;
+    if (propId == CSSPropertyWebkitPerspectiveOrigin) {
+        propId1 = CSSPropertyWebkitPerspectiveOriginX;
+        propId2 = CSSPropertyWebkitPerspectiveOriginY;
+    }
+
+    switch (propId) {
+        case CSSPropertyWebkitPerspectiveOrigin:
+            if (m_valueList->size() > 2)
+                return false;
+            parse2ValuesFillPosition(m_valueList.get(), value, value2);
+            break;
+        case CSSPropertyWebkitPerspectiveOriginX: {
+            value = parseFillPositionX(m_valueList.get());
+            if (value)
+                m_valueList->next();
+            break;
+        }
+        case CSSPropertyWebkitPerspectiveOriginY: {
+            value = parseFillPositionY(m_valueList.get());
+            if (value)
+                m_valueList->next();
+            break;
+        }
+        default:
+            ASSERT_NOT_REACHED();
+            return false;
+    }
+
+    return value;
+}
+
+bool CSSPropertyParser::parseTouchAction(bool important)
+{
+    if (!RuntimeEnabledFeatures::cssTouchActionEnabled())
+        return false;
+
+    CSSParserValue* value = m_valueList->current();
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    if (m_valueList->size() == 1 && value && (value->id == CSSValueAuto || value->id == CSSValueNone || value->id == CSSValueManipulation)) {
+        list->append(cssValuePool().createIdentifierValue(value->id));
+        addProperty(CSSPropertyTouchAction, list.release(), important);
+        m_valueList->next();
+        return true;
+    }
+
+    bool isValid = true;
+    while (isValid && value) {
+        switch (value->id) {
+        case CSSValuePanX:
+        case CSSValuePanY: {
+            RefPtrWillBeRawPtr<CSSValue> panValue = cssValuePool().createIdentifierValue(value->id);
+            if (list->hasValue(panValue.get())) {
+                isValid = false;
+                break;
+            }
+            list->append(panValue.release());
+            break;
+        }
+        default:
+            isValid = false;
+            break;
+        }
+        if (isValid)
+            value = m_valueList->next();
+    }
+
+    if (list->length() && isValid) {
+        addProperty(CSSPropertyTouchAction, list.release(), important);
+        return true;
+    }
+
+    return false;
+}
+
+void CSSPropertyParser::addTextDecorationProperty(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue> value, bool important)
+{
+    // The text-decoration-line property takes priority over text-decoration, unless the latter has important priority set.
+    if (propId == CSSPropertyTextDecoration && !important && !inShorthand()) {
+        for (unsigned i = 0; i < m_parsedProperties.size(); ++i) {
+            if (m_parsedProperties[i].id() == CSSPropertyTextDecorationLine)
+                return;
+        }
+    }
+    addProperty(propId, value, important);
+}
+
+bool CSSPropertyParser::parseTextDecoration(CSSPropertyID propId, bool important)
+{
+    if (propId == CSSPropertyTextDecorationLine
+        && !RuntimeEnabledFeatures::css3TextDecorationsEnabled())
+        return false;
+
+    CSSParserValue* value = m_valueList->current();
+    if (value && value->id == CSSValueNone) {
+        addTextDecorationProperty(propId, cssValuePool().createIdentifierValue(CSSValueNone), important);
+        m_valueList->next();
+        return true;
+    }
+
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+    bool isValid = true;
+    while (isValid && value) {
+        switch (value->id) {
+        case CSSValueUnderline:
+        case CSSValueOverline:
+        case CSSValueLineThrough:
+        case CSSValueBlink:
+            list->append(cssValuePool().createIdentifierValue(value->id));
+            break;
+        default:
+            isValid = false;
+            break;
+        }
+        if (isValid)
+            value = m_valueList->next();
+    }
+
+    // Values are either valid or in shorthand scope.
+    if (list->length() && (isValid || inShorthand())) {
+        addTextDecorationProperty(propId, list.release(), important);
+        return true;
+    }
+
+    return false;
+}
+
+bool CSSPropertyParser::parseTextUnderlinePosition(bool important)
+{
+    // The text-underline-position property has syntax "auto | [ under || [ left | right ] ]".
+    // However, values 'left' and 'right' are not implemented yet, so we will parse syntax
+    // "auto | under" for now.
+    CSSParserValue* value = m_valueList->current();
+    switch (value->id) {
+    case CSSValueAuto:
+    case CSSValueUnder:
+        if (m_valueList->next())
+            return false;
+        addProperty(CSSPropertyTextUnderlinePosition, cssValuePool().createIdentifierValue(value->id), important);
+        return true;
+    default:
+        return false;
+    }
+}
+
+bool CSSPropertyParser::parseTextEmphasisStyle(bool important)
+{
+    unsigned valueListSize = m_valueList->size();
+
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> fill;
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> shape;
+
+    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+        if (value->unit == CSSPrimitiveValue::CSS_STRING) {
+            if (fill || shape || (valueListSize != 1 && !inShorthand()))
+                return false;
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, createPrimitiveStringValue(value), important);
+            m_valueList->next();
+            return true;
+        }
+
+        if (value->id == CSSValueNone) {
+            if (fill || shape || (valueListSize != 1 && !inShorthand()))
+                return false;
+            addProperty(CSSPropertyWebkitTextEmphasisStyle, cssValuePool().createIdentifierValue(CSSValueNone), important);
+            m_valueList->next();
+            return true;
+        }
+
+        if (value->id == CSSValueOpen || value->id == CSSValueFilled) {
+            if (fill)
+                return false;
+            fill = cssValuePool().createIdentifierValue(value->id);
+        } else if (value->id == CSSValueDot || value->id == CSSValueCircle || value->id == CSSValueDoubleCircle || value->id == CSSValueTriangle || value->id == CSSValueSesame) {
+            if (shape)
+                return false;
+            shape = cssValuePool().createIdentifierValue(value->id);
+        } else if (!inShorthand())
+            return false;
+        else
+            break;
+    }
+
+    if (fill && shape) {
+        RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
+        parsedValues->append(fill.release());
+        parsedValues->append(shape.release());
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, parsedValues.release(), important);
+        return true;
+    }
+    if (fill) {
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, fill.release(), important);
+        return true;
+    }
+    if (shape) {
+        addProperty(CSSPropertyWebkitTextEmphasisStyle, shape.release(), important);
+        return true;
+    }
+
+    return false;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseTextIndent()
+{
+    RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createSpaceSeparated();
+
+    // <length> | <percentage> | inherit
+    if (m_valueList->size() == 1) {
+        CSSParserValue* value = m_valueList->current();
+        if (!value->id && validUnit(value, FLength | FPercent)) {
+            list->append(createPrimitiveNumericValue(value));
+            m_valueList->next();
+            return list.release();
+        }
+    }
+
+    if (!RuntimeEnabledFeatures::css3TextEnabled())
+        return nullptr;
+
+    // The case where text-indent has only <length>(or <percentage>) value
+    // is handled above if statement even though css3TextEnabled() returns true.
+
+    // [ [ <length> | <percentage> ] && each-line ] | inherit
+    if (m_valueList->size() != 2)
+        return nullptr;
+
+    CSSParserValue* firstValue = m_valueList->current();
+    CSSParserValue* secondValue = m_valueList->next();
+    CSSParserValue* lengthOrPercentageValue = 0;
+
+    // [ <length> | <percentage> ] each-line
+    if (validUnit(firstValue, FLength | FPercent) && secondValue->id == CSSValueEachLine)
+        lengthOrPercentageValue = firstValue;
+    // each-line [ <length> | <percentage> ]
+    else if (firstValue->id == CSSValueEachLine && validUnit(secondValue, FLength | FPercent))
+        lengthOrPercentageValue = secondValue;
+
+    if (lengthOrPercentageValue) {
+        list->append(createPrimitiveNumericValue(lengthOrPercentageValue));
+        list->append(cssValuePool().createIdentifierValue(CSSValueEachLine));
+        m_valueList->next();
+        return list.release();
+    }
+
+    return nullptr;
+}
+
+bool CSSPropertyParser::parseLineBoxContain(bool important)
+{
+    LineBoxContain lineBoxContain = LineBoxContainNone;
+
+    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+        if (value->id == CSSValueBlock) {
+            if (lineBoxContain & LineBoxContainBlock)
+                return false;
+            lineBoxContain |= LineBoxContainBlock;
+        } else if (value->id == CSSValueInline) {
+            if (lineBoxContain & LineBoxContainInline)
+                return false;
+            lineBoxContain |= LineBoxContainInline;
+        } else if (value->id == CSSValueFont) {
+            if (lineBoxContain & LineBoxContainFont)
+                return false;
+            lineBoxContain |= LineBoxContainFont;
+        } else if (value->id == CSSValueGlyphs) {
+            if (lineBoxContain & LineBoxContainGlyphs)
+                return false;
+            lineBoxContain |= LineBoxContainGlyphs;
+        } else if (value->id == CSSValueReplaced) {
+            if (lineBoxContain & LineBoxContainReplaced)
+                return false;
+            lineBoxContain |= LineBoxContainReplaced;
+        } else if (value->id == CSSValueInlineBox) {
+            if (lineBoxContain & LineBoxContainInlineBox)
+                return false;
+            lineBoxContain |= LineBoxContainInlineBox;
+        } else
+            return false;
+    }
+
+    if (!lineBoxContain)
+        return false;
+
+    addProperty(CSSPropertyWebkitLineBoxContain, CSSLineBoxContainValue::create(lineBoxContain), important);
+    return true;
+}
+
+bool CSSPropertyParser::parseFontFeatureTag(CSSValueList* settings)
+{
+    // Feature tag name consists of 4-letter characters.
+    static const unsigned tagNameLength = 4;
+
+    CSSParserValue* value = m_valueList->current();
+    // Feature tag name comes first
+    if (value->unit != CSSPrimitiveValue::CSS_STRING)
+        return false;
+    if (value->string.length() != tagNameLength)
+        return false;
+    for (unsigned i = 0; i < tagNameLength; ++i) {
+        // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification.
+        UChar character = value->string[i];
+        if (character < 0x20 || character > 0x7E)
+            return false;
+    }
+
+    AtomicString tag = value->string;
+    int tagValue = 1;
+    // Feature tag values could follow: <integer> | on | off
+    value = m_valueList->next();
+    if (value) {
+        if (value->unit == CSSPrimitiveValue::CSS_NUMBER && value->isInt && value->fValue >= 0) {
+            tagValue = clampToInteger(value->fValue);
+            if (tagValue < 0)
+                return false;
+            m_valueList->next();
+        } else if (value->id == CSSValueOn || value->id == CSSValueOff) {
+            tagValue = value->id == CSSValueOn;
+            m_valueList->next();
+        }
+    }
+    settings->append(CSSFontFeatureValue::create(tag, tagValue));
+    return true;
+}
+
+bool CSSPropertyParser::parseFontFeatureSettings(bool important)
+{
+    if (m_valueList->size() == 1 && m_valueList->current()->id == CSSValueNormal) {
+        RefPtrWillBeRawPtr<CSSPrimitiveValue> normalValue = cssValuePool().createIdentifierValue(CSSValueNormal);
+        m_valueList->next();
+        addProperty(CSSPropertyWebkitFontFeatureSettings, normalValue.release(), important);
+        return true;
+    }
+
+    RefPtrWillBeRawPtr<CSSValueList> settings = CSSValueList::createCommaSeparated();
+    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+        if (!parseFontFeatureTag(settings.get()))
+            return false;
+
+        // If the list isn't parsed fully, the current value should be comma.
+        value = m_valueList->current();
+        if (value && !isComma(value))
+            return false;
+    }
+    if (settings->length()) {
+        addProperty(CSSPropertyWebkitFontFeatureSettings, settings.release(), important);
+        return true;
+    }
+    return false;
+}
+
+bool CSSPropertyParser::parseFontVariantLigatures(bool important)
+{
+    RefPtrWillBeRawPtr<CSSValueList> ligatureValues = CSSValueList::createSpaceSeparated();
+    bool sawCommonLigaturesValue = false;
+    bool sawDiscretionaryLigaturesValue = false;
+    bool sawHistoricalLigaturesValue = false;
+    bool sawContextualLigaturesValue = false;
+
+    for (CSSParserValue* value = m_valueList->current(); value; value = m_valueList->next()) {
+        if (value->unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        switch (value->id) {
+        case CSSValueNoCommonLigatures:
+        case CSSValueCommonLigatures:
+            if (sawCommonLigaturesValue)
+                return false;
+            sawCommonLigaturesValue = true;
+            ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+            break;
+        case CSSValueNoDiscretionaryLigatures:
+        case CSSValueDiscretionaryLigatures:
+            if (sawDiscretionaryLigaturesValue)
+                return false;
+            sawDiscretionaryLigaturesValue = true;
+            ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+            break;
+        case CSSValueNoHistoricalLigatures:
+        case CSSValueHistoricalLigatures:
+            if (sawHistoricalLigaturesValue)
+                return false;
+            sawHistoricalLigaturesValue = true;
+            ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+            break;
+        case CSSValueNoContextual:
+        case CSSValueContextual:
+            if (sawContextualLigaturesValue)
+                return false;
+            sawContextualLigaturesValue = true;
+            ligatureValues->append(cssValuePool().createIdentifierValue(value->id));
+            break;
+        default:
+            return false;
+        }
+    }
+
+    if (!ligatureValues->length())
+        return false;
+
+    addProperty(CSSPropertyFontVariantLigatures, ligatureValues.release(), important);
+    return true;
+}
+
+bool CSSPropertyParser::parseCalculation(CSSParserValue* value, ValueRange range)
+{
+    ASSERT(isCalculation(value));
+
+    CSSParserValueList* args = value->function->args.get();
+    if (!args || !args->size())
+        return false;
+
+    ASSERT(!m_parsedCalculation);
+    m_parsedCalculation = CSSCalcValue::create(value->function->name, args, range);
+
+    if (!m_parsedCalculation)
+        return false;
+
+    return true;
+}
+
+bool CSSPropertyParser::parseViewportProperty(CSSPropertyID propId, bool important)
+{
+    ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
+
+    CSSParserValue* value = m_valueList->current();
+    if (!value)
+        return false;
+
+    CSSValueID id = value->id;
+    bool validPrimitive = false;
+
+    switch (propId) {
+    case CSSPropertyMinWidth: // auto | extend-to-zoom | <length> | <percentage>
+    case CSSPropertyMaxWidth:
+    case CSSPropertyMinHeight:
+    case CSSPropertyMaxHeight:
+        if (id == CSSValueAuto || id == CSSValueInternalExtendToZoom)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FLength | FPercent | FNonNeg));
+        break;
+    case CSSPropertyWidth: // shorthand
+        return parseViewportShorthand(propId, CSSPropertyMinWidth, CSSPropertyMaxWidth, important);
+    case CSSPropertyHeight:
+        return parseViewportShorthand(propId, CSSPropertyMinHeight, CSSPropertyMaxHeight, important);
+    case CSSPropertyMinZoom: // auto | <number> | <percentage>
+    case CSSPropertyMaxZoom:
+    case CSSPropertyZoom:
+        if (id == CSSValueAuto)
+            validPrimitive = true;
+        else
+            validPrimitive = (!id && validUnit(value, FNumber | FPercent | FNonNeg));
+        break;
+    case CSSPropertyUserZoom: // zoom | fixed
+        if (id == CSSValueZoom || id == CSSValueFixed)
+            validPrimitive = true;
+        break;
+    case CSSPropertyOrientation: // auto | portrait | landscape
+        if (id == CSSValueAuto || id == CSSValuePortrait || id == CSSValueLandscape)
+            validPrimitive = true;
+    default:
+        break;
+    }
+
+    RefPtrWillBeRawPtr<CSSValue> parsedValue;
+    if (validPrimitive) {
+        parsedValue = parseValidPrimitive(id, value);
+        m_valueList->next();
+    }
+
+    if (parsedValue) {
+        if (!m_valueList->current() || inShorthand()) {
+            addProperty(propId, parsedValue.release(), important);
+            return true;
+        }
+    }
+
+    return false;
+}
+
+bool CSSPropertyParser::parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important)
+{
+    ASSERT(RuntimeEnabledFeatures::cssViewportEnabled() || isUASheetBehavior(m_context.mode()));
+    unsigned numValues = m_valueList->size();
+
+    if (numValues > 2)
+        return false;
+
+    ShorthandScope scope(this, propId);
+
+    if (!parseViewportProperty(first, important))
+        return false;
+
+    // If just one value is supplied, the second value
+    // is implicitly initialized with the first value.
+    if (numValues == 1)
+        m_valueList->previous();
+
+    return parseViewportProperty(second, important);
+}
+
+template <typename CharacterType>
+static CSSPropertyID cssPropertyID(const CharacterType* propertyName, unsigned length)
+{
+    char buffer[maxCSSPropertyNameLength + 1]; // 1 for null character
+
+    for (unsigned i = 0; i != length; ++i) {
+        CharacterType c = propertyName[i];
+        if (c == 0 || c >= 0x7F)
+            return CSSPropertyInvalid; // illegal character
+        buffer[i] = toASCIILower(c);
+    }
+    buffer[length] = '\0';
+
+    const char* name = buffer;
+    const Property* hashTableEntry = findProperty(name, length);
+    return hashTableEntry ? static_cast<CSSPropertyID>(hashTableEntry->id) : CSSPropertyInvalid;
+}
+
+CSSPropertyID cssPropertyID(const String& string)
+{
+    unsigned length = string.length();
+
+    if (!length)
+        return CSSPropertyInvalid;
+    if (length > maxCSSPropertyNameLength)
+        return CSSPropertyInvalid;
+
+    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
+}
+
+CSSPropertyID cssPropertyID(const CSSParserString& string)
+{
+    unsigned length = string.length();
+
+    if (!length)
+        return CSSPropertyInvalid;
+    if (length > maxCSSPropertyNameLength)
+        return CSSPropertyInvalid;
+
+    return string.is8Bit() ? cssPropertyID(string.characters8(), length) : cssPropertyID(string.characters16(), length);
+}
+
+template <typename CharacterType>
+static CSSValueID cssValueKeywordID(const CharacterType* valueKeyword, unsigned length)
+{
+    char buffer[maxCSSValueKeywordLength + 1]; // 1 for null character
+
+    for (unsigned i = 0; i != length; ++i) {
+        CharacterType c = valueKeyword[i];
+        if (c == 0 || c >= 0x7F)
+            return CSSValueInvalid; // illegal character
+        buffer[i] = WTF::toASCIILower(c);
+    }
+    buffer[length] = '\0';
+
+    const Value* hashTableEntry = findValue(buffer, length);
+    return hashTableEntry ? static_cast<CSSValueID>(hashTableEntry->id) : CSSValueInvalid;
+}
+
+CSSValueID cssValueKeywordID(const CSSParserString& string)
+{
+    unsigned length = string.length();
+    if (!length)
+        return CSSValueInvalid;
+    if (length > maxCSSValueKeywordLength)
+        return CSSValueInvalid;
+
+    return string.is8Bit() ? cssValueKeywordID(string.characters8(), length) : cssValueKeywordID(string.characters16(), length);
+}
+
+bool isValidNthToken(const CSSParserString& token)
+{
+    // The tokenizer checks for the construct of an+b.
+    // However, since the {ident} rule precedes the {nth} rule, some of those
+    // tokens are identified as string literal. Furthermore we need to accept
+    // "odd" and "even" which does not match to an+b.
+    return equalIgnoringCase(token, "odd") || equalIgnoringCase(token, "even")
+        || equalIgnoringCase(token, "n") || equalIgnoringCase(token, "-n");
+}
+
+bool CSSPropertyParser::isSystemColor(int id)
+{
+    return (id >= CSSValueActiveborder && id <= CSSValueWindowtext) || id == CSSValueMenu;
+}
+
+bool CSSPropertyParser::parseSVGValue(CSSPropertyID propId, bool important)
+{
+    CSSParserValue* value = m_valueList->current();
+    if (!value)
+        return false;
+
+    CSSValueID id = value->id;
+
+    bool validPrimitive = false;
+    RefPtrWillBeRawPtr<CSSValue> parsedValue;
+
+    switch (propId) {
+    /* The comment to the right defines all valid value of these
+     * properties as defined in SVG 1.1, Appendix N. Property index */
+    case CSSPropertyAlignmentBaseline:
+    // auto | baseline | before-edge | text-before-edge | middle |
+    // central | after-edge | text-after-edge | ideographic | alphabetic |
+    // hanging | mathematical | inherit
+        if (id == CSSValueAuto || id == CSSValueBaseline || id == CSSValueMiddle
+            || (id >= CSSValueBeforeEdge && id <= CSSValueMathematical))
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyBaselineShift:
+    // baseline | super | sub | <percentage> | <length> | inherit
+        if (id == CSSValueBaseline || id == CSSValueSub
+            || id >= CSSValueSuper)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
+        break;
+
+    case CSSPropertyDominantBaseline:
+    // auto | use-script | no-change | reset-size | ideographic |
+    // alphabetic | hanging | mathematical | central | middle |
+    // text-after-edge | text-before-edge | inherit
+        if (id == CSSValueAuto || id == CSSValueMiddle
+            || (id >= CSSValueUseScript && id <= CSSValueResetSize)
+            || (id >= CSSValueCentral && id <= CSSValueMathematical))
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyEnableBackground:
+    // accumulate | new [x] [y] [width] [height] | inherit
+        if (id == CSSValueAccumulate) // TODO : new
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyMarkerStart:
+    case CSSPropertyMarkerMid:
+    case CSSPropertyMarkerEnd:
+    case CSSPropertyMask:
+        if (id == CSSValueNone) {
+            validPrimitive = true;
+        } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+            parsedValue = CSSPrimitiveValue::create(value->string, CSSPrimitiveValue::CSS_URI);
+            if (parsedValue)
+                m_valueList->next();
+        }
+        break;
+
+    case CSSPropertyClipRule: // nonzero | evenodd | inherit
+    case CSSPropertyFillRule:
+        if (id == CSSValueNonzero || id == CSSValueEvenodd)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyStrokeMiterlimit: // <miterlimit> | inherit
+        validPrimitive = validUnit(value, FNumber | FNonNeg, SVGAttributeMode);
+        break;
+
+    case CSSPropertyStrokeLinejoin: // miter | round | bevel | inherit
+        if (id == CSSValueMiter || id == CSSValueRound || id == CSSValueBevel)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyStrokeLinecap: // butt | round | square | inherit
+        if (id == CSSValueButt || id == CSSValueRound || id == CSSValueSquare)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyStrokeOpacity: // <opacity-value> | inherit
+    case CSSPropertyFillOpacity:
+    case CSSPropertyStopOpacity:
+    case CSSPropertyFloodOpacity:
+        validPrimitive = (!id && validUnit(value, FNumber | FPercent, SVGAttributeMode));
+        break;
+
+    case CSSPropertyShapeRendering:
+    // auto | optimizeSpeed | crispEdges | geometricPrecision | inherit
+        if (id == CSSValueAuto || id == CSSValueOptimizespeed
+            || id == CSSValueCrispedges || id == CSSValueGeometricprecision)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyImageRendering: // auto | optimizeSpeed |
+    case CSSPropertyColorRendering: // optimizeQuality | inherit
+        if (id == CSSValueAuto || id == CSSValueOptimizespeed
+            || id == CSSValueOptimizequality)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyBufferedRendering: // auto | dynamic | static
+        if (id == CSSValueAuto || id == CSSValueDynamic || id == CSSValueStatic)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyColorProfile: // auto | sRGB | <name> | <uri> inherit
+        if (id == CSSValueAuto || id == CSSValueSrgb)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyColorInterpolation: // auto | sRGB | linearRGB | inherit
+    case CSSPropertyColorInterpolationFilters:
+        if (id == CSSValueAuto || id == CSSValueSrgb || id == CSSValueLinearrgb)
+            validPrimitive = true;
+        break;
+
+    /* Start of supported CSS properties with validation. This is needed for parseShortHand to work
+     * correctly and allows optimization in applyRule(..)
+     */
+
+    case CSSPropertyTextAnchor: // start | middle | end | inherit
+        if (id == CSSValueStart || id == CSSValueMiddle || id == CSSValueEnd)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyGlyphOrientationVertical: // auto | <angle> | inherit
+        if (id == CSSValueAuto) {
+            validPrimitive = true;
+            break;
+        }
+    /* fallthrough intentional */
+    case CSSPropertyGlyphOrientationHorizontal: // <angle> (restricted to _deg_ per SVG 1.1 spec) | inherit
+        if (value->unit == CSSPrimitiveValue::CSS_DEG || value->unit == CSSPrimitiveValue::CSS_NUMBER) {
+            parsedValue = CSSPrimitiveValue::create(value->fValue, CSSPrimitiveValue::CSS_DEG);
+
+            if (parsedValue)
+                m_valueList->next();
+        }
+        break;
+
+    case CSSPropertyFill: // <paint> | inherit
+    case CSSPropertyStroke: // <paint> | inherit
+        {
+            if (id == CSSValueNone) {
+                parsedValue = SVGPaint::createNone();
+            } else if (id == CSSValueCurrentcolor) {
+                parsedValue = SVGPaint::createCurrentColor();
+            } else if (isSystemColor(id)) {
+                parsedValue = SVGPaint::createColor(RenderTheme::theme().systemColor(id));
+            } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+                RGBA32 c = Color::transparent;
+                if (m_valueList->next()) {
+                    if (parseColorFromValue(m_valueList->current(), c))
+                        parsedValue = SVGPaint::createURIAndColor(value->string, c);
+                    else if (m_valueList->current()->id == CSSValueNone)
+                        parsedValue = SVGPaint::createURIAndNone(value->string);
+                    else if (m_valueList->current()->id == CSSValueCurrentcolor)
+                        parsedValue = SVGPaint::createURIAndCurrentColor(value->string);
+                }
+                if (!parsedValue)
+                    parsedValue = SVGPaint::createURI(value->string);
+            } else {
+                parsedValue = parseSVGPaint();
+            }
+
+            if (parsedValue)
+                m_valueList->next();
+        }
+        break;
+
+    case CSSPropertyStopColor: // TODO : icccolor
+    case CSSPropertyFloodColor:
+    case CSSPropertyLightingColor:
+        if (isSystemColor(id)) {
+            parsedValue = cssValuePool().createColorValue(RenderTheme::theme().systemColor(id).rgb());
+        } else if ((id >= CSSValueAqua && id <= CSSValueTransparent)
+            || (id >= CSSValueAliceblue && id <= CSSValueYellowgreen) || id == CSSValueGrey) {
+            StyleColor styleColor = SVGPaint::colorFromRGBColorString(value->string);
+            ASSERT(!styleColor.isCurrentColor());
+            parsedValue = cssValuePool().createColorValue(styleColor.color().rgb());
+        } else if (id == CSSValueCurrentcolor) {
+            parsedValue = cssValuePool().createIdentifierValue(id);
+        } else { // TODO : svgcolor (iccColor)
+            parsedValue = parseColor();
+        }
+
+        if (parsedValue)
+            m_valueList->next();
+
+        break;
+
+    case CSSPropertyPaintOrder:
+        if (!RuntimeEnabledFeatures::svgPaintOrderEnabled())
+            return false;
+
+        if (m_valueList->size() == 1 && id == CSSValueNormal)
+            validPrimitive = true;
+        else if ((parsedValue = parsePaintOrder()))
+            m_valueList->next();
+        break;
+
+    case CSSPropertyVectorEffect: // none | non-scaling-stroke | inherit
+        if (id == CSSValueNone || id == CSSValueNonScalingStroke)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyWritingMode:
+    // lr-tb | rl_tb | tb-rl | lr | rl | tb | inherit
+        if (id == CSSValueLrTb || id == CSSValueRlTb || id == CSSValueTbRl || id == CSSValueLr || id == CSSValueRl || id == CSSValueTb)
+            validPrimitive = true;
+        break;
+
+    case CSSPropertyStrokeWidth: // <length> | inherit
+    case CSSPropertyStrokeDashoffset:
+        validPrimitive = validUnit(value, FLength | FPercent, SVGAttributeMode);
+        break;
+    case CSSPropertyStrokeDasharray: // none | <dasharray> | inherit
+        if (id == CSSValueNone)
+            validPrimitive = true;
+        else
+            parsedValue = parseSVGStrokeDasharray();
+
+        break;
+
+    case CSSPropertyKerning: // auto | normal | <length> | inherit
+        if (id == CSSValueAuto || id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            validPrimitive = validUnit(value, FLength, SVGAttributeMode);
+        break;
+
+    case CSSPropertyClipPath: // <uri> | none | inherit
+    case CSSPropertyFilter:
+        if (id == CSSValueNone) {
+            validPrimitive = true;
+        } else if (value->unit == CSSPrimitiveValue::CSS_URI) {
+            parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+            if (parsedValue)
+                m_valueList->next();
+        }
+        break;
+    case CSSPropertyMaskType: // luminance | alpha | inherit
+        if (id == CSSValueLuminance || id == CSSValueAlpha)
+            validPrimitive = true;
+        break;
+
+    /* shorthand properties */
+    case CSSPropertyMarker: {
+        ShorthandScope scope(this, propId);
+        CSSPropertyParser::ImplicitScope implicitScope(this, PropertyImplicit);
+        if (!parseValue(CSSPropertyMarkerStart, important))
+            return false;
+        if (m_valueList->current()) {
+            rollbackLastProperties(1);
+            return false;
+        }
+        CSSValue* value = m_parsedProperties.last().value();
+        addProperty(CSSPropertyMarkerMid, value, important);
+        addProperty(CSSPropertyMarkerEnd, value, important);
+        return true;
+    }
+    default:
+        // If you crash here, it's because you added a css property and are not handling it
+        // in either this switch statement or the one in CSSPropertyParser::parseValue
+        ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", propId);
+        return false;
+    }
+
+    if (validPrimitive) {
+        if (id)
+            parsedValue = CSSPrimitiveValue::createIdentifier(id);
+        else if (value->unit == CSSPrimitiveValue::CSS_STRING)
+            parsedValue = CSSPrimitiveValue::create(value->string, (CSSPrimitiveValue::UnitTypes) value->unit);
+        else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+            parsedValue = CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit);
+        else if (value->unit >= CSSParserValue::Q_EMS)
+            parsedValue = CSSPrimitiveValue::createAllowingMarginQuirk(value->fValue, CSSPrimitiveValue::CSS_EMS);
+        if (isCalculation(value)) {
+            // FIXME calc() http://webkit.org/b/16662 : actually create a CSSPrimitiveValue here, ie
+            // parsedValue = CSSPrimitiveValue::create(m_parsedCalculation.release());
+            m_parsedCalculation.release();
+            parsedValue = nullptr;
+        }
+        m_valueList->next();
+    }
+    if (!parsedValue || (m_valueList->current() && !inShorthand()))
+        return false;
+
+    addProperty(propId, parsedValue.release(), important);
+    return true;
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSVGStrokeDasharray()
+{
+    RefPtrWillBeRawPtr<CSSValueList> ret = CSSValueList::createCommaSeparated();
+    CSSParserValue* value = m_valueList->current();
+    bool validPrimitive = true;
+    while (value) {
+        validPrimitive = validUnit(value, FLength | FPercent | FNonNeg, SVGAttributeMode);
+        if (!validPrimitive)
+            break;
+        if (value->id)
+            ret->append(CSSPrimitiveValue::createIdentifier(value->id));
+        else if (value->unit >= CSSPrimitiveValue::CSS_NUMBER && value->unit <= CSSPrimitiveValue::CSS_KHZ)
+            ret->append(CSSPrimitiveValue::create(value->fValue, (CSSPrimitiveValue::UnitTypes) value->unit));
+        value = m_valueList->next();
+        if (value && value->unit == CSSParserValue::Operator && value->iValue == ',')
+            value = m_valueList->next();
+    }
+    if (!validPrimitive)
+        return nullptr;
+    return ret.release();
+}
+
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parseSVGPaint()
+{
+    RGBA32 c = Color::transparent;
+    if (!parseColorFromValue(m_valueList->current(), c))
+        return SVGPaint::createUnknown();
+    return SVGPaint::createColor(Color(c));
+}
+
+// normal | [ fill || stroke || markers ]
+PassRefPtrWillBeRawPtr<CSSValue> CSSPropertyParser::parsePaintOrder() const
+{
+    if (m_valueList->size() > 3)
+        return nullptr;
+
+    CSSParserValue* value = m_valueList->current();
+    if (!value)
+        return nullptr;
+
+    RefPtrWillBeRawPtr<CSSValueList> parsedValues = CSSValueList::createSpaceSeparated();
+
+    // The default paint-order is: Fill, Stroke, Markers.
+    bool seenFill = false, seenStroke = false, seenMarkers = false;
+
+    do {
+        switch (value->id) {
+        case CSSValueNormal:
+            // normal inside [fill || stroke || markers] not valid
+            return nullptr;
+        case CSSValueFill:
+            if (seenFill)
+                return nullptr;
+
+            seenFill = true;
+            break;
+        case CSSValueStroke:
+            if (seenStroke)
+                return nullptr;
+
+            seenStroke = true;
+            break;
+        case CSSValueMarkers:
+            if (seenMarkers)
+                return nullptr;
+
+            seenMarkers = true;
+            break;
+        default:
+            return nullptr;
+        }
+
+        parsedValues->append(CSSPrimitiveValue::createIdentifier(value->id));
+    } while ((value = m_valueList->next()));
+
+    // fill out the rest of the paint order
+    if (!seenFill)
+        parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueFill));
+    if (!seenStroke)
+        parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueStroke));
+    if (!seenMarkers)
+        parsedValues->append(CSSPrimitiveValue::createIdentifier(CSSValueMarkers));
+
+    return parsedValues.release();
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/parser/CSSPropertyParser.h b/Source/core/css/parser/CSSPropertyParser.h
new file mode 100644
index 0000000..9d667ea
--- /dev/null
+++ b/Source/core/css/parser/CSSPropertyParser.h
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2003 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2004, 2005, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2009 - 2010  Torch Mobile (Beijing) Co. Ltd. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef CSSPropertyParser_h
+#define CSSPropertyParser_h
+
+// FIXME: Way too many.
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "core/css/CSSCalculationValue.h"
+#include "core/css/CSSFilterValue.h"
+#include "core/css/CSSGradientValue.h"
+#include "core/css/CSSParserMode.h"
+#include "core/css/CSSParserValues.h"
+#include "core/css/CSSProperty.h"
+#include "core/css/CSSPropertySourceData.h"
+#include "core/css/CSSSelector.h"
+#include "platform/graphics/Color.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+// FIXME: Many of these may not be used.
+class AnimationParseContext;
+class CSSArrayFunctionValue;
+class CSSBorderImageSliceValue;
+class CSSPrimitiveValue;
+class CSSSelectorList;
+class CSSValue;
+class CSSValueList;
+class CSSBasicShape;
+class CSSBasicShapeInset;
+class Document;
+class Element;
+class ImmutableStylePropertySet;
+class StyleKeyframe;
+class StylePropertyShorthand;
+class StyleKeyframe;
+class UseCounter;
+
+// Inputs: PropertyID, isImportant bool, CSSParserValueList.
+// Outputs: Vector of CSSProperties
+
+class CSSPropertyParser {
+    STACK_ALLOCATED();
+public:
+    CSSPropertyParser(OwnPtr<CSSParserValueList>&,
+        const CSSParserContext&, bool inViewport, bool savedImportant,
+        WillBeHeapVector<CSSProperty, 256>&, bool& hasFontFaceOnlyValues);
+    ~CSSPropertyParser();
+
+    // FIXME: Should this be on a separate ColorParser object?
+    template<typename StringType>
+    static bool fastParseColor(RGBA32&, const StringType&, bool strict);
+
+    bool parseValue(CSSPropertyID, bool important);
+
+    static bool isSystemColor(int id);
+
+private:
+    bool inShorthand() const { return m_inParseShorthand; }
+    bool inQuirksMode() const { return isQuirksModeBehavior(m_context.mode()); }
+
+    bool inViewport() const { return m_inViewport; }
+    bool parseViewportProperty(CSSPropertyID propId, bool important);
+    bool parseViewportShorthand(CSSPropertyID propId, CSSPropertyID first, CSSPropertyID second, bool important);
+
+    KURL completeURL(const String& url) const;
+
+    void addPropertyWithPrefixingVariant(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important, bool implicit = false);
+    void addProperty(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important, bool implicit = false);
+    void rollbackLastProperties(int num);
+    bool hasProperties() const { return !m_parsedProperties.isEmpty(); }
+    void addExpandedPropertyForValue(CSSPropertyID propId, PassRefPtrWillBeRawPtr<CSSValue>, bool);
+
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseValidPrimitive(CSSValueID ident, CSSParserValue*);
+
+    bool parseShorthand(CSSPropertyID, const StylePropertyShorthand&, bool important);
+    bool parse4Values(CSSPropertyID, const CSSPropertyID* properties, bool important);
+    bool parseContent(CSSPropertyID, bool important);
+    bool parseQuotes(CSSPropertyID, bool important);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseAttr(CSSParserValueList* args);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseBackgroundColor();
+
+    bool parseFillImage(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+    enum FillPositionFlag { InvalidFillPosition = 0, AmbiguousFillPosition = 1, XFillPosition = 2, YFillPosition = 4 };
+    enum FillPositionParsingMode { ResolveValuesAsPercent = 0, ResolveValuesAsKeyword = 1 };
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseFillPositionComponent(CSSParserValueList*, unsigned& cumulativeFlags, FillPositionFlag& individualFlag, FillPositionParsingMode = ResolveValuesAsPercent);
+    PassRefPtrWillBeRawPtr<CSSValue> parseFillPositionX(CSSParserValueList*);
+    PassRefPtrWillBeRawPtr<CSSValue> parseFillPositionY(CSSParserValueList*);
+    void parse2ValuesFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+    bool isPotentialPositionValue(CSSParserValue*);
+    void parseFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+    void parse3ValuesFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>);
+    void parse4ValuesFillPosition(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>, PassRefPtrWillBeRawPtr<CSSPrimitiveValue>);
+
+    void parseFillRepeat(RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+    PassRefPtrWillBeRawPtr<CSSValue> parseFillSize(CSSPropertyID, bool &allowComma);
+
+    bool parseFillProperty(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+    bool parseFillShorthand(CSSPropertyID, const CSSPropertyID* properties, int numProperties, bool important);
+
+    void addFillValue(RefPtrWillBeRawPtr<CSSValue>& lval, PassRefPtrWillBeRawPtr<CSSValue> rval);
+
+    void addAnimationValue(RefPtrWillBeRawPtr<CSSValue>& lval, PassRefPtrWillBeRawPtr<CSSValue> rval);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationDelay();
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationDirection();
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationDuration();
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationFillMode();
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationIterationCount();
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationName();
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationPlayState();
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationProperty(AnimationParseContext&);
+    PassRefPtrWillBeRawPtr<CSSValue> parseAnimationTimingFunction();
+
+    bool parseTransformOriginShorthand(RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+    bool parseCubicBezierTimingFunctionValue(CSSParserValueList*& args, double& result);
+    bool parseAnimationProperty(CSSPropertyID, RefPtrWillBeRawPtr<CSSValue>&, AnimationParseContext&);
+    bool parseTransitionShorthand(CSSPropertyID, bool important);
+    bool parseAnimationShorthand(CSSPropertyID, bool important);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseColumnWidth();
+    PassRefPtrWillBeRawPtr<CSSValue> parseColumnCount();
+    bool parseColumnsShorthand(bool important);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseGridPosition();
+    bool parseIntegerOrStringFromGridPosition(RefPtrWillBeRawPtr<CSSPrimitiveValue>& numericValue, RefPtrWillBeRawPtr<CSSPrimitiveValue>& gridLineName);
+    bool parseGridItemPositionShorthand(CSSPropertyID, bool important);
+    bool parseGridAreaShorthand(bool important);
+    bool parseSingleGridAreaLonghand(RefPtrWillBeRawPtr<CSSValue>&);
+    bool parseGridTrackList(CSSPropertyID, bool important);
+    bool parseGridTrackRepeatFunction(CSSValueList&);
+    PassRefPtrWillBeRawPtr<CSSValue> parseGridTrackSize(CSSParserValueList& inputList);
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGridBreadth(CSSParserValue*);
+    PassRefPtrWillBeRawPtr<CSSValue> parseGridTemplateAreas();
+    void parseGridLineNames(CSSParserValueList* inputList, CSSValueList&);
+
+    bool parseClipShape(CSSPropertyID, bool important);
+
+    bool parseItemPositionOverflowPosition(CSSPropertyID, bool important);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseShapeProperty(CSSPropertyID propId);
+    PassRefPtrWillBeRawPtr<CSSValue> parseBasicShapeAndOrBox();
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseBasicShape();
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseShapeRadius(CSSParserValue*);
+
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeRectangle(CSSParserValueList* args);
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeCircle(CSSParserValueList* args);
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseDeprecatedBasicShapeCircle(CSSParserValueList* args);
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeEllipse(CSSParserValueList* args);
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseDeprecatedBasicShapeEllipse(CSSParserValueList*);
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapePolygon(CSSParserValueList* args);
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeInsetRectangle(CSSParserValueList* args);
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseBasicShapeInset(CSSParserValueList* args);
+
+    bool parseFont(bool important);
+    PassRefPtrWillBeRawPtr<CSSValueList> parseFontFamily();
+
+    bool parseCounter(CSSPropertyID, int defaultValue, bool important);
+    PassRefPtrWillBeRawPtr<CSSValue> parseCounterContent(CSSParserValueList* args, bool counters);
+
+    bool parseColorParameters(CSSParserValue*, int* colorValues, bool parseAlpha);
+    bool parseHSLParameters(CSSParserValue*, double* colorValues, bool parseAlpha);
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseColor(CSSParserValue* = 0);
+    bool parseColorFromValue(CSSParserValue*, RGBA32&);
+
+    bool parseLineHeight(bool important);
+    bool parseFontSize(bool important);
+    bool parseFontVariant(bool important);
+    bool parseFontWeight(bool important);
+    bool parseFontFaceSrc();
+    bool parseFontFaceUnicodeRange();
+
+    bool parseSVGValue(CSSPropertyID propId, bool important);
+    PassRefPtrWillBeRawPtr<CSSValue> parseSVGPaint();
+    PassRefPtrWillBeRawPtr<CSSValue> parseSVGStrokeDasharray();
+
+    PassRefPtrWillBeRawPtr<CSSValue> parsePaintOrder() const;
+
+    // CSS3 Parsing Routines (for properties specific to CSS3)
+    PassRefPtrWillBeRawPtr<CSSValueList> parseShadow(CSSParserValueList*, CSSPropertyID);
+    bool parseBorderImageShorthand(CSSPropertyID, bool important);
+    PassRefPtrWillBeRawPtr<CSSValue> parseBorderImage(CSSPropertyID);
+    bool parseBorderImageRepeat(RefPtrWillBeRawPtr<CSSValue>&);
+    bool parseBorderImageSlice(CSSPropertyID, RefPtrWillBeRawPtr<CSSBorderImageSliceValue>&);
+    bool parseBorderImageWidth(RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
+    bool parseBorderImageOutset(RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
+    bool parseBorderRadius(CSSPropertyID, bool important);
+
+    bool parseAspectRatio(bool important);
+
+    bool parseReflect(CSSPropertyID, bool important);
+
+    bool parseFlex(CSSParserValueList* args, bool important);
+
+    bool parseObjectPosition(bool important);
+
+    // Image generators
+    bool parseCanvas(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+    bool parseDeprecatedGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+    bool parseDeprecatedLinearGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+    bool parseDeprecatedRadialGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+    bool parseLinearGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+    bool parseRadialGradient(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&, CSSGradientRepeat repeating);
+    bool parseGradientColorStops(CSSParserValueList*, CSSGradientValue*, bool expectComma);
+
+    bool parseCrossfade(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseImageSet(CSSParserValueList*);
+
+    bool parseWillChange(bool important);
+
+    PassRefPtrWillBeRawPtr<CSSValueList> parseFilter();
+    PassRefPtrWillBeRawPtr<CSSFilterValue> parseBuiltinFilterArguments(CSSParserValueList*, CSSFilterValue::FilterOperationType);
+
+    static bool isBlendMode(CSSValueID);
+    static bool isCompositeOperator(CSSValueID);
+
+    PassRefPtrWillBeRawPtr<CSSValueList> parseTransform();
+    PassRefPtrWillBeRawPtr<CSSValue> parseTransformValue(CSSParserValue*);
+    bool parseTransformOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2, CSSPropertyID& propId3, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+    bool parsePerspectiveOrigin(CSSPropertyID propId, CSSPropertyID& propId1, CSSPropertyID& propId2,  RefPtrWillBeRawPtr<CSSValue>&, RefPtrWillBeRawPtr<CSSValue>&);
+
+    bool parseTextEmphasisStyle(bool important);
+
+    bool parseTouchAction(bool important);
+
+    void addTextDecorationProperty(CSSPropertyID, PassRefPtrWillBeRawPtr<CSSValue>, bool important);
+    bool parseTextDecoration(CSSPropertyID propId, bool important);
+    bool parseTextUnderlinePosition(bool important);
+
+    PassRefPtrWillBeRawPtr<CSSValue> parseTextIndent();
+
+    bool parseLineBoxContain(bool important);
+    bool parseCalculation(CSSParserValue*, ValueRange);
+
+    bool parseFontFeatureTag(CSSValueList*);
+    bool parseFontFeatureSettings(bool important);
+
+    bool parseFontVariantLigatures(bool important);
+
+    bool parseGeneratedImage(CSSParserValueList*, RefPtrWillBeRawPtr<CSSValue>&);
+
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveNumericValue(CSSParserValue*);
+    PassRefPtrWillBeRawPtr<CSSPrimitiveValue> createPrimitiveStringValue(CSSParserValue*);
+
+    bool validWidthOrHeight(CSSParserValue*);
+
+    PassRefPtrWillBeRawPtr<CSSBasicShape> parseInsetRoundedCorners(PassRefPtrWillBeRawPtr<CSSBasicShapeInset>, CSSParserValueList*);
+
+    enum SizeParameterType {
+        None,
+        Auto,
+        Length,
+        PageSize,
+        Orientation,
+    };
+
+    bool parsePage(CSSPropertyID propId, bool important);
+    bool parseSize(CSSPropertyID propId, bool important);
+    SizeParameterType parseSizeParameter(CSSValueList* parsedValues, CSSParserValue*, SizeParameterType prevParamType);
+
+    bool parseFontFaceSrcURI(CSSValueList*);
+    bool parseFontFaceSrcLocal(CSSValueList*);
+
+    enum PropertyType {
+        PropertyExplicit,
+        PropertyImplicit
+    };
+
+    class ImplicitScope {
+        WTF_MAKE_NONCOPYABLE(ImplicitScope);
+    public:
+        ImplicitScope(CSSPropertyParser* parser, PropertyType propertyType)
+            : m_parser(parser)
+        {
+            m_parser->m_implicitShorthand = propertyType == CSSPropertyParser::PropertyImplicit;
+        }
+
+        ~ImplicitScope()
+        {
+            m_parser->m_implicitShorthand = false;
+        }
+
+    private:
+        CSSPropertyParser* m_parser;
+    };
+
+    // FIXME: MSVC doesn't like ShorthandScope being private
+    // since ~OwnPtr can't access its destructor if non-inlined.
+public:
+    class ShorthandScope {
+        WTF_MAKE_FAST_ALLOCATED;
+    public:
+        ShorthandScope(CSSPropertyParser* parser, CSSPropertyID propId) : m_parser(parser)
+        {
+            if (!(m_parser->m_inParseShorthand++))
+                m_parser->m_currentShorthand = propId;
+        }
+        ~ShorthandScope()
+        {
+            if (!(--m_parser->m_inParseShorthand))
+                m_parser->m_currentShorthand = CSSPropertyInvalid;
+        }
+
+    private:
+        CSSPropertyParser* m_parser;
+    };
+
+private:
+    enum ReleaseParsedCalcValueCondition {
+        ReleaseParsedCalcValue,
+        DoNotReleaseParsedCalcValue
+    };
+
+    enum Units {
+        FUnknown = 0x0000,
+        FInteger = 0x0001,
+        FNumber = 0x0002, // Real Numbers
+        FPercent = 0x0004,
+        FLength = 0x0008,
+        FAngle = 0x0010,
+        FTime = 0x0020,
+        FFrequency = 0x0040,
+        FPositiveInteger = 0x0080,
+        FRelative = 0x0100,
+        FResolution = 0x0200,
+        FNonNeg = 0x0400
+    };
+
+    friend inline Units operator|(Units a, Units b)
+    {
+        return static_cast<Units>(static_cast<unsigned>(a) | static_cast<unsigned>(b));
+    }
+
+    bool validCalculationUnit(CSSParserValue*, Units, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+
+    bool shouldAcceptUnitLessValues(CSSParserValue*, Units, CSSParserMode);
+
+    inline bool validUnit(CSSParserValue* value, Units unitflags, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue) { return validUnit(value, unitflags, m_context.mode(), releaseCalc); }
+    bool validUnit(CSSParserValue*, Units, CSSParserMode, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+
+    bool parseBorderImageQuad(Units, RefPtrWillBeRawPtr<CSSPrimitiveValue>&);
+    int colorIntFromValue(CSSParserValue*);
+    double parsedDouble(CSSParserValue*, ReleaseParsedCalcValueCondition releaseCalc = DoNotReleaseParsedCalcValue);
+    bool isCalculation(CSSParserValue*);
+
+private:
+    // Inputs:
+    // FIXME: This should not be an OwnPtr&, many callers will need to be changed.
+    const OwnPtr<CSSParserValueList>& m_valueList;
+    const CSSParserContext& m_context;
+    const bool m_inViewport;
+    const bool m_important; // FIXME: This is only used by font-face-src and unicode-range and undoubtably wrong!
+
+    // Outputs:
+    WillBeHeapVector<CSSProperty, 256>& m_parsedProperties;
+    bool m_hasFontFaceOnlyValues;
+
+    // Locals during parsing:
+    int m_inParseShorthand;
+    CSSPropertyID m_currentShorthand;
+    bool m_implicitShorthand;
+    RefPtrWillBeRawPtr<CSSCalcValue> m_parsedCalculation;
+
+    // FIXME: There is probably a small set of APIs we could expose for these
+    // classes w/o needing to make them friends.
+    friend class ShadowParseContext;
+    friend class BorderImageParseContext;
+    friend class BorderImageSliceParseContext;
+    friend class BorderImageQuadParseContext;
+    friend class TransformOperationInfo;
+    friend bool parseDeprecatedGradientColorStop(CSSPropertyParser*, CSSParserValue*, CSSGradientColorStop&);
+    friend PassRefPtrWillBeRawPtr<CSSPrimitiveValue> parseGradientColorOrKeyword(CSSPropertyParser*, CSSParserValue*);
+};
+
+CSSPropertyID cssPropertyID(const CSSParserString&);
+CSSPropertyID cssPropertyID(const String&);
+CSSValueID cssValueKeywordID(const CSSParserString&);
+
+bool isKeywordPropertyID(CSSPropertyID);
+bool isValidKeywordPropertyAndValue(CSSPropertyID, int valueID, const CSSParserContext&);
+
+} // namespace WebCore
+
+#endif // CSSPropertyParser_h
diff --git a/Source/core/css/parser/MediaQueryInputStream.cpp b/Source/core/css/parser/MediaQueryInputStream.cpp
new file mode 100644
index 0000000..660bcc0
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryInputStream.cpp
@@ -0,0 +1,66 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryInputStream.h"
+
+#include "core/html/parser/InputStreamPreprocessor.h"
+
+namespace WebCore {
+
+MediaQueryInputStream::MediaQueryInputStream(String input)
+    : m_offset(0)
+    , m_string(input)
+{
+}
+
+UChar MediaQueryInputStream::peek(unsigned lookaheadOffset)
+{
+    ASSERT((m_offset + lookaheadOffset) <= maxLength());
+    if ((m_offset + lookaheadOffset) >= m_string.length())
+        return kEndOfFileMarker;
+    return m_string[m_offset + lookaheadOffset];
+}
+
+void MediaQueryInputStream::advance(unsigned offset)
+{
+    ASSERT(m_offset + offset <= maxLength());
+    m_offset += offset;
+}
+
+void MediaQueryInputStream::pushBack(UChar cc)
+{
+    --m_offset;
+    ASSERT(currentInputChar() == cc);
+}
+
+unsigned long long MediaQueryInputStream::getUInt(unsigned start, unsigned end)
+{
+    ASSERT(start <= end && ((m_offset + end) <= m_string.length()));
+    bool isResultOK = false;
+    unsigned long long result = 0;
+    if (start < end) {
+        if (m_string.is8Bit())
+            result = charactersToUInt64Strict(m_string.characters8() + m_offset + start, end - start, &isResultOK);
+        else
+            result = charactersToUInt64Strict(m_string.characters16() + m_offset + start, end - start, &isResultOK);
+    }
+    return isResultOK ? result : 0;
+}
+
+double MediaQueryInputStream::getDouble(unsigned start, unsigned end)
+{
+    ASSERT(start <= end && ((m_offset + end) <= m_string.length()));
+    bool isResultOK = false;
+    double result = 0.0;
+    if (start < end) {
+        if (m_string.is8Bit())
+            result = charactersToDouble(m_string.characters8() + m_offset + start, end - start, &isResultOK);
+        else
+            result = charactersToDouble(m_string.characters16() + m_offset + start, end - start, &isResultOK);
+    }
+    return isResultOK ? result : 0.0;
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/parser/MediaQueryInputStream.h b/Source/core/css/parser/MediaQueryInputStream.h
new file mode 100644
index 0000000..b31615c
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryInputStream.h
@@ -0,0 +1,57 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryInputStream_h
+#define MediaQueryInputStream_h
+
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class MediaQueryInputStream {
+    WTF_MAKE_NONCOPYABLE(MediaQueryInputStream);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    MediaQueryInputStream(String input);
+
+    UChar peek(unsigned);
+    inline UChar currentInputChar()
+    {
+        return peek(0);
+    }
+
+    void advance(unsigned = 1);
+    void pushBack(UChar);
+
+    inline size_t maxLength()
+    {
+        return m_string.length() + 1;
+    }
+
+    inline size_t leftChars()
+    {
+        return m_string.length() - m_offset;
+
+    }
+
+    unsigned long long getUInt(unsigned start, unsigned end);
+    double getDouble(unsigned start, unsigned end);
+
+    template<bool characterPredicate(UChar)>
+    unsigned skipWhilePredicate(unsigned offset)
+    {
+        while ((m_offset + offset) < m_string.length() && characterPredicate(m_string[m_offset + offset]))
+            ++offset;
+        return offset;
+    }
+
+private:
+    size_t m_offset;
+    String m_string;
+};
+
+} // namespace WebCore
+
+#endif // MediaQueryInputStream_h
+
diff --git a/Source/core/css/parser/MediaQueryParser.cpp b/Source/core/css/parser/MediaQueryParser.cpp
new file mode 100644
index 0000000..8340dd1
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryParser.cpp
@@ -0,0 +1,243 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryParser.h"
+
+#include "MediaTypeNames.h"
+#include "core/css/parser/CSSPropertyParser.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+namespace WebCore {
+
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQueryParser::parse(const String& queryString)
+{
+    return MediaQueryParser(queryString).parseImpl();
+}
+
+const MediaQueryParser::State MediaQueryParser::ReadRestrictor = &MediaQueryParser::readRestrictor;
+const MediaQueryParser::State MediaQueryParser::ReadMediaType = &MediaQueryParser::readMediaType;
+const MediaQueryParser::State MediaQueryParser::ReadAnd = &MediaQueryParser::readAnd;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureStart = &MediaQueryParser::readFeatureStart;
+const MediaQueryParser::State MediaQueryParser::ReadFeature = &MediaQueryParser::readFeature;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureColon = &MediaQueryParser::readFeatureColon;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureValue = &MediaQueryParser::readFeatureValue;
+const MediaQueryParser::State MediaQueryParser::ReadFeatureEnd = &MediaQueryParser::readFeatureEnd;
+const MediaQueryParser::State MediaQueryParser::SkipUntilComma = &MediaQueryParser::skipUntilComma;
+const MediaQueryParser::State MediaQueryParser::SkipUntilParenthesis = &MediaQueryParser::skipUntilParenthesis;
+const MediaQueryParser::State MediaQueryParser::Done = &MediaQueryParser::done;
+
+// FIXME: Replace the MediaQueryTokenizer with a generic CSSTokenizer, once there is one,
+// or better yet, replace the MediaQueryParser with a generic thread-safe CSS parser.
+MediaQueryParser::MediaQueryParser(const String& queryString)
+    : m_state(&MediaQueryParser::readRestrictor)
+    , m_querySet(MediaQuerySet::create())
+{
+    MediaQueryTokenizer::tokenize(queryString, m_tokens);
+}
+
+void MediaQueryParser::setStateAndRestrict(State state, MediaQuery::Restrictor restrictor)
+{
+    m_mediaQueryData.setRestrictor(restrictor);
+    m_state = state;
+}
+
+// State machine member functions start here
+void MediaQueryParser::readRestrictor(MediaQueryTokenType type, TokenIterator& token)
+{
+    readMediaType(type, token);
+}
+
+void MediaQueryParser::readMediaType(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == LeftParenthesisToken) {
+        m_state = ReadFeature;
+    } else if (type == IdentToken) {
+        if (m_state == ReadRestrictor && equalIgnoringCase(token->value(), "not")) {
+            setStateAndRestrict(ReadMediaType, MediaQuery::Not);
+        } else if (m_state == ReadRestrictor && equalIgnoringCase(token->value(), "only")) {
+            setStateAndRestrict(ReadMediaType, MediaQuery::Only);
+        } else {
+            m_mediaQueryData.setMediaType(token->value());
+            m_state = ReadAnd;
+        }
+    } else if (type == EOFToken && (!m_querySet->queryVector().size() || m_state != ReadRestrictor)) {
+        m_state = Done;
+    } else {
+        if (type == CommaToken)
+            --token;
+        m_state = SkipUntilComma;
+    }
+}
+
+void MediaQueryParser::readAnd(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == IdentToken && equalIgnoringCase(token->value(), "and")) {
+        m_state = ReadFeatureStart;
+    } else if (type == CommaToken) {
+        m_querySet->addMediaQuery(m_mediaQueryData.takeMediaQuery());
+        m_state = ReadRestrictor;
+    } else if (type == EOFToken) {
+        m_state = Done;
+    } else {
+        m_state = SkipUntilComma;
+    }
+}
+
+void MediaQueryParser::readFeatureStart(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == LeftParenthesisToken)
+        m_state = ReadFeature;
+    else
+        m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::readFeature(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == IdentToken) {
+        m_mediaQueryData.setMediaFeature(token->value());
+        m_state = ReadFeatureColon;
+    } else {
+        m_state = SkipUntilComma;
+    }
+}
+
+void MediaQueryParser::readFeatureColon(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == ColonToken) {
+        m_state = ReadFeatureValue;
+    } else if (type == RightParenthesisToken || type == EOFToken) {
+        --token;
+        m_state = ReadFeatureEnd;
+    } else {
+        m_state = SkipUntilParenthesis;
+    }
+}
+
+void MediaQueryParser::readFeatureValue(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == DimensionToken && token->unitType() == CSSPrimitiveValue::CSS_UNKNOWN) {
+        m_state = SkipUntilComma;
+    } else {
+        m_mediaQueryData.addParserValue(type, *token);
+        m_state = ReadFeatureEnd;
+    }
+}
+
+void MediaQueryParser::readFeatureEnd(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == RightParenthesisToken || type == EOFToken) {
+        if (m_mediaQueryData.addExpression())
+            m_state = ReadAnd;
+        else
+            m_state = SkipUntilComma;
+    } else if (type == DelimiterToken && token->delimiter() == '/') {
+        m_mediaQueryData.addParserValue(type, *token);
+        m_state = ReadFeatureValue;
+    } else {
+        m_state = SkipUntilParenthesis;
+    }
+}
+
+void MediaQueryParser::skipUntilComma(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == CommaToken || type == EOFToken) {
+        m_state = ReadRestrictor;
+        m_mediaQueryData.clear();
+        m_querySet->addMediaQuery(MediaQuery::createNotAll());
+    }
+}
+
+void MediaQueryParser::skipUntilParenthesis(MediaQueryTokenType type, TokenIterator& token)
+{
+    if (type == RightParenthesisToken)
+        m_state = SkipUntilComma;
+}
+
+void MediaQueryParser::done(MediaQueryTokenType type, TokenIterator& token) { }
+
+void MediaQueryParser::processToken(TokenIterator& token)
+{
+    MediaQueryTokenType type = token->type();
+
+    // Call the function that handles current state
+    if (type != WhitespaceToken)
+        ((this)->*(m_state))(type, token);
+}
+
+// The state machine loop
+PassRefPtrWillBeRawPtr<MediaQuerySet> MediaQueryParser::parseImpl()
+{
+    for (Vector<MediaQueryToken>::iterator token = m_tokens.begin(); token != m_tokens.end(); ++token)
+        processToken(token);
+
+    if (m_state != ReadAnd && m_state != ReadRestrictor && m_state != Done)
+        m_querySet->addMediaQuery(MediaQuery::createNotAll());
+    else if (m_mediaQueryData.currentMediaQueryChanged())
+        m_querySet->addMediaQuery(m_mediaQueryData.takeMediaQuery());
+
+    return m_querySet;
+}
+
+MediaQueryData::MediaQueryData()
+    : m_restrictor(MediaQuery::None)
+    , m_mediaType(MediaTypeNames::all)
+    , m_expressions(adoptPtrWillBeNoop(new ExpressionHeapVector))
+    , m_mediaTypeSet(false)
+{
+}
+
+void MediaQueryData::clear()
+{
+    m_restrictor = MediaQuery::None;
+    m_mediaType = MediaTypeNames::all;
+    m_mediaTypeSet = false;
+    m_mediaFeature = String();
+    m_valueList.clear();
+    m_expressions = adoptPtrWillBeNoop(new ExpressionHeapVector);
+}
+
+PassOwnPtrWillBeRawPtr<MediaQuery> MediaQueryData::takeMediaQuery()
+{
+    OwnPtrWillBeRawPtr<MediaQuery> mediaQuery = adoptPtrWillBeNoop(new MediaQuery(m_restrictor, m_mediaType, m_expressions.release()));
+    clear();
+    return mediaQuery.release();
+}
+
+bool MediaQueryData::addExpression()
+{
+    OwnPtrWillBeRawPtr<MediaQueryExp> expression = MediaQueryExp::create(m_mediaFeature, &m_valueList);
+    bool isValid = !!expression;
+    m_expressions->append(expression.release());
+    m_valueList.clear();
+    return isValid;
+}
+
+void MediaQueryData::addParserValue(MediaQueryTokenType type, MediaQueryToken& token)
+{
+    CSSParserValue value;
+    if (type == NumberToken || type == PercentageToken || type == DimensionToken) {
+        value.setFromNumber(token.numericValue(), token.unitType());
+        value.isInt = (token.numericValueType() == IntegerValueType);
+    } else if (type == DelimiterToken) {
+        value.unit = CSSParserValue::Operator;
+        value.iValue = token.delimiter();
+    } else {
+        CSSParserFunction* function = new CSSParserFunction;
+        function->name.init(token.value());
+        value.setFromFunction(function);
+        CSSParserString tokenValue;
+        tokenValue.init(token.value());
+        value.id = cssValueKeywordID(tokenValue);
+    }
+    m_valueList.addValue(value);
+}
+
+void MediaQueryData::setMediaType(const String& mediaType)
+{
+    m_mediaType = mediaType;
+    m_mediaTypeSet = true;
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/parser/MediaQueryParser.h b/Source/core/css/parser/MediaQueryParser.h
new file mode 100644
index 0000000..e31fc33
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryParser.h
@@ -0,0 +1,100 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryParser_h
+#define MediaQueryParser_h
+
+#include "core/css/CSSParserValues.h"
+#include "core/css/MediaList.h"
+#include "core/css/MediaQuery.h"
+#include "core/css/MediaQueryExp.h"
+#include "core/css/parser/MediaQueryToken.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class MediaQuerySet;
+
+class MediaQueryData {
+    ALLOW_ONLY_INLINE_ALLOCATION();
+private:
+    MediaQuery::Restrictor m_restrictor;
+    String m_mediaType;
+    OwnPtrWillBeMember<ExpressionHeapVector> m_expressions;
+    String m_mediaFeature;
+    CSSParserValueList m_valueList;
+    bool m_mediaTypeSet;
+
+public:
+    MediaQueryData();
+    void clear();
+    bool addExpression();
+    void addParserValue(MediaQueryTokenType, MediaQueryToken&);
+    void setMediaType(const String&);
+    PassOwnPtrWillBeRawPtr<MediaQuery> takeMediaQuery();
+
+    inline bool currentMediaQueryChanged() const
+    {
+        return (m_restrictor != MediaQuery::None || m_mediaTypeSet || m_expressions->size() > 0);
+    }
+
+    inline void setRestrictor(MediaQuery::Restrictor restrictor) { m_restrictor = restrictor; }
+
+    inline void setMediaFeature(const String& str) { m_mediaFeature = str; }
+};
+
+class MediaQueryParser {
+    STACK_ALLOCATED();
+public:
+    static PassRefPtrWillBeRawPtr<MediaQuerySet> parse(const String&);
+
+private:
+    MediaQueryParser(const String&);
+    virtual ~MediaQueryParser() { };
+
+    PassRefPtrWillBeRawPtr<MediaQuerySet> parseImpl();
+
+    typedef Vector<MediaQueryToken>::iterator TokenIterator;
+
+    void processToken(TokenIterator&);
+
+    void readRestrictor(MediaQueryTokenType, TokenIterator&);
+    void readMediaType(MediaQueryTokenType, TokenIterator&);
+    void readAnd(MediaQueryTokenType, TokenIterator&);
+    void readFeatureStart(MediaQueryTokenType, TokenIterator&);
+    void readFeature(MediaQueryTokenType, TokenIterator&);
+    void readFeatureColon(MediaQueryTokenType, TokenIterator&);
+    void readFeatureValue(MediaQueryTokenType, TokenIterator&);
+    void readFeatureEnd(MediaQueryTokenType, TokenIterator&);
+    void skipUntilComma(MediaQueryTokenType, TokenIterator&);
+    void skipUntilParenthesis(MediaQueryTokenType, TokenIterator&);
+    void done(MediaQueryTokenType, TokenIterator&);
+
+    typedef void (MediaQueryParser::*State)(MediaQueryTokenType, TokenIterator&);
+
+    void setStateAndRestrict(State, MediaQuery::Restrictor);
+
+    State m_state;
+    Vector<MediaQueryToken> m_tokens;
+    MediaQueryData m_mediaQueryData;
+    RefPtrWillBeMember<MediaQuerySet> m_querySet;
+
+    const static State ReadRestrictor;
+    const static State ReadMediaType;
+    const static State ReadAnd;
+    const static State ReadFeatureStart;
+    const static State ReadFeature;
+    const static State ReadFeatureColon;
+    const static State ReadFeatureValue;
+    const static State ReadFeatureEnd;
+    const static State SkipUntilComma;
+    const static State SkipUntilParenthesis;
+    const static State Done;
+
+};
+
+} // namespace WebCore
+
+#endif // MediaQueryParser_h
diff --git a/Source/core/css/parser/MediaQueryToken.cpp b/Source/core/css/parser/MediaQueryToken.cpp
new file mode 100644
index 0000000..4930829
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryToken.cpp
@@ -0,0 +1,62 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryToken.h"
+
+#include "wtf/HashMap.h"
+#include "wtf/text/StringHash.h"
+
+namespace WebCore {
+
+
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type)
+    : m_type(type)
+    , m_delimiter(0)
+    , m_unit(CSSPrimitiveValue::CSS_UNKNOWN)
+{
+}
+
+// Just a helper used for Delimiter tokens.
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type, UChar c)
+    : m_type(type)
+    , m_delimiter(c)
+    , m_unit(CSSPrimitiveValue::CSS_UNKNOWN)
+{
+    ASSERT(m_type == DelimiterToken);
+}
+
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type, String value)
+    : m_type(type)
+    , m_value(value)
+    , m_delimiter(0)
+    , m_unit(CSSPrimitiveValue::CSS_UNKNOWN)
+{
+}
+
+MediaQueryToken::MediaQueryToken(MediaQueryTokenType type, double numericValue, NumericValueType numericValueType)
+    : m_type(type)
+    , m_delimiter(0)
+    , m_numericValueType(numericValueType)
+    , m_numericValue(numericValue)
+    , m_unit(CSSPrimitiveValue::CSS_NUMBER)
+{
+    ASSERT(type == NumberToken);
+}
+
+void MediaQueryToken::convertToDimensionWithUnit(String unit)
+{
+    ASSERT(m_type == NumberToken);
+    m_type = DimensionToken;
+    m_unit = CSSPrimitiveValue::getUnitTable().get(unit.lower());
+}
+
+void MediaQueryToken::convertToPercentage()
+{
+    ASSERT(m_type == NumberToken);
+    m_type = PercentageToken;
+    m_unit = CSSPrimitiveValue::CSS_PERCENTAGE;
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/parser/MediaQueryToken.h b/Source/core/css/parser/MediaQueryToken.h
new file mode 100644
index 0000000..06cbef6
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryToken.h
@@ -0,0 +1,69 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryToken_h
+#define MediaQueryToken_h
+
+#include "core/css/CSSPrimitiveValue.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+enum MediaQueryTokenType {
+    IdentToken = 0,
+    FunctionToken = 1,
+    DelimiterToken = 2,
+    NumberToken = 3,
+    PercentageToken = 4,
+    DimensionToken = 5,
+    WhitespaceToken = 6,
+    ColonToken = 7,
+    SemicolonToken = 8,
+    CommaToken = 9,
+    LeftParenthesisToken = 10,
+    RightParenthesisToken = 11,
+    EOFToken = 12,
+};
+
+enum NumericValueType {
+    IntegerValueType,
+    NumberValueType,
+};
+
+class MediaQueryToken {
+public:
+    MediaQueryToken(MediaQueryTokenType);
+    MediaQueryToken(MediaQueryTokenType, String);
+
+    MediaQueryToken(MediaQueryTokenType, UChar); // for DelimiterToken
+    MediaQueryToken(MediaQueryTokenType, double, NumericValueType); // for NumberToken
+
+    // Converts NumberToken to DimensionToken.
+    void convertToDimensionWithUnit(String);
+
+    // Converts NumberToken to PercentageToken.
+    void convertToPercentage();
+
+    MediaQueryTokenType type() const { return m_type; }
+    String value() const { return m_value; }
+
+    UChar delimiter() const { return m_delimiter; }
+    NumericValueType numericValueType() const { return m_numericValueType; }
+    double numericValue() const { return m_numericValue; }
+    CSSPrimitiveValue::UnitTypes unitType() const { return m_unit; }
+
+private:
+    MediaQueryTokenType m_type;
+    String m_value;
+
+    UChar m_delimiter; // Could be rolled into m_value?
+
+    NumericValueType m_numericValueType;
+    double m_numericValue;
+    CSSPrimitiveValue::UnitTypes m_unit;
+};
+
+}
+
+#endif // MediaQueryToken_h
diff --git a/Source/core/css/parser/MediaQueryTokenizer.cpp b/Source/core/css/parser/MediaQueryTokenizer.cpp
new file mode 100644
index 0000000..4486a4d
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryTokenizer.cpp
@@ -0,0 +1,431 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+#include "core/css/parser/MediaQueryInputStream.h"
+#include "core/html/parser/HTMLParserIdioms.h"
+#include "wtf/unicode/CharacterNames.h"
+
+namespace WebCore {
+
+const unsigned codePointsNumber = SCHAR_MAX;
+
+class MediaQueryTokenizer::CodePoints {
+public:
+    MediaQueryTokenizer::CodePoint codePoints[codePointsNumber];
+
+    // FIXME: Move the codePoint array to be a static one, generated by build scripts
+    CodePoints()
+    {
+        memset(codePoints, 0, codePointsNumber);
+        codePoints['\n'] = &MediaQueryTokenizer::whiteSpace;
+        codePoints['\r'] = &MediaQueryTokenizer::whiteSpace;
+        codePoints['\t'] = &MediaQueryTokenizer::whiteSpace;
+        codePoints[' '] = &MediaQueryTokenizer::whiteSpace;
+        codePoints['\f'] = &MediaQueryTokenizer::whiteSpace;
+        codePoints['('] = &MediaQueryTokenizer::leftParenthesis;
+        codePoints[')'] = &MediaQueryTokenizer::rightParenthesis;
+        codePoints['+'] = &MediaQueryTokenizer::plusOrFullStop;
+        codePoints['.'] = &MediaQueryTokenizer::plusOrFullStop;
+        codePoints[','] = &MediaQueryTokenizer::comma;
+        codePoints['-'] = &MediaQueryTokenizer::hyphenMinus;
+        codePoints['/'] = &MediaQueryTokenizer::solidus;
+        codePoints[':'] = &MediaQueryTokenizer::colon;
+        codePoints[';'] = &MediaQueryTokenizer::semiColon;
+        codePoints['\\'] = &MediaQueryTokenizer::reverseSolidus;
+        for (unsigned char digit = '0'; digit <= '9'; ++digit)
+            codePoints[digit] = &MediaQueryTokenizer::asciiDigit;
+        for (unsigned char alpha = 'a'; alpha <= 'z'; ++alpha)
+            codePoints[alpha] = &MediaQueryTokenizer::nameStart;
+        for (unsigned char alpha = 'A'; alpha <= 'Z'; ++alpha)
+            codePoints[alpha] = &MediaQueryTokenizer::nameStart;
+        codePoints['_'] = &MediaQueryTokenizer::nameStart;
+        codePoints[kEndOfFileMarker] = &MediaQueryTokenizer::endOfFile;
+    }
+};
+
+MediaQueryTokenizer::CodePoints* MediaQueryTokenizer::codePoints()
+{
+    static CodePoints codePoints;
+    return &codePoints;
+}
+
+// http://dev.w3.org/csswg/css-syntax/#name-start-code-point
+static bool isNameStart(UChar c)
+{
+    if (isASCIIAlpha(c))
+        return true;
+    if (c == '_')
+        return true;
+    return !isASCII(c);
+}
+
+// http://www.w3.org/TR/css-syntax-3/#name-code-point
+static bool isNameChar(UChar c)
+{
+    return isNameStart(c) || isASCIIDigit(c) || c == '-';
+}
+
+// http://www.w3.org/TR/css-syntax-3/#check-if-two-code-points-are-a-valid-escape
+static bool twoCharsAreValidEscape(UChar first, UChar second)
+{
+    return ((first == '\\') && (second != '\n') && (second != kEndOfFileMarker));
+}
+
+MediaQueryTokenizer::MediaQueryTokenizer(MediaQueryInputStream& inputStream)
+    : m_input(inputStream)
+{
+}
+
+void MediaQueryTokenizer::reconsume(UChar c)
+{
+    m_input.pushBack(c);
+}
+
+UChar MediaQueryTokenizer::consume()
+{
+    UChar current = m_input.currentInputChar();
+    m_input.advance();
+    return current;
+}
+
+void MediaQueryTokenizer::consume(unsigned offset)
+{
+    m_input.advance(offset);
+}
+
+MediaQueryToken MediaQueryTokenizer::whiteSpace(UChar cc)
+{
+    // CSS Tokenization is currently lossy, but we could record
+    // the exact whitespace instead of discarding it here.
+    consumeUntilNonWhitespace();
+    return MediaQueryToken(WhitespaceToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::leftParenthesis(UChar cc)
+{
+    return MediaQueryToken(LeftParenthesisToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::rightParenthesis(UChar cc)
+{
+    return MediaQueryToken(RightParenthesisToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::plusOrFullStop(UChar cc)
+{
+    if (nextCharsAreNumber()) {
+        reconsume(cc);
+        return consumeNumericToken();
+    }
+    return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::comma(UChar cc)
+{
+    return MediaQueryToken(CommaToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::hyphenMinus(UChar cc)
+{
+    if (nextCharsAreNumber()) {
+        reconsume(cc);
+        return consumeNumericToken();
+    }
+    if (nextCharsAreIdentifier()) {
+        reconsume(cc);
+        return consumeIdentLikeToken();
+    }
+    return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::solidus(UChar cc)
+{
+    return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::colon(UChar cc)
+{
+    return MediaQueryToken(ColonToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::semiColon(UChar cc)
+{
+    return MediaQueryToken(SemicolonToken);
+}
+
+MediaQueryToken MediaQueryTokenizer::reverseSolidus(UChar cc)
+{
+    if (twoCharsAreValidEscape(cc, m_input.currentInputChar())) {
+        reconsume(cc);
+        return consumeIdentLikeToken();
+    }
+    return MediaQueryToken(DelimiterToken, cc);
+}
+
+MediaQueryToken MediaQueryTokenizer::asciiDigit(UChar cc)
+{
+    reconsume(cc);
+    return consumeNumericToken();
+}
+
+MediaQueryToken MediaQueryTokenizer::nameStart(UChar cc)
+{
+    reconsume(cc);
+    return consumeIdentLikeToken();
+}
+
+MediaQueryToken MediaQueryTokenizer::endOfFile(UChar cc)
+{
+    return MediaQueryToken(EOFToken);
+}
+
+void MediaQueryTokenizer::tokenize(String string, Vector<MediaQueryToken>& outTokens)
+{
+    // According to the spec, we should perform preprocessing here.
+    // See: http://www.w3.org/TR/css-syntax-3/#input-preprocessing
+    //
+    // However, we can skip this step since:
+    // * We're using HTML spaces (which accept \r and \f as a valid white space)
+    // * Do not count white spaces
+    // * consumeEscape replaces NULLs for replacement characters
+
+    MediaQueryInputStream input(string);
+    MediaQueryTokenizer tokenizer(input);
+    while (true) {
+        outTokens.append(tokenizer.nextToken());
+        if (outTokens.last().type() == EOFToken)
+            return;
+    }
+}
+
+MediaQueryToken MediaQueryTokenizer::nextToken()
+{
+    // Unlike the HTMLTokenizer, the CSS Syntax spec is written
+    // as a stateless, (fixed-size) look-ahead tokenizer.
+    // We could move to the stateful model and instead create
+    // states for all the "next 3 codepoints are X" cases.
+    // State-machine tokenizers are easier to write to handle
+    // incremental tokenization of partial sources.
+    // However, for now we follow the spec exactly.
+    UChar cc = consume();
+    CodePoint codePointFunc = 0;
+
+    if (isASCII(cc)) {
+        ASSERT_WITH_SECURITY_IMPLICATION(cc < codePointsNumber);
+        codePointFunc = codePoints()->codePoints[cc];
+    } else {
+        codePointFunc = &MediaQueryTokenizer::nameStart;
+    }
+
+    if (codePointFunc)
+        return ((this)->*(codePointFunc))(cc);
+
+    return MediaQueryToken(DelimiterToken, cc);
+}
+
+static int getSign(MediaQueryInputStream& input, unsigned& offset)
+{
+    int sign = 1;
+    if (input.currentInputChar() == '+') {
+        ++offset;
+    } else if (input.peek(offset) == '-') {
+        sign = -1;
+        ++offset;
+    }
+    return sign;
+}
+
+static unsigned long long getInteger(MediaQueryInputStream& input, unsigned& offset)
+{
+    unsigned intStartPos = offset;
+    offset = input.skipWhilePredicate<isASCIIDigit>(offset);
+    unsigned intEndPos = offset;
+    return input.getUInt(intStartPos, intEndPos);
+}
+
+static double getFraction(MediaQueryInputStream& input, unsigned& offset, unsigned& digitsNumber)
+{
+    unsigned fractionStartPos = 0;
+    unsigned fractionEndPos = 0;
+    if (input.peek(offset) == '.' && isASCIIDigit(input.peek(++offset))) {
+        fractionStartPos = offset - 1;
+        offset = input.skipWhilePredicate<isASCIIDigit>(offset);
+        fractionEndPos = offset;
+    }
+    digitsNumber = fractionEndPos- fractionStartPos;
+    return input.getDouble(fractionStartPos, fractionEndPos);
+}
+
+static unsigned long long getExponent(MediaQueryInputStream& input, unsigned& offset, int sign)
+{
+    unsigned exponentStartPos = 0;
+    unsigned exponentEndPos = 0;
+    if ((input.peek(offset) == 'E' || input.peek(offset) == 'e')) {
+        int offsetBeforeExponent = offset;
+        ++offset;
+        if (input.peek(offset) == '+') {
+            ++offset;
+        } else if (input.peek(offset) =='-') {
+            sign = -1;
+            ++offset;
+        }
+        exponentStartPos = offset;
+        offset = input.skipWhilePredicate<isASCIIDigit>(offset);
+        exponentEndPos = offset;
+        if (exponentEndPos == exponentStartPos)
+            offset = offsetBeforeExponent;
+    }
+    return input.getUInt(exponentStartPos, exponentEndPos);
+}
+
+// This method merges the following spec sections for efficiency
+// http://www.w3.org/TR/css3-syntax/#consume-a-number
+// http://www.w3.org/TR/css3-syntax/#convert-a-string-to-a-number
+MediaQueryToken MediaQueryTokenizer::consumeNumber()
+{
+    ASSERT(nextCharsAreNumber());
+    NumericValueType type = IntegerValueType;
+    double value = 0;
+    unsigned offset = 0;
+    int exponentSign = 1;
+    unsigned fractionDigits;
+    int sign = getSign(m_input, offset);
+    unsigned long long integerPart = getInteger(m_input, offset);
+    double fractionPart = getFraction(m_input, offset, fractionDigits);
+    unsigned long long exponentPart = getExponent(m_input, offset, exponentSign);
+    double exponent = pow(10, (float)exponentSign * (double)exponentPart);
+    value = (double)sign * ((double)integerPart + fractionPart) * exponent;
+
+    m_input.advance(offset);
+    if (fractionDigits > 0)
+        type = NumberValueType;
+
+    return MediaQueryToken(NumberToken, value, type);
+}
+
+// http://www.w3.org/TR/css3-syntax/#consume-a-numeric-token
+MediaQueryToken MediaQueryTokenizer::consumeNumericToken()
+{
+    MediaQueryToken token = consumeNumber();
+    if (nextCharsAreIdentifier())
+        token.convertToDimensionWithUnit(consumeName());
+    else if (consumeIfNext('%'))
+        token.convertToPercentage();
+    return token;
+}
+
+// http://www.w3.org/TR/css3-syntax/#consume-an-ident-like-token
+MediaQueryToken MediaQueryTokenizer::consumeIdentLikeToken()
+{
+    String name = consumeName();
+    if (consumeIfNext('('))
+        return MediaQueryToken(FunctionToken, name);
+    return MediaQueryToken(IdentToken, name);
+}
+
+void MediaQueryTokenizer::consumeUntilNonWhitespace()
+{
+    // Using HTML space here rather than CSS space since we don't do preprocessing
+    while (isHTMLSpace<UChar>(m_input.currentInputChar()))
+        consume();
+}
+
+bool MediaQueryTokenizer::consumeIfNext(UChar character)
+{
+    if (m_input.currentInputChar() == character) {
+        consume();
+        return true;
+    }
+    return false;
+}
+
+// http://www.w3.org/TR/css3-syntax/#consume-a-name
+String MediaQueryTokenizer::consumeName()
+{
+    // FIXME: Is this as efficient as it can be?
+    // The possibility of escape chars mandates a copy AFAICT.
+    Vector<UChar> result;
+    while (true) {
+        if (isNameChar(m_input.currentInputChar())) {
+            result.append(consume());
+            continue;
+        }
+        if (nextTwoCharsAreValidEscape()) {
+            // "consume()" fixes a spec bug.
+            // The first code point should be consumed before consuming the escaped code point.
+            consume();
+            result.append(consumeEscape());
+            continue;
+        }
+        return String(result);
+    }
+}
+
+// http://www.w3.org/TR/css-syntax-3/#consume-an-escaped-code-point
+UChar MediaQueryTokenizer::consumeEscape()
+{
+    UChar cc = consume();
+    ASSERT(cc != '\n');
+    if (isASCIIHexDigit(cc)) {
+        unsigned consumedHexDigits = 1;
+        String hexChars;
+        do {
+            hexChars.append(cc);
+            cc = consume();
+            consumedHexDigits++;
+        } while (consumedHexDigits < 6 && isASCIIHexDigit(cc));
+        bool ok = false;
+        UChar codePoint = hexChars.toUIntStrict(&ok, 16);
+        if (!ok)
+            return WTF::Unicode::replacementCharacter;
+        return codePoint;
+    }
+
+    // Replaces NULLs with replacement characters, since we do not perform preprocessing
+    if (cc == kEndOfFileMarker)
+        return WTF::Unicode::replacementCharacter;
+    return cc;
+}
+
+bool MediaQueryTokenizer::nextTwoCharsAreValidEscape()
+{
+    if (m_input.leftChars() < 2)
+        return false;
+    return twoCharsAreValidEscape(m_input.peek(1), m_input.peek(2));
+}
+
+// http://www.w3.org/TR/css3-syntax/#starts-with-a-number
+bool MediaQueryTokenizer::nextCharsAreNumber()
+{
+    UChar first = m_input.currentInputChar();
+    UChar second = m_input.peek(1);
+    if (isASCIIDigit(first))
+        return true;
+    if (first == '+' || first == '-')
+        return ((isASCIIDigit(second)) || (second == '.' && isASCIIDigit(m_input.peek(2))));
+    if (first =='.')
+        return (isASCIIDigit(second));
+    return false;
+}
+
+// http://www.w3.org/TR/css3-syntax/#would-start-an-identifier
+bool MediaQueryTokenizer::nextCharsAreIdentifier()
+{
+    UChar firstChar = m_input.currentInputChar();
+    if (isNameStart(firstChar) || nextTwoCharsAreValidEscape())
+        return true;
+
+    if (firstChar == '-') {
+        if (isNameStart(m_input.peek(1)))
+            return true;
+        return nextTwoCharsAreValidEscape();
+    }
+
+    return false;
+}
+
+} // namespace WebCore
diff --git a/Source/core/css/parser/MediaQueryTokenizer.h b/Source/core/css/parser/MediaQueryTokenizer.h
new file mode 100644
index 0000000..73df890
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryTokenizer.h
@@ -0,0 +1,74 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaQueryTokenizer_h
+#define MediaQueryTokenizer_h
+
+#include "core/css/parser/MediaQueryToken.h"
+#include "core/html/parser/InputStreamPreprocessor.h"
+#include "wtf/text/WTFString.h"
+
+#include <climits>
+
+namespace WebCore {
+
+class MediaQueryInputStream;
+
+class MediaQueryTokenizer {
+    WTF_MAKE_NONCOPYABLE(MediaQueryTokenizer);
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    static void tokenize(String, Vector<MediaQueryToken>&);
+
+private:
+    class CodePoints;
+
+    MediaQueryTokenizer(MediaQueryInputStream&);
+
+    MediaQueryToken nextToken();
+
+    UChar consume();
+    void consume(unsigned);
+    void reconsume(UChar);
+
+    MediaQueryToken consumeNumericToken();
+    MediaQueryToken consumeIdentLikeToken();
+    MediaQueryToken consumeNumber();
+
+    void consumeUntilNonWhitespace();
+
+    bool consumeIfNext(UChar);
+    String consumeName();
+    UChar consumeEscape();
+
+    bool nextTwoCharsAreValidEscape();
+    bool nextCharsAreNumber();
+    bool nextCharsAreIdentifier();
+
+    typedef MediaQueryToken (MediaQueryTokenizer::*CodePoint)(UChar);
+
+    MediaQueryToken whiteSpace(UChar);
+    MediaQueryToken leftParenthesis(UChar);
+    MediaQueryToken rightParenthesis(UChar);
+    MediaQueryToken plusOrFullStop(UChar);
+    MediaQueryToken comma(UChar);
+    MediaQueryToken hyphenMinus(UChar);
+    MediaQueryToken solidus(UChar);
+    MediaQueryToken colon(UChar);
+    MediaQueryToken semiColon(UChar);
+    MediaQueryToken reverseSolidus(UChar);
+    MediaQueryToken asciiDigit(UChar);
+    MediaQueryToken nameStart(UChar);
+    MediaQueryToken endOfFile(UChar);
+
+    CodePoints* codePoints();
+
+    MediaQueryInputStream& m_input;
+};
+
+
+
+} // namespace WebCore
+
+#endif // MediaQueryTokenizer_h
diff --git a/Source/core/css/parser/MediaQueryTokenizerTest.cpp b/Source/core/css/parser/MediaQueryTokenizerTest.cpp
new file mode 100644
index 0000000..1138de9
--- /dev/null
+++ b/Source/core/css/parser/MediaQueryTokenizerTest.cpp
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/css/parser/MediaQueryTokenizer.h"
+
+#include "wtf/PassOwnPtr.h"
+#include <gtest/gtest.h>
+
+namespace WebCore {
+
+typedef pair<String, MediaQueryTokenType* > TestCase;
+TEST(MediaQueryTokenizerTest, Basic)
+{
+    Vector<TestCase> testcases;
+    MediaQueryTokenType tokenTypeArr[] = {LeftParenthesisToken, IdentToken, ColonToken, WhitespaceToken, PercentageToken, RightParenthesisToken, EOFToken };
+    TestCase testCase1("(max-width: 50%)", (MediaQueryTokenType*)&tokenTypeArr);
+    testcases.append(testCase1);
+    Vector<MediaQueryToken> tokens;
+    MediaQueryTokenizer::tokenize(testcases[0].first, tokens);
+    for (size_t i = 0; i < tokens.size(); i++) {
+        ASSERT_EQ(testcases[0].second[i], tokens[i].type());
+    }
+}
+
+} // namespace
diff --git a/Source/core/css/resolver/AnimatedStyleBuilder.cpp b/Source/core/css/resolver/AnimatedStyleBuilder.cpp
index c193849..50f2f24 100644
--- a/Source/core/css/resolver/AnimatedStyleBuilder.cpp
+++ b/Source/core/css/resolver/AnimatedStyleBuilder.cpp
@@ -67,7 +67,7 @@
 {
     if (value->isLength())
         return toAnimatableLength(value)->toLength(state.cssToLengthConversionData(), range);
-    RefPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
+    RefPtrWillBeRawPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
     CSSPrimitiveValue* cssPrimitiveValue = toCSSPrimitiveValue(cssValue.get());
     return cssPrimitiveValue->convertToLength<AnyConversion>(state.cssToLengthConversionData());
 }
@@ -78,7 +78,7 @@
         return BorderImageLength(toAnimatableLength(value)->toLength(state.cssToLengthConversionData(), NonNegativeValues));
     if (value->isDouble())
         return BorderImageLength(clampTo<double>(toAnimatableDouble(value)->toDouble(), 0));
-    RefPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
+    RefPtrWillBeRawPtr<CSSValue> cssValue = toAnimatableUnknown(value)->toCSSValue();
     CSSPrimitiveValue* cssPrimitiveValue = toCSSPrimitiveValue(cssValue.get());
     return BorderImageLength(cssPrimitiveValue->convertToLength<AnyConversion>(state.cssToLengthConversionData()));
 }
@@ -177,7 +177,7 @@
                 fillLayer->setImage(toAnimatableImage(layerValue)->toStyleImage());
             } else {
                 ASSERT(toAnimatableUnknown(layerValue)->toCSSValueID() == CSSValueNone);
-                fillLayer->setImage(0);
+                fillLayer->setImage(nullptr);
             }
             break;
         case CSSPropertyBackgroundPositionX:
@@ -225,6 +225,27 @@
     }
 }
 
+FontWeight animatableValueToFontWeight(const AnimatableValue* value)
+{
+    int index = round(toAnimatableDouble(value)->toDouble() / 100) - 1;
+
+    static const FontWeight weights[] = {
+        FontWeight100,
+        FontWeight200,
+        FontWeight300,
+        FontWeight400,
+        FontWeight500,
+        FontWeight600,
+        FontWeight700,
+        FontWeight800,
+        FontWeight900
+    };
+
+    index = clampTo<int>(index, 0, WTF_ARRAY_LENGTH(weights) - 1);
+
+    return weights[index];
+}
+
 } // namespace
 
 // FIXME: Generate this function.
@@ -351,6 +372,9 @@
     case CSSPropertyFontSize:
         style->setFontSize(clampTo<float>(toAnimatableDouble(value)->toDouble(), 0));
         return;
+    case CSSPropertyFontWeight:
+        style->setFontWeight(animatableValueToFontWeight(value));
+        return;
     case CSSPropertyHeight:
         style->setHeight(animatableValueToLength(value, state, NonNegativeValues));
         return;
diff --git a/Source/core/css/resolver/CSSToStyleMap.cpp b/Source/core/css/resolver/CSSToStyleMap.cpp
index 406b16c..698c925 100644
--- a/Source/core/css/resolver/CSSToStyleMap.cpp
+++ b/Source/core/css/resolver/CSSToStyleMap.cpp
@@ -180,11 +180,15 @@
 
 void CSSToStyleMap::mapFillSize(CSSPropertyID, FillLayer* layer, CSSValue* value) const
 {
-    if (!value->isPrimitiveValue()) {
-        layer->setSizeType(SizeNone);
+    if (value->isInitialValue()) {
+        layer->setSizeType(FillLayer::initialFillSizeType(layer->type()));
+        layer->setSizeLength(FillLayer::initialFillSizeLength(layer->type()));
         return;
     }
 
+    if (!value->isPrimitiveValue())
+        return;
+
     CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
     if (primitiveValue->getValueID() == CSSValueContain)
         layer->setSizeType(Contain);
@@ -195,7 +199,7 @@
 
     LengthSize b = FillLayer::initialFillSizeLength(layer->type());
 
-    if (value->isInitialValue() || primitiveValue->getValueID() == CSSValueContain || primitiveValue->getValueID() == CSSValueCover) {
+    if (primitiveValue->getValueID() == CSSValueContain || primitiveValue->getValueID() == CSSValueCover) {
         layer->setSizeLength(b);
         return;
     }
@@ -458,7 +462,7 @@
         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
         switch (primitiveValue->getValueID()) {
         case CSSValueLinear:
-            return LinearTimingFunction::create();
+            return LinearTimingFunction::preset();
             break;
         case CSSValueEase:
             return CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease);
@@ -475,13 +479,16 @@
         case CSSValueStepStart:
             return StepsTimingFunction::preset(StepsTimingFunction::Start);
             break;
+        case CSSValueStepMiddle:
+            return StepsTimingFunction::preset(StepsTimingFunction::Middle);
+            break;
         case CSSValueStepEnd:
             return StepsTimingFunction::preset(StepsTimingFunction::End);
             break;
         default:
             break;
         }
-        return 0;
+        return nullptr;
     }
 
     if (value->isCubicBezierTimingFunctionValue()) {
@@ -489,17 +496,24 @@
         return CubicBezierTimingFunction::create(cubicTimingFunction->x1(), cubicTimingFunction->y1(), cubicTimingFunction->x2(), cubicTimingFunction->y2());
     } else if (value->isStepsTimingFunctionValue()) {
         CSSStepsTimingFunctionValue* stepsTimingFunction = toCSSStepsTimingFunctionValue(value);
-        return StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtStart());
+        return StepsTimingFunction::create(stepsTimingFunction->numberOfSteps(), stepsTimingFunction->stepAtPosition());
     }
 
-    return 0;
+    return nullptr;
 }
 
 void CSSToStyleMap::mapAnimationTimingFunction(CSSAnimationData* animation, CSSValue* value) const
 {
     RefPtr<TimingFunction> timingFunction = animationTimingFunction(value, true);
-    if (timingFunction)
-        animation->setTimingFunction(timingFunction);
+    if (timingFunction) {
+        // Step middle timing functions are supported up to this point for use in the Web Animations API,
+        // but should not be supported for CSS Animations and Transitions.
+        bool isStepMiddleFunction = (timingFunction->type() == TimingFunction::StepsFunction) && (toStepsTimingFunction(*timingFunction).stepAtPosition() == StepsTimingFunction::StepAtMiddle);
+        if (isStepMiddleFunction)
+            animation->setTimingFunction(CubicBezierTimingFunction::preset(CubicBezierTimingFunction::Ease));
+        else
+            animation->setTimingFunction(timingFunction);
+    }
 }
 
 void CSSToStyleMap::mapNinePieceImage(RenderStyle* mutableStyle, CSSPropertyID property, CSSValue* value, NinePieceImage& image)
diff --git a/Source/core/css/resolver/ElementStyleResources.cpp b/Source/core/css/resolver/ElementStyleResources.cpp
index 2eb83af..2234aac 100644
--- a/Source/core/css/resolver/ElementStyleResources.cpp
+++ b/Source/core/css/resolver/ElementStyleResources.cpp
@@ -54,7 +54,7 @@
     if (value->isCursorImageValue())
         return cursorOrPendingFromValue(property, toCSSCursorImageValue(value));
 
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<StyleImage> ElementStyleResources::generatedOrPendingFromValue(CSSPropertyID property, CSSImageGeneratorValue* value)
diff --git a/Source/core/css/resolver/ElementStyleResources.h b/Source/core/css/resolver/ElementStyleResources.h
index 4049452..b37e6e2 100644
--- a/Source/core/css/resolver/ElementStyleResources.h
+++ b/Source/core/css/resolver/ElementStyleResources.h
@@ -42,7 +42,7 @@
 class TextLinkColors;
 
 typedef WillBePersistentHeapHashMap<FilterOperation*, RefPtrWillBeMember<CSSSVGDocumentValue> > PendingSVGDocumentMap;
-typedef HashMap<CSSPropertyID, RefPtr<CSSValue> > PendingImagePropertyMap;
+typedef WillBePersistentHeapHashMap<CSSPropertyID, RefPtrWillBeMember<CSSValue> > PendingImagePropertyMap;
 
 // Holds information about resources, requested by stylesheets.
 // Lifetime: per-element style resolve.
diff --git a/Source/core/css/resolver/FilterOperationResolver.cpp b/Source/core/css/resolver/FilterOperationResolver.cpp
index 167558d..fdb2e95 100644
--- a/Source/core/css/resolver/FilterOperationResolver.cpp
+++ b/Source/core/css/resolver/FilterOperationResolver.cpp
@@ -86,7 +86,11 @@
     if (!inValue->isValueList())
         return false;
 
+#ifdef BLINK_SCALE_FILTERS_AT_RECORD_TIME
     float zoomFactor = unadjustedConversionData.zoom() * state.elementStyleResources().deviceScaleFactor();
+#else
+    float zoomFactor = unadjustedConversionData.zoom();
+#endif
     const CSSToLengthConversionData& conversionData = unadjustedConversionData.copyWithAdjustedZoom(zoomFactor);
     FilterOperations operations;
     for (CSSValueListIterator i = inValue; i.hasMore(); i.advance()) {
diff --git a/Source/core/css/resolver/FontBuilder.cpp b/Source/core/css/resolver/FontBuilder.cpp
index b165a53..7750099 100644
--- a/Source/core/css/resolver/FontBuilder.cpp
+++ b/Source/core/css/resolver/FontBuilder.cpp
@@ -27,7 +27,7 @@
 #include "core/css/CSSFontFeatureValue.h"
 #include "core/css/CSSToLengthConversionData.h"
 #include "core/css/FontSize.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/RenderTheme.h"
 #include "core/rendering/RenderView.h"
@@ -93,7 +93,7 @@
     const AtomicString& standardFontFamily = m_document->settings()->genericFontFamilySettings().standard();
     if (!standardFontFamily.isEmpty()) {
         scope.fontDescription().firstFamily().setFamily(standardFontFamily);
-        scope.fontDescription().firstFamily().appendFamily(0);
+        scope.fontDescription().firstFamily().appendFamily(nullptr);
     }
     scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
     setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueMedium, false));
@@ -134,7 +134,7 @@
     scope.set(fontDescription);
 }
 
-void FontBuilder::setFontFamilyInitial(float effectiveZoom)
+void FontBuilder::setFontFamilyInitial()
 {
     FontDescriptionChangeScope scope(this);
 
@@ -142,7 +142,7 @@
 
     // We need to adjust the size to account for the generic family change from monospace to non-monospace.
     if (scope.fontDescription().keywordSize() && scope.fontDescription().useFixedDefaultSize())
-        setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, false));
+        scope.fontDescription().setSpecifiedSize(FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, false));
     scope.fontDescription().setGenericFamily(initialDesc.genericFamily());
     if (!initialDesc.firstFamily().familyIsEmpty())
         scope.fontDescription().setFamily(initialDesc.firstFamily());
@@ -158,7 +158,7 @@
 }
 
 // FIXME: I am not convinced FontBuilder needs to know anything about CSSValues.
-void FontBuilder::setFontFamilyValue(CSSValue* value, float effectiveZoom)
+void FontBuilder::setFontFamilyValue(CSSValue* value)
 {
     FontDescriptionChangeScope scope(this);
 
@@ -219,7 +219,7 @@
             if (!currFamily) {
                 // Filling in the first family.
                 firstFamily.setFamily(face);
-                firstFamily.appendFamily(0); // Remove any inherited family-fallback list.
+                firstFamily.appendFamily(nullptr); // Remove any inherited family-fallback list.
                 currFamily = &firstFamily;
                 scope.fontDescription().setIsSpecifiedFont(scope.fontDescription().genericFamily() == FontDescription::NoFamily);
             } else {
@@ -237,10 +237,10 @@
         return;
 
     if (scope.fontDescription().keywordSize() && scope.fontDescription().useFixedDefaultSize() != oldFamilyUsedFixedDefaultSize)
-        setSize(scope.fontDescription(), effectiveZoom, FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, !oldFamilyUsedFixedDefaultSize));
+        scope.fontDescription().setSpecifiedSize(FontSize::fontSizeForKeyword(m_document, CSSValueXxSmall + scope.fontDescription().keywordSize() - 1, !oldFamilyUsedFixedDefaultSize));
 }
 
-void FontBuilder::setFontSizeInitial(float effectiveZoom)
+void FontBuilder::setFontSizeInitial()
 {
     FontDescriptionChangeScope scope(this);
 
@@ -250,10 +250,10 @@
         return;
 
     scope.fontDescription().setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
-    setSize(scope.fontDescription(), effectiveZoom, size);
+    scope.fontDescription().setSpecifiedSize(size);
 }
 
-void FontBuilder::setFontSizeInherit(const FontDescription& parentFontDescription, float effectiveZoom)
+void FontBuilder::setFontSizeInherit(const FontDescription& parentFontDescription)
 {
     FontDescriptionChangeScope scope(this);
 
@@ -263,7 +263,7 @@
         return;
 
     scope.fontDescription().setKeywordSize(parentFontDescription.keywordSize());
-    setSize(scope.fontDescription(), effectiveZoom, size);
+    scope.fontDescription().setSpecifiedSize(size);
 }
 
 // FIXME: Figure out where we fall in the size ranges (xx-small to xxx-large)
@@ -279,7 +279,7 @@
 }
 
 // FIXME: Have to pass RenderStyles here for calc/computed values. This shouldn't be neecessary.
-void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle, float effectiveZoom)
+void FontBuilder::setFontSizeValue(CSSValue* value, RenderStyle* parentStyle, const RenderStyle* rootElementStyle)
 {
     if (!value->isPrimitiveValue())
         return;
@@ -350,7 +350,8 @@
     // Cap font size here to make sure that doesn't happen.
     size = std::min(maximumAllowedFontSize, size);
 
-    setSize(scope.fontDescription(), effectiveZoom, size);
+
+    scope.fontDescription().setSpecifiedSize(size);
 }
 
 void FontBuilder::setWeight(FontWeight fontWeight)
@@ -381,6 +382,7 @@
     scope.fontDescription().setCommonLigaturesState(FontDescription::NormalLigaturesState);
     scope.fontDescription().setDiscretionaryLigaturesState(FontDescription::NormalLigaturesState);
     scope.fontDescription().setHistoricalLigaturesState(FontDescription::NormalLigaturesState);
+    scope.fontDescription().setContextualLigaturesState(FontDescription::NormalLigaturesState);
 }
 
 void FontBuilder::setFontVariantLigaturesInherit(const FontDescription& parentFontDescription)
@@ -390,6 +392,7 @@
     scope.fontDescription().setCommonLigaturesState(parentFontDescription.commonLigaturesState());
     scope.fontDescription().setDiscretionaryLigaturesState(parentFontDescription.discretionaryLigaturesState());
     scope.fontDescription().setHistoricalLigaturesState(parentFontDescription.historicalLigaturesState());
+    scope.fontDescription().setContextualLigaturesState(parentFontDescription.historicalLigaturesState());
 }
 
 void FontBuilder::setFontVariantLigaturesValue(CSSValue* value)
@@ -399,6 +402,7 @@
     FontDescription::LigaturesState commonLigaturesState = FontDescription::NormalLigaturesState;
     FontDescription::LigaturesState discretionaryLigaturesState = FontDescription::NormalLigaturesState;
     FontDescription::LigaturesState historicalLigaturesState = FontDescription::NormalLigaturesState;
+    FontDescription::LigaturesState contextualLigaturesState = FontDescription::NormalLigaturesState;
 
     if (value->isValueList()) {
         CSSValueList* valueList = toCSSValueList(value);
@@ -426,6 +430,12 @@
                 case CSSValueHistoricalLigatures:
                     historicalLigaturesState = FontDescription::EnabledLigaturesState;
                     break;
+                case CSSValueNoContextual:
+                    contextualLigaturesState = FontDescription::DisabledLigaturesState;
+                    break;
+                case CSSValueContextual:
+                    contextualLigaturesState = FontDescription::EnabledLigaturesState;
+                    break;
                 default:
                     ASSERT_NOT_REACHED();
                     break;
@@ -443,6 +453,7 @@
     scope.fontDescription().setCommonLigaturesState(commonLigaturesState);
     scope.fontDescription().setDiscretionaryLigaturesState(discretionaryLigaturesState);
     scope.fontDescription().setHistoricalLigaturesState(historicalLigaturesState);
+    scope.fontDescription().setContextualLigaturesState(contextualLigaturesState);
 }
 
 void FontBuilder::setScript(const String& locale)
@@ -452,25 +463,25 @@
     scope.fontDescription().setScript(localeToScriptCodeForFontSelection(locale));
 }
 
-void FontBuilder::setItalic(FontItalic italic)
+void FontBuilder::setStyle(FontStyle italic)
 {
     FontDescriptionChangeScope scope(this);
 
-    scope.fontDescription().setItalic(italic);
+    scope.fontDescription().setStyle(italic);
 }
 
-void FontBuilder::setSmallCaps(FontSmallCaps smallCaps)
+void FontBuilder::setVariant(FontVariant smallCaps)
 {
     FontDescriptionChangeScope scope(this);
 
-    scope.fontDescription().setSmallCaps(smallCaps);
+    scope.fontDescription().setVariant(smallCaps);
 }
 
-void FontBuilder::setTextRenderingMode(TextRenderingMode textRenderingMode)
+void FontBuilder::setTextRendering(TextRenderingMode textRenderingMode)
 {
     FontDescriptionChangeScope scope(this);
 
-    scope.fontDescription().setTextRenderingMode(textRenderingMode);
+    scope.fontDescription().setTextRendering(textRenderingMode);
 }
 
 void FontBuilder::setKerning(FontDescription::Kerning kerning)
@@ -524,7 +535,7 @@
     if (!m_useSVGZoomRules) {
         zoomFactor = effectiveZoom;
         // FIXME: Why is this here!!!!?!
-        if (Frame* frame = m_document->frame())
+        if (LocalFrame* frame = m_document->frame())
             zoomFactor *= frame->textZoomFactor();
     }
 
@@ -621,14 +632,11 @@
     setSize(scope.fontDescription(), style->effectiveZoom(), size);
 }
 
-void FontBuilder::checkForZoomChange(RenderStyle* style, const RenderStyle* parentStyle)
+void FontBuilder::updateComputedSize(RenderStyle* style, const RenderStyle* parentStyle)
 {
     FontDescriptionChangeScope scope(this);
 
-    if (style->effectiveZoom() == parentStyle->effectiveZoom())
-        return;
-
-    setSize(scope.fontDescription(), style->effectiveZoom(), scope.fontDescription().specifiedSize());
+    scope.fontDescription().setComputedSize(getComputedSizeFromSpecifiedSize(scope.fontDescription(), style->effectiveZoom(), scope.fontDescription().specifiedSize()));
 }
 
 // FIXME: style param should come first
@@ -637,8 +645,8 @@
     if (!m_fontDirty)
         return;
 
+    updateComputedSize(style, parentStyle);
     checkForGenericFamilyChange(style, parentStyle);
-    checkForZoomChange(style, parentStyle);
     checkForOrientationChange(style);
     style->font().update(fontSelector);
     m_fontDirty = false;
@@ -654,7 +662,7 @@
         if (!standardFont.isEmpty()) {
             fontDescription.setGenericFamily(FontDescription::StandardFamily);
             fontDescription.firstFamily().setFamily(standardFont);
-            fontDescription.firstFamily().appendFamily(0);
+            fontDescription.firstFamily().appendFamily(nullptr);
         }
         fontDescription.setKeywordSize(CSSValueMedium - CSSValueXxSmall + 1);
         int size = FontSize::fontSizeForKeyword(m_document, CSSValueMedium, false);
diff --git a/Source/core/css/resolver/FontBuilder.h b/Source/core/css/resolver/FontBuilder.h
index ab44a4f..96f24d2 100644
--- a/Source/core/css/resolver/FontBuilder.h
+++ b/Source/core/css/resolver/FontBuilder.h
@@ -51,13 +51,13 @@
     void inheritFrom(const FontDescription&);
     void fromSystemFont(CSSValueID, float effectiveZoom);
 
-    void setFontFamilyInitial(float effectiveZoom);
+    void setFontFamilyInitial();
     void setFontFamilyInherit(const FontDescription&);
-    void setFontFamilyValue(CSSValue*, float effectiveZoom);
+    void setFontFamilyValue(CSSValue*);
 
-    void setFontSizeInitial(float effectiveZoom);
-    void setFontSizeInherit(const FontDescription&, float effectiveZoom);
-    void setFontSizeValue(CSSValue*, RenderStyle* parentStyle, const RenderStyle* rootElementStyle, float effectiveZoom);
+    void setFontSizeInitial();
+    void setFontSizeInherit(const FontDescription&);
+    void setFontSizeValue(CSSValue*, RenderStyle* parentStyle, const RenderStyle* rootElementStyle);
 
     void setWeight(FontWeight);
     void setWeightBolder();
@@ -71,9 +71,9 @@
     void setFeatureSettingsValue(CSSValue*);
 
     void setScript(const String& locale);
-    void setItalic(FontItalic);
-    void setSmallCaps(FontSmallCaps);
-    void setTextRenderingMode(TextRenderingMode);
+    void setStyle(FontStyle);
+    void setVariant(FontVariant);
+    void setTextRendering(TextRenderingMode);
     void setKerning(FontDescription::Kerning);
     void setFontSmoothing(FontSmoothingMode);
 
@@ -90,7 +90,14 @@
     // FIXME: This is only used by an ASSERT in StyleResolver. Remove?
     bool fontDirty() const { return m_fontDirty; }
 
+    static TextRenderingMode initialTextRendering() { return AutoTextRendering; }
+    static FontVariant initialVariant() { return FontVariantNormal; }
+    static FontStyle initialStyle() { return FontStyleNormal; }
+    static FontDescription::Kerning initialKerning() { return FontDescription::AutoKerning; }
+    static FontSmoothingMode initialFontSmoothing() { return AutoSmoothing; }
+
     friend class FontDescriptionChangeScope;
+
 private:
 
     // FIXME: "size" arg should be first for consistency with other similar functions.
@@ -98,7 +105,7 @@
     void checkForOrientationChange(RenderStyle*);
     // This function fixes up the default font size if it detects that the current generic font family has changed. -dwh
     void checkForGenericFamilyChange(RenderStyle*, const RenderStyle* parentStyle);
-    void checkForZoomChange(RenderStyle*, const RenderStyle* parentStyle);
+    void updateComputedSize(RenderStyle*, const RenderStyle* parentStyle);
 
     float getComputedSizeFromSpecifiedSize(FontDescription&, float effectiveZoom, float specifiedSize);
 
diff --git a/Source/core/css/resolver/MatchResult.h b/Source/core/css/resolver/MatchResult.h
index bbcae30..25d9b91 100644
--- a/Source/core/css/resolver/MatchResult.h
+++ b/Source/core/css/resolver/MatchResult.h
@@ -67,10 +67,12 @@
     };
 };
 
-struct MatchResult {
+class MatchResult {
+    STACK_ALLOCATED();
+public:
     MatchResult() : isCacheable(true) { }
     Vector<MatchedProperties, 64> matchedProperties;
-    Vector<StyleRule*, 64> matchedRules;
+    WillBeHeapVector<RawPtrWillBeMember<StyleRule>, 64> matchedRules;
     MatchRanges ranges;
     bool isCacheable;
 
diff --git a/Source/core/css/resolver/MatchedPropertiesCache.cpp b/Source/core/css/resolver/MatchedPropertiesCache.cpp
index 860c5c0..56a7f5b 100644
--- a/Source/core/css/resolver/MatchedPropertiesCache.cpp
+++ b/Source/core/css/resolver/MatchedPropertiesCache.cpp
@@ -37,7 +37,7 @@
 
 void CachedMatchedProperties::set(const RenderStyle* style, const RenderStyle* parentStyle, const MatchResult& matchResult)
 {
-    matchedProperties.append(matchResult.matchedProperties);
+    matchedProperties.appendVector(matchResult.matchedProperties);
     ranges = matchResult.ranges;
 
     // Note that we don't cache the original RenderStyle instance. It may be further modified.
@@ -49,8 +49,8 @@
 void CachedMatchedProperties::clear()
 {
     matchedProperties.clear();
-    renderStyle = 0;
-    parentRenderStyle = 0;
+    renderStyle = nullptr;
+    parentRenderStyle = nullptr;
 }
 
 MatchedPropertiesCache::MatchedPropertiesCache()
@@ -89,7 +89,7 @@
     if (++m_additionsSinceLastSweep >= maxAdditionsBetweenSweeps
         && !m_sweepTimer.isActive()) {
         static const unsigned sweepTimeInSeconds = 60;
-        m_sweepTimer.startOneShot(sweepTimeInSeconds);
+        m_sweepTimer.startOneShot(sweepTimeInSeconds, FROM_HERE);
     }
 
     ASSERT(hash);
diff --git a/Source/core/css/resolver/MediaQueryResult.h b/Source/core/css/resolver/MediaQueryResult.h
index 1dc00f4..a809bf9 100644
--- a/Source/core/css/resolver/MediaQueryResult.h
+++ b/Source/core/css/resolver/MediaQueryResult.h
@@ -29,8 +29,8 @@
 
 namespace WebCore {
 
-class MediaQueryResult : public RefCounted<MediaQueryResult> {
-    WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED;
+class MediaQueryResult : public RefCountedWillBeGarbageCollectedFinalized<MediaQueryResult> {
+    WTF_MAKE_NONCOPYABLE(MediaQueryResult); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
     MediaQueryResult(const MediaQueryExp& expr, bool result)
         : m_expression(expr)
@@ -38,6 +38,8 @@
     {
     }
 
+    void trace(Visitor* visitor) { visitor->trace(m_expression); }
+
     MediaQueryExp m_expression;
     bool m_result;
 };
diff --git a/Source/core/css/resolver/ScopedStyleResolver.cpp b/Source/core/css/resolver/ScopedStyleResolver.cpp
index f63a5df..e9693d0 100644
--- a/Source/core/css/resolver/ScopedStyleResolver.cpp
+++ b/Source/core/css/resolver/ScopedStyleResolver.cpp
@@ -50,17 +50,17 @@
     if (!sheetDocument)
         return 0;
     Node* ownerNode = sheet->ownerNode();
-    if (!ownerNode || !ownerNode->hasTagName(HTMLNames::styleTag))
+    if (!isHTMLStyleElement(ownerNode))
         return &document;
 
-    HTMLStyleElement* styleElement = toHTMLStyleElement(ownerNode);
-    if (!styleElement->scoped()) {
-        if (styleElement->isInShadowTree())
-            return styleElement->containingShadowRoot();
+    HTMLStyleElement& styleElement = toHTMLStyleElement(*ownerNode);
+    if (!styleElement.scoped()) {
+        if (styleElement.isInShadowTree())
+            return styleElement.containingShadowRoot();
         return &document;
     }
 
-    ContainerNode* parent = styleElement->parentNode();
+    ContainerNode* parent = styleElement.parentNode();
     if (!parent)
         return 0;
 
@@ -78,10 +78,13 @@
     resolver->processScopedRules(ruleSet, sheet->baseURL(), &m_scopingNode);
 }
 
-void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features)
+void ScopedStyleResolver::collectFeaturesTo(RuleFeatureSet& features, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents)
 {
-    for (size_t i = 0; i < m_authorStyleSheets.size(); ++i)
-        features.add(m_authorStyleSheets[i]->contents()->ruleSet().features());
+    for (size_t i = 0; i < m_authorStyleSheets.size(); ++i) {
+        StyleSheetContents* contents = m_authorStyleSheets[i]->contents();
+        if (contents->hasOneClient() || visitedSharedStyleSheetContents.add(contents).isNewEntry)
+            features.add(contents->ruleSet().features());
+    }
 }
 
 void ScopedStyleResolver::resetAuthorStyle()
@@ -102,7 +105,7 @@
     return it->value.get();
 }
 
-void ScopedStyleResolver::addKeyframeStyle(PassRefPtr<StyleRuleKeyframes> rule)
+void ScopedStyleResolver::addKeyframeStyle(PassRefPtrWillBeRawPtr<StyleRuleKeyframes> rule)
 {
     AtomicString s(rule->name());
     if (rule->isVendorPrefixed()) {
diff --git a/Source/core/css/resolver/ScopedStyleResolver.h b/Source/core/css/resolver/ScopedStyleResolver.h
index 824b68a..5979088 100644
--- a/Source/core/css/resolver/ScopedStyleResolver.h
+++ b/Source/core/css/resolver/ScopedStyleResolver.h
@@ -31,6 +31,7 @@
 #include "core/css/RuleSet.h"
 #include "core/dom/ContainerNode.h"
 #include "wtf/HashMap.h"
+#include "wtf/HashSet.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 
@@ -56,12 +57,12 @@
 
 public:
     const StyleRuleKeyframes* keyframeStylesForAnimation(const StringImpl* animationName);
-    void addKeyframeStyle(PassRefPtr<StyleRuleKeyframes>);
+    void addKeyframeStyle(PassRefPtrWillBeRawPtr<StyleRuleKeyframes>);
 
     void collectMatchingAuthorRules(ElementRuleCollector&, bool includeEmptyRules, bool applyAuthorStyles, CascadeScope, CascadeOrder = ignoreCascadeOrder);
     void matchPageRules(PageRuleCollector&);
     void addRulesFromSheet(CSSStyleSheet*, const MediaQueryEvaluator&, StyleResolver*);
-    void collectFeaturesTo(RuleFeatureSet&);
+    void collectFeaturesTo(RuleFeatureSet&, HashSet<const StyleSheetContents*>& visitedSharedStyleSheetContents);
     void resetAuthorStyle();
     void collectViewportRulesTo(StyleResolver*) const;
 
@@ -73,7 +74,7 @@
 
     Vector<CSSStyleSheet*> m_authorStyleSheets;
 
-    typedef HashMap<const StringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
+    typedef WillBePersistentHeapHashMap<const StringImpl*, RefPtrWillBeMember<StyleRuleKeyframes> > KeyframesRuleMap;
     KeyframesRuleMap m_keyframesRuleMap;
 };
 
diff --git a/Source/core/css/resolver/ScopedStyleTree.cpp b/Source/core/css/resolver/ScopedStyleTree.cpp
index 1938fd7..3fb5a45 100644
--- a/Source/core/css/resolver/ScopedStyleTree.cpp
+++ b/Source/core/css/resolver/ScopedStyleTree.cpp
@@ -34,6 +34,8 @@
 
 namespace WebCore {
 
+class StyleSheetContents;
+
 ScopedStyleResolver* ScopedStyleTree::ensureScopedStyleResolver(ContainerNode& scopingNode)
 {
     bool isNewEntry;
@@ -191,8 +193,9 @@
 
 void ScopedStyleTree::collectFeaturesTo(RuleFeatureSet& features)
 {
+    HashSet<const StyleSheetContents*> visitedSharedStyleSheetContents;
     for (HashMap<const ContainerNode*, OwnPtr<ScopedStyleResolver> >::iterator it = m_authorStyles.begin(); it != m_authorStyles.end(); ++it)
-        it->value->collectFeaturesTo(features);
+        it->value->collectFeaturesTo(features, visitedSharedStyleSheetContents);
 }
 
 inline void ScopedStyleTree::reparentNodes(const ScopedStyleResolver* oldParent, ScopedStyleResolver* newParent)
diff --git a/Source/core/css/resolver/SharedStyleFinder.cpp b/Source/core/css/resolver/SharedStyleFinder.cpp
index ac80231..bcb46b4 100644
--- a/Source/core/css/resolver/SharedStyleFinder.cpp
+++ b/Source/core/css/resolver/SharedStyleFinder.cpp
@@ -40,6 +40,7 @@
 #include "core/dom/Node.h"
 #include "core/dom/NodeRenderStyle.h"
 #include "core/dom/QualifiedName.h"
+#include "core/dom/SiblingRuleHelper.h"
 #include "core/dom/SpaceSplitString.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/InsertionPoint.h"
@@ -57,7 +58,7 @@
 
 bool SharedStyleFinder::canShareStyleWithControl(Element& candidate) const
 {
-    if (!candidate.hasTagName(inputTag) || !element().hasTagName(inputTag))
+    if (!isHTMLInputElement(candidate) || !isHTMLInputElement(element()))
         return false;
 
     HTMLInputElement& candidateInput = toHTMLInputElement(candidate);
@@ -150,7 +151,7 @@
     // FIXME: Consider removing this, it's unlikely we'll have so many progress elements
     // that sharing the style makes sense. Instead we should just not support style sharing
     // for them.
-    if (element().hasTagName(progressTag)) {
+    if (isHTMLProgressElement(element())) {
         if (element().shouldAppearIndeterminate() != candidate.shouldAppearIndeterminate())
             return false;
     }
@@ -331,7 +332,7 @@
     }
 
     // Tracking child index requires unique style for each node. This may get set by the sibling rule match above.
-    if (!element().parentOrShadowHostElement()->childrenSupportStyleSharing()) {
+    if (!SiblingRuleHelper(element().parentElementOrShadowRoot()).childrenSupportStyleSharing()) {
         INCREMENT_STYLE_STATS_COUNTER(m_styleResolver, sharedStyleRejectedByParent);
         return 0;
     }
diff --git a/Source/core/css/resolver/StyleAdjuster.cpp b/Source/core/css/resolver/StyleAdjuster.cpp
index 7e8b3ee..dae46cd 100644
--- a/Source/core/css/resolver/StyleAdjuster.cpp
+++ b/Source/core/css/resolver/StyleAdjuster.cpp
@@ -36,6 +36,7 @@
 #include "core/dom/Element.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLTableCellElement.h"
 #include "core/html/HTMLTextAreaElement.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/Settings.h"
@@ -43,7 +44,9 @@
 #include "core/rendering/style/GridPosition.h"
 #include "core/rendering/style/RenderStyle.h"
 #include "core/rendering/style/RenderStyleConstants.h"
+#include "core/svg/SVGSVGElement.h"
 #include "platform/Length.h"
+#include "platform/transforms/TransformOperations.h"
 #include "wtf/Assertions.h"
 
 namespace WebCore {
@@ -158,6 +161,34 @@
     return isDisplayFlexibleBox(parentStyle->display()) || isDisplayGridBox(parentStyle->display());
 }
 
+static bool hasWillChangeThatCreatesStackingContext(const RenderStyle* style, Element* e)
+{
+    for (size_t i = 0; i < style->willChangeProperties().size(); ++i) {
+        switch (style->willChangeProperties()[i]) {
+        case CSSPropertyOpacity:
+        case CSSPropertyWebkitTransform:
+        case CSSPropertyWebkitTransformStyle:
+        case CSSPropertyWebkitPerspective:
+        case CSSPropertyWebkitMask:
+        case CSSPropertyWebkitMaskBoxImage:
+        case CSSPropertyWebkitClipPath:
+        case CSSPropertyWebkitBoxReflect:
+        case CSSPropertyWebkitFilter:
+        case CSSPropertyZIndex:
+        case CSSPropertyPosition:
+            return true;
+        case CSSPropertyMixBlendMode:
+        case CSSPropertyIsolation:
+            if (RuntimeEnabledFeatures::cssCompositingEnabled())
+                return true;
+            break;
+        default:
+            break;
+        }
+    }
+    return false;
+}
+
 void StyleAdjuster::adjustRenderStyle(RenderStyle* style, RenderStyle* parentStyle, Element *e)
 {
     ASSERT(parentStyle);
@@ -174,12 +205,12 @@
             if (e->hasTagName(tdTag)) {
                 style->setDisplay(TABLE_CELL);
                 style->setFloating(NoFloat);
-            } else if (e->hasTagName(tableTag)) {
+            } else if (isHTMLTableElement(*e)) {
                 style->setDisplay(style->isDisplayInlineType() ? INLINE_TABLE : TABLE);
             }
         }
 
-        if (e && (e->hasTagName(tdTag) || e->hasTagName(thTag))) {
+        if (e && isHTMLTableCellElement(*e)) {
             if (style->whiteSpace() == KHTML_NOWRAP) {
                 // Figure out if we are really nowrapping or if we should just
                 // use normal instead. If the width of the cell is fixed, then
@@ -192,18 +223,18 @@
         }
 
         // Tables never support the -webkit-* values for text-align and will reset back to the default.
-        if (e && e->hasTagName(tableTag) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
+        if (isHTMLTableElement(e) && (style->textAlign() == WEBKIT_LEFT || style->textAlign() == WEBKIT_CENTER || style->textAlign() == WEBKIT_RIGHT))
             style->setTextAlign(TASTART);
 
         // Frames and framesets never honor position:relative or position:absolute. This is necessary to
         // fix a crash where a site tries to position these objects. They also never honor display.
-        if (e && (e->hasTagName(frameTag) || e->hasTagName(framesetTag))) {
+        if (e && (isHTMLFrameElement(*e) || isHTMLFrameSetElement(*e))) {
             style->setPosition(StaticPosition);
             style->setDisplay(BLOCK);
         }
 
         // Ruby text does not support float or position. This might change with evolution of the specification.
-        if (e && e->hasTagName(rtTag)) {
+        if (isHTMLRTElement(e)) {
             style->setPosition(StaticPosition);
             style->setFloating(NoFloat);
         }
@@ -213,7 +244,7 @@
         if (e && e->hasTagName(thTag) && style->textAlign() == TASTART)
             style->setTextAlign(CENTER);
 
-        if (e && e->hasTagName(legendTag))
+        if (isHTMLLegendElement(e))
             style->setDisplay(BLOCK);
 
         // Per the spec, position 'static' and 'relative' in the top layer compute to 'absolute'.
@@ -229,14 +260,20 @@
         if (style->display() == INLINE && style->styleType() == NOPSEUDO && style->writingMode() != parentStyle->writingMode())
             style->setDisplay(INLINE_BLOCK);
 
-        // After performing the display mutation, check table rows. We do not honor position:relative or position:sticky on
-        // table rows or cells. This has been established for position:relative in CSS2.1 (and caused a crash in containingBlock()
+        // After performing the display mutation, check table rows. We do not honor position: relative table rows or cells.
+        // This has been established for position: relative in CSS2.1 (and caused a crash in containingBlock()
         // on some sites).
         if ((style->display() == TABLE_HEADER_GROUP || style->display() == TABLE_ROW_GROUP
             || style->display() == TABLE_FOOTER_GROUP || style->display() == TABLE_ROW)
             && style->position() == RelativePosition)
             style->setPosition(StaticPosition);
 
+        // Cannot support position: sticky for table columns and column groups because current code is only doing
+        // background painting through columns / column groups
+        if ((style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_COLUMN)
+            && style->position() == StickyPosition)
+            style->setPosition(StaticPosition);
+
         // writing-mode does not apply to table row groups, table column groups, table rows, and table columns.
         // FIXME: Table cells should be allowed to be perpendicular or flipped with respect to the table, though.
         if (style->display() == TABLE_COLUMN || style->display() == TABLE_COLUMN_GROUP || style->display() == TABLE_FOOTER_GROUP
@@ -275,17 +312,25 @@
         || style->position() == StickyPosition
         || (style->position() == FixedPosition && e && e->document().settings() && e->document().settings()->fixedPositionCreatesStackingContext())
         || isInTopLayer(e, style)
+        || hasWillChangeThatCreatesStackingContext(style, e)
         ))
         style->setZIndex(0);
 
+    // will-change:transform should result in the same rendering behavior as having a transform,
+    // including the creation of a containing block for fixed position descendants.
+    if (!style->hasTransform() && style->willChangeProperties().contains(CSSPropertyWebkitTransform)) {
+        bool makeIdentity = true;
+        style->setTransform(TransformOperations(makeIdentity));
+    }
+
     // Textarea considers overflow visible as auto.
-    if (e && e->hasTagName(textareaTag)) {
+    if (isHTMLTextAreaElement(e)) {
         style->setOverflowX(style->overflowX() == OVISIBLE ? OAUTO : style->overflowX());
         style->setOverflowY(style->overflowY() == OVISIBLE ? OAUTO : style->overflowY());
     }
 
     // For now, <marquee> requires an overflow clip to work properly.
-    if (e && e->hasTagName(marqueeTag)) {
+    if (isHTMLMarqueeElement(e)) {
         style->setOverflowX(OHIDDEN);
         style->setOverflowY(OHIDDEN);
     }
@@ -330,7 +375,7 @@
     if (e && e->isFormControlElement() && style->fontSize() >= 11) {
         // Don't apply intrinsic margins to image buttons. The designer knows how big the images are,
         // so we have to treat all image buttons as though they were explicitly sized.
-        if (!e->hasTagName(inputTag) || !toHTMLInputElement(e)->isImageButton())
+        if (!isHTMLInputElement(*e) || !toHTMLInputElement(e)->isImageButton())
             addIntrinsicMargins(style);
     }
 
@@ -348,8 +393,6 @@
         || style->hasFilter()))
         style->setTransformStyle3D(TransformStyle3DFlat);
 
-    adjustGridItemPosition(style, parentStyle);
-
     if (e && e->isSVGElement()) {
         // Spec: http://www.w3.org/TR/SVG/masking.html#OverflowProperty
         if (style->overflowY() == OSCROLL)
@@ -363,49 +406,18 @@
             style->setOverflowX(OVISIBLE);
 
         // Only the root <svg> element in an SVG document fragment tree honors css position
-        if (!(e->hasTagName(SVGNames::svgTag) && e->parentNode() && !e->parentNode()->isSVGElement()))
+        if (!(isSVGSVGElement(*e) && e->parentNode() && !e->parentNode()->isSVGElement()))
             style->setPosition(RenderStyle::initialPosition());
 
         // RenderSVGRoot handles zooming for the whole SVG subtree, so foreignObject content should
         // not be scaled again.
-        if (e->hasTagName(SVGNames::foreignObjectTag))
+        if (isSVGForeignObjectElement(*e))
             style->setEffectiveZoom(RenderStyle::initialZoom());
 
         // SVG text layout code expects us to be a block-level style element.
-        if ((e->hasTagName(SVGNames::foreignObjectTag) || e->hasTagName(SVGNames::textTag)) && style->isDisplayInlineType())
+        if ((isSVGForeignObjectElement(*e) || isSVGTextElement(*e)) && style->isDisplayInlineType())
             style->setDisplay(BLOCK);
     }
 }
 
-void StyleAdjuster::adjustGridItemPosition(RenderStyle* style, RenderStyle* parentStyle) const
-{
-    const GridPosition& columnStartPosition = style->gridColumnStart();
-    const GridPosition& columnEndPosition = style->gridColumnEnd();
-    const GridPosition& rowStartPosition = style->gridRowStart();
-    const GridPosition& rowEndPosition = style->gridRowEnd();
-
-    // If opposing grid-placement properties both specify a grid span, they both compute to ‘auto’.
-    if (columnStartPosition.isSpan() && columnEndPosition.isSpan()) {
-        style->setGridColumnStart(GridPosition());
-        style->setGridColumnEnd(GridPosition());
-    }
-
-    if (rowStartPosition.isSpan() && rowEndPosition.isSpan()) {
-        style->setGridRowStart(GridPosition());
-        style->setGridRowEnd(GridPosition());
-    }
-
-    // Unknown named grid area compute to 'auto'.
-    const NamedGridAreaMap& map = parentStyle->namedGridArea();
-
-#define CLEAR_UNKNOWN_NAMED_AREA(prop, Prop) \
-    if (prop.isNamedGridArea() && !map.contains(prop.namedGridLine())) \
-        style->setGrid##Prop(GridPosition());
-
-    CLEAR_UNKNOWN_NAMED_AREA(columnStartPosition, ColumnStart);
-    CLEAR_UNKNOWN_NAMED_AREA(columnEndPosition, ColumnEnd);
-    CLEAR_UNKNOWN_NAMED_AREA(rowStartPosition, RowStart);
-    CLEAR_UNKNOWN_NAMED_AREA(rowEndPosition, RowEnd);
-}
-
 }
diff --git a/Source/core/css/resolver/StyleAdjuster.h b/Source/core/css/resolver/StyleAdjuster.h
index 96e5927..787beaf 100644
--- a/Source/core/css/resolver/StyleAdjuster.h
+++ b/Source/core/css/resolver/StyleAdjuster.h
@@ -41,8 +41,6 @@
     void adjustRenderStyle(RenderStyle* styleToAdjust, RenderStyle* parentStyle, Element*);
 
 private:
-    void adjustGridItemPosition(RenderStyle*, RenderStyle*) const;
-
     const CachedUAStyle& m_cachedUAStyle;
     bool m_useQuirksModeStyles;
 };
diff --git a/Source/core/css/resolver/StyleBuilderCustom.cpp b/Source/core/css/resolver/StyleBuilderCustom.cpp
index a30084f..4594e70 100644
--- a/Source/core/css/resolver/StyleBuilderCustom.cpp
+++ b/Source/core/css/resolver/StyleBuilderCustom.cpp
@@ -67,7 +67,7 @@
 #include "core/css/resolver/FontBuilder.h"
 #include "core/css/resolver/StyleBuilder.h"
 #include "core/css/resolver/TransformBuilder.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/style/CounterContent.h"
 #include "core/rendering/style/CursorList.h"
@@ -77,7 +77,6 @@
 #include "core/rendering/style/SVGRenderStyle.h"
 #include "core/rendering/style/SVGRenderStyleDefs.h"
 #include "core/rendering/style/StyleGeneratedImage.h"
-#include "core/svg/SVGColor.h"
 #include "core/svg/SVGPaint.h"
 #include "platform/fonts/FontDescription.h"
 #include "wtf/MathExtras.h"
@@ -156,7 +155,7 @@
     if (state.applyPropertyToRegularStyle())
         state.style()->setColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color()));
     if (state.applyPropertyToVisitedLinkStyle())
-        state.style()->setVisitedLinkColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color(), state.element()->isLink() /* forVisitedLink */));
+        state.style()->setVisitedLinkColor(state.document().textLinkColors().colorFromPrimitiveValue(primitiveValue, state.style()->color(), true));
 }
 
 void StyleBuilderFunctions::applyInitialCSSPropertyCursor(StyleResolverState& state)
@@ -236,7 +235,7 @@
 
 void StyleBuilderFunctions::applyInitialCSSPropertyFontFamily(StyleResolverState& state)
 {
-    state.fontBuilder().setFontFamilyInitial(state.style()->effectiveZoom());
+    state.fontBuilder().setFontFamilyInitial();
 }
 
 void StyleBuilderFunctions::applyInheritCSSPropertyFontFamily(StyleResolverState& state)
@@ -246,22 +245,22 @@
 
 void StyleBuilderFunctions::applyValueCSSPropertyFontFamily(StyleResolverState& state, CSSValue* value)
 {
-    state.fontBuilder().setFontFamilyValue(value, state.style()->effectiveZoom());
+    state.fontBuilder().setFontFamilyValue(value);
 }
 
 void StyleBuilderFunctions::applyInitialCSSPropertyFontSize(StyleResolverState& state)
 {
-    state.fontBuilder().setFontSizeInitial(state.style()->effectiveZoom());
+    state.fontBuilder().setFontSizeInitial();
 }
 
 void StyleBuilderFunctions::applyInheritCSSPropertyFontSize(StyleResolverState& state)
 {
-    state.fontBuilder().setFontSizeInherit(state.parentFontDescription(), state.style()->effectiveZoom());
+    state.fontBuilder().setFontSizeInherit(state.parentFontDescription());
 }
 
 void StyleBuilderFunctions::applyValueCSSPropertyFontSize(StyleResolverState& state, CSSValue* value)
 {
-    state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle(), state.style()->effectiveZoom());
+    state.fontBuilder().setFontSizeValue(value, state.parentStyle(), state.rootElementStyle());
 }
 
 void StyleBuilderFunctions::applyInitialCSSPropertyFontWeight(StyleResolverState& state)
@@ -308,7 +307,7 @@
         lineHeight = RenderStyle::initialLineHeight();
     } else if (primitiveValue->isLength()) {
         float multiplier = state.style()->effectiveZoom();
-        if (Frame* frame = state.document().frame())
+        if (LocalFrame* frame = state.document().frame())
             multiplier *= frame->textZoomFactor();
         lineHeight = primitiveValue->computeLength<Length>(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier));
     } else if (primitiveValue->isPercentage()) {
@@ -317,7 +316,7 @@
         lineHeight = Length(primitiveValue->getDoubleValue() * 100.0, Percent);
     } else if (primitiveValue->isCalculated()) {
         double multiplier = state.style()->effectiveZoom();
-        if (Frame* frame = state.document().frame())
+        if (LocalFrame* frame = state.document().frame())
             multiplier *= frame->textZoomFactor();
         Length zoomedLength = Length(primitiveValue->cssCalcValue()->toCalcValue(state.cssToLengthConversionData().copyWithAdjustedZoom(multiplier)));
         lineHeight = Length(valueForLength(zoomedLength, state.style()->fontSize()), Fixed);
@@ -689,7 +688,7 @@
     if (value->isPrimitiveValue()) {
         CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value);
         if (primitiveValue->getValueID() == CSSValueNone) {
-            state.style()->setClipPath(0);
+            state.style()->setClipPath(nullptr);
         } else if (primitiveValue->isShape()) {
             state.style()->setClipPath(ShapeClipPathOperation::create(basicShapeForValue(state, primitiveValue->getShapeValue())));
         } else if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_URI) {
@@ -864,6 +863,43 @@
     state.style()->setTextUnderlinePosition(static_cast<TextUnderlinePosition>(t));
 }
 
+void StyleBuilderFunctions::applyInitialCSSPropertyWillChange(StyleResolverState& state)
+{
+    state.style()->setWillChangeContents(false);
+    state.style()->setWillChangeScrollPosition(false);
+    state.style()->setWillChangeProperties(Vector<CSSPropertyID>());
+}
+
+void StyleBuilderFunctions::applyInheritCSSPropertyWillChange(StyleResolverState& state)
+{
+    state.style()->setWillChangeContents(state.parentStyle()->willChangeContents());
+    state.style()->setWillChangeScrollPosition(state.parentStyle()->willChangeScrollPosition());
+    state.style()->setWillChangeProperties(state.parentStyle()->willChangeProperties());
+}
+
+void StyleBuilderFunctions::applyValueCSSPropertyWillChange(StyleResolverState& state, CSSValue* value)
+{
+    ASSERT(value->isValueList());
+    bool willChangeContents = false;
+    bool willChangeScrollPosition = false;
+    Vector<CSSPropertyID> willChangeProperties;
+
+    for (CSSValueListIterator i(value); i.hasMore(); i.advance()) {
+        CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(i.value());
+        if (CSSPropertyID propertyID = primitiveValue->getPropertyID())
+            willChangeProperties.append(propertyID);
+        else if (primitiveValue->getValueID() == CSSValueContents)
+            willChangeContents = true;
+        else if (primitiveValue->getValueID() == CSSValueScrollPosition)
+            willChangeScrollPosition = true;
+        else
+            ASSERT_NOT_REACHED();
+    }
+    state.style()->setWillChangeContents(willChangeContents);
+    state.style()->setWillChangeScrollPosition(willChangeScrollPosition);
+    state.style()->setWillChangeProperties(willChangeProperties);
+}
+
 // Everything below this line is from the old StyleResolver::applyProperty
 // and eventually needs to move into new StyleBuilderFunctions calls intead.
 
@@ -1037,13 +1073,14 @@
     return true;
 }
 
-static Color colorFromSVGColorCSSValue(SVGColor* svgColor, const Color& fgColor)
+static Color colorFromSVGPaintCSSValue(SVGPaint* svgPaint, const Color& fgColor)
 {
     Color color;
-    if (svgColor->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
+    if (svgPaint->paintType() == SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR
+        || svgPaint->paintType() == SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR)
         color = fgColor;
     else
-        color = svgColor->color();
+        color = svgPaint->color();
     return color;
 }
 
@@ -1944,6 +1981,7 @@
     case CSSPropertyWhiteSpace:
     case CSSPropertyWidows:
     case CSSPropertyWidth:
+    case CSSPropertyWillChange:
     case CSSPropertyWordBreak:
     case CSSPropertyWordSpacing:
     case CSSPropertyWordWrap:
@@ -2039,7 +2077,7 @@
         }
         if (value->isSVGPaint()) {
             SVGPaint* svgPaint = toSVGPaint(value);
-            svgStyle->setFillPaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
+            svgStyle->setFillPaint(svgPaint->paintType(), colorFromSVGPaintCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
         }
         break;
     }
@@ -2057,7 +2095,7 @@
         }
         if (value->isSVGPaint()) {
             SVGPaint* svgPaint = toSVGPaint(value);
-            svgStyle->setStrokePaint(svgPaint->paintType(), colorFromSVGColorCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
+            svgStyle->setStrokePaint(svgPaint->paintType(), colorFromSVGPaintCSSValue(svgPaint, state.style()->color()), svgPaint->uri(), state.applyPropertyToRegularStyle(), state.applyPropertyToVisitedLinkStyle());
         }
         break;
     }
@@ -2088,22 +2126,28 @@
     case CSSPropertyStopColor:
     {
         HANDLE_SVG_INHERIT_AND_INITIAL(stopColor, StopColor);
-        if (value->isSVGColor())
-            state.style()->accessSVGStyle()->setStopColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
+        if (primitiveValue->isRGBColor())
+            state.style()->accessSVGStyle()->setStopColor(primitiveValue->getRGBA32Value());
+        else if (primitiveValue->getValueID() == CSSValueCurrentcolor)
+            state.style()->accessSVGStyle()->setStopColor(state.style()->color());
         break;
     }
     case CSSPropertyLightingColor:
     {
         HANDLE_SVG_INHERIT_AND_INITIAL(lightingColor, LightingColor);
-        if (value->isSVGColor())
-            state.style()->accessSVGStyle()->setLightingColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
+        if (primitiveValue->isRGBColor())
+            state.style()->accessSVGStyle()->setLightingColor(primitiveValue->getRGBA32Value());
+        else if (primitiveValue->getValueID() == CSSValueCurrentcolor)
+            state.style()->accessSVGStyle()->setLightingColor(state.style()->color());
         break;
     }
     case CSSPropertyFloodColor:
     {
         HANDLE_SVG_INHERIT_AND_INITIAL(floodColor, FloodColor);
-        if (value->isSVGColor())
-            state.style()->accessSVGStyle()->setFloodColor(colorFromSVGColorCSSValue(toSVGColor(value), state.style()->color()));
+        if (primitiveValue->isRGBColor())
+            state.style()->accessSVGStyle()->setFloodColor(primitiveValue->getRGBA32Value());
+        else if (primitiveValue->getValueID() == CSSValueCurrentcolor)
+            state.style()->accessSVGStyle()->setFloodColor(state.style()->color());
         break;
     }
     case CSSPropertyGlyphOrientationHorizontal:
diff --git a/Source/core/css/resolver/StyleResolver.cpp b/Source/core/css/resolver/StyleResolver.cpp
index 7daa31e..7e1c31e 100644
--- a/Source/core/css/resolver/StyleResolver.cpp
+++ b/Source/core/css/resolver/StyleResolver.cpp
@@ -71,10 +71,10 @@
 #include "core/dom/Text.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/style/KeyframeList.h"
 #include "core/svg/SVGDocumentExtensions.h"
@@ -93,7 +93,7 @@
     // If any changes to CSS Animations were detected, stash the update away for application after the
     // render object is updated if we're in the appropriate scope.
     if (state.animationUpdate())
-        element.ensureActiveAnimations()->cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
+        element.ensureActiveAnimations().cssAnimations().setPendingUpdate(state.takeAnimationUpdate());
 }
 
 } // namespace
@@ -168,7 +168,7 @@
 #endif
 }
 
-void StyleResolver::initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& watchedSelectors)
+void StyleResolver::initWatchedSelectorRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedSelectors)
 {
     if (!watchedSelectors.size())
         return;
@@ -177,14 +177,14 @@
         m_watchedSelectorsRules->addStyleRule(watchedSelectors[i].get(), RuleHasNoSpecialState);
 }
 
-void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::lazyAppendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
 {
     unsigned size = styleSheets.size();
     for (unsigned i = firstNew; i < size; ++i)
         m_pendingStyleSheets.add(styleSheets[i].get());
 }
 
-void StyleResolver::removePendingAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::removePendingAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
 {
     for (unsigned i = 0; i < styleSheets.size(); ++i)
         m_pendingStyleSheets.remove(styleSheets[i].get());
@@ -216,7 +216,7 @@
     finishAppendAuthorStyleSheets();
 }
 
-void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >& styleSheets)
+void StyleResolver::appendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& styleSheets)
 {
     // This handles sheets added to the end of the stylesheet list only. In other cases the style resolver
     // needs to be reconstructed. To handle insertions too the rule order numbers would need to be updated.
@@ -246,7 +246,7 @@
     m_needCollectFeatures = true;
 }
 
-void StyleResolver::addTreeBoundaryCrossingRules(const Vector<MinimalRuleData>& rules, ContainerNode* scope)
+void StyleResolver::addTreeBoundaryCrossingRules(const WillBeHeapVector<MinimalRuleData>& rules, ContainerNode* scope)
 {
     for (unsigned i = 0; i < rules.size(); ++i) {
         const MinimalRuleData& info = rules[i];
@@ -256,7 +256,7 @@
 
 void StyleResolver::processScopedRules(const RuleSet& authorRules, const KURL& sheetBaseURL, ContainerNode* scope)
 {
-    const Vector<StyleRuleKeyframes*> keyframesRules = authorRules.keyframesRules();
+    const WillBeHeapVector<RawPtrWillBeMember<StyleRuleKeyframes> > keyframesRules = authorRules.keyframesRules();
     for (unsigned i = 0; i < keyframesRules.size(); ++i)
         ensureScopedStyleResolver(scope)->addKeyframeStyle(keyframesRules[i]);
 
@@ -264,7 +264,7 @@
 
     // FIXME(BUG 72461): We don't add @font-face rules of scoped style sheets for the moment.
     if (!scope || scope->isDocumentNode()) {
-        const Vector<StyleRuleFontFace*> fontFaceRules = authorRules.fontFaceRules();
+        const WillBeHeapVector<RawPtrWillBeMember<StyleRuleFontFace> > fontFaceRules = authorRules.fontFaceRules();
         for (unsigned i = 0; i < fontFaceRules.size(); ++i)
             addFontFaceRule(&m_document, document().styleEngine()->fontSelector(), fontFaceRules[i]);
         if (fontFaceRules.size())
@@ -292,12 +292,12 @@
     m_styleTree.remove(scopingNode);
 }
 
-static PassOwnPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
+static PassOwnPtrWillBeRawPtr<RuleSet> makeRuleSet(const Vector<RuleFeature>& rules)
 {
     size_t size = rules.size();
     if (!size)
         return nullptr;
-    OwnPtr<RuleSet> ruleSet = RuleSet::create();
+    OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
     for (size_t i = 0; i < size; ++i)
         ruleSet->addRule(rules[i].rule, rules[i].selectorIndex, rules[i].hasDocumentSecurityOrigin ? RuleHasDocumentSecurityOrigin : RuleHasNoSpecialState);
     return ruleSet.release();
@@ -591,13 +591,14 @@
 
 PassRefPtr<RenderStyle> StyleResolver::styleForDocument(Document& document, CSSFontSelector* fontSelector)
 {
-    const Frame* frame = document.frame();
+    const LocalFrame* frame = document.frame();
 
     RefPtr<RenderStyle> documentStyle = RenderStyle::create();
     documentStyle->setDisplay(BLOCK);
     documentStyle->setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
     documentStyle->setZoom(frame && !document.printing() ? frame->pageZoomFactor() : 1);
     documentStyle->setLocale(document.contentLanguage());
+    documentStyle->setZIndex(0);
 
     // This overrides any -webkit-user-modify inherited from the parent iframe.
     documentStyle->setUserModify(document.inDesignMode() ? READ_WRITE : READ_ONLY);
@@ -717,7 +718,7 @@
     applyAnimatedProperties(state, element);
 
     // FIXME: Shouldn't this be on RenderBody::styleDidChange?
-    if (element->hasTagName(bodyTag))
+    if (isHTMLBodyElement(*element))
         document().textLinkColors().setTextColor(state.style()->color());
 
     setAnimationUpdateIfNeeded(state, *element);
@@ -740,8 +741,7 @@
     StyleResolverState state(document(), element, parentStyle);
 
     MatchResult result;
-    if (keyframe->properties())
-        result.addMatchedProperties(keyframe->properties());
+    result.addMatchedProperties(&keyframe->properties());
 
     ASSERT(!state.style());
 
@@ -766,10 +766,8 @@
     // We don't need to bother with !important. Since there is only ever one
     // decl, there's nothing to override. So just add the first properties.
     bool inheritedOnly = false;
-    if (keyframe->properties()) {
-        applyMatchedProperties<AnimationProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
-        applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
-    }
+    applyMatchedProperties<AnimationProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
+    applyMatchedProperties<HighPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
 
     // If our font got dirtied, go ahead and update it now.
     updateFont(state);
@@ -779,8 +777,7 @@
         StyleBuilder::applyProperty(CSSPropertyLineHeight, state, state.lineHeightValue());
 
     // Now do rest of the properties.
-    if (keyframe->properties())
-        applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
+    applyMatchedProperties<LowPriorityProperties>(state, result, false, 0, result.matchedProperties.size() - 1, inheritedOnly);
 
     // If our font got dirtied by one of the non-essential font props,
     // go ahead and update it a second time.
@@ -797,7 +794,7 @@
 
 // This function is used by the WebAnimations JavaScript API method animate().
 // FIXME: Remove this when animate() switches away from resolution-dependent parsing.
-PassRefPtr<KeyframeEffectModel> StyleResolver::createKeyframeEffectModel(Element& element, const Vector<RefPtr<MutableStylePropertySet> >& propertySetVector, KeyframeEffectModel::KeyframeVector& keyframes)
+PassRefPtrWillBeRawPtr<KeyframeEffectModel> StyleResolver::createKeyframeEffectModel(Element& element, const Vector<RefPtr<MutableStylePropertySet> >& propertySetVector, KeyframeEffectModel::KeyframeVector& keyframes)
 {
     ASSERT(propertySetVector.size() == keyframes.size());
 
@@ -818,26 +815,26 @@
 {
     RenderObject* parentRenderer = parent.renderer();
     if (!parentRenderer)
-        return 0;
+        return nullptr;
 
     if (pseudoId < FIRST_INTERNAL_PSEUDOID && !parentRenderer->style()->hasPseudoStyle(pseudoId))
-        return 0;
+        return nullptr;
 
     if (pseudoId == BACKDROP && !parent.isInTopLayer())
-        return 0;
+        return nullptr;
 
     if (!parentRenderer->canHaveGeneratedChildren())
-        return 0;
+        return nullptr;
 
     RenderStyle* parentStyle = parentRenderer->style();
     StyleResolverState state(document(), &parent, parentStyle);
     if (!pseudoStyleForElementInternal(parent, pseudoId, parentStyle, state))
-        return 0;
+        return nullptr;
     RefPtr<RenderStyle> style = state.takeStyle();
     ASSERT(style);
 
     if (!pseudoElementRendererIsNeeded(style.get()))
-        return 0;
+        return nullptr;
 
     parentStyle->addCachedPseudoStyle(style.release());
     RefPtr<PseudoElement> pseudo = PseudoElement::create(&parent, pseudoId);
@@ -908,11 +905,11 @@
 {
     ASSERT(parentStyle);
     if (!element)
-        return 0;
+        return nullptr;
 
     StyleResolverState state(document(), element, parentStyle);
     if (!pseudoStyleForElementInternal(*element, pseudoStyleRequest, parentStyle, state))
-        return 0;
+        return nullptr;
 
     if (PseudoElement* pseudoElement = element->pseudoElement(pseudoStyleRequest.pseudoId))
         setAnimationUpdateIfNeeded(state, *pseudoElement);
@@ -1025,7 +1022,7 @@
     return collector.matchedStyleRuleList();
 }
 
-PassRefPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::pseudoCSSRulesForElement(Element* element, PseudoId pseudoId, unsigned rulesToInclude)
 {
     ASSERT(element);
     StyleResolverState state(document(), element);
@@ -1035,7 +1032,7 @@
     return collector.matchedCSSRuleList();
 }
 
-PassRefPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
+PassRefPtrWillBeRawPtr<CSSRuleList> StyleResolver::cssRulesForElement(Element* element, unsigned rulesToInclude)
 {
     return pseudoCSSRulesForElement(element, NOPSEUDO, rulesToInclude);
 }
diff --git a/Source/core/css/resolver/StyleResolver.h b/Source/core/css/resolver/StyleResolver.h
index 5dc926a..a848bb4 100644
--- a/Source/core/css/resolver/StyleResolver.h
+++ b/Source/core/css/resolver/StyleResolver.h
@@ -37,6 +37,7 @@
 #include "core/css/resolver/StyleBuilder.h"
 #include "core/css/resolver/StyleResolverState.h"
 #include "core/css/resolver/StyleResourceLoader.h"
+#include "heap/Handle.h"
 #include "wtf/Deque.h"
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
@@ -71,7 +72,7 @@
 class StyleRulePage;
 class ViewportStyleResolver;
 
-struct MatchResult;
+class MatchResult;
 
 enum StyleSharingBehavior {
     AllowStyleSharing,
@@ -91,6 +92,8 @@
 typedef WTF::Deque<Element*, styleSharingListSize> StyleSharingList;
 
 struct CSSPropertyValue {
+    STACK_ALLOCATED();
+public:
     CSSPropertyValue(CSSPropertyID property, CSSValue* value)
         : property(property), value(value) { }
     // Stores value=propertySet.getPropertyCSSValue(id).get().
@@ -119,7 +122,7 @@
         RuleMatchingBehavior = MatchAllRules);
 
     PassRefPtr<RenderStyle> styleForKeyframe(Element*, const RenderStyle&, RenderStyle* parentStyle, const StyleKeyframe*, const AtomicString& animationName);
-    static PassRefPtr<KeyframeEffectModel> createKeyframeEffectModel(Element&, const Vector<RefPtr<MutableStylePropertySet> >&, KeyframeEffectModel::KeyframeVector&);
+    static PassRefPtrWillBeRawPtr<KeyframeEffectModel> createKeyframeEffectModel(Element&, const Vector<RefPtr<MutableStylePropertySet> >&, KeyframeEffectModel::KeyframeVector&);
 
     PassRefPtr<RenderStyle> pseudoStyleForElement(Element*, const PseudoStyleRequest&, RenderStyle* parentStyle);
 
@@ -135,15 +138,15 @@
 
     // FIXME: It could be better to call appendAuthorStyleSheets() directly after we factor StyleResolver further.
     // https://bugs.webkit.org/show_bug.cgi?id=108890
-    void appendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&);
+    void appendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
     void resetAuthorStyle(const ContainerNode*);
     void finishAppendAuthorStyleSheets();
 
     TreeBoundaryCrossingRules& treeBoundaryCrossingRules() { return m_treeBoundaryCrossingRules; }
     void processScopedRules(const RuleSet& authorRules, const KURL&, ContainerNode* scope = 0);
 
-    void lazyAppendAuthorStyleSheets(unsigned firstNew, const Vector<RefPtr<CSSStyleSheet> >&);
-    void removePendingAuthorStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&);
+    void lazyAppendAuthorStyleSheets(unsigned firstNew, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
+    void removePendingAuthorStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
     void appendPendingAuthorStyleSheets();
     bool hasPendingAuthorStyleSheets() const { return m_pendingStyleSheets.size() > 0 || m_needCollectFeatures; }
 
@@ -174,8 +177,8 @@
         AllButEmptyCSSRules = UAAndUserCSSRules | AuthorCSSRules | CrossOriginCSSRules,
         AllCSSRules         = AllButEmptyCSSRules | EmptyCSSRules,
     };
-    PassRefPtr<CSSRuleList> cssRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
-    PassRefPtr<CSSRuleList> pseudoCSSRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
+    PassRefPtrWillBeRawPtr<CSSRuleList> cssRulesForElement(Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
+    PassRefPtrWillBeRawPtr<CSSRuleList> pseudoCSSRulesForElement(Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
     PassRefPtr<StyleRuleList> styleRulesForElement(Element*, unsigned rulesToInclude);
 
     // |properties| is an array with |count| elements.
@@ -196,13 +199,18 @@
     // Exposed for RenderStyle::isStyleAvilable().
     static RenderStyle* styleNotYetAvailable() { return s_styleNotYetAvailable; }
 
-    RuleFeatureSet& ensureRuleFeatureSet()
+    RuleFeatureSet& ensureUpdatedRuleFeatureSet()
     {
         if (hasPendingAuthorStyleSheets())
             appendPendingAuthorStyleSheets();
         return m_features;
     }
 
+    RuleFeatureSet& ruleFeatureSet()
+    {
+        return m_features;
+    }
+
     StyleSharingList& styleSharingList() { return m_styleSharingList; }
 
     bool hasRulesForId(const AtomicString&) const;
@@ -227,9 +235,9 @@
     virtual void fontsNeedUpdate(CSSFontSelector*) OVERRIDE;
 
 private:
-    void initWatchedSelectorRules(const Vector<RefPtr<StyleRule> >& watchedSelectors);
+    void initWatchedSelectorRules(const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedSelectors);
 
-    void addTreeBoundaryCrossingRules(const Vector<MinimalRuleData>&, ContainerNode* scope);
+    void addTreeBoundaryCrossingRules(const WillBeHeapVector<MinimalRuleData>&, ContainerNode* scope);
 
     // FIXME: This should probably go away, folded into FontBuilder.
     void updateFont(StyleResolverState&);
@@ -267,7 +275,7 @@
     template <StyleApplicationPass pass>
     void applyAnimatedProperties(StyleResolverState&, const AnimationEffect::CompositableValueMap&);
     void matchPageRules(MatchResult&, RuleSet*, bool isLeftPage, bool isFirstPage, const String& pageName);
-    void matchPageRulesForList(Vector<StyleRulePage*>& matchedRules, const Vector<StyleRulePage*>&, bool isLeftPage, bool isFirstPage, const String& pageName);
+    void matchPageRulesForList(WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >& matchedRules, const WillBeHeapVector<RawPtrWillBeMember<StyleRulePage> >&, bool isLeftPage, bool isFirstPage, const String& pageName);
     void collectViewportRules();
     Settings* documentSettings() { return m_document.settings(); }
 
@@ -279,7 +287,7 @@
     bool pseudoStyleForElementInternal(Element&, const PseudoStyleRequest&, RenderStyle* parentStyle, StyleResolverState&);
 
     // FIXME: This likely belongs on RuleSet.
-    typedef HashMap<StringImpl*, RefPtr<StyleRuleKeyframes> > KeyframesRuleMap;
+    typedef WillBePersistentHeapHashMap<StringImpl*, RefPtrWillBeMember<StyleRuleKeyframes> > KeyframesRuleMap;
     KeyframesRuleMap m_keyframesRuleMap;
 
     static RenderStyle* s_styleNotYetAvailable;
@@ -289,7 +297,7 @@
     MatchedPropertiesCache m_matchedPropertiesCache;
 
     OwnPtr<MediaQueryEvaluator> m_medium;
-    MediaQueryResultList m_viewportDependentMediaQueryResults;
+    WillBePersistentMediaQueryResultList m_viewportDependentMediaQueryResults;
 
     RefPtr<RenderStyle> m_rootDefaultStyle;
 
@@ -305,11 +313,11 @@
     // FIXME: The entire logic of collecting features on StyleResolver, as well as transferring them
     // between various parts of machinery smells wrong. This needs to be better somehow.
     RuleFeatureSet m_features;
-    OwnPtr<RuleSet> m_siblingRuleSet;
-    OwnPtr<RuleSet> m_uncommonAttributeRuleSet;
+    OwnPtrWillBePersistent<RuleSet> m_siblingRuleSet;
+    OwnPtrWillBePersistent<RuleSet> m_uncommonAttributeRuleSet;
 
     // FIXME: watched selectors should be implemented using injected author stylesheets: http://crbug.com/316960
-    OwnPtr<RuleSet> m_watchedSelectorsRules;
+    OwnPtrWillBePersistent<RuleSet> m_watchedSelectorsRules;
     TreeBoundaryCrossingRules m_treeBoundaryCrossingRules;
 
     bool m_needCollectFeatures;
diff --git a/Source/core/css/resolver/StyleResolverState.cpp b/Source/core/css/resolver/StyleResolverState.cpp
index 3e59ff1..370877c 100644
--- a/Source/core/css/resolver/StyleResolverState.cpp
+++ b/Source/core/css/resolver/StyleResolverState.cpp
@@ -32,7 +32,7 @@
 StyleResolverState::StyleResolverState(Document& document, Element* element, RenderStyle* parentStyle)
     : m_elementContext(element ? ElementResolveContext(*element) : ElementResolveContext())
     , m_document(document)
-    , m_style(0)
+    , m_style(nullptr)
     , m_cssToLengthConversionData(0, rootElementStyle(), document.renderView())
     , m_parentStyle(parentStyle)
     , m_applyPropertyToRegularStyle(true)
@@ -42,7 +42,7 @@
     , m_currentRule(0)
 {
     if (m_elementContext.resetStyleInheritance())
-        m_parentStyle = 0;
+        m_parentStyle = nullptr;
     else if (!parentStyle && m_elementContext.parentNode())
         m_parentStyle = m_elementContext.parentNode()->renderStyle();
 
diff --git a/Source/core/css/resolver/StyleResolverState.h b/Source/core/css/resolver/StyleResolverState.h
index 9c93a43..4e01e8c 100644
--- a/Source/core/css/resolver/StyleResolverState.h
+++ b/Source/core/css/resolver/StyleResolverState.h
@@ -42,6 +42,7 @@
 class StyleRule;
 
 class StyleResolverState {
+STACK_ALLOCATED();
 WTF_MAKE_NONCOPYABLE(StyleResolverState);
 public:
     StyleResolverState(Document&, Element*, RenderStyle* parentStyle = 0);
diff --git a/Source/core/css/resolver/StyleResourceLoader.cpp b/Source/core/css/resolver/StyleResourceLoader.cpp
index 0b20f73..8319059 100644
--- a/Source/core/css/resolver/StyleResourceLoader.cpp
+++ b/Source/core/css/resolver/StyleResourceLoader.cpp
@@ -88,7 +88,7 @@
     if (CSSImageSetValue* imageSetValue = pendingImage->cssImageSetValue())
         return imageSetValue->cachedImageSet(fetcher, deviceScaleFactor, options);
 
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<StyleImage> StyleResourceLoader::loadPendingImage(StylePendingImage* pendingImage, float deviceScaleFactor)
diff --git a/Source/core/css/resolver/ViewportStyleResolver.cpp b/Source/core/css/resolver/ViewportStyleResolver.cpp
index f10190a..372df90 100644
--- a/Source/core/css/resolver/ViewportStyleResolver.cpp
+++ b/Source/core/css/resolver/ViewportStyleResolver.cpp
@@ -57,16 +57,16 @@
 {
     rules->compactRulesIfNeeded();
 
-    const Vector<StyleRuleViewport*>& viewportRules = rules->viewportRules();
+    const WillBeHeapVector<RawPtrWillBeMember<StyleRuleViewport> >& viewportRules = rules->viewportRules();
     for (size_t i = 0; i < viewportRules.size(); ++i)
         addViewportRule(viewportRules[i], origin);
 }
 
 void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule, Origin origin)
 {
-    StylePropertySet* propertySet = viewportRule->mutableProperties();
+    StylePropertySet& propertySet = viewportRule->mutableProperties();
 
-    unsigned propertyCount = propertySet->propertyCount();
+    unsigned propertyCount = propertySet.propertyCount();
     if (!propertyCount)
         return;
 
@@ -74,14 +74,14 @@
         m_hasAuthorStyle = true;
 
     if (!m_propertySet) {
-        m_propertySet = propertySet->mutableCopy();
+        m_propertySet = propertySet.mutableCopy();
         return;
     }
 
     // We cannot use mergeAndOverrideOnConflict() here because it doesn't
     // respect the !important declaration (but addParsedProperty() does).
     for (unsigned i = 0; i < propertyCount; ++i)
-        m_propertySet->addParsedProperty(propertySet->propertyAt(i).toCSSProperty());
+        m_propertySet->addParsedProperty(propertySet.propertyAt(i).toCSSProperty());
 }
 
 void ViewportStyleResolver::clearDocument()
@@ -96,7 +96,7 @@
 
     if (!m_propertySet || (!m_hasAuthorStyle && m_document->hasLegacyViewportTag())) {
         ASSERT(!m_hasAuthorStyle);
-        m_propertySet = 0;
+        m_propertySet = nullptr;
         m_document->setViewportDescription(ViewportDescription());
         return;
     }
@@ -115,7 +115,7 @@
 
     m_document->setViewportDescription(description);
 
-    m_propertySet = 0;
+    m_propertySet = nullptr;
     m_hasAuthorStyle = false;
 }
 
@@ -129,7 +129,7 @@
     if (id == CSSPropertyUserZoom)
         defaultValue = 1;
 
-    RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
+    RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
     if (!value || !value->isPrimitiveValue())
         return defaultValue;
 
@@ -179,7 +179,7 @@
         || id == CSSPropertyMaxWidth
         || id == CSSPropertyMinWidth);
 
-    RefPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
+    RefPtrWillBeRawPtr<CSSValue> value = m_propertySet->getPropertyCSSValue(id);
     if (!value || !value->isPrimitiveValue())
         return Length(); // auto
 
diff --git a/Source/core/css/svg.css b/Source/core/css/svg.css
index 3975ab4..f860d7b 100644
--- a/Source/core/css/svg.css
+++ b/Source/core/css/svg.css
@@ -51,10 +51,14 @@
     display: block
 }
 
-text, tspan, textPath {
+text {
    white-space: nowrap
 }
 
+tspan, textPath {
+   white-space: inherit
+}
+
 /* states */
 
 :focus {
diff --git a/Source/core/css/themeChromium.css b/Source/core/css/themeChromium.css
index 0a413e1..6094c1d 100644
--- a/Source/core/css/themeChromium.css
+++ b/Source/core/css/themeChromium.css
@@ -30,7 +30,7 @@
 
 /* These styles override other user-agent styles for Chromium. */
 
-input:disabled, isindex:disabled, textarea:disabled {
+input:disabled, textarea:disabled {
     color: #545454; /* Color::light() for #000000. See RenderTextControl.cpp:disabledTextColor */
 }
 
diff --git a/Source/core/css/themeMac.css b/Source/core/css/themeMac.css
new file mode 100644
index 0000000..e68eaf9
--- /dev/null
+++ b/Source/core/css/themeMac.css
@@ -0,0 +1,16 @@
+/* Copyright 2014 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+select, input[type="color"][list] {
+    background-color: #f8f8f8;
+    border: 1px solid #a6a6a6;
+}
+
+select[size],
+select[multiple],
+select[size][multiple] {
+    background: white;
+    border: 1px inset gray;
+}
diff --git a/Source/core/dom/ActiveDOMObject.cpp b/Source/core/dom/ActiveDOMObject.cpp
index be52d0f..9ff9b5f 100644
--- a/Source/core/dom/ActiveDOMObject.cpp
+++ b/Source/core/dom/ActiveDOMObject.cpp
@@ -79,8 +79,29 @@
 {
 }
 
+void ActiveDOMObject::willStop()
+{
+}
+
 void ActiveDOMObject::stop()
 {
 }
 
+void ActiveDOMObject::didMoveToNewExecutionContext(ExecutionContext* context)
+{
+    observeContext(context);
+
+    if (context->activeDOMObjectsAreStopped()) {
+        stop();
+        return;
+    }
+
+    if (context->activeDOMObjectsAreSuspended()) {
+        suspend();
+        return;
+    }
+
+    resume();
+}
+
 } // namespace WebCore
diff --git a/Source/core/dom/ActiveDOMObject.h b/Source/core/dom/ActiveDOMObject.h
index 1157363..d51cac9 100644
--- a/Source/core/dom/ActiveDOMObject.h
+++ b/Source/core/dom/ActiveDOMObject.h
@@ -55,8 +55,13 @@
     // which don't need special treatment can skip implementation.
     virtual void suspend();
     virtual void resume();
+    // willStop is called when stop() for the owner worker is called. It's not
+    // called if the owner is a Document. It's ok to post a task to the context.
+    virtual void willStop();
     virtual void stop();
 
+    void didMoveToNewExecutionContext(ExecutionContext*);
+
 protected:
     virtual ~ActiveDOMObject();
 
diff --git a/Source/core/dom/ActiveDOMObjectTest.cpp b/Source/core/dom/ActiveDOMObjectTest.cpp
new file mode 100644
index 0000000..9be6d83
--- /dev/null
+++ b/Source/core/dom/ActiveDOMObjectTest.cpp
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2014, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/dom/Document.h"
+
+#include "core/testing/DummyPageHolder.h"
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class MockActiveDOMObject : public ActiveDOMObject {
+public:
+    MockActiveDOMObject(ExecutionContext* context) : ActiveDOMObject(context) { }
+
+    MOCK_METHOD0(suspend, void());
+    MOCK_METHOD0(resume, void());
+    MOCK_METHOD0(stop, void());
+};
+
+class ActiveDOMObjectTest : public ::testing::Test {
+protected:
+    ActiveDOMObjectTest();
+
+    Document& srcDocument() const { return m_srcPageHolder->document(); }
+    Document& destDocument() const { return m_destPageHolder->document(); }
+    MockActiveDOMObject& activeDOMObject() { return m_activeDOMObject; }
+
+private:
+    OwnPtr<DummyPageHolder> m_srcPageHolder;
+    OwnPtr<DummyPageHolder> m_destPageHolder;
+    MockActiveDOMObject m_activeDOMObject;
+};
+
+ActiveDOMObjectTest::ActiveDOMObjectTest()
+    : m_srcPageHolder(DummyPageHolder::create(IntSize(800, 600)))
+    , m_destPageHolder(DummyPageHolder::create(IntSize(800, 600)))
+    , m_activeDOMObject(&m_srcPageHolder->document())
+{
+    m_activeDOMObject.suspendIfNeeded();
+}
+
+TEST_F(ActiveDOMObjectTest, NewContextObserved)
+{
+    unsigned initialSrcCount = srcDocument().activeDOMObjectCount();
+    unsigned initialDestCount = destDocument().activeDOMObjectCount();
+
+    EXPECT_CALL(activeDOMObject(), resume());
+    activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+
+    EXPECT_EQ(initialSrcCount - 1, srcDocument().activeDOMObjectCount());
+    EXPECT_EQ(initialDestCount + 1, destDocument().activeDOMObjectCount());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToActiveDocument)
+{
+    EXPECT_CALL(activeDOMObject(), resume());
+    activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToSuspendedDocument)
+{
+    destDocument().suspendScheduledTasks();
+
+    EXPECT_CALL(activeDOMObject(), suspend());
+    activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+TEST_F(ActiveDOMObjectTest, MoveToStoppedDocument)
+{
+    destDocument().detach();
+
+    EXPECT_CALL(activeDOMObject(), stop());
+    activeDOMObject().didMoveToNewExecutionContext(&destDocument());
+}
+
+} // unnamed namespace
diff --git a/Source/core/dom/Attr.cpp b/Source/core/dom/Attr.cpp
index 93c3c94..c6454fa 100644
--- a/Source/core/dom/Attr.cpp
+++ b/Source/core/dom/Attr.cpp
@@ -170,7 +170,7 @@
 {
     ASSERT(m_element);
     ASSERT(m_element->elementData());
-    return *m_element->ensureUniqueElementData()->getAttributeItem(qualifiedName());
+    return *m_element->ensureUniqueElementData().getAttributeItem(qualifiedName());
 }
 
 void Attr::detachFromElementWithValue(const AtomicString& value)
diff --git a/Source/core/dom/Attr.idl b/Source/core/dom/Attr.idl
index 2403170..a2fab30 100644
--- a/Source/core/dom/Attr.idl
+++ b/Source/core/dom/Attr.idl
@@ -24,7 +24,7 @@
 
     [TreatReturnedNullStringAs=Null] readonly attribute DOMString name;
 
-    [DeprecateAs=AttributeSpecified] readonly attribute boolean specified;
+    [MeasureAs=AttributeSpecified] readonly attribute boolean specified;
 
     [TreatReturnedNullStringAs=Null, TreatNullAs=NullString, RaisesException=Setter, CustomElementCallbacks] attribute DOMString value;
 
diff --git a/Source/core/dom/CSSSelectorWatch.cpp b/Source/core/dom/CSSSelectorWatch.cpp
index b6ac2e3..a9f941d 100644
--- a/Source/core/dom/CSSSelectorWatch.cpp
+++ b/Source/core/dom/CSSSelectorWatch.cpp
@@ -36,8 +36,8 @@
 #include "core/css/StylePropertySet.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/style/StyleRareNonInheritedData.h"
 
 namespace WebCore {
@@ -54,10 +54,10 @@
 
 CSSSelectorWatch& CSSSelectorWatch::from(Document& document)
 {
-    CSSSelectorWatch* watch = static_cast<CSSSelectorWatch*>(DocumentSupplement::from(&document, kSupplementName));
+    CSSSelectorWatch* watch = static_cast<CSSSelectorWatch*>(DocumentSupplement::from(document, kSupplementName));
     if (!watch) {
         watch = new CSSSelectorWatch(document);
-        DocumentSupplement::provideTo(&document, kSupplementName, adoptPtr(watch));
+        DocumentSupplement::provideTo(document, kSupplementName, adoptPtr(watch));
     }
     return *watch;
 }
@@ -69,7 +69,7 @@
 
     if (m_timerExpirations < 1) {
         m_timerExpirations++;
-        m_callbackSelectorChangeTimer.startOneShot(0);
+        m_callbackSelectorChangeTimer.startOneShot(0, FROM_HERE);
         return;
     }
     if (m_document.frame()) {
@@ -125,7 +125,7 @@
     } else {
         m_timerExpirations = 0;
         if (!m_callbackSelectorChangeTimer.isActive())
-            m_callbackSelectorChangeTimer.startOneShot(0);
+            m_callbackSelectorChangeTimer.startOneShot(0, FROM_HERE);
     }
 }
 
@@ -156,7 +156,7 @@
         if (!allCompound(selectorList))
             continue;
 
-        RefPtr<StyleRule> rule = StyleRule::create();
+        RefPtrWillBeRawPtr<StyleRule> rule = StyleRule::create();
         rule->wrapperAdoptSelectorList(selectorList);
         rule->setProperties(callbackPropertySet);
         m_watchedCallbackSelectors.append(rule.release());
diff --git a/Source/core/dom/CSSSelectorWatch.h b/Source/core/dom/CSSSelectorWatch.h
index e1cbbed..79a19d6 100644
--- a/Source/core/dom/CSSSelectorWatch.h
+++ b/Source/core/dom/CSSSelectorWatch.h
@@ -50,7 +50,7 @@
     static CSSSelectorWatch& from(Document&);
 
     void watchCSSSelectors(const Vector<String>& selectors);
-    const Vector<RefPtr<StyleRule> >& watchedCallbackSelectors() const { return m_watchedCallbackSelectors; }
+    const WillBeHeapVector<RefPtrWillBeMember<StyleRule> >& watchedCallbackSelectors() const { return m_watchedCallbackSelectors; }
 
     void updateSelectorMatches(const Vector<String>& removedSelectors, const Vector<String>& addedSelectors);
 
@@ -60,7 +60,7 @@
 
     Document& m_document;
 
-    Vector<RefPtr<StyleRule> > m_watchedCallbackSelectors;
+    WillBePersistentHeapVector<RefPtrWillBeMember<StyleRule> > m_watchedCallbackSelectors;
 
     // Maps a CSS selector string with a -webkit-callback property to the number
     // of matching RenderStyle objects in this document.
diff --git a/Source/core/dom/CharacterData.cpp b/Source/core/dom/CharacterData.cpp
index 2eecf98..4b2a386 100644
--- a/Source/core/dom/CharacterData.cpp
+++ b/Source/core/dom/CharacterData.cpp
@@ -195,7 +195,7 @@
 
     if (!isInShadowTree()) {
         if (document().hasListenerType(Document::DOMCHARACTERDATAMODIFIED_LISTENER))
-            dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMCharacterDataModified, true, 0, oldData, m_data));
+            dispatchScopedEvent(MutationEvent::create(EventTypeNames::DOMCharacterDataModified, true, nullptr, oldData, m_data));
         dispatchSubtreeModifiedEvent();
     }
     InspectorInstrumentation::characterDataModified(this);
diff --git a/Source/core/dom/ChildNode.h b/Source/core/dom/ChildNode.h
index 79aa891..19bcc5a 100644
--- a/Source/core/dom/ChildNode.h
+++ b/Source/core/dom/ChildNode.h
@@ -12,22 +12,19 @@
 
 class ChildNode {
 public:
-    static Element* previousElementSibling(Node* node)
+    static Element* previousElementSibling(Node& node)
     {
-        ASSERT(node);
-        return ElementTraversal::previousSibling(*node);
+        return ElementTraversal::previousSibling(node);
     }
 
-    static Element* nextElementSibling(Node* node)
+    static Element* nextElementSibling(Node& node)
     {
-        ASSERT(node);
-        return ElementTraversal::nextSibling(*node);
+        return ElementTraversal::nextSibling(node);
     }
 
-    static void remove(Node* node, ExceptionState& exceptionState)
+    static void remove(Node& node, ExceptionState& exceptionState)
     {
-        ASSERT(node);
-        return node->remove(exceptionState);
+        return node.remove(exceptionState);
     }
 };
 
diff --git a/Source/core/dom/ChildNodeList.cpp b/Source/core/dom/ChildNodeList.cpp
index ee585c4..bdef1e0 100644
--- a/Source/core/dom/ChildNodeList.cpp
+++ b/Source/core/dom/ChildNodeList.cpp
@@ -29,15 +29,14 @@
 
 namespace WebCore {
 
-ChildNodeList::ChildNodeList(PassRefPtr<ContainerNode> parent)
+ChildNodeList::ChildNodeList(ContainerNode& parent)
     : m_parent(parent)
 {
-    ASSERT(m_parent);
 }
 
 Node* ChildNodeList::virtualOwnerNode() const
 {
-    return ownerNode();
+    return &ownerNode();
 }
 
 ChildNodeList::~ChildNodeList()
diff --git a/Source/core/dom/ChildNodeList.h b/Source/core/dom/ChildNodeList.h
index 0fe38cc..c91a043 100644
--- a/Source/core/dom/ChildNodeList.h
+++ b/Source/core/dom/ChildNodeList.h
@@ -33,7 +33,7 @@
 
 class ChildNodeList FINAL : public NodeList {
 public:
-    static PassRefPtr<ChildNodeList> create(PassRefPtr<ContainerNode> rootNode)
+    static PassRefPtr<ChildNodeList> create(ContainerNode& rootNode)
     {
         return adoptRef(new ChildNodeList(rootNode));
     }
@@ -46,17 +46,17 @@
 
     // Non-DOM API.
     void invalidateCache() { m_collectionIndexCache.invalidate(); }
-    ContainerNode* ownerNode() const { return m_parent.get(); }
+    ContainerNode& ownerNode() const { return *m_parent; }
 
     // CollectionIndexCache API.
-    ContainerNode& rootNode() const { return *m_parent; }
+    ContainerNode& rootNode() const { return ownerNode(); }
     bool canTraverseBackward() const { return true; }
     Node* itemBefore(const Node* previousItem) const;
     Node* traverseToFirstElement(const ContainerNode& root) const { return root.firstChild(); }
     Node* traverseForwardToOffset(unsigned offset, Node& currentNode, unsigned& currentOffset, const ContainerNode& root) const;
 
 private:
-    explicit ChildNodeList(PassRefPtr<ContainerNode> rootNode);
+    explicit ChildNodeList(ContainerNode& rootNode);
 
     virtual bool isChildNodeList() const OVERRIDE { return true; }
     virtual Node* virtualOwnerNode() const OVERRIDE;
diff --git a/Source/core/dom/ClassCollection.cpp b/Source/core/dom/ClassCollection.cpp
index 59099c0..73d6a3a 100644
--- a/Source/core/dom/ClassCollection.cpp
+++ b/Source/core/dom/ClassCollection.cpp
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-ClassCollection::ClassCollection(ContainerNode* rootNode, const AtomicString& classNames)
+ClassCollection::ClassCollection(ContainerNode& rootNode, const AtomicString& classNames)
     : HTMLCollection(rootNode, ClassCollectionType, DoesNotOverrideItemAfter)
     , m_classNames(classNames, document().inQuirksMode())
     , m_originalClassNames(classNames)
@@ -44,7 +44,7 @@
 
 ClassCollection::~ClassCollection()
 {
-    ownerNode()->nodeLists()->removeCache(this, ClassCollectionType, m_originalClassNames);
+    ownerNode().nodeLists()->removeCache(this, ClassCollectionType, m_originalClassNames);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/ClassCollection.h b/Source/core/dom/ClassCollection.h
index a906537..257cbb3 100644
--- a/Source/core/dom/ClassCollection.h
+++ b/Source/core/dom/ClassCollection.h
@@ -40,7 +40,7 @@
 public:
     // classNames argument is an AtomicString because it is common for Elements to share the same class names.
     // It is also used to construct a SpaceSplitString (m_classNames) and its constructor requires an AtomicString.
-    static PassRefPtr<ClassCollection> create(ContainerNode* rootNode, CollectionType type, const AtomicString& classNames)
+    static PassRefPtr<ClassCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& classNames)
     {
         ASSERT_UNUSED(type, type == ClassCollectionType);
         return adoptRef(new ClassCollection(rootNode, classNames));
@@ -51,7 +51,7 @@
     bool elementMatches(const Element&) const;
 
 private:
-    ClassCollection(ContainerNode* rootNode, const AtomicString& classNames);
+    ClassCollection(ContainerNode& rootNode, const AtomicString& classNames);
 
     SpaceSplitString m_classNames;
     AtomicString m_originalClassNames;
diff --git a/Source/core/dom/ContainerNode.cpp b/Source/core/dom/ContainerNode.cpp
index d63b98e..a722ab5 100644
--- a/Source/core/dom/ContainerNode.cpp
+++ b/Source/core/dom/ContainerNode.cpp
@@ -268,7 +268,7 @@
     ASSERT(newChild);
     ASSERT(nextChild.parentNode() == this);
     ASSERT(!newChild->isDocumentFragment());
-    ASSERT(!hasTagName(templateTag));
+    ASSERT(!isHTMLTemplateElement(this));
 
     if (nextChild.previousSibling() == newChild || nextChild == newChild) // nothing to do
         return;
@@ -425,7 +425,7 @@
 
     document().removeFocusedElementOfSubtree(child.get());
 
-    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
+    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
         fullscreen->removeFullScreenElementOfSubtree(child.get());
 
     // Events fired when blurring currently focused node might have moved this
@@ -509,7 +509,7 @@
     // The container node can be removed from event handlers.
     RefPtr<ContainerNode> protect(this);
 
-    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document()))
+    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document()))
         fullscreen->removeFullScreenElementOfSubtree(this, true);
 
     // Do any prep work needed before actually starting to detach
@@ -528,7 +528,7 @@
         document().removeFocusedElementOfSubtree(this, true);
 
         // Removing a node from a selection can cause widget updates.
-        document().nodeChildrenWillBeRemoved(this);
+        document().nodeChildrenWillBeRemoved(*this);
     }
 
 
@@ -537,7 +537,7 @@
         RenderWidget::UpdateSuspendScope suspendWidgetHierarchyUpdates;
         {
             NoEventDispatchAssertion assertNoEventDispatch;
-            removedChildren.reserveInitialCapacity(childNodeCount());
+            removedChildren.reserveInitialCapacity(countChildren());
             while (m_firstChild) {
                 removedChildren.append(m_firstChild);
                 removeBetween(0, m_firstChild->nextSibling(), *m_firstChild);
@@ -614,7 +614,7 @@
     ASSERT(newChild);
     ASSERT(!newChild->parentNode()); // Use appendChild if you need to handle reparenting (and want DOM mutation events).
     ASSERT(!newChild->isDocumentFragment());
-    ASSERT(!hasTagName(templateTag));
+    ASSERT(!isHTMLTemplateElement(this));
 
     if (document() != newChild->document())
         document().adoptNode(newChild.get(), ASSERT_NO_EXCEPTION);
@@ -711,7 +711,7 @@
         } else if ((o->isText() && !o->isBR()) || o->isReplaced()) {
             point = FloatPoint();
             if (o->isText() && toRenderText(o)->firstTextBox()) {
-                point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root()->lineTop());
+                point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root().lineTop().toFloat());
             } else if (o->isBox()) {
                 RenderBox* box = toRenderBox(o);
                 point.moveBy(box->location());
@@ -808,10 +808,13 @@
     // renderer we can just ignore the state change.
     if (!renderer())
         return;
-    // FIXME: This could probably setNeedsStyleRecalc(LocalStyleChange) in the affectedByFocus case
-    // and only setNeedsStyleRecalc(SubtreeStyleChange) in the childrenAffectedByFocus case.
-    if (renderStyle()->affectedByFocus() || (isElementNode() && toElement(this)->childrenAffectedByFocus()))
+
+    if ((isElementNode() && toElement(this)->childrenAffectedByFocus())
+        || (renderStyle()->affectedByFocus() && renderStyle()->hasPseudoStyle(FIRST_LETTER)))
         setNeedsStyleRecalc(SubtreeStyleChange);
+    else if (renderStyle()->affectedByFocus())
+        setNeedsStyleRecalc(LocalStyleChange);
+
     if (renderer() && renderer()->style()->hasAppearance())
         RenderTheme::theme().stateChanged(renderer(), FocusState);
 }
@@ -824,9 +827,15 @@
     Node::setFocus(received);
 
     focusStateChanged();
+
+    if (renderer() || received)
+        return;
+
     // If :focus sets display: none, we lose focus but still need to recalc our style.
-    if (!renderer() && !received)
+    if (isElementNode() && toElement(this)->childrenAffectedByFocus())
         setNeedsStyleRecalc(SubtreeStyleChange);
+    else
+        setNeedsStyleRecalc(LocalStyleChange);
 }
 
 void ContainerNode::setActive(bool down)
@@ -838,7 +847,8 @@
 
     // FIXME: Why does this not need to handle the display: none transition like :hover does?
     if (renderer()) {
-        if (isElementNode() && toElement(this)->childrenAffectedByActive())
+        if ((isElementNode() && toElement(this)->childrenAffectedByActive())
+            || (renderStyle()->affectedByActive() && renderStyle()->hasPseudoStyle(FIRST_LETTER)))
             setNeedsStyleRecalc(SubtreeStyleChange);
         else if (renderStyle()->affectedByActive())
             setNeedsStyleRecalc(LocalStyleChange);
@@ -866,7 +876,8 @@
         return;
     }
 
-    if (isElementNode() && toElement(this)->childrenAffectedByHover())
+    if ((isElementNode() && toElement(this)->childrenAffectedByHover())
+        || (renderStyle()->affectedByHover() && renderStyle()->hasPseudoStyle(FIRST_LETTER)))
         setNeedsStyleRecalc(SubtreeStyleChange);
     else if (renderStyle()->affectedByHover())
         setNeedsStyleRecalc(LocalStyleChange);
@@ -877,10 +888,10 @@
 
 PassRefPtr<HTMLCollection> ContainerNode::children()
 {
-    return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(this, NodeChildren);
+    return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, NodeChildren);
 }
 
-unsigned ContainerNode::childNodeCount() const
+unsigned ContainerNode::countChildren() const
 {
     unsigned count = 0;
     Node *n;
@@ -889,7 +900,7 @@
     return count;
 }
 
-Node *ContainerNode::childNode(unsigned index) const
+Node* ContainerNode::traverseToChildAt(unsigned index) const
 {
     unsigned i;
     Node *n = firstChild();
@@ -902,12 +913,12 @@
 {
     if (selectors.isEmpty()) {
         exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
-        return 0;
+        return nullptr;
     }
 
     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
     if (!selectorQuery)
-        return 0;
+        return nullptr;
     return selectorQuery->queryFirst(*this);
 }
 
@@ -915,12 +926,12 @@
 {
     if (selectors.isEmpty()) {
         exceptionState.throwDOMException(SyntaxError, "The provided selector is empty.");
-        return 0;
+        return nullptr;
     }
 
     SelectorQuery* selectorQuery = document().selectorQueryCache().add(selectors, document(), exceptionState);
     if (!selectorQuery)
-        return 0;
+        return nullptr;
     return selectorQuery->queryAll(*this);
 }
 
@@ -989,43 +1000,43 @@
 PassRefPtr<HTMLCollection> ContainerNode::getElementsByTagName(const AtomicString& localName)
 {
     if (localName.isNull())
-        return 0;
+        return nullptr;
 
     if (document().isHTMLDocument())
-        return ensureRareData().ensureNodeLists().addCache<HTMLTagCollection>(this, HTMLTagCollectionType, localName);
-    return ensureRareData().ensureNodeLists().addCache<TagCollection>(this, TagCollectionType, localName);
+        return ensureRareData().ensureNodeLists().addCache<HTMLTagCollection>(*this, HTMLTagCollectionType, localName);
+    return ensureRareData().ensureNodeLists().addCache<TagCollection>(*this, TagCollectionType, localName);
 }
 
 PassRefPtr<HTMLCollection> ContainerNode::getElementsByTagNameNS(const AtomicString& namespaceURI, const AtomicString& localName)
 {
     if (localName.isNull())
-        return 0;
+        return nullptr;
 
     if (namespaceURI == starAtom)
         return getElementsByTagName(localName);
 
-    return ensureRareData().ensureNodeLists().addCache(this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
+    return ensureRareData().ensureNodeLists().addCache(*this, namespaceURI.isEmpty() ? nullAtom : namespaceURI, localName);
 }
 
 // Takes an AtomicString in argument because it is common for elements to share the same name attribute.
 // Therefore, the NameNodeList factory function expects an AtomicString type.
 PassRefPtr<NodeList> ContainerNode::getElementsByName(const AtomicString& elementName)
 {
-    return ensureRareData().ensureNodeLists().addCache<NameNodeList>(this, NameNodeListType, elementName);
+    return ensureRareData().ensureNodeLists().addCache<NameNodeList>(*this, NameNodeListType, elementName);
 }
 
 // Takes an AtomicString in argument because it is common for elements to share the same set of class names.
 // Therefore, the ClassNodeList factory function expects an AtomicString type.
 PassRefPtr<HTMLCollection> ContainerNode::getElementsByClassName(const AtomicString& classNames)
 {
-    return ensureRareData().ensureNodeLists().addCache<ClassCollection>(this, ClassCollectionType, classNames);
+    return ensureRareData().ensureNodeLists().addCache<ClassCollection>(*this, ClassCollectionType, classNames);
 }
 
 PassRefPtr<RadioNodeList> ContainerNode::radioNodeList(const AtomicString& name, bool onlyMatchImgElements)
 {
-    ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
+    ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
     CollectionType type = onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType;
-    return ensureRareData().ensureNodeLists().addCache<RadioNodeList>(this, type, name);
+    return ensureRareData().ensureNodeLists().addCache<RadioNodeList>(*this, type, name);
 }
 
 #ifndef NDEBUG
diff --git a/Source/core/dom/ContainerNode.h b/Source/core/dom/ContainerNode.h
index b0b1ee5..9f22455 100644
--- a/Source/core/dom/ContainerNode.h
+++ b/Source/core/dom/ContainerNode.h
@@ -82,15 +82,16 @@
 
     Node* firstChild() const { return m_firstChild; }
     Node* lastChild() const { return m_lastChild; }
-    bool hasChildNodes() const { return m_firstChild; }
+    bool hasChildren() const { return m_firstChild; }
 
     bool hasOneChild() const { return m_firstChild && !m_firstChild->nextSibling(); }
     bool hasOneTextChild() const { return hasOneChild() && m_firstChild->isTextNode(); }
+    bool hasChildCount(unsigned) const;
 
     PassRefPtr<HTMLCollection> children();
 
-    unsigned childNodeCount() const;
-    Node* childNode(unsigned index) const;
+    unsigned countChildren() const;
+    Node* traverseToChildAt(unsigned index) const;
 
     PassRefPtr<Element> querySelector(const AtomicString& selectors, ExceptionState&);
     PassRefPtr<NodeList> querySelectorAll(const AtomicString& selectors, ExceptionState&);
@@ -176,6 +177,16 @@
 
 DEFINE_NODE_TYPE_CASTS(ContainerNode, isContainerNode());
 
+inline bool ContainerNode::hasChildCount(unsigned count) const
+{
+    Node* child = m_firstChild;
+    while (count && child) {
+        child = child->nextSibling();
+        --count;
+    }
+    return !count && !child;
+}
+
 inline ContainerNode::ContainerNode(TreeScope* treeScope, ConstructionType type)
     : Node(treeScope, type)
     , m_firstChild(0)
@@ -204,18 +215,18 @@
         child->detach(childrenContext);
 }
 
-inline unsigned Node::childNodeCount() const
+inline unsigned Node::countChildren() const
 {
     if (!isContainerNode())
         return 0;
-    return toContainerNode(this)->childNodeCount();
+    return toContainerNode(this)->countChildren();
 }
 
-inline Node* Node::childNode(unsigned index) const
+inline Node* Node::traverseToChildAt(unsigned index) const
 {
     if (!isContainerNode())
         return 0;
-    return toContainerNode(this)->childNode(index);
+    return toContainerNode(this)->traverseToChildAt(index);
 }
 
 inline Node* Node::firstChild() const
@@ -232,13 +243,19 @@
     return toContainerNode(this)->lastChild();
 }
 
-inline Node* Node::highestAncestor() const
+inline Node& Node::highestAncestor() const
 {
     Node* node = const_cast<Node*>(this);
     Node* highest = node;
     for (; node; node = node->parentNode())
         highest = node;
-    return highest;
+    return *highest;
+}
+
+inline Node* Node::parentElementOrShadowRoot() const
+{
+    ContainerNode* parent = parentNode();
+    return parent && (parent->isElementNode() || parent->isShadowRoot()) ? parent : 0;
 }
 
 // This constant controls how much buffer is initially allocated
@@ -282,7 +299,7 @@
         }
         Vector<RefPtr<Node> >& nodeVector = *m_childNodes;
         if (m_currentIndex >= nodeVector.size())
-            return 0;
+            return nullptr;
         return nodeVector[m_currentIndex++];
     }
 
diff --git a/Source/core/dom/ContainerNodeAlgorithms.h b/Source/core/dom/ContainerNodeAlgorithms.h
index b863c25..f7cefcb 100644
--- a/Source/core/dom/ContainerNodeAlgorithms.h
+++ b/Source/core/dom/ContainerNodeAlgorithms.h
@@ -96,7 +96,7 @@
         if (next == 0)
             tail = 0;
 
-        if (n->hasChildNodes())
+        if (n->hasChildren())
             Private::addChildNodesToDeletionQueue<GenericNode, GenericNodeContainer>(head, tail, static_cast<GenericNodeContainer&>(*n));
 
         delete n;
diff --git a/Source/core/dom/ContextFeatures.cpp b/Source/core/dom/ContextFeatures.cpp
index 980dde1..377c50e 100644
--- a/Source/core/dom/ContextFeatures.cpp
+++ b/Source/core/dom/ContextFeatures.cpp
@@ -54,21 +54,21 @@
 {
     if (!document)
         return RuntimeEnabledFeatures::dialogElementEnabled();
-    return document->contextFeatures()->isEnabled(document, DialogElement, RuntimeEnabledFeatures::dialogElementEnabled());
+    return document->contextFeatures().isEnabled(document, DialogElement, RuntimeEnabledFeatures::dialogElementEnabled());
 }
 
 bool ContextFeatures::styleScopedEnabled(Document* document)
 {
     if (!document)
         return RuntimeEnabledFeatures::styleScopedEnabled();
-    return document->contextFeatures()->isEnabled(document, StyleScoped, RuntimeEnabledFeatures::styleScopedEnabled());
+    return document->contextFeatures().isEnabled(document, StyleScoped, RuntimeEnabledFeatures::styleScopedEnabled());
 }
 
 bool ContextFeatures::pagePopupEnabled(Document* document)
 {
     if (!document)
         return false;
-    return document->contextFeatures()->isEnabled(document, PagePopup, false);
+    return document->contextFeatures().isEnabled(document, PagePopup, false);
 }
 
 bool ContextFeatures::mutationEventsEnabled(Document* document)
@@ -76,25 +76,25 @@
     ASSERT(document);
     if (!document)
         return true;
-    return document->contextFeatures()->isEnabled(document, MutationEvents, true);
+    return document->contextFeatures().isEnabled(document, MutationEvents, true);
 }
 
 bool ContextFeatures::pushStateEnabled(Document* document)
 {
-    return document->contextFeatures()->isEnabled(document, PushState, true);
+    return document->contextFeatures().isEnabled(document, PushState, true);
 }
 
-void provideContextFeaturesTo(Page* page, ContextFeaturesClient* client)
+void provideContextFeaturesTo(Page& page, ContextFeaturesClient* client)
 {
     RefCountedSupplement<Page, ContextFeatures>::provideTo(page, ContextFeatures::supplementName(), ContextFeatures::create(client));
 }
 
-void provideContextFeaturesToDocumentFrom(Document* document, Page* page)
+void provideContextFeaturesToDocumentFrom(Document& document, Page& page)
 {
     ContextFeatures* provided = static_cast<ContextFeatures*>(RefCountedSupplement<Page, ContextFeatures>::from(page, ContextFeatures::supplementName()));
     if (!provided)
         return;
-    document->setContextFeatures(provided);
+    document.setContextFeatures(*provided);
 }
 
 }
diff --git a/Source/core/dom/ContextFeatures.h b/Source/core/dom/ContextFeatures.h
index 109b781..8868cc8 100644
--- a/Source/core/dom/ContextFeatures.h
+++ b/Source/core/dom/ContextFeatures.h
@@ -85,8 +85,8 @@
     virtual void urlDidChange(Document*) { }
 };
 
-void provideContextFeaturesTo(Page*, ContextFeaturesClient*);
-void provideContextFeaturesToDocumentFrom(Document*, Page*);
+void provideContextFeaturesTo(Page&, ContextFeaturesClient*);
+void provideContextFeaturesToDocumentFrom(Document&, Page&);
 
 inline PassRefPtr<ContextFeatures> ContextFeatures::create(ContextFeaturesClient* client)
 {
diff --git a/Source/core/dom/ContextLifecycleNotifier.cpp b/Source/core/dom/ContextLifecycleNotifier.cpp
index 048978c..9a585d8 100644
--- a/Source/core/dom/ContextLifecycleNotifier.cpp
+++ b/Source/core/dom/ContextLifecycleNotifier.cpp
@@ -86,6 +86,17 @@
     }
 }
 
+void ContextLifecycleNotifier::notifyWillStopActiveDOMObjects()
+{
+    TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
+    ActiveDOMObjectSet::iterator activeObjectsEnd = m_activeDOMObjects.end();
+    for (ActiveDOMObjectSet::iterator iter = m_activeDOMObjects.begin(); iter != activeObjectsEnd; ++iter) {
+        ASSERT((*iter)->executionContext() == context());
+        ASSERT((*iter)->suspendIfNeededCalled());
+        (*iter)->willStop();
+    }
+}
+
 void ContextLifecycleNotifier::notifyStoppingActiveDOMObjects()
 {
     TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverActiveDOMObjects);
diff --git a/Source/core/dom/ContextLifecycleNotifier.h b/Source/core/dom/ContextLifecycleNotifier.h
index 93d8540..f5f7599 100644
--- a/Source/core/dom/ContextLifecycleNotifier.h
+++ b/Source/core/dom/ContextLifecycleNotifier.h
@@ -53,6 +53,7 @@
 
     void notifyResumingActiveDOMObjects();
     void notifySuspendingActiveDOMObjects();
+    void notifyWillStopActiveDOMObjects();
     void notifyStoppingActiveDOMObjects();
 
     bool contains(ActiveDOMObject* object) const { return m_activeDOMObjects.contains(object); }
diff --git a/Source/core/dom/DOMError.h b/Source/core/dom/DOMError.h
index a66d0e2..bd442ed 100644
--- a/Source/core/dom/DOMError.h
+++ b/Source/core/dom/DOMError.h
@@ -29,36 +29,39 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/DOMException.h"
 #include "core/dom/ExceptionCode.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-class DOMError : public RefCounted<DOMError>, public ScriptWrappable {
+class DOMError : public RefCountedWillBeGarbageCollectedFinalized<DOMError>, public ScriptWrappable {
 public:
-    static PassRefPtr<DOMError> create(const String& name)
+    static PassRefPtrWillBeRawPtr<DOMError> create(const String& name)
     {
-        return adoptRef(new DOMError(name));
+        return adoptRefWillBeNoop(new DOMError(name));
     }
-    static PassRefPtr<DOMError> create(const String& name, const String& message)
+    static PassRefPtrWillBeRawPtr<DOMError> create(const String& name, const String& message)
     {
-        return adoptRef(new DOMError(name, message));
+        return adoptRefWillBeNoop(new DOMError(name, message));
     }
 
-    static PassRefPtr<DOMError> create(ExceptionCode ec)
+    static PassRefPtrWillBeRawPtr<DOMError> create(ExceptionCode ec)
     {
-        return adoptRef(new DOMError(DOMException::getErrorName(ec), DOMException::getErrorMessage(ec)));
+        return adoptRefWillBeNoop(new DOMError(DOMException::getErrorName(ec), DOMException::getErrorMessage(ec)));
     }
 
-    static PassRefPtr<DOMError> create(ExceptionCode ec, const String& message)
+    static PassRefPtrWillBeRawPtr<DOMError> create(ExceptionCode ec, const String& message)
     {
-        return adoptRef(new DOMError(DOMException::getErrorName(ec), message));
+        return adoptRefWillBeNoop(new DOMError(DOMException::getErrorName(ec), message));
     }
 
     const String& name() const { return m_name; }
     const String& message() const { return m_message; }
 
+    void trace(Visitor*) { }
+
 protected:
     explicit DOMError(const String& name);
     DOMError(const String& name, const String& message);
diff --git a/Source/core/dom/DOMError.idl b/Source/core/dom/DOMError.idl
index b2ea60f..8e8d494 100644
--- a/Source/core/dom/DOMError.idl
+++ b/Source/core/dom/DOMError.idl
@@ -26,6 +26,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 [
+    WillBeGarbageCollected,
     NoInterfaceObject
 ] interface DOMError {
     readonly attribute DOMString name;
diff --git a/Source/core/dom/DOMImplementation.cpp b/Source/core/dom/DOMImplementation.cpp
index 661d4f5..0bf96bf 100644
--- a/Source/core/dom/DOMImplementation.cpp
+++ b/Source/core/dom/DOMImplementation.cpp
@@ -38,6 +38,8 @@
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/XMLDocument.h"
 #include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLDocument.h"
 #include "core/html/HTMLMediaElement.h"
 #include "core/html/HTMLViewSourceDocument.h"
@@ -46,8 +48,6 @@
 #include "core/html/PluginDocument.h"
 #include "core/html/TextDocument.h"
 #include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/frame/UseCounter.h"
 #include "core/page/Page.h"
 #include "core/svg/SVGDocument.h"
 #include "platform/ContentType.h"
@@ -193,7 +193,7 @@
 {
     AtomicString prefix, localName;
     if (!Document::parseQualifiedName(qualifiedName, prefix, localName, exceptionState))
-        return 0;
+        return nullptr;
 
     return DocumentType::create(&m_document, qualifiedName, publicId, systemId);
 }
@@ -225,7 +225,7 @@
     if (!qualifiedName.isEmpty()) {
         documentElement = doc->createElementNS(namespaceURI, qualifiedName, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return nullptr;
     }
 
     if (doctype)
@@ -349,7 +349,7 @@
     return d.release();
 }
 
-PassRefPtr<Document> DOMImplementation::createDocument(const String& type, Frame* frame, const KURL& url, bool inViewSourceMode)
+PassRefPtr<Document> DOMImplementation::createDocument(const String& type, LocalFrame* frame, const KURL& url, bool inViewSourceMode)
 {
     return createDocument(type, DocumentInit(url, frame), inViewSourceMode);
 }
diff --git a/Source/core/dom/DOMImplementation.h b/Source/core/dom/DOMImplementation.h
index 7a93cc0..429aa8b 100644
--- a/Source/core/dom/DOMImplementation.h
+++ b/Source/core/dom/DOMImplementation.h
@@ -35,7 +35,7 @@
 class DocumentInit;
 class DocumentType;
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class HTMLDocument;
 class KURL;
 class XMLDocument;
@@ -47,7 +47,7 @@
 
     void ref() { m_document.ref(); }
     void deref() { m_document.deref(); }
-    Document* document() { return &m_document; }
+    Document& document() const { return m_document; }
 
     // DOM methods & attributes for DOMImplementation
     static bool hasFeature(const String& feature, const String& version);
@@ -64,7 +64,7 @@
     PassRefPtr<HTMLDocument> createHTMLDocument(const String& title);
 
     // Other methods (not part of DOM)
-    static PassRefPtr<Document> createDocument(const String& mimeType, Frame*, const KURL&, bool inViewSourceMode);
+    static PassRefPtr<Document> createDocument(const String& mimeType, LocalFrame*, const KURL&, bool inViewSourceMode);
     static PassRefPtr<Document> createDocument(const String& mimeType, const DocumentInit&, bool inViewSourceMode);
 
     static bool isXMLMIMEType(const String&);
diff --git a/Source/core/dom/DOMStringList.idl b/Source/core/dom/DOMStringList.idl
index 1c75bcb..06e7f3e 100644
--- a/Source/core/dom/DOMStringList.idl
+++ b/Source/core/dom/DOMStringList.idl
@@ -27,6 +27,5 @@
 ] interface DOMStringList {
     readonly attribute unsigned long length;
     [TreatReturnedNullStringAs=Null] getter DOMString item([Default=Undefined] optional unsigned long index);
-    boolean contains([Default=Undefined] optional DOMString string);
+    [MeasureAs=DOMStringListContains] boolean contains([Default=Undefined] optional DOMString string);
 };
-
diff --git a/Source/core/dom/DOMURL.cpp b/Source/core/dom/DOMURL.cpp
index 8881223..feba9b9 100644
--- a/Source/core/dom/DOMURL.cpp
+++ b/Source/core/dom/DOMURL.cpp
@@ -63,20 +63,24 @@
     }
 }
 
-String DOMURL::createObjectURL(ExecutionContext* executionContext, Blob* blob)
+String DOMURL::createObjectURL(ExecutionContext* executionContext, Blob* blob, ExceptionState& exceptionState)
 {
     if (!executionContext || !blob)
         return String();
-    return createPublicURL(executionContext, blob);
+    if (blob->hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, String(blob->isFile() ? "File" : "Blob") + " has been closed.");
+        return String();
+    }
+    return createPublicURL(executionContext, blob, blob->uuid());
 }
 
-String DOMURL::createPublicURL(ExecutionContext* executionContext, URLRegistrable* registrable)
+String DOMURL::createPublicURL(ExecutionContext* executionContext, URLRegistrable* registrable, const String& uuid)
 {
     KURL publicURL = BlobURL::createPublicURL(executionContext->securityOrigin());
     if (publicURL.isEmpty())
         return String();
 
-    executionContext->publicURLManager().registerURL(executionContext->securityOrigin(), publicURL, registrable);
+    executionContext->publicURLManager().registerURL(executionContext->securityOrigin(), publicURL, registrable, uuid);
 
     return publicURL.string();
 }
@@ -91,4 +95,12 @@
     executionContext->publicURLManager().revoke(url);
 }
 
+void DOMURL::revokeObjectUUID(ExecutionContext* executionContext, const String& uuid)
+{
+    if (!executionContext)
+        return;
+
+    executionContext->publicURLManager().revoke(uuid);
+}
+
 } // namespace WebCore
diff --git a/Source/core/dom/DOMURL.h b/Source/core/dom/DOMURL.h
index 2b112f7..60a4af2 100644
--- a/Source/core/dom/DOMURL.h
+++ b/Source/core/dom/DOMURL.h
@@ -29,6 +29,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/DOMURLUtils.h"
+#include "heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
@@ -42,27 +43,27 @@
 class ExecutionContext;
 class URLRegistrable;
 
-class DOMURL FINAL : public ScriptWrappable, public DOMURLUtils, public RefCounted<DOMURL> {
-
+class DOMURL FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMURL>, public ScriptWrappable, public DOMURLUtils {
 public:
-    static PassRefPtr<DOMURL> create(const String& url, ExceptionState& exceptionState)
+    static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, ExceptionState& exceptionState)
     {
-        return adoptRef(new DOMURL(url, blankURL(), exceptionState));
+        return adoptRefWillBeNoop(new DOMURL(url, blankURL(), exceptionState));
     }
-    static PassRefPtr<DOMURL> create(const String& url, const String& base, ExceptionState& exceptionState)
+    static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, const String& base, ExceptionState& exceptionState)
     {
-        return adoptRef(new DOMURL(url, KURL(KURL(), base), exceptionState));
+        return adoptRefWillBeNoop(new DOMURL(url, KURL(KURL(), base), exceptionState));
     }
-    static PassRefPtr<DOMURL> create(const String& url, PassRefPtr<DOMURL> base, ExceptionState& exceptionState)
+    static PassRefPtrWillBeRawPtr<DOMURL> create(const String& url, PassRefPtrWillBeRawPtr<DOMURL> base, ExceptionState& exceptionState)
     {
         ASSERT(base);
-        return adoptRef(new DOMURL(url, base->m_url, exceptionState));
+        return adoptRefWillBeNoop(new DOMURL(url, base->m_url, exceptionState));
     }
 
-    static String createObjectURL(ExecutionContext*, Blob*);
+    static String createObjectURL(ExecutionContext*, Blob*, ExceptionState&);
     static void revokeObjectURL(ExecutionContext*, const String&);
 
-    static String createPublicURL(ExecutionContext*, URLRegistrable*);
+    static String createPublicURL(ExecutionContext*, URLRegistrable*, const String& uuid = String());
+    static void revokeObjectUUID(ExecutionContext*, const String&);
 
     virtual KURL url() const OVERRIDE { return m_url; }
     virtual void setURL(const KURL& url) OVERRIDE { m_url = url; }
@@ -70,6 +71,8 @@
     virtual String input() const OVERRIDE { return m_input; }
     virtual void setInput(const String&) OVERRIDE;
 
+    void trace(Visitor*) { }
+
 private:
     DOMURL(const String& url, const KURL& base, ExceptionState&);
 
diff --git a/Source/core/dom/DOMURLUtils.cpp b/Source/core/dom/DOMURLUtils.cpp
index 7e1fa19..0ac6d79 100644
--- a/Source/core/dom/DOMURLUtils.cpp
+++ b/Source/core/dom/DOMURLUtils.cpp
@@ -31,54 +31,54 @@
 
 namespace WebCore {
 
-void DOMURLUtils::setHref(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHref(DOMURLUtils& impl, const String& value)
 {
-    impl->setInput(value);
+    impl.setInput(value);
 }
 
-void DOMURLUtils::setProtocol(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setProtocol(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (url.isNull())
         return;
     url.setProtocol(value);
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setUsername(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setUsername(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (url.isNull())
         return;
     url.setUser(value);
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setPassword(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPassword(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (url.isNull())
         return;
     url.setPass(value);
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setHost(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHost(DOMURLUtils& impl, const String& value)
 {
     if (value.isEmpty())
         return;
 
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (!url.canSetHostOrPort())
         return;
 
     url.setHostAndPort(value);
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setHostname(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHostname(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (!url.canSetHostOrPort())
         return;
 
@@ -94,40 +94,40 @@
 
     url.setHost(value.substring(i));
 
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setPort(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPort(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (!url.canSetHostOrPort())
         return;
 
     url.setPort(value);
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setPathname(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setPathname(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (!url.canSetPathname())
         return;
     url.setPath(value);
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setSearch(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setSearch(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (!url.isValid())
         return;
     url.setQuery(value);
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
-void DOMURLUtils::setHash(DOMURLUtils* impl, const String& value)
+void DOMURLUtils::setHash(DOMURLUtils& impl, const String& value)
 {
-    KURL url = impl->url();
+    KURL url = impl.url();
     if (url.isNull())
         return;
 
@@ -136,7 +136,7 @@
     else
         url.setFragmentIdentifier(value);
 
-    impl->setURL(url);
+    impl.setURL(url);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/DOMURLUtils.h b/Source/core/dom/DOMURLUtils.h
index 1987ecd..e871ebf 100644
--- a/Source/core/dom/DOMURLUtils.h
+++ b/Source/core/dom/DOMURLUtils.h
@@ -41,17 +41,17 @@
     virtual void setInput(const String&) = 0;
     virtual ~DOMURLUtils() { };
 
-    static void setHref(DOMURLUtils*, const String&);
+    static void setHref(DOMURLUtils&, const String&);
 
-    static void setProtocol(DOMURLUtils*, const String&);
-    static void setUsername(DOMURLUtils*, const String&);
-    static void setPassword(DOMURLUtils*, const String&);
-    static void setHost(DOMURLUtils*, const String&);
-    static void setHostname(DOMURLUtils*, const String&);
-    static void setPort(DOMURLUtils*, const String&);
-    static void setPathname(DOMURLUtils*, const String&);
-    static void setSearch(DOMURLUtils*, const String&);
-    static void setHash(DOMURLUtils*, const String&);
+    static void setProtocol(DOMURLUtils&, const String&);
+    static void setUsername(DOMURLUtils&, const String&);
+    static void setPassword(DOMURLUtils&, const String&);
+    static void setHost(DOMURLUtils&, const String&);
+    static void setHostname(DOMURLUtils&, const String&);
+    static void setPort(DOMURLUtils&, const String&);
+    static void setPathname(DOMURLUtils&, const String&);
+    static void setSearch(DOMURLUtils&, const String&);
+    static void setHash(DOMURLUtils&, const String&);
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/DOMURLUtilsReadOnly.cpp b/Source/core/dom/DOMURLUtilsReadOnly.cpp
index 15b1268..61dc0ad 100644
--- a/Source/core/dom/DOMURLUtilsReadOnly.cpp
+++ b/Source/core/dom/DOMURLUtilsReadOnly.cpp
@@ -32,11 +32,11 @@
 
 namespace WebCore {
 
-String DOMURLUtilsReadOnly::href(DOMURLUtilsReadOnly* impl)
+String DOMURLUtilsReadOnly::href(DOMURLUtilsReadOnly& impl)
 {
-    const KURL& url = impl->url();
+    const KURL& url = impl.url();
     if (url.isNull())
-        return impl->input();
+        return impl.input();
     return url.string();
 }
 
diff --git a/Source/core/dom/DOMURLUtilsReadOnly.h b/Source/core/dom/DOMURLUtilsReadOnly.h
index 36d6085..7f49e8c 100644
--- a/Source/core/dom/DOMURLUtilsReadOnly.h
+++ b/Source/core/dom/DOMURLUtilsReadOnly.h
@@ -39,37 +39,37 @@
     virtual String input() const = 0;
     virtual ~DOMURLUtilsReadOnly() { };
 
-    static String href(DOMURLUtilsReadOnly*);
+    static String href(DOMURLUtilsReadOnly&);
 
     static String origin(const KURL&);
-    static String origin(DOMURLUtilsReadOnly* impl) { return origin(impl->url()); }
+    static String origin(DOMURLUtilsReadOnly& impl) { return origin(impl.url()); }
 
     static String protocol(const KURL& url) { return url.protocol() + ":"; }
-    static String protocol(DOMURLUtilsReadOnly* impl) { return protocol(impl->url()); }
+    static String protocol(DOMURLUtilsReadOnly& impl) { return protocol(impl.url()); }
 
     static String username(const KURL& url) { return url.user(); }
-    static String username(DOMURLUtilsReadOnly* impl) { return username(impl->url()); }
+    static String username(DOMURLUtilsReadOnly& impl) { return username(impl.url()); }
 
     static String password(const KURL& url) { return url.pass(); }
-    static String password(DOMURLUtilsReadOnly* impl) { return password(impl->url()); }
+    static String password(DOMURLUtilsReadOnly& impl) { return password(impl.url()); }
 
     static String host(const KURL&);
-    static String host(DOMURLUtilsReadOnly* impl) { return host(impl->url()); }
+    static String host(DOMURLUtilsReadOnly& impl) { return host(impl.url()); }
 
     static String hostname(const KURL& url) { return url.host(); }
-    static String hostname(DOMURLUtilsReadOnly* impl) { return hostname(impl->url()); }
+    static String hostname(DOMURLUtilsReadOnly& impl) { return hostname(impl.url()); }
 
     static String port(const KURL&);
-    static String port(DOMURLUtilsReadOnly* impl) { return port(impl->url()); }
+    static String port(DOMURLUtilsReadOnly& impl) { return port(impl.url()); }
 
     static String pathname(const KURL& url) { return url.path(); }
-    static String pathname(DOMURLUtilsReadOnly* impl) { return pathname(impl->url()); }
+    static String pathname(DOMURLUtilsReadOnly& impl) { return pathname(impl.url()); }
 
     static String search(const KURL&);
-    static String search(DOMURLUtilsReadOnly* impl) { return search(impl->url()); }
+    static String search(DOMURLUtilsReadOnly& impl) { return search(impl.url()); }
 
     static String hash(const KURL&);
-    static String hash(DOMURLUtilsReadOnly* impl) { return hash(impl->url()); }
+    static String hash(DOMURLUtilsReadOnly& impl) { return hash(impl.url()); }
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/DatasetDOMStringMap.cpp b/Source/core/dom/DatasetDOMStringMap.cpp
index 14c082d..8690449 100644
--- a/Source/core/dom/DatasetDOMStringMap.cpp
+++ b/Source/core/dom/DatasetDOMStringMap.cpp
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "core/dom/DatasetDOMStringMap.h"
 
-#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/Element.h"
@@ -71,14 +70,9 @@
     return stringBuilder.toString();
 }
 
-static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
+template<typename CharType1, typename CharType2>
+static bool propertyNameMatchesAttributeName(const CharType1* propertyName, const CharType2* attributeName, unsigned propertyLength, unsigned attributeLength)
 {
-    if (!attributeName.startsWith("data-"))
-        return false;
-
-    unsigned propertyLength = propertyName.length();
-    unsigned attributeLength = attributeName.length();
-
     unsigned a = 5;
     unsigned p = 0;
     bool wordBoundary = false;
@@ -97,6 +91,25 @@
     return (a == attributeLength && p == propertyLength);
 }
 
+static bool propertyNameMatchesAttributeName(const String& propertyName, const String& attributeName)
+{
+    if (!attributeName.startsWith("data-"))
+        return false;
+
+    unsigned propertyLength = propertyName.length();
+    unsigned attributeLength = attributeName.length();
+
+    if (propertyName.is8Bit()) {
+        if (attributeName.is8Bit())
+            return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters8(), propertyLength, attributeLength);
+        return propertyNameMatchesAttributeName(propertyName.characters8(), attributeName.characters16(), propertyLength, attributeLength);
+    }
+
+    if (attributeName.is8Bit())
+        return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters8(), propertyLength, attributeLength);
+    return propertyNameMatchesAttributeName(propertyName.characters16(), attributeName.characters16(), propertyLength, attributeLength);
+}
+
 static bool isValidPropertyName(const String& name)
 {
     unsigned length = name.length();
@@ -144,9 +157,9 @@
 
     unsigned length = m_element->attributeCount();
     for (unsigned i = 0; i < length; i++) {
-        const Attribute* attribute = m_element->attributeItem(i);
-        if (isValidAttributeName(attribute->localName()))
-            names.append(convertAttributeNameToPropertyName(attribute->localName()));
+        const Attribute& attribute = m_element->attributeItem(i);
+        if (isValidAttributeName(attribute.localName()))
+            names.append(convertAttributeNameToPropertyName(attribute.localName()));
     }
 }
 
@@ -157,9 +170,9 @@
 
     unsigned length = m_element->attributeCount();
     for (unsigned i = 0; i < length; i++) {
-        const Attribute* attribute = m_element->attributeItem(i);
-        if (propertyNameMatchesAttributeName(name, attribute->localName()))
-            return attribute->value();
+        const Attribute& attribute = m_element->attributeItem(i);
+        if (propertyNameMatchesAttributeName(name, attribute.localName()))
+            return attribute.value();
     }
 
     return String();
@@ -172,8 +185,8 @@
 
     unsigned length = m_element->attributeCount();
     for (unsigned i = 0; i < length; i++) {
-        const Attribute* attribute = m_element->attributeItem(i);
-        if (propertyNameMatchesAttributeName(name, attribute->localName()))
+        const Attribute& attribute = m_element->attributeItem(i);
+        if (propertyNameMatchesAttributeName(name, attribute.localName()))
             return true;
     }
 
@@ -183,7 +196,7 @@
 void DatasetDOMStringMap::setItem(const String& name, const String& value, ExceptionState& exceptionState)
 {
     if (!isValidPropertyName(name)) {
-        exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet(name, "DOMStringMap", "'" + name + "' is not a valid property name."));
+        exceptionState.throwDOMException(SyntaxError, "'" + name + "' is not a valid property name.");
         return;
     }
 
diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
index 13a6cc2..db5f3b0 100644
--- a/Source/core/dom/Document.cpp
+++ b/Source/core/dom/Document.cpp
@@ -109,16 +109,17 @@
 #include "core/events/ScopedEventQueue.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/History.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/PageConsole.h"
 #include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/HTMLAllCollection.h"
 #include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLBaseElement.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLCollection.h"
 #include "core/html/HTMLDialogElement.h"
@@ -126,16 +127,20 @@
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLHeadElement.h"
 #include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLImport.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/html/HTMLMetaElement.h"
 #include "core/html/HTMLNameCollection.h"
 #include "core/html/HTMLScriptElement.h"
 #include "core/html/HTMLStyleElement.h"
+#include "core/html/HTMLTemplateElement.h"
 #include "core/html/HTMLTitleElement.h"
 #include "core/html/PluginDocument.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/html/canvas/CanvasRenderingContext2D.h"
+#include "core/html/canvas/WebGLRenderingContext.h"
 #include "core/html/forms/FormController.h"
+#include "core/html/imports/HTMLImport.h"
 #include "core/html/parser/HTMLDocumentParser.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/html/parser/NestingLevelIncrementer.h"
@@ -173,6 +178,7 @@
 #include "platform/DateComponents.h"
 #include "platform/Language.h"
 #include "platform/TraceEvent.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
 #include "platform/network/HTTPParsers.h"
 #include "platform/scroll/ScrollbarTheme.h"
 #include "platform/text/PlatformLocale.h"
@@ -304,7 +310,7 @@
     return element.document().frame() && element.rootEditableElement();
 }
 
-static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, Frame* targetFrame)
+static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, LocalFrame* targetFrame)
 {
     // targetFrame can be 0 when we're trying to navigate a top-level frame
     // that has a 0 opener.
@@ -312,7 +318,7 @@
         return false;
 
     const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal();
-    for (Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
+    for (LocalFrame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) {
         Document* ancestorDocument = ancestorFrame->document();
         // FIXME: Should be an ASSERT? Frames should alway have documents.
         if (!ancestorDocument)
@@ -332,7 +338,7 @@
     return false;
 }
 
-static void printNavigationErrorMessage(const Frame& frame, const KURL& activeURL, const char* reason)
+static void printNavigationErrorMessage(const LocalFrame& frame, const KURL& activeURL, const char* reason)
 {
     String message = "Unsafe JavaScript attempt to initiate navigation for frame with URL '" + frame.document()->url().string() + "' from frame with URL '" + activeURL.string() + "'. " + reason + "\n";
 
@@ -422,6 +428,7 @@
     , m_visuallyOrdered(false)
     , m_readyState(Complete)
     , m_isParsing(false)
+    , m_historyItemDocumentStateDirty(false)
     , m_gotoAnchorNeededAfterStylesheetsLoad(false)
     , m_containsValidityStyleRules(false)
     , m_updateFocusAppearanceRestoresSelection(false)
@@ -477,7 +484,8 @@
     ScriptWrappable::init(this);
 
     if (m_frame) {
-        provideContextFeaturesToDocumentFrom(this, m_frame->page());
+        ASSERT(m_frame->page());
+        provideContextFeaturesToDocumentFrom(*this, *m_frame->page());
 
         m_fetcher = m_frame->loader().documentLoader()->fetcher();
     }
@@ -545,15 +553,12 @@
         m_import = 0;
     }
 
-    if (m_timeline) {
-        m_timeline->detachFromDocument();
-    }
+    m_timeline->detachFromDocument();
+    m_transitionTimeline->detachFromDocument();
 
-    if (m_transitionTimeline) {
-        m_transitionTimeline->detachFromDocument();
-    }
-
-    m_styleEngine.clear(); // We need to destory CSSFontSelector before destroying m_fetcher.
+    // We need to destroy CSSFontSelector before destroying m_fetcher.
+    if (m_styleEngine)
+        m_styleEngine->detachFromDocument();
 
     if (m_elemSheet)
         m_elemSheet->clearOwnerNode();
@@ -584,12 +589,12 @@
     ASSERT_WITH_SECURITY_IMPLICATION(!m_deletionHasBegun);
     // We must make sure not to be retaining any of our children through
     // these extra pointers or we will create a reference cycle.
-    m_docType = 0;
-    m_focusedElement = 0;
-    m_hoverNode = 0;
-    m_activeHoverElement = 0;
-    m_titleElement = 0;
-    m_documentElement = 0;
+    m_docType = nullptr;
+    m_focusedElement = nullptr;
+    m_hoverNode = nullptr;
+    m_activeHoverElement = nullptr;
+    m_titleElement = nullptr;
+    m_documentElement = nullptr;
     m_contextFeatures = ContextFeatures::defaultSwitch();
     m_userActionElements.documentDidRemoveLastRef();
     m_associatedFormControls.clear();
@@ -620,7 +625,7 @@
     m_scriptedAnimationController.clear();
 
     if (svgExtensions())
-        accessSVGExtensions()->pauseAnimations();
+        accessSVGExtensions().pauseAnimations();
 
     m_lifecycle.advanceTo(DocumentLifecycle::Disposed);
     lifecycleNotifier().notifyDocumentWasDisposed();
@@ -677,16 +682,16 @@
     clearStyleResolver();
 }
 
-DOMImplementation* Document::implementation()
+DOMImplementation& Document::implementation()
 {
     if (!m_implementation)
         m_implementation = DOMImplementation::create(*this);
-    return m_implementation.get();
+    return *m_implementation;
 }
 
 bool Document::hasManifest() const
 {
-    return documentElement() && documentElement()->hasTagName(htmlTag) && documentElement()->hasAttribute(manifestAttr);
+    return isHTMLHtmlElement(documentElement()) && documentElement()->hasAttribute(manifestAttr);
 }
 
 Location* Document::location() const
@@ -694,7 +699,7 @@
     if (!frame())
         return 0;
 
-    return domWindow()->location();
+    return &domWindow()->location();
 }
 
 void Document::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
@@ -713,7 +718,7 @@
 {
     if (!isValidName(name)) {
         exceptionState.throwDOMException(InvalidCharacterError, "The tag name provided ('" + name + "') is not a valid name.");
-        return 0;
+        return nullptr;
     }
 
     if (isXHTMLDocument() || isHTMLDocument())
@@ -726,7 +731,7 @@
 {
     if (!isValidName(localName)) {
         exceptionState.throwDOMException(InvalidCharacterError, "The tag name provided ('" + localName + "') is not a valid name.");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<Element> element;
@@ -736,7 +741,7 @@
     } else {
         element = createElement(localName, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return nullptr;
     }
 
     if (!typeExtension.isEmpty())
@@ -764,7 +769,7 @@
 {
     QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
     if (qName == nullQName())
-        return 0;
+        return nullptr;
 
     return createElement(qName, false);
 }
@@ -773,7 +778,7 @@
 {
     QualifiedName qName(createQualifiedName(namespaceURI, qualifiedName, exceptionState));
     if (qName == nullQName())
-        return 0;
+        return nullptr;
 
     RefPtr<Element> element;
     if (CustomElement::isValidName(qName.localName()) && registrationContext())
@@ -829,7 +834,7 @@
     return 0;
 }
 
-Frame* Document::executingFrame()
+LocalFrame* Document::executingFrame()
 {
     DOMWindow* window = executingWindow();
     if (!window)
@@ -856,11 +861,11 @@
 {
     if (isHTMLDocument()) {
         exceptionState.throwDOMException(NotSupportedError, "This operation is not supported for HTML documents.");
-        return 0;
+        return nullptr;
     }
     if (data.contains("]]>")) {
         exceptionState.throwDOMException(InvalidCharacterError, "String cannot contain ']]>' since that is the end delimiter of a CData section.");
-        return 0;
+        return nullptr;
     }
     return CDATASection::create(*this, data);
 }
@@ -869,11 +874,11 @@
 {
     if (!isValidName(target)) {
         exceptionState.throwDOMException(InvalidCharacterError, "The target provided ('" + target + "') is not a valid name.");
-        return 0;
+        return nullptr;
     }
     if (data.contains("?>")) {
         exceptionState.throwDOMException(InvalidCharacterError, "The data provided ('" + data + "') contains '?>'.");
-        return 0;
+        return nullptr;
     }
     return ProcessingInstruction::create(*this, target, data);
 }
@@ -883,11 +888,25 @@
     return Text::createEditingText(*this, text);
 }
 
+bool Document::importContainerNodeChildren(ContainerNode* oldContainerNode, PassRefPtr<ContainerNode> newContainerNode, ExceptionState& exceptionState)
+{
+    for (Node* oldChild = oldContainerNode->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
+        RefPtr<Node> newChild = importNode(oldChild, true, exceptionState);
+        if (exceptionState.hadException())
+            return false;
+        newContainerNode->appendChild(newChild.release(), exceptionState);
+        if (exceptionState.hadException())
+            return false;
+    }
+
+    return true;
+}
+
 PassRefPtr<Node> Document::importNode(Node* importedNode, bool deep, ExceptionState& exceptionState)
 {
     if (!importedNode) {
-        exceptionState.throwDOMException(NotSupportedError, "The node provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
 
     switch (importedNode->nodeType()) {
@@ -909,21 +928,18 @@
         // oldElement has mismatched prefix/namespace?
         if (!hasValidNamespaceForElements(oldElement->tagQName())) {
             exceptionState.throwDOMException(NamespaceError, "The imported node has an invalid namespace.");
-            return 0;
+            return nullptr;
         }
         RefPtr<Element> newElement = createElement(oldElement->tagQName(), false);
 
         newElement->cloneDataFromElement(*oldElement);
 
         if (deep) {
-            for (Node* oldChild = oldElement->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
-                RefPtr<Node> newChild = importNode(oldChild, true, exceptionState);
-                if (exceptionState.hadException())
-                    return 0;
-                newElement->appendChild(newChild.release(), exceptionState);
-                if (exceptionState.hadException())
-                    return 0;
-            }
+            if (!importContainerNodeChildren(oldElement, newElement, exceptionState))
+                return nullptr;
+            if (isHTMLTemplateElement(*oldElement)
+                && !importContainerNodeChildren(toHTMLTemplateElement(oldElement)->content(), toHTMLTemplateElement(newElement)->content(), exceptionState))
+                return nullptr;
         }
 
         return newElement.release();
@@ -935,37 +951,29 @@
             // ShadowRoot nodes should not be explicitly importable.
             // Either they are imported along with their host node, or created implicitly.
             exceptionState.throwDOMException(NotSupportedError, "The node provided is a shadow root, which may not be imported.");
-            return 0;
+            return nullptr;
         }
         DocumentFragment* oldFragment = toDocumentFragment(importedNode);
         RefPtr<DocumentFragment> newFragment = createDocumentFragment();
-        if (deep) {
-            for (Node* oldChild = oldFragment->firstChild(); oldChild; oldChild = oldChild->nextSibling()) {
-                RefPtr<Node> newChild = importNode(oldChild, true, exceptionState);
-                if (exceptionState.hadException())
-                    return 0;
-                newFragment->appendChild(newChild.release(), exceptionState);
-                if (exceptionState.hadException())
-                    return 0;
-            }
-        }
+        if (deep && !importContainerNodeChildren(oldFragment, newFragment, exceptionState))
+            return nullptr;
 
         return newFragment.release();
     }
     case DOCUMENT_NODE:
         exceptionState.throwDOMException(NotSupportedError, "The node provided is a document, which may not be imported.");
-        return 0;
+        return nullptr;
     }
 
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<Node> Document::adoptNode(PassRefPtr<Node> source, ExceptionState& exceptionState)
 {
     if (!source) {
-        exceptionState.throwDOMException(NotSupportedError, "The node provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
 
     EventQueueScope scope;
@@ -974,7 +982,7 @@
     case DOCUMENT_NODE:
     case DOCUMENT_TYPE_NODE:
         exceptionState.throwDOMException(NotSupportedError, "The node provided is of type '" + source->nodeName() + "', which may not be adopted.");
-        return 0;
+        return nullptr;
     case ATTRIBUTE_NODE: {
         Attr* attr = toAttr(source.get());
         if (attr->ownerElement())
@@ -985,20 +993,20 @@
         if (source->isShadowRoot()) {
             // ShadowRoot cannot disconnect itself from the host node.
             exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a shadow root, which may not be adopted.");
-            return 0;
+            return nullptr;
         }
 
         if (source->isFrameOwnerElement()) {
             HTMLFrameOwnerElement* frameOwnerElement = toHTMLFrameOwnerElement(source.get());
             if (frame() && frame()->tree().isDescendantOf(frameOwnerElement->contentFrame())) {
                 exceptionState.throwDOMException(HierarchyRequestError, "The node provided is a frame which contains this document.");
-                return 0;
+                return nullptr;
             }
         }
         if (source->parentNode()) {
             source->parentNode()->removeChild(source.get(), exceptionState);
             if (exceptionState.hadException())
-                return 0;
+                return nullptr;
         }
     }
 
@@ -1148,7 +1156,7 @@
 
 void Document::setXMLVersion(const String& version, ExceptionState& exceptionState)
 {
-    if (!implementation()->hasFeature("XML", String())) {
+    if (!implementation().hasFeature("XML", String())) {
         exceptionState.throwDOMException(NotSupportedError, "This document does not support XML.");
         return;
     }
@@ -1163,7 +1171,7 @@
 
 void Document::setXMLStandalone(bool standalone, ExceptionState& exceptionState)
 {
-    if (!implementation()->hasFeature("XML", String())) {
+    if (!implementation().hasFeature("XML", String())) {
         exceptionState.throwDOMException(NotSupportedError, "This document does not support XML.");
         return;
     }
@@ -1218,11 +1226,11 @@
 PassRefPtr<Range> Document::caretRangeFromPoint(int x, int y)
 {
     if (!renderView())
-        return 0;
+        return nullptr;
     HitTestResult result = hitTestInDocument(this, x, y);
     RenderObject* renderer = result.renderer();
     if (!renderer)
-        return 0;
+        return nullptr;
 
     Node* node = renderer->node();
     Node* shadowAncestorNode = ancestorInThisScope(node);
@@ -1234,7 +1242,7 @@
 
     PositionWithAffinity positionWithAffinity = renderer->positionForPoint(result.localPoint());
     if (positionWithAffinity.position().isNull())
-        return 0;
+        return nullptr;
 
     Position rangeCompliantPosition = positionWithAffinity.position().parentAnchoredEquivalent();
     return Range::create(*this, rangeCompliantPosition, rangeCompliantPosition);
@@ -1321,7 +1329,7 @@
     // Title set by JavaScript -- overrides any title elements.
     m_titleSetExplicitly = true;
     if (!isHTMLDocument() && !isXHTMLDocument())
-        m_titleElement = 0;
+        m_titleElement = nullptr;
     else if (!m_titleElement) {
         if (HTMLElement* headElement = head()) {
             m_titleElement = HTMLTitleElement::create(*this);
@@ -1329,7 +1337,7 @@
         }
     }
 
-    if (m_titleElement && m_titleElement->hasTagName(titleTag))
+    if (isHTMLTitleElement(m_titleElement))
         toHTMLTitleElement(m_titleElement)->setText(title);
     else
         updateTitle(title);
@@ -1352,19 +1360,14 @@
     if (m_titleElement != titleElement)
         return;
 
-    m_titleElement = 0;
+    m_titleElement = nullptr;
     m_titleSetExplicitly = false;
 
     // FIXME: This is broken for SVG.
     // Update title based on first title element in the head, if one exists.
     if (HTMLElement* headElement = head()) {
-        for (Element* element = ElementTraversal::firstWithin(*headElement); element; element = ElementTraversal::nextSibling(*element)) {
-            if (!element->hasTagName(titleTag))
-                continue;
-            HTMLTitleElement* title = toHTMLTitleElement(element);
+        if (HTMLTitleElement* title = Traversal<HTMLTitleElement>::firstChild(*headElement))
             setTitleElement(title->text(), title);
-            break;
-        }
     }
 
     if (!m_titleElement)
@@ -1426,11 +1429,11 @@
     return DOCUMENT_NODE;
 }
 
-FormController* Document::formController()
+FormController& Document::formController()
 {
     if (!m_formController)
         m_formController = FormController::create();
-    return m_formController.get();
+    return *m_formController;
 }
 
 Vector<String> Document::formElementsState() const
@@ -1444,7 +1447,7 @@
 {
     if (!stateVector.size() && !m_formController)
         return;
-    formController()->setStateForNewFormElements(stateVector);
+    formController().setStateForNewFormElements(stateVector);
 }
 
 FrameView* Document::view() const
@@ -1476,8 +1479,8 @@
 {
     // FIXME: Probably this should be handled within the bindings layer and TypeError should be thrown.
     if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, "The provided node is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
     return NodeIterator::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
 }
@@ -1485,8 +1488,8 @@
 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
 {
     if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, "The provided node is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
     // FIXME: It might be a good idea to emit a warning if |whatToShow| contains a bit that is not defined in
     // NodeFilter.
@@ -1496,8 +1499,8 @@
 PassRefPtr<NodeIterator> Document::createNodeIterator(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState)
 {
     if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, "The provided node is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
     // FIXME: Ditto.
     return NodeIterator::create(root, whatToShow, filter);
@@ -1506,8 +1509,8 @@
 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, ExceptionState& exceptionState)
 {
     if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, "The provided node is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
     return TreeWalker::create(root, NodeFilter::SHOW_ALL, PassRefPtr<NodeFilter>());
 }
@@ -1515,8 +1518,8 @@
 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, ExceptionState& exceptionState)
 {
     if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, "The provided node is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
     return TreeWalker::create(root, whatToShow, PassRefPtr<NodeFilter>());
 }
@@ -1524,8 +1527,8 @@
 PassRefPtr<TreeWalker> Document::createTreeWalker(Node* root, unsigned whatToShow, PassRefPtr<NodeFilter> filter, ExceptionState& exceptionState)
 {
     if (!root) {
-        exceptionState.throwDOMException(NotSupportedError, "The provided node is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
     return TreeWalker::create(root, whatToShow, filter);
 }
@@ -1560,8 +1563,7 @@
 
     ASSERT(shouldCallRecalcStyleForDocument());
 
-    if (!view()->isServicingAnimations())
-        view()->scheduleAnimation();
+    page()->animator().scheduleVisualUpdate();
     m_lifecycle.advanceTo(DocumentLifecycle::StyleRecalcPending);
 
     InspectorInstrumentation::didScheduleStyleRecalculation(this);
@@ -1582,17 +1584,14 @@
 
 void Document::updateStyleInvalidationIfNeeded()
 {
+    if (!isActive())
+        return;
     if (!childNeedsStyleInvalidation())
         return;
     TRACE_EVENT0("webkit", "Document::computeNeedsStyleRecalcState");
-    if (!styleResolver()) {
-        clearChildNeedsStyleInvalidation();
-        return;
-    }
+    ASSERT(styleResolver());
 
-    // FIXME: the style resolver can be deleted at present. Either resolve
-    // crbug.com/335964 or move the invalidation data elsewhere.
-    styleResolver()->ensureRuleFeatureSet().computeStyleInvalidation(*this);
+    styleResolver()->ruleFeatureSet().computeStyleInvalidation(*this);
 }
 
 void Document::updateDistributionForNodeIfNeeded(Node* node)
@@ -1664,28 +1663,32 @@
         documentElement()->setNeedsStyleRecalc(SubtreeStyleChange);
     }
 
+    EOverflow overflowX = OAUTO;
+    EOverflow overflowY = OAUTO;
+    float columnGap = 0;
+    if (overflowStyle) {
+        overflowX = overflowStyle->overflowX();
+        overflowY = overflowStyle->overflowY();
+        // Visible overflow on the viewport is meaningless, and the spec says to treat it as 'auto':
+        if (overflowX == OVISIBLE)
+            overflowX = OAUTO;
+        if (overflowY == OVISIBLE)
+            overflowY = OAUTO;
+        // Column-gap is (ab)used by the current paged overflow implementation (in lack of other
+        // ways to specify gaps between pages), so we have to propagate it too.
+        columnGap = overflowStyle->columnGap();
+    }
+
     RefPtr<RenderStyle> documentStyle = renderView()->style();
     if (documentStyle->writingMode() != rootWritingMode
         || documentStyle->direction() != rootDirection
-        || (overflowStyle && (documentStyle->overflowX() != overflowStyle->overflowX() || documentStyle->overflowY() != overflowStyle->overflowY()))) {
+        || documentStyle->overflowX() != overflowX
+        || documentStyle->overflowY() != overflowY
+        || documentStyle->columnGap() != columnGap) {
         RefPtr<RenderStyle> newStyle = RenderStyle::clone(documentStyle.get());
         newStyle->setWritingMode(rootWritingMode);
         newStyle->setDirection(rootDirection);
-        EOverflow overflowX = OAUTO;
-        EOverflow overflowY = OAUTO;
-        if (overflowStyle) {
-            overflowX = overflowStyle->overflowX();
-            overflowY = overflowStyle->overflowY();
-            // Visible overflow on the viewport is meaningless, and the spec says to treat it as 'auto':
-            if (overflowX == OVISIBLE)
-                overflowX = OAUTO;
-            if (overflowY == OVISIBLE)
-                overflowY = OAUTO;
-
-            // Column-gap is (ab)used by the current paged overflow implementation (in lack of other
-            // ways to specify gaps between pages), so we have to propagate it too.
-            newStyle->setColumnGap(overflowStyle->columnGap());
-        }
+        newStyle->setColumnGap(columnGap);
         newStyle->setOverflowX(overflowX);
         newStyle->setOverflowY(overflowY);
         renderView()->setStyle(newStyle);
@@ -1716,7 +1719,7 @@
 {
     ASSERT(isMainThread());
 
-    if (!shouldCallRecalcStyleForDocument())
+    if (change != Force && !shouldCallRecalcStyleForDocument())
         return;
 
     if (inStyleRecalc())
@@ -1728,8 +1731,8 @@
     RELEASE_ASSERT(!view()->isInPerformLayout());
     RELEASE_ASSERT(!view()->isPainting());
 
-    // Script can run below in PostAttachCallbacks or WidgetUpdates, so protect the Frame.
-    RefPtr<Frame> protect(m_frame);
+    // Script can run below in PostAttachCallbacks or WidgetUpdates, so protect the LocalFrame.
+    RefPtr<LocalFrame> protect(m_frame);
 
     TRACE_EVENT0("webkit", "Document::recalcStyle");
     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "RecalcStyle");
@@ -1746,8 +1749,8 @@
     }
 
     // FIXME: We should update style on our ancestor chain before proceeding
-    // however doing so currently causes several tests to crash, as Frame::setDocument calls Document::attach
-    // before setting the DOMWindow on the Frame, or the SecurityOrigin on the document. The attach, in turn
+    // however doing so currently causes several tests to crash, as LocalFrame::setDocument calls Document::attach
+    // before setting the DOMWindow on the LocalFrame, or the SecurityOrigin on the document. The attach, in turn
     // resolves style (here) and then when we resolve style on the parent chain, we may end up
     // re-attaching our containing iframe, which when asked HTMLFrameElementBase::isURLAllowed
     // hits a null-dereference due to security code always assuming the document has a SecurityOrigin.
@@ -1802,7 +1805,7 @@
         if (m_styleEngine->hasResolver()) {
             // Pseudo element removal and similar may only work with these flags still set. Reset them after the style recalc.
             StyleResolver& resolver = m_styleEngine->ensureResolver();
-            m_styleEngine->resetCSSFeatureFlags(resolver.ensureRuleFeatureSet());
+            m_styleEngine->resetCSSFeatureFlags(resolver.ensureUpdatedRuleFeatureSet());
             resolver.clearStyleSharingList();
         }
 
@@ -1821,8 +1824,6 @@
     if (m_focusedElement && !m_focusedElement->isFocusable())
         clearFocusedElementSoon();
 
-    DocumentAnimations::serviceAfterStyleRecalc(*this);
-
     InspectorInstrumentation::didRecalculateStyle(cookie);
 }
 
@@ -1864,9 +1865,6 @@
     // Only do a layout if changes have occurred that make it necessary.
     if (isActive() && frameView && renderView() && (frameView->layoutPending() || renderView()->needsLayout()))
         frameView->layout();
-
-    if (isActive() && frameView)
-        frameView->partialLayout().reset();
 }
 
 void Document::setNeedsFocusedElementCheck()
@@ -1877,7 +1875,7 @@
 void Document::clearFocusedElementSoon()
 {
     if (!m_clearFocusedElementTimer.isActive())
-        m_clearFocusedElementTimer.startOneShot(0);
+        m_clearFocusedElementTimer.startOneShot(0, FROM_HERE);
 }
 
 void Document::clearFocusedElementTimerFired(Timer<Document>*)
@@ -1886,7 +1884,7 @@
     m_clearFocusedElementTimer.stop();
 
     if (m_focusedElement && !m_focusedElement->isFocusable())
-        setFocusedElement(0);
+        setFocusedElement(nullptr);
 }
 
 void Document::recalcStyleForLayoutIgnoringPendingStylesheets()
@@ -1930,38 +1928,6 @@
         view()->flushAnyPendingPostLayoutTasks();
 }
 
-void Document::partialUpdateLayoutIgnorePendingStylesheets(Node* stopLayoutAtNode)
-{
-    // Non-overlay scrollbars can cause a second layout that is dependent
-    // on a first layout. This is disabled for partial layout for now.
-    if (!RuntimeEnabledFeatures::partialLayoutEnabled() || !ScrollbarTheme::theme()->usesOverlayScrollbars()) {
-        updateLayoutIgnorePendingStylesheets();
-        return;
-    }
-
-    StyleEngine::IgnoringPendingStylesheet ignoring(m_styleEngine.get());
-    recalcStyleForLayoutIgnoringPendingStylesheets();
-
-    if (stopLayoutAtNode) {
-        RenderObject* renderer = stopLayoutAtNode->renderer();
-        bool canPartialLayout = renderer;
-        while (renderer) {
-            if (!renderer->supportsPartialLayout()) {
-                canPartialLayout = false;
-                break;
-            }
-            renderer = renderer->parent();
-        }
-        if (canPartialLayout && view())
-            view()->partialLayout().setStopAtRenderer(stopLayoutAtNode->renderer());
-    }
-
-    updateLayout();
-
-    if (view())
-        view()->partialLayout().reset();
-}
-
 PassRefPtr<RenderStyle> Document::styleForElementIgnoringPendingStylesheets(Element* element)
 {
     ASSERT_ARG(element, element->document() == this);
@@ -2106,7 +2072,7 @@
     m_scriptedAnimationController.clear();
 
     if (svgExtensions())
-        accessSVGExtensions()->pauseAnimations();
+        accessSVGExtensions().pauseAnimations();
 
     // FIXME: This shouldn't be needed once DOMWindow becomes ExecutionContext.
     if (m_domWindow)
@@ -2128,10 +2094,10 @@
     setRenderer(0);
     m_renderView = 0;
 
-    m_hoverNode = 0;
-    m_focusedElement = 0;
-    m_activeHoverElement = 0;
-    m_autofocusElement = 0;
+    m_hoverNode = nullptr;
+    m_focusedElement = nullptr;
+    m_activeHoverElement = nullptr;
+    m_autofocusElement = nullptr;
 
     ContainerNode::detach(context);
 
@@ -2143,7 +2109,7 @@
     if (Document* parentDoc = parentDocument())
         parentDoc->didClearTouchEventHandlers(this);
 
-    // This is required, as our Frame might delete itself as soon as it detaches
+    // This is required, as our LocalFrame might delete itself as soon as it detaches
     // us. However, this violates Node::detach() semantics, as it's never
     // possible to re-attach. Eventually Document::detach() should be renamed,
     // or this setting of the frame to 0 could be made explicit in each of the
@@ -2196,10 +2162,10 @@
 
     // If the renderer is gone then we are in the process of destruction.
     // This method will be called before m_frame = 0.
-    if (!topDocument()->renderView())
+    if (!topDocument().renderView())
         return 0;
 
-    return topDocument()->m_axObjectCache.get();
+    return topDocument().m_axObjectCache.get();
 }
 
 AXObjectCache* Document::axObjectCache() const
@@ -2211,16 +2177,16 @@
     // document.  This is because we need to be able to get from any WebCoreAXObject
     // to any other WebCoreAXObject on the same page.  Using a single cache allows
     // lookups across nested webareas (i.e. multiple documents).
-    Document* topDocument = this->topDocument();
+    Document& topDocument = this->topDocument();
 
     // If the document has already been detached, do not make a new axObjectCache.
-    if (!topDocument->renderView())
+    if (!topDocument.renderView())
         return 0;
 
     ASSERT(topDocument == this || !m_axObjectCache);
-    if (!topDocument->m_axObjectCache)
-        topDocument->m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
-    return topDocument->m_axObjectCache.get();
+    if (!topDocument.m_axObjectCache)
+        topDocument.m_axObjectCache = adoptPtr(new AXObjectCache(topDocument));
+    return topDocument.m_axObjectCache.get();
 }
 
 PassRefPtr<DocumentParser> Document::createParser()
@@ -2237,8 +2203,7 @@
 {
     if (!isHTMLDocument())
         return false;
-    HTMLElement* bodyElement = body();
-    return bodyElement && bodyElement->hasTagName(framesetTag);
+    return isHTMLFrameSetElement(body());
 }
 
 ScriptableDocumentParser* Document::scriptableDocumentParser() const
@@ -2323,9 +2288,9 @@
     if (!documentElement())
         return 0;
 
-    for (Node* child = documentElement()->firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(framesetTag) || child->hasTagName(bodyTag))
-            return toHTMLElement(child);
+    for (HTMLElement* child = Traversal<HTMLElement>::firstWithin(*documentElement()); child; child = Traversal<HTMLElement>::nextSibling(*child)) {
+        if (isHTMLFrameSetElement(*child) || isHTMLBodyElement(*child))
+            return child;
     }
 
     return 0;
@@ -2336,7 +2301,7 @@
     RefPtr<HTMLElement> newBody = prpNewBody;
 
     if (!newBody) {
-        exceptionState.throwDOMException(HierarchyRequestError, "The node provided is invalid.");
+        exceptionState.throwDOMException(HierarchyRequestError, ExceptionMessages::argumentNullOrIncorrectType(1, "HTMLElement"));
         return;
     }
     if (!documentElement()) {
@@ -2344,7 +2309,7 @@
         return;
     }
 
-    if (!newBody->hasTagName(bodyTag) && !newBody->hasTagName(framesetTag)) {
+    if (!isHTMLBodyElement(*newBody) && !isHTMLFrameSetElement(*newBody)) {
         exceptionState.throwDOMException(HierarchyRequestError, "The new body element is of type '" + newBody->tagName() + "'. It must be either a 'BODY' or 'FRAMESET' element.");
         return;
     }
@@ -2365,11 +2330,7 @@
     if (!de)
         return 0;
 
-    for (Node* node = de->firstChild(); node; node = node->nextSibling()) {
-        if (node->hasTagName(headTag))
-            return toHTMLHeadElement(node);
-    }
-    return 0;
+    return Traversal<HTMLHeadElement>::firstChild(*de);
 }
 
 Element* Document::viewportDefiningElement(RenderStyle* rootStyle) const
@@ -2389,7 +2350,7 @@
         if (!rootStyle)
             return 0;
     }
-    if (bodyElement && rootStyle->isOverflowVisible() && rootElement->hasTagName(htmlTag))
+    if (bodyElement && rootStyle->isOverflowVisible() && isHTMLHtmlElement(*rootElement))
         return bodyElement;
     return rootElement;
 }
@@ -2463,7 +2424,7 @@
     // To align the HTML load event and the SVGLoad event for the outermost <svg> element, fire it from
     // here, instead of doing it from SVGElement::finishedParsingChildren.
     if (svgExtensions())
-        accessSVGExtensions()->dispatchSVGLoadEventToOutermostSVGElements();
+        accessSVGExtensions().dispatchSVGLoadEventToOutermostSVGElements();
 
     if (protectedWindow)
         protectedWindow->documentWasClosed();
@@ -2520,7 +2481,7 @@
     }
 
     if (svgExtensions())
-        accessSVGExtensions()->startAnimations();
+        accessSVGExtensions().startAnimations();
 }
 
 bool Document::dispatchBeforeUnloadEvent(Chrome& chrome, bool& didAllowNavigation)
@@ -2563,8 +2524,8 @@
 
     if (m_loadEventProgress >= LoadEventTried && m_loadEventProgress <= UnloadEventInProgress) {
         Element* currentFocusedElement = focusedElement();
-        if (currentFocusedElement && currentFocusedElement->hasTagName(inputTag))
-            toHTMLInputElement(currentFocusedElement)->endEditing();
+        if (isHTMLInputElement(currentFocusedElement))
+            toHTMLInputElement(*currentFocusedElement).endEditing();
         if (m_loadEventProgress < PageHideInProgress) {
             m_loadEventProgress = PageHideInProgress;
             if (DOMWindow* window = domWindow())
@@ -2628,8 +2589,8 @@
     //    (a) Only schedule a layout once the stylesheets are loaded.
     //    (b) Only schedule layout once we have a body element.
 
-    return (haveStylesheetsLoaded() && body())
-        || (documentElement() && !documentElement()->hasTagName(htmlTag));
+    return (haveStylesheetsAndImportsLoaded() && body())
+        || (documentElement() && !isHTMLHtmlElement(*documentElement()));
 }
 
 bool Document::shouldParserYieldAgressivelyBeforeScriptExecution()
@@ -2713,7 +2674,7 @@
 
     m_url = newURL;
     updateBaseURL();
-    contextFeatures()->urlDidChange(this);
+    contextFeatures().urlDidChange(this);
 }
 
 void Document::updateBaseURL()
@@ -2746,10 +2707,8 @@
     if (!equalIgnoringFragmentIdentifier(oldBaseURL, m_baseURL)) {
         // Base URL change changes any relative visited links.
         // FIXME: There are other URLs in the tree that would need to be re-evaluated on dynamic base URL change. Style should be invalidated too.
-        for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element)) {
-            if (element->hasTagName(aTag))
-                toHTMLAnchorElement(element)->invalidateCachedVisitedLinkHash();
-        }
+        for (HTMLAnchorElement* anchor = Traversal<HTMLAnchorElement>::firstWithin(*this); anchor; anchor = Traversal<HTMLAnchorElement>::next(*anchor))
+            anchor->invalidateCachedVisitedLinkHash();
     }
 }
 
@@ -2764,21 +2723,19 @@
     // Find the first href attribute in a base element and the first target attribute in a base element.
     const AtomicString* href = 0;
     const AtomicString* target = 0;
-    for (Element* element = ElementTraversal::firstWithin(*this); element && (!href || !target); element = ElementTraversal::next(*element)) {
-        if (element->hasTagName(baseTag)) {
-            if (!href) {
-                const AtomicString& value = element->fastGetAttribute(hrefAttr);
-                if (!value.isNull())
-                    href = &value;
-            }
-            if (!target) {
-                const AtomicString& value = element->fastGetAttribute(targetAttr);
-                if (!value.isNull())
-                    target = &value;
-            }
-            if (contentSecurityPolicy()->isActive())
-                UseCounter::count(*this, UseCounter::ContentSecurityPolicyWithBaseElement);
+    for (HTMLBaseElement* base = Traversal<HTMLBaseElement>::firstWithin(*this); base && (!href || !target); base = Traversal<HTMLBaseElement>::next(*base)) {
+        if (!href) {
+            const AtomicString& value = base->fastGetAttribute(hrefAttr);
+            if (!value.isNull())
+                href = &value;
         }
+        if (!target) {
+            const AtomicString& value = base->fastGetAttribute(targetAttr);
+            if (!value.isNull())
+                target = &value;
+        }
+        if (contentSecurityPolicy()->isActive())
+            UseCounter::count(*this, UseCounter::ContentSecurityPolicyWithBaseElement);
     }
 
     // FIXME: Since this doesn't share code with completeURL it may not handle encodings correctly.
@@ -2809,7 +2766,7 @@
     frame()->script().disableEval(errorMessage);
 }
 
-bool Document::canNavigate(Frame* targetFrame)
+bool Document::canNavigate(LocalFrame* targetFrame)
 {
     if (!m_frame)
         return false;
@@ -2820,7 +2777,7 @@
     if (!targetFrame)
         return true;
 
-    // Frame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
+    // LocalFrame-busting is generally allowed, but blocked for sandboxed frames lacking the 'allow-top-navigation' flag.
     if (!isSandboxed(SandboxTopNavigation) && targetFrame == m_frame->tree().top())
         return true;
 
@@ -2872,10 +2829,10 @@
     return false;
 }
 
-Frame* Document::findUnsafeParentScrollPropagationBoundary()
+LocalFrame* Document::findUnsafeParentScrollPropagationBoundary()
 {
-    Frame* currentFrame = m_frame;
-    Frame* ancestorFrame = currentFrame->tree().parent();
+    LocalFrame* currentFrame = m_frame;
+    LocalFrame* ancestorFrame = currentFrame->tree().parent();
 
     while (ancestorFrame) {
         if (!ancestorFrame->document()->securityOrigin()->canAccess(securityOrigin()))
@@ -2890,11 +2847,14 @@
 {
     m_needsNotifyRemoveAllPendingStylesheet = false;
 
-    styleResolverChanged(RecalcStyleDeferred, AnalyzedStyleUpdate);
+    styleResolverChanged(RecalcStyleDeferred, hasNodesWithPlaceholderStyle() ? FullStyleUpdate : AnalyzedStyleUpdate);
     executeScriptsWaitingForResourcesIfNeeded();
 
     if (m_gotoAnchorNeededAfterStylesheetsLoad && view())
         view()->scrollToFragment(m_url);
+
+    if (m_import)
+        m_import->didRemoveAllPendingStylesheet();
 }
 
 void Document::executeScriptsWaitingForResourcesIfNeeded()
@@ -2906,11 +2866,11 @@
 }
 
 
-CSSStyleSheet* Document::elementSheet()
+CSSStyleSheet& Document::elementSheet()
 {
     if (!m_elemSheet)
         m_elemSheet = CSSStyleSheet::createInline(this, m_baseURL);
-    return m_elemSheet.get();
+    return *m_elemSheet;
 }
 
 void Document::processHttpEquiv(const AtomicString& equiv, const AtomicString& content, bool inDocumentHeadElement)
@@ -2939,10 +2899,12 @@
 
 void Document::processHttpEquivContentSecurityPolicy(const AtomicString& equiv, const AtomicString& content)
 {
+    if (import() && import()->isChild())
+        return;
     if (equalIgnoringCase(equiv, "content-security-policy"))
-        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Enforce, ContentSecurityPolicy::HeaderSourceMeta);
+        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceMeta);
     else if (equalIgnoringCase(equiv, "content-security-policy-report-only"))
-        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicy::Report, ContentSecurityPolicy::HeaderSourceMeta);
+        contentSecurityPolicy()->didReceiveHeader(content, ContentSecurityPolicyHeaderTypeReport, ContentSecurityPolicyHeaderSourceMeta);
     else
         ASSERT_NOT_REACHED();
 }
@@ -3005,7 +2967,7 @@
 
 void Document::processHttpEquivXFrameOptions(const AtomicString& content)
 {
-    Frame* frame = this->frame();
+    LocalFrame* frame = this->frame();
     if (!frame)
         return;
 
@@ -3095,7 +3057,7 @@
     // See http://www.whatwg.org/specs/web-apps/current-work/#fetching-resources
     // for why we walk the parent chain for srcdoc documents.
     Document* referrerDocument = this;
-    if (Frame* frame = m_frame) {
+    if (LocalFrame* frame = m_frame) {
         while (frame->document()->isSrcdocDocument()) {
             frame = frame->tree().parent();
             // Srcdoc documents cannot be top-level documents, by definition,
@@ -3347,7 +3309,7 @@
         return;
     bool contains = node->containsIncludingShadowDOM(m_focusedElement.get());
     if (contains && (m_focusedElement != node || !amongChildrenOnly))
-        setFocusedElement(0);
+        setFocusedElement(nullptr);
 }
 
 void Document::hoveredNodeDetached(Node* node)
@@ -3416,7 +3378,7 @@
 
     bool focusChangeBlocked = false;
     RefPtr<Element> oldFocusedElement = m_focusedElement;
-    m_focusedElement = 0;
+    m_focusedElement = nullptr;
 
     // Remove focus from the existing focus node (if any)
     if (oldFocusedElement) {
@@ -3435,7 +3397,7 @@
             if (m_focusedElement) {
                 // handler shifted focus
                 focusChangeBlocked = true;
-                newFocusedElement = 0;
+                newFocusedElement = nullptr;
             }
 
             oldFocusedElement->dispatchFocusOutEvent(EventTypeNames::focusout, newFocusedElement.get()); // DOM level 3 name for the bubbling blur event.
@@ -3446,7 +3408,7 @@
             if (m_focusedElement) {
                 // handler shifted focus
                 focusChangeBlocked = true;
-                newFocusedElement = 0;
+                newFocusedElement = nullptr;
             }
         }
 
@@ -3534,7 +3496,7 @@
 
 SetFocusedElementDone:
     updateStyleIfNeeded();
-    if (Frame* frame = this->frame())
+    if (LocalFrame* frame = this->frame())
         frame->selection().didChangeFocus();
     return !focusChangeBlocked;
 }
@@ -3597,7 +3559,7 @@
     }
 }
 
-void Document::nodeChildrenWillBeRemoved(ContainerNode* container)
+void Document::nodeChildrenWillBeRemoved(ContainerNode& container)
 {
     NoEventDispatchAssertion assertNoEventDispatch;
     if (!m_ranges.isEmpty()) {
@@ -3608,12 +3570,12 @@
 
     HashSet<NodeIterator*>::const_iterator nodeIteratorsEnd = m_nodeIterators.end();
     for (HashSet<NodeIterator*>::const_iterator it = m_nodeIterators.begin(); it != nodeIteratorsEnd; ++it) {
-        for (Node* n = container->firstChild(); n; n = n->nextSibling())
+        for (Node* n = container.firstChild(); n; n = n->nextSibling())
             (*it)->nodeWillBeRemoved(*n);
     }
 
-    if (Frame* frame = this->frame()) {
-        for (Node* n = container->firstChild(); n; n = n->nextSibling()) {
+    if (LocalFrame* frame = this->frame()) {
+        for (Node* n = container.firstChild(); n; n = n->nextSibling()) {
             frame->eventHandler().nodeWillBeRemoved(*n);
             frame->selection().nodeWillBeRemoved(*n);
             frame->page()->dragCaretController().nodeWillBeRemoved(*n);
@@ -3633,7 +3595,7 @@
             (*it)->nodeWillBeRemoved(n);
     }
 
-    if (Frame* frame = this->frame()) {
+    if (LocalFrame* frame = this->frame()) {
         frame->eventHandler().nodeWillBeRemoved(n);
         frame->selection().nodeWillBeRemoved(n);
         frame->page()->dragCaretController().nodeWillBeRemoved(n);
@@ -3665,7 +3627,7 @@
     m_markers->shiftMarkers(text, offset + length, 0 - length);
 }
 
-void Document::didMergeTextNodes(Text* oldNode, unsigned offset)
+void Document::didMergeTextNodes(Text& oldNode, unsigned offset)
 {
     if (!m_ranges.isEmpty()) {
         NodeWithIndex oldNodeWithIndex(oldNode);
@@ -3675,12 +3637,12 @@
     }
 
     if (m_frame)
-        m_frame->selection().didMergeTextNodes(*oldNode, offset);
+        m_frame->selection().didMergeTextNodes(oldNode, offset);
 
     // FIXME: This should update markers for spelling and grammar checking.
 }
 
-void Document::didSplitTextNode(Text* oldNode)
+void Document::didSplitTextNode(Text& oldNode)
 {
     if (!m_ranges.isEmpty()) {
         HashSet<Range*>::const_iterator end = m_ranges.end();
@@ -3689,7 +3651,7 @@
     }
 
     if (m_frame)
-        m_frame->selection().didSplitTextNode(*oldNode);
+        m_frame->selection().didSplitTextNode(oldNode);
 
     // FIXME: This should update markers for spelling and grammar checking.
 }
@@ -3744,14 +3706,14 @@
         return event.release();
 
     exceptionState.throwDOMException(NotSupportedError, "The provided event type ('" + eventType + "') is invalid.");
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<Event> Document::createEvent(ExceptionState& exceptionState)
 {
     if (!isSVGDocument()) {
         exceptionState.throwTypeError(ExceptionMessages::notEnoughArguments(1, 0));
-        return 0;
+        return nullptr;
     }
 
     UseCounter::count(this, UseCounter::DocumentCreateEventOptionalArgument);
@@ -3945,7 +3907,7 @@
 
 const KURL& Document::firstPartyForCookies() const
 {
-    return topDocument()->url();
+    return topDocument().url();
 }
 
 static bool isValidNameNonASCII(const LChar* characters, unsigned length)
@@ -4113,7 +4075,7 @@
 
         CString originalBytes = m_titleElement->textContent().latin1();
         OwnPtr<TextCodec> codec = newTextCodec(newData.encoding());
-        String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), true);
+        String correctlyDecodedTitle = codec->decode(originalBytes.data(), originalBytes.length(), DataEOF);
         m_titleElement->setTextContent(correctlyDecodedTitle);
     }
 
@@ -4163,7 +4125,7 @@
 
 static Editor::Command command(Document* document, const String& commandName, bool userInterface = false)
 {
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
     if (!frame || frame->document() != document)
         return Editor::Command();
 
@@ -4233,11 +4195,7 @@
     if (!head())
         return KURL();
 
-    RefPtr<HTMLCollection> children = head()->children();
-    for (unsigned i = 0; Element* child = children->item(i); i++) {
-        if (!child->hasTagName(linkTag))
-            continue;
-        HTMLLinkElement* linkElement = toHTMLLinkElement(child);
+    for (HTMLLinkElement* linkElement = Traversal<HTMLLinkElement>::firstChild(*head()); linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
         if (!equalIgnoringCase(linkElement->type(), openSearchMIMEType) || !equalIgnoringCase(linkElement->rel(), openSearchRelation))
             continue;
         if (linkElement->href().isEmpty())
@@ -4264,7 +4222,7 @@
 {
     ASSERT(!pi->isLoading());
     UseCounter::count(*this, UseCounter::XSLProcessingInstruction);
-    RefPtr<XSLTProcessor> processor = XSLTProcessor::create();
+    RefPtrWillBeRawPtr<XSLTProcessor> processor = XSLTProcessor::create();
     processor->setXSLStyleSheet(toXSLStyleSheet(pi->sheet()));
     String resultMIMEType;
     String newSource;
@@ -4272,7 +4230,7 @@
     if (!processor->transformToString(this, resultMIMEType, newSource, resultEncoding))
         return;
     // FIXME: If the transform failed we should probably report an error (like Mozilla does).
-    Frame* ownerFrame = frame();
+    LocalFrame* ownerFrame = frame();
     processor->createDocumentFromSource(newSource, resultEncoding, resultMIMEType, this, ownerFrame);
     InspectorInstrumentation::frameDocumentUpdated(ownerFrame);
 }
@@ -4285,7 +4243,7 @@
 void Document::setDesignMode(InheritedBool value)
 {
     m_designMode = value;
-    for (Frame* frame = m_frame; frame && frame->document(); frame = frame->tree().traverseNext(m_frame))
+    for (LocalFrame* frame = m_frame; frame && frame->document(); frame = frame->tree().traverseNext(m_frame))
         frame->document()->setNeedsStyleRecalc(SubtreeStyleChange);
 }
 
@@ -4307,20 +4265,21 @@
 {
     if (!m_frame)
         return 0;
-    Frame* parent = m_frame->tree().parent();
+    LocalFrame* parent = m_frame->tree().parent();
     if (!parent)
         return 0;
     return parent->document();
 }
 
-Document* Document::topDocument() const
+Document& Document::topDocument() const
 {
     Document* doc = const_cast<Document*>(this);
     Element* element;
     while ((element = doc->ownerElement()))
         doc = &element->document();
 
-    return doc;
+    ASSERT(doc);
+    return *doc;
 }
 
 WeakPtr<Document> Document::contextDocument()
@@ -4329,14 +4288,14 @@
         return m_contextDocument;
     if (m_frame)
         return m_weakFactory.createWeakPtr();
-    return WeakPtr<Document>(0);
+    return WeakPtr<Document>(nullptr);
 }
 
 PassRefPtr<Attr> Document::createAttribute(const AtomicString& name, ExceptionState& exceptionState)
 {
     AtomicString prefix, localName;
     if (!parseQualifiedName(name, prefix, localName, exceptionState))
-        return 0;
+        return nullptr;
 
     QualifiedName qName(prefix, localName, nullAtom);
 
@@ -4348,21 +4307,21 @@
     return m_svgExtensions.get();
 }
 
-SVGDocumentExtensions* Document::accessSVGExtensions()
+SVGDocumentExtensions& Document::accessSVGExtensions()
 {
     if (!m_svgExtensions)
         m_svgExtensions = adoptPtr(new SVGDocumentExtensions(this));
-    return m_svgExtensions.get();
+    return *m_svgExtensions;
 }
 
 bool Document::hasSVGRootNode() const
 {
-    return documentElement() && documentElement()->hasTagName(SVGNames::svgTag);
+    return isSVGSVGElement(documentElement());
 }
 
 PassRefPtr<HTMLCollection> Document::ensureCachedCollection(CollectionType type)
 {
-    return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(this, type);
+    return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
 }
 
 PassRefPtr<HTMLCollection> Document::images()
@@ -4408,17 +4367,17 @@
 
 PassRefPtr<HTMLCollection> Document::all()
 {
-    return ensureRareData().ensureNodeLists().addCache<HTMLAllCollection>(this, DocAll);
+    return ensureRareData().ensureNodeLists().addCache<HTMLAllCollection>(*this, DocAll);
 }
 
 PassRefPtr<HTMLCollection> Document::windowNamedItems(const AtomicString& name)
 {
-    return ensureRareData().ensureNodeLists().addCache<HTMLNameCollection>(this, WindowNamedItems, name);
+    return ensureRareData().ensureNodeLists().addCache<HTMLNameCollection>(*this, WindowNamedItems, name);
 }
 
 PassRefPtr<HTMLCollection> Document::documentNamedItems(const AtomicString& name)
 {
-    return ensureRareData().ensureNodeLists().addCache<HTMLNameCollection>(this, DocumentNamedItems, name);
+    return ensureRareData().ensureNodeLists().addCache<HTMLNameCollection>(*this, DocumentNamedItems, name);
 }
 
 void Document::finishedParsing()
@@ -4437,7 +4396,7 @@
     // Keep it alive until we are done.
     RefPtr<Document> protect(this);
 
-    if (RefPtr<Frame> f = frame()) {
+    if (RefPtr<LocalFrame> f = frame()) {
         // FrameLoader::finishedParsing() might end up calling Document::implicitClose() if all
         // resource loads are complete. HTMLObjectElements can start loading their resources from
         // post attach callbacks triggered by recalcStyle().  This means if we parse out an <object>
@@ -4456,7 +4415,7 @@
     // so that dynamically inserted content can also benefit from sharing optimizations.
     // Note that we don't refresh the timer on cache access since that could lead to huge caches being kept
     // alive indefinitely by something innocuous like JS setting .innerHTML repeatedly on a timer.
-    m_elementDataCacheClearTimer.startOneShot(10);
+    m_elementDataCacheClearTimer.startOneShot(10, FROM_HERE);
 
     // Parser should have picked up all preloads by now
     m_fetcher->clearPreloads();
@@ -4478,13 +4437,7 @@
     Vector<IconURL> secondaryIcons;
 
     // Start from the last child node so that icons seen later take precedence as required by the spec.
-    RefPtr<HTMLCollection> children = head() ? head()->children() : 0;
-    unsigned length = children ? children->length() : 0;
-    for (unsigned i = 0; i < length; i++) {
-        Element* child = children->item(i);
-        if (!child->hasTagName(linkTag))
-            continue;
-        HTMLLinkElement* linkElement = toHTMLLinkElement(child);
+    for (HTMLLinkElement* linkElement = head() ? Traversal<HTMLLinkElement>::firstChild(*head()) : 0; linkElement; linkElement = Traversal<HTMLLinkElement>::nextSibling(*linkElement)) {
         if (!(linkElement->iconType() & iconTypesMask))
             continue;
         if (linkElement->href().isEmpty())
@@ -4544,6 +4497,13 @@
     initSecurityContext(DocumentInit(m_url, m_frame, contextDocument(), m_import));
 }
 
+static PassRefPtr<ContentSecurityPolicy> contentSecurityPolicyFor(Document* document)
+{
+    if (document->import() && document->import()->isChild())
+        return document->import()->master()->contentSecurityPolicy();
+    return ContentSecurityPolicy::create(document);
+}
+
 void Document::initSecurityContext(const DocumentInit& initializer)
 {
     if (haveInitializedSecurityOrigin()) {
@@ -4565,7 +4525,7 @@
     m_cookieURL = m_url;
     enforceSandboxFlags(initializer.sandboxFlags());
     setSecurityOrigin(isSandboxed(SandboxOrigin) ? SecurityOrigin::createUnique() : SecurityOrigin::create(m_url));
-    setContentSecurityPolicy(ContentSecurityPolicy::create(this));
+    setContentSecurityPolicy(contentSecurityPolicyFor(this));
 
     if (Settings* settings = initializer.settings()) {
         if (!settings->webSecurityEnabled()) {
@@ -4633,7 +4593,7 @@
     // http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#event-handler-attributes
     // Also, if the listening node came from other document, which happens on context-less event dispatching,
     // we also need to ask the owner document of the node.
-    Frame* frame = executingFrame();
+    LocalFrame* frame = executingFrame();
     if (!frame)
         return false;
     if (!frame->script().canExecuteScripts(NotAboutToExecuteScript))
@@ -4649,7 +4609,7 @@
     // FIXME: Eventually we'd like to evaluate scripts which are inserted into a
     // viewless document but this'll do for now.
     // See http://bugs.webkit.org/show_bug.cgi?id=5727
-    Frame* frame = executingFrame();
+    LocalFrame* frame = executingFrame();
     if (!frame)
         return false;
     if (!node->document().executingFrame())
@@ -4681,7 +4641,7 @@
 {
     m_updateFocusAppearanceRestoresSelection = restorePreviousSelection;
     if (!m_updateFocusAppearanceTimer.isActive())
-        m_updateFocusAppearanceTimer.startOneShot(0);
+        m_updateFocusAppearanceTimer.startOneShot(0, FROM_HERE);
 }
 
 void Document::cancelFocusAppearanceUpdate()
@@ -4712,23 +4672,31 @@
     m_ranges.remove(range);
 }
 
-CanvasRenderingContext* Document::getCSSCanvasContext(const String& type, const String& name, int width, int height)
+void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, bool& is2d, RefPtr<CanvasRenderingContext2D>& context2d, bool& is3d, RefPtr<WebGLRenderingContext>& context3d)
 {
-    HTMLCanvasElement* element = getCSSCanvasElement(name);
-    if (!element)
-        return 0;
-    element->setSize(IntSize(width, height));
-    return element->getContext(type);
+    HTMLCanvasElement& element = getCSSCanvasElement(name);
+    element.setSize(IntSize(width, height));
+    CanvasRenderingContext* context = element.getContext(type);
+    if (!context)
+        return;
+
+    if (context->is2d()) {
+        is2d = true;
+        context2d = toCanvasRenderingContext2D(context);
+    } else if (context->is3d()) {
+        is3d = true;
+        context3d = toWebGLRenderingContext(context);
+    }
 }
 
-HTMLCanvasElement* Document::getCSSCanvasElement(const String& name)
+HTMLCanvasElement& Document::getCSSCanvasElement(const String& name)
 {
-    RefPtr<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, 0).storedValue->value;
+    RefPtr<HTMLCanvasElement>& element = m_cssCanvasElements.add(name, nullptr).storedValue->value;
     if (!element) {
         element = HTMLCanvasElement::create(*this);
         element->setAccelerationDisabled(true);
     }
-    return element.get();
+    return *element;
 }
 
 void Document::initDNSPrefetch()
@@ -4763,7 +4731,7 @@
 
 void Document::addMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, ScriptState* state)
 {
-    internalAddMessage(source, level, message, sourceURL, lineNumber, 0, state);
+    internalAddMessage(source, level, message, sourceURL, lineNumber, nullptr, state);
 }
 
 void Document::internalAddMessage(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state)
@@ -4796,7 +4764,7 @@
     }
 
     if (FrameHost* host = frameHost())
-        host->console().addMessage(source, level, message, String(), 0, 0, 0, 0, requestIdentifier);
+        host->console().addMessage(source, level, message, String(), 0, 0, nullptr, 0, requestIdentifier);
 }
 
 // FIXME(crbug.com/305497): This should be removed after ExecutionContext-DOMWindow migration.
@@ -4908,7 +4876,7 @@
     --m_loadEventDelayCount;
 
     if (frame() && !m_loadEventDelayCount && !m_loadEventDelayTimer.isActive())
-        m_loadEventDelayTimer.startOneShot(0);
+        m_loadEventDelayTimer.startOneShot(0, FROM_HERE);
 }
 
 void Document::loadEventDelayTimerFired(Timer<Document>*)
@@ -4921,7 +4889,7 @@
 {
     // FIXME: Remove this timer once we don't need to compute layout to load plugins.
     if (!m_pluginLoadingTimer.isActive())
-        m_pluginLoadingTimer.startOneShot(0);
+        m_pluginLoadingTimer.startOneShot(0, FROM_HERE);
 }
 
 void Document::pluginLoadingTimerFired(Timer<Document>*)
@@ -4959,17 +4927,17 @@
     m_scriptedAnimationController->serviceScriptedAnimations(monotonicAnimationStartTime);
 }
 
-PassRefPtr<Touch> Document::createTouch(DOMWindow* window, EventTarget* target, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const
+PassRefPtrWillBeRawPtr<Touch> Document::createTouch(DOMWindow* window, EventTarget* target, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const
 {
     // FIXME: It's not clear from the documentation at
     // http://developer.apple.com/library/safari/#documentation/UserExperience/Reference/DocumentAdditionsReference/DocumentAdditions/DocumentAdditions.html
     // when this method should throw and nor is it by inspection of iOS behavior. It would be nice to verify any cases where it throws under iOS
     // and implement them here. See https://bugs.webkit.org/show_bug.cgi?id=47819
-    Frame* frame = window ? window->frame() : this->frame();
+    LocalFrame* frame = window ? window->frame() : this->frame();
     return Touch::create(frame, target, identifier, screenX, screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force);
 }
 
-PassRefPtr<TouchList> Document::createTouchList(Vector<RefPtr<Touch> >& touches) const
+PassRefPtrWillBeRawPtr<TouchList> Document::createTouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches) const
 {
     return TouchList::create(touches);
 }
@@ -5072,7 +5040,7 @@
 {
     if (!view())
         return IntSize();
-    return view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
+    return view()->unscaledVisibleContentSize(IncludeScrollbars);
 }
 
 Node* eventTargetNodeForDocument(Document* doc)
@@ -5098,7 +5066,7 @@
 
     LayoutRect visibleContentRect = view()->visibleContentRect();
     for (size_t i = 0; i < quads.size(); ++i) {
-        quads[i].move(-visibleContentRect.x(), -visibleContentRect.y());
+        quads[i].move(-FloatSize(visibleContentRect.x(), visibleContentRect.y()));
         adjustFloatQuadForAbsoluteZoom(quads[i], renderer);
     }
 }
@@ -5109,7 +5077,7 @@
         return;
 
     LayoutRect visibleContentRect = view()->visibleContentRect();
-    rect.move(-visibleContentRect.x(), -visibleContentRect.y());
+    rect.move(-FloatSize(visibleContentRect.x(), visibleContentRect.y()));
     adjustFloatRectForAbsoluteZoom(rect, renderer);
 }
 
@@ -5130,9 +5098,9 @@
     frame()->loader().checkLoadComplete();
 }
 
-void Document::setContextFeatures(PassRefPtr<ContextFeatures> features)
+void Document::setContextFeatures(ContextFeatures& features)
 {
-    m_contextFeatures = features;
+    m_contextFeatures = PassRefPtr<ContextFeatures>(features);
 }
 
 static RenderObject* nearestCommonHoverAncestor(RenderObject* obj1, RenderObject* obj2)
@@ -5173,7 +5141,7 @@
                 m_userActionElements.setInActiveChain(curr->node(), false);
             }
         }
-        setActiveHoverElement(0);
+        setActiveHoverElement(nullptr);
     } else {
         Element* newActiveElement = innerElementInDocument;
         if (!oldActiveElement && newActiveElement && request.active() && !request.touchMove()) {
@@ -5336,7 +5304,7 @@
         return;
     m_associatedFormControls.add(element);
     if (!m_didAssociateFormControlsTimer.isActive())
-        m_didAssociateFormControlsTimer.startOneShot(0);
+        m_didAssociateFormControlsTimer.startOneShot(0, FROM_HERE);
 }
 
 void Document::didAssociateFormControlsTimerFired(Timer<Document>* timer)
@@ -5404,7 +5372,7 @@
 void Document::setAutofocusElement(Element* element)
 {
     if (!element) {
-        m_autofocusElement = 0;
+        m_autofocusElement = nullptr;
         return;
     }
     if (m_hasAutofocused)
@@ -5429,7 +5397,7 @@
         return false;
     if (!page->focusController().isActive() || !page->focusController().isFocused())
         return false;
-    if (Frame* focusedFrame = page->focusController().focusedFrame()) {
+    if (LocalFrame* focusedFrame = page->focusController().focusedFrame()) {
         if (focusedFrame->tree().isDescendantOf(frame()))
             return true;
     }
@@ -5447,4 +5415,38 @@
     Node::defaultEventHandler(event);
 }
 
+template<unsigned type>
+bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
+{
+    if (nodeListCounts[type] && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
+        return true;
+    return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
+}
+
+template<>
+bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
+{
+    return false;
+}
+
+bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const
+{
+    if (attrName)
+        return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListCounts, *attrName);
+
+    for (int type = 0; type < numNodeListInvalidationTypes; type++) {
+        if (m_nodeListCounts[type])
+            return true;
+    }
+
+    return false;
+}
+
+void Document::invalidateNodeListCaches(const QualifiedName* attrName)
+{
+    HashSet<LiveNodeListBase*>::iterator end = m_listsInvalidatedAtDocument.end();
+    for (HashSet<LiveNodeListBase*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)
+        (*it)->invalidateCache(attrName);
+}
+
 } // namespace WebCore
diff --git a/Source/core/dom/Document.h b/Source/core/dom/Document.h
index 43ed676..18e4b8b 100644
--- a/Source/core/dom/Document.h
+++ b/Source/core/dom/Document.h
@@ -31,7 +31,6 @@
 #include "bindings/v8/ScriptValue.h"
 #include "core/animation/css/CSSPendingAnimations.h"
 #include "core/dom/ContainerNode.h"
-#include "core/dom/DOMTimeStamp.h"
 #include "core/dom/DocumentEncodingData.h"
 #include "core/dom/DocumentInit.h"
 #include "core/dom/DocumentLifecycle.h"
@@ -50,6 +49,7 @@
 #include "core/page/FocusType.h"
 #include "core/page/PageVisibilityState.h"
 #include "core/rendering/HitTestRequest.h"
+#include "heap/Handle.h"
 #include "platform/Timer.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/ReferrerPolicy.h"
@@ -69,7 +69,7 @@
 class CSSStyleDeclaration;
 class CSSStyleSheet;
 class CSSStyleSheetResource;
-class CanvasRenderingContext;
+class CanvasRenderingContext2D;
 class CharacterData;
 class Chrome;
 class Comment;
@@ -99,7 +99,7 @@
 class FloatRect;
 class FontFaceSet;
 class FormController;
-class Frame;
+class LocalFrame;
 class FrameHost;
 class FrameView;
 class HTMLAllCollection;
@@ -162,6 +162,7 @@
 class TransformSource;
 class TreeWalker;
 class VisitedLinkState;
+class WebGLRenderingContext;
 class XMLHttpRequest;
 
 struct AnnotatedRegionValue;
@@ -295,7 +296,7 @@
     void setDoctype(PassRefPtr<DocumentType>);
     DocumentType* doctype() const { return m_docType.get(); }
 
-    DOMImplementation* implementation();
+    DOMImplementation& implementation();
 
     Element* documentElement() const
     {
@@ -440,13 +441,12 @@
 
     void evaluateMediaQueryList();
 
-    // Never returns 0.
-    FormController* formController();
+    FormController& formController();
     Vector<String> formElementsState() const;
     void setStateForNewFormElements(const Vector<String>&);
 
     FrameView* view() const; // can be null
-    Frame* frame() const { return m_frame; } // can be null
+    LocalFrame* frame() const { return m_frame; } // can be null
     FrameHost* frameHost() const; // can be null
     Page* page() const; // can be null
     Settings* settings() const; // can be null
@@ -476,7 +476,6 @@
         RunPostLayoutTasksSynchronously,
     };
     void updateLayoutIgnorePendingStylesheets(RunPostLayoutTasks = RunPostLayoutTasksAsyhnchronously);
-    void partialUpdateLayoutIgnorePendingStylesheets(Node*);
     PassRefPtr<RenderStyle> styleForElementIgnoringPendingStylesheets(Element*);
     PassRefPtr<RenderStyle> styleForPage(int pageIndex);
 
@@ -557,10 +556,10 @@
     virtual String userAgent(const KURL&) const OVERRIDE FINAL;
     virtual void disableEval(const String& errorMessage) OVERRIDE FINAL;
 
-    bool canNavigate(Frame* targetFrame);
-    Frame* findUnsafeParentScrollPropagationBoundary();
+    bool canNavigate(LocalFrame* targetFrame);
+    LocalFrame* findUnsafeParentScrollPropagationBoundary();
 
-    CSSStyleSheet* elementSheet();
+    CSSStyleSheet& elementSheet();
 
     virtual PassRefPtr<DocumentParser> createParser();
     DocumentParser* parser() const { return m_parser.get(); }
@@ -597,6 +596,9 @@
     void setParsing(bool);
     bool parsing() const { return m_isParsing; }
 
+    void setHistoryItemDocumentStateDirty(bool dirty) { m_historyItemDocumentStateDirty = dirty; }
+    bool historyItemDocumentStateDirty() const { return m_historyItemDocumentStateDirty; }
+
     bool shouldScheduleLayout();
     bool shouldParserYieldAgressivelyBeforeScriptExecution();
     int elapsedTime() const;
@@ -657,15 +659,15 @@
 
     void updateRangesAfterChildrenChanged(ContainerNode*);
     // nodeChildrenWillBeRemoved is used when removing all node children at once.
-    void nodeChildrenWillBeRemoved(ContainerNode*);
+    void nodeChildrenWillBeRemoved(ContainerNode&);
     // nodeWillBeRemoved is only safe when removing one node at a time.
     void nodeWillBeRemoved(Node&);
     bool canReplaceChild(const Node& newChild, const Node& oldChild) const;
 
     void didInsertText(Node*, unsigned offset, unsigned length);
     void didRemoveText(Node*, unsigned offset, unsigned length);
-    void didMergeTextNodes(Text* oldNode, unsigned offset);
-    void didSplitTextNode(Text* oldNode);
+    void didMergeTextNodes(Text& oldNode, unsigned offset);
+    void didSplitTextNode(Text& oldNode);
 
     void clearDOMWindow() { m_domWindow = 0; }
     DOMWindow* domWindow() const { return m_domWindow; }
@@ -783,7 +785,7 @@
     // have been calculated on the fly (without associating it with the actual element) somewhere.
     Element* viewportDefiningElement(RenderStyle* rootStyle = 0) const;
 
-    DocumentMarkerController* markers() const { return m_markers.get(); }
+    DocumentMarkerController& markers() const { return *m_markers; }
 
     bool directionSetOnDocumentElement() const { return m_directionSetOnDocumentElement; }
     bool writingModeSetOnDocumentElement() const { return m_writingModeSetOnDocumentElement; }
@@ -806,7 +808,7 @@
     bool inDesignMode() const;
 
     Document* parentDocument() const;
-    Document* topDocument() const;
+    Document& topDocument() const;
     WeakPtr<Document> contextDocument();
 
     ScriptRunner* scriptRunner() { return m_scriptRunner.get(); }
@@ -841,8 +843,8 @@
     void cancelFocusAppearanceUpdate();
 
     // Extension for manipulating canvas drawing contexts for use in CSS
-    CanvasRenderingContext* getCSSCanvasContext(const String& type, const String& name, int width, int height);
-    HTMLCanvasElement* getCSSCanvasElement(const String& name);
+    void getCSSCanvasContext(const String& type, const String& name, int width, int height, bool&, RefPtr<CanvasRenderingContext2D>&, bool&, RefPtr<WebGLRenderingContext>&);
+    HTMLCanvasElement& getCSSCanvasElement(const String& name);
 
     bool isDNSPrefetchEnabled() const { return m_isDNSPrefetchEnabled; }
     void parseDNSPrefetchControlHeader(const String&);
@@ -874,7 +876,7 @@
     virtual void removeAllEventListeners() OVERRIDE FINAL;
 
     const SVGDocumentExtensions* svgExtensions();
-    SVGDocumentExtensions* accessSVGExtensions();
+    SVGDocumentExtensions& accessSVGExtensions();
 
     void initSecurityContext();
     void initSecurityContext(const DocumentInit&);
@@ -926,10 +928,10 @@
     bool isDelayingLoadEvent() const { return m_loadEventDelayCount; }
     void loadPluginsSoon();
 
-    PassRefPtr<Touch> createTouch(DOMWindow*, EventTarget*, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const;
-    PassRefPtr<TouchList> createTouchList(Vector<RefPtr<Touch> >&) const;
+    PassRefPtrWillBeRawPtr<Touch> createTouch(DOMWindow*, EventTarget*, int identifier, int pageX, int pageY, int screenX, int screenY, int radiusX, int radiusY, float rotationAngle, float force) const;
+    PassRefPtrWillBeRawPtr<TouchList> createTouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >&) const;
 
-    const DocumentTiming* timing() const { return &m_documentTiming; }
+    const DocumentTiming& timing() const { return m_documentTiming; }
 
     int requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
     void cancelAnimationFrame(int id);
@@ -986,8 +988,8 @@
     void incrementActiveParserCount() { ++m_activeParserCount; }
     void decrementActiveParserCount();
 
-    void setContextFeatures(PassRefPtr<ContextFeatures>);
-    ContextFeatures* contextFeatures() const { return m_contextFeatures.get(); }
+    void setContextFeatures(ContextFeatures&);
+    ContextFeatures& contextFeatures() const { return *m_contextFeatures; }
 
     ElementDataCache* elementDataCache() { return m_elementDataCache.get(); }
 
@@ -1001,8 +1003,8 @@
     Locale& getCachedLocale(const AtomicString& locale = nullAtom);
 
     AnimationClock& animationClock() { return *m_animationClock; }
-    DocumentTimeline* timeline() const { return m_timeline.get(); }
-    DocumentTimeline* transitionTimeline() const { return m_transitionTimeline.get(); }
+    DocumentTimeline& timeline() const { return *m_timeline; }
+    DocumentTimeline& transitionTimeline() const { return *m_transitionTimeline; }
     CSSPendingAnimations& cssPendingAnimations() { return m_cssPendingAnimations; }
 
     void addToTopLayer(Element*, const Element* before = 0);
@@ -1021,7 +1023,7 @@
 
     virtual DOMWindow* executingWindow() OVERRIDE FINAL;
     virtual void userEventWasHandled() OVERRIDE FINAL { resetLastHandledUserGestureTimestamp(); }
-    Frame* executingFrame();
+    LocalFrame* executingFrame();
 
     DocumentLifecycleNotifier& lifecycleNotifier();
     DocumentLifecycle& lifecycle() { return m_lifecycle; }
@@ -1048,6 +1050,8 @@
     // process. See http://crbug.com/339659.
     virtual void defaultEventHandler(Event*) OVERRIDE;
 
+    void updateStyleInvalidationIfNeeded();
+
 protected:
     Document(const DocumentInit&, DocumentClassFlags = DefaultDocumentClass);
 
@@ -1059,6 +1063,8 @@
 
     virtual PassRefPtr<Document> cloneDocumentWithoutChildren();
 
+    bool importContainerNodeChildren(ContainerNode* oldContainerNode, PassRefPtr<ContainerNode> newContainerNode, ExceptionState&);
+
 private:
     friend class Node;
     friend class IgnoreDestructiveWriteCountIncrementer;
@@ -1070,7 +1076,6 @@
     void inheritHtmlAndBodyElementStyles(StyleRecalcChange);
 
     void updateDistributionIfNeeded();
-    void updateStyleInvalidationIfNeeded();
     void updateUseShadowTreesIfNeeded();
 
     void updateStyle(StyleRecalcChange);
@@ -1119,7 +1124,7 @@
     PassRefPtr<HTMLCollection> ensureCachedCollection(CollectionType);
 
     // Note that dispatching a window load event may cause the DOMWindow to be detached from
-    // the Frame, so callers should take a reference to the DOMWindow (which owns us) to
+    // the LocalFrame, so callers should take a reference to the DOMWindow (which owns us) to
     // prevent the Document from getting blown away from underneath them.
     void dispatchWindowLoadEvent();
 
@@ -1154,7 +1159,7 @@
     // do eventually load.
     PendingSheetLayout m_pendingSheetLayout;
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
     DOMWindow* m_domWindow;
     HTMLImport* m_import;
 
@@ -1204,8 +1209,8 @@
 
     MutationObserverOptions m_mutationObserverTypes;
 
-    OwnPtr<StyleEngine> m_styleEngine;
-    RefPtr<StyleSheetList> m_styleSheetList;
+    OwnPtrWillBePersistent<StyleEngine> m_styleEngine;
+    RefPtrWillBePersistent<StyleSheetList> m_styleSheetList;
 
     OwnPtr<FormController> m_formController;
 
@@ -1215,6 +1220,7 @@
     bool m_visuallyOrdered;
     ReadyState m_readyState;
     bool m_isParsing;
+    bool m_historyItemDocumentStateDirty;
 
     bool m_gotoAnchorNeededAfterStylesheetsLoad;
     bool m_isDNSPrefetchEnabled;
@@ -1304,7 +1310,7 @@
     bool m_directionSetOnDocumentElement;
     bool m_writingModeSetOnDocumentElement;
     DocumentTiming m_documentTiming;
-    RefPtr<MediaQueryMatcher> m_mediaQueryMatcher;
+    RefPtrWillBePersistent<MediaQueryMatcher> m_mediaQueryMatcher;
     bool m_writeRecursionIsTooDeep;
     unsigned m_writeRecursionDepth;
 
diff --git a/Source/core/dom/Document.idl b/Source/core/dom/Document.idl
index 158f5bb..e61390b 100644
--- a/Source/core/dom/Document.idl
+++ b/Source/core/dom/Document.idl
@@ -20,6 +20,8 @@
 
 callback CustomElementConstructor = Element ();
 
+typedef (CanvasRenderingContext2D or WebGLRenderingContext) RenderingContext;
+
 [
     SpecialWrapFor=HTMLDocument|XMLDocument
 ] interface Document : Node {
@@ -139,9 +141,9 @@
     // WebKit extensions
 
     [TreatReturnedNullStringAs=Null] readonly attribute DOMString preferredStylesheetSet;
-             [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectedStylesheetSet;
+    [TreatReturnedNullStringAs=Null, TreatNullAs=NullString] attribute DOMString selectedStylesheetSet;
 
-    CanvasRenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
+    RenderingContext getCSSCanvasContext(DOMString contextId, DOMString name, long width, long height);
 
     // HTML 5
     HTMLCollection getElementsByClassName(DOMString classNames);
diff --git a/Source/core/dom/DocumentFullscreen.cpp b/Source/core/dom/DocumentFullscreen.cpp
index 407e55d..b1f88cd 100644
--- a/Source/core/dom/DocumentFullscreen.cpp
+++ b/Source/core/dom/DocumentFullscreen.cpp
@@ -30,47 +30,47 @@
 
 namespace WebCore {
 
-bool DocumentFullscreen::webkitIsFullScreen(Document* document)
+bool DocumentFullscreen::webkitIsFullScreen(Document& document)
 {
     if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
         return fullscreen->webkitIsFullScreen();
     return false;
 }
 
-bool DocumentFullscreen::webkitFullScreenKeyboardInputAllowed(Document* document)
+bool DocumentFullscreen::webkitFullScreenKeyboardInputAllowed(Document& document)
 {
     if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
         return fullscreen->webkitFullScreenKeyboardInputAllowed();
     return false;
 }
 
-Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document* document)
+Element* DocumentFullscreen::webkitCurrentFullScreenElement(Document& document)
 {
     if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
         return fullscreen->webkitCurrentFullScreenElement();
     return 0;
 }
 
-void DocumentFullscreen::webkitCancelFullScreen(Document* document)
+void DocumentFullscreen::webkitCancelFullScreen(Document& document)
 {
-    FullscreenElementStack::from(document)->webkitCancelFullScreen();
+    FullscreenElementStack::from(document).webkitCancelFullScreen();
 }
 
-bool DocumentFullscreen::webkitFullscreenEnabled(Document* document)
+bool DocumentFullscreen::webkitFullscreenEnabled(Document& document)
 {
     return FullscreenElementStack::webkitFullscreenEnabled(document);
 }
 
-Element* DocumentFullscreen::webkitFullscreenElement(Document* document)
+Element* DocumentFullscreen::webkitFullscreenElement(Document& document)
 {
     if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document))
         return fullscreen->webkitFullscreenElement();
     return 0;
 }
 
-void DocumentFullscreen::webkitExitFullscreen(Document* document)
+void DocumentFullscreen::webkitExitFullscreen(Document& document)
 {
-    FullscreenElementStack::from(document)->webkitExitFullscreen();
+    FullscreenElementStack::from(document).webkitExitFullscreen();
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/DocumentFullscreen.h b/Source/core/dom/DocumentFullscreen.h
index ff5338d..01a5ac9 100644
--- a/Source/core/dom/DocumentFullscreen.h
+++ b/Source/core/dom/DocumentFullscreen.h
@@ -33,14 +33,14 @@
 
 class DocumentFullscreen {
 public:
-    static bool webkitIsFullScreen(Document*);
-    static bool webkitFullScreenKeyboardInputAllowed(Document*);
-    static Element* webkitCurrentFullScreenElement(Document*);
-    static void webkitCancelFullScreen(Document*);
+    static bool webkitIsFullScreen(Document&);
+    static bool webkitFullScreenKeyboardInputAllowed(Document&);
+    static Element* webkitCurrentFullScreenElement(Document&);
+    static void webkitCancelFullScreen(Document&);
 
-    static bool webkitFullscreenEnabled(Document*);
-    static Element* webkitFullscreenElement(Document*);
-    static void webkitExitFullscreen(Document*);
+    static bool webkitFullscreenEnabled(Document&);
+    static Element* webkitFullscreenElement(Document&);
+    static void webkitExitFullscreen(Document&);
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/DocumentFullscreen.idl b/Source/core/dom/DocumentFullscreen.idl
index 917d481..6e9a236 100644
--- a/Source/core/dom/DocumentFullscreen.idl
+++ b/Source/core/dom/DocumentFullscreen.idl
@@ -19,9 +19,7 @@
  * Boston, MA 02110-1301, USA.
  */
 
-[
-    RuntimeEnabled=Fullscreen,
-] partial interface Document {
+partial interface Document {
     // Mozilla version
     readonly attribute boolean webkitIsFullScreen;
     readonly attribute boolean webkitFullScreenKeyboardInputAllowed;
diff --git a/Source/core/dom/DocumentInit.cpp b/Source/core/dom/DocumentInit.cpp
index 0c3013a..922ad7e 100644
--- a/Source/core/dom/DocumentInit.cpp
+++ b/Source/core/dom/DocumentInit.cpp
@@ -31,13 +31,13 @@
 #include "RuntimeEnabledFeatures.h"
 #include "core/dom/Document.h"
 #include "core/dom/custom/CustomElementRegistrationContext.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLImportsController.h"
-#include "core/frame/Frame.h"
+#include "core/html/imports/HTMLImportsController.h"
 
 namespace WebCore {
 
-static Document* parentDocument(Frame* frame)
+static Document* parentDocument(LocalFrame* frame)
 {
     if (!frame)
         return 0;
@@ -48,12 +48,12 @@
 }
 
 
-static Document* ownerDocument(Frame* frame)
+static Document* ownerDocument(LocalFrame* frame)
 {
     if (!frame)
         return 0;
 
-    Frame* ownerFrame = frame->tree().parent();
+    LocalFrame* ownerFrame = frame->tree().parent();
     if (!ownerFrame)
         ownerFrame = frame->loader().opener();
     if (!ownerFrame)
@@ -61,7 +61,7 @@
     return ownerFrame->document();
 }
 
-DocumentInit::DocumentInit(const KURL& url, Frame* frame, WeakPtr<Document> contextDocument, HTMLImport* import)
+DocumentInit::DocumentInit(const KURL& url, LocalFrame* frame, WeakPtr<Document> contextDocument, HTMLImport* import)
     : m_url(url)
     , m_frame(frame)
     , m_parent(parentDocument(frame))
@@ -90,7 +90,7 @@
 
 bool DocumentInit::shouldSetURL() const
 {
-    Frame* frame = frameForSecurityContext();
+    LocalFrame* frame = frameForSecurityContext();
     return (frame && frame->ownerElement()) || !m_url.isEmpty();
 }
 
@@ -99,7 +99,7 @@
     return m_parent && m_frame->loader().shouldTreatURLAsSrcdocDocument(m_url);
 }
 
-Frame* DocumentInit::frameForSecurityContext() const
+LocalFrame* DocumentInit::frameForSecurityContext() const
 {
     if (m_frame)
         return m_frame;
@@ -142,7 +142,7 @@
 PassRefPtr<CustomElementRegistrationContext> DocumentInit::registrationContext(Document* document) const
 {
     if (!document->isHTMLDocument() && !document->isXHTMLDocument())
-        return 0;
+        return nullptr;
 
     if (m_createNewRegistrationContext)
         return CustomElementRegistrationContext::create();
diff --git a/Source/core/dom/DocumentInit.h b/Source/core/dom/DocumentInit.h
index 9bc28cd..bd5f7f6 100644
--- a/Source/core/dom/DocumentInit.h
+++ b/Source/core/dom/DocumentInit.h
@@ -39,18 +39,18 @@
 
 class CustomElementRegistrationContext;
 class Document;
-class Frame;
+class LocalFrame;
 class HTMLImport;
 class Settings;
 
 class DocumentInit {
 public:
-    explicit DocumentInit(const KURL& = KURL(), Frame* = 0, WeakPtr<Document> = WeakPtr<Document>(), HTMLImport* = 0);
+    explicit DocumentInit(const KURL& = KURL(), LocalFrame* = 0, WeakPtr<Document> = WeakPtr<Document>(), HTMLImport* = 0);
     DocumentInit(const DocumentInit&);
     ~DocumentInit();
 
     const KURL& url() const { return m_url; }
-    Frame* frame() const { return m_frame; }
+    LocalFrame* frame() const { return m_frame; }
     HTMLImport* import() const { return m_import; }
 
     bool hasSecurityContext() const { return frameForSecurityContext(); }
@@ -62,7 +62,7 @@
     Document* parent() const { return m_parent.get(); }
     Document* owner() const { return m_owner.get(); }
     KURL parentBaseURL() const;
-    Frame* ownerFrame() const;
+    LocalFrame* ownerFrame() const;
     Settings* settings() const;
 
     DocumentInit& withRegistrationContext(CustomElementRegistrationContext*);
@@ -73,10 +73,10 @@
     static DocumentInit fromContext(WeakPtr<Document> contextDocument, const KURL& = KURL());
 
 private:
-    Frame* frameForSecurityContext() const;
+    LocalFrame* frameForSecurityContext() const;
 
     KURL m_url;
-    Frame* m_frame;
+    LocalFrame* m_frame;
     RefPtr<Document> m_parent;
     RefPtr<Document> m_owner;
     WeakPtr<Document> m_contextDocument;
diff --git a/Source/core/dom/DocumentMarker.cpp b/Source/core/dom/DocumentMarker.cpp
index 5796c8e..a37e522 100644
--- a/Source/core/dom/DocumentMarker.cpp
+++ b/Source/core/dom/DocumentMarker.cpp
@@ -117,7 +117,7 @@
     : m_type(type)
     , m_startOffset(startOffset)
     , m_endOffset(endOffset)
-    , m_details(description.isEmpty() ? 0 : DocumentMarkerDescription::create(description))
+    , m_details(description.isEmpty() ? nullptr : DocumentMarkerDescription::create(description))
     , m_hash(0)
 {
 }
@@ -126,7 +126,7 @@
     : m_type(type)
     , m_startOffset(startOffset)
     , m_endOffset(endOffset)
-    , m_details(description.isEmpty() ? 0 : DocumentMarkerDescription::create(description))
+    , m_details(description.isEmpty() ? nullptr : DocumentMarkerDescription::create(description))
     , m_hash(hash)
 {
 }
diff --git a/Source/core/dom/DocumentMarkerControllerTest.cpp b/Source/core/dom/DocumentMarkerControllerTest.cpp
index f7132ed..b218814 100644
--- a/Source/core/dom/DocumentMarkerControllerTest.cpp
+++ b/Source/core/dom/DocumentMarkerControllerTest.cpp
@@ -51,7 +51,7 @@
     virtual void SetUp() OVERRIDE;
 
     Document& document() const { return *m_document; }
-    DocumentMarkerController& markerController() const { return *m_document->markers(); }
+    DocumentMarkerController& markerController() const { return m_document->markers(); }
 
     PassRefPtr<Text> createTextNode(const char*);
     void markNodeContents(PassRefPtr<Node>);
diff --git a/Source/core/dom/DocumentOrderedMap.cpp b/Source/core/dom/DocumentOrderedMap.cpp
index cd28b03..5989a2b 100644
--- a/Source/core/dom/DocumentOrderedMap.cpp
+++ b/Source/core/dom/DocumentOrderedMap.cpp
@@ -41,24 +41,24 @@
 
 using namespace HTMLNames;
 
-inline bool keyMatchesId(StringImpl* key, Element* element)
+inline bool keyMatchesId(StringImpl* key, Element& element)
 {
-    return element->getIdAttribute().impl() == key;
+    return element.getIdAttribute().impl() == key;
 }
 
-inline bool keyMatchesMapName(StringImpl* key, Element* element)
+inline bool keyMatchesMapName(StringImpl* key, Element& element)
 {
-    return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().impl() == key;
+    return isHTMLMapElement(element) && toHTMLMapElement(element).getName().impl() == key;
 }
 
-inline bool keyMatchesLowercasedMapName(StringImpl* key, Element* element)
+inline bool keyMatchesLowercasedMapName(StringImpl* key, Element& element)
 {
-    return element->hasTagName(mapTag) && toHTMLMapElement(element)->getName().lower().impl() == key;
+    return isHTMLMapElement(element) && toHTMLMapElement(element).getName().lower().impl() == key;
 }
 
-inline bool keyMatchesLabelForAttribute(StringImpl* key, Element* element)
+inline bool keyMatchesLabelForAttribute(StringImpl* key, Element& element)
 {
-    return element->hasTagName(labelTag) && element->getAttribute(forAttr).impl() == key;
+    return isHTMLLabelElement(element) && element.getAttribute(forAttr).impl() == key;
 }
 
 void DocumentOrderedMap::add(StringImpl* key, Element* element)
@@ -101,7 +101,7 @@
     }
 }
 
-template<bool keyMatches(StringImpl*, Element*)>
+template<bool keyMatches(StringImpl*, Element&)>
 inline Element* DocumentOrderedMap::get(StringImpl* key, const TreeScope* scope) const
 {
     ASSERT(key);
@@ -117,7 +117,7 @@
 
     // We know there's at least one node that matches; iterate to find the first one.
     for (Element* element = ElementTraversal::firstWithin(scope->rootNode()); element; element = ElementTraversal::next(*element)) {
-        if (!keyMatches(key, element))
+        if (!keyMatches(key, *element))
             continue;
         entry->element = element;
         return element;
@@ -148,7 +148,7 @@
         entry->orderedList.reserveCapacity(entry->count);
         for (Element* element = entry->element ? entry->element : ElementTraversal::firstWithin(scope->rootNode()); entry->orderedList.size() < entry->count; element = ElementTraversal::next(*element)) {
             ASSERT(element);
-            if (!keyMatchesId(key, element))
+            if (!keyMatchesId(key, *element))
                 continue;
             entry->orderedList.uncheckedAppend(element);
         }
diff --git a/Source/core/dom/DocumentOrderedMap.h b/Source/core/dom/DocumentOrderedMap.h
index 19c470e..fdcf438 100644
--- a/Source/core/dom/DocumentOrderedMap.h
+++ b/Source/core/dom/DocumentOrderedMap.h
@@ -55,7 +55,7 @@
     Element* getElementByLabelForAttribute(StringImpl*, const TreeScope*) const;
 
 private:
-    template<bool keyMatches(StringImpl*, Element*)> Element* get(StringImpl*, const TreeScope*) const;
+    template<bool keyMatches(StringImpl*, Element&)> Element* get(StringImpl*, const TreeScope*) const;
 
     struct MapEntry {
         explicit MapEntry(Element* firstElement)
diff --git a/Source/core/dom/DocumentStyleSheetCollection.cpp b/Source/core/dom/DocumentStyleSheetCollection.cpp
index c252e12..7d86028 100644
--- a/Source/core/dom/DocumentStyleSheetCollection.cpp
+++ b/Source/core/dom/DocumentStyleSheetCollection.cpp
@@ -81,6 +81,9 @@
             Document* document = candidate.importedDocument();
             if (!document)
                 continue;
+            if (collector.hasVisited(document))
+                continue;
+            collector.willVisit(document);
             document->styleEngine()->updateStyleSheetsInImport(collector);
             continue;
         }
diff --git a/Source/core/dom/DocumentStyleSheetCollector.cpp b/Source/core/dom/DocumentStyleSheetCollector.cpp
index f3dd8a6..a624b53 100644
--- a/Source/core/dom/DocumentStyleSheetCollector.cpp
+++ b/Source/core/dom/DocumentStyleSheetCollector.cpp
@@ -33,9 +33,10 @@
 
 namespace WebCore {
 
-DocumentStyleSheetCollector::DocumentStyleSheetCollector(Vector<RefPtr<StyleSheet> >& sheetsForList, Vector<RefPtr<CSSStyleSheet> >& activeList)
+DocumentStyleSheetCollector::DocumentStyleSheetCollector(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetsForList, WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeList, HashSet<Document*>& visitedDocuments)
     : m_styleSheetsForStyleSheetList(sheetsForList)
     , m_activeAuthorStyleSheets(activeList)
+    , m_visitedDocuments(visitedDocuments)
 {
 }
 
@@ -43,9 +44,9 @@
 {
 }
 
-void DocumentStyleSheetCollector::appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& sheets)
+void DocumentStyleSheetCollector::appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
 {
-    m_activeAuthorStyleSheets.append(sheets);
+    m_activeAuthorStyleSheets.appendVector(sheets);
 }
 
 void DocumentStyleSheetCollector::appendActiveStyleSheet(CSSStyleSheet* sheet)
@@ -59,12 +60,12 @@
 }
 
 ActiveDocumentStyleSheetCollector::ActiveDocumentStyleSheetCollector(StyleSheetCollection& collection)
-    : DocumentStyleSheetCollector(collection.m_styleSheetsForStyleSheetList, collection.m_activeAuthorStyleSheets)
+    : DocumentStyleSheetCollector(collection.m_styleSheetsForStyleSheetList, collection.m_activeAuthorStyleSheets, m_visitedDocuments)
 {
 }
 
-ImportedDocumentStyleSheetCollector::ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector& collector, Vector<RefPtr<StyleSheet> >& sheetForList)
-    : DocumentStyleSheetCollector(sheetForList, collector.m_activeAuthorStyleSheets)
+ImportedDocumentStyleSheetCollector::ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector& collector, WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetForList)
+    : DocumentStyleSheetCollector(sheetForList, collector.m_activeAuthorStyleSheets, collector.m_visitedDocuments)
 {
 }
 
diff --git a/Source/core/dom/DocumentStyleSheetCollector.h b/Source/core/dom/DocumentStyleSheetCollector.h
index fef627c..531970e 100644
--- a/Source/core/dom/DocumentStyleSheetCollector.h
+++ b/Source/core/dom/DocumentStyleSheetCollector.h
@@ -27,39 +27,52 @@
 #ifndef DocumentStyleSheetCollector_h
 #define DocumentStyleSheetCollector_h
 
+#include "heap/Handle.h"
+#include "wtf/HashSet.h"
 #include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace WebCore {
 
 class CSSStyleSheet;
+class Document;
 class StyleSheet;
 class StyleSheetCollection;
 
 class DocumentStyleSheetCollector {
+    // This class contains references to two on-heap collections, therefore
+    // it's unhealthy to have it anywhere but on the stack, where stack
+    // scanning will keep them alive.
+    STACK_ALLOCATED();
 public:
     friend class ImportedDocumentStyleSheetCollector;
 
-    DocumentStyleSheetCollector(Vector<RefPtr<StyleSheet> >& sheetsForList, Vector<RefPtr<CSSStyleSheet> >& activeList);
+    DocumentStyleSheetCollector(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheetsForList, WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeList, HashSet<Document*>&);
     ~DocumentStyleSheetCollector();
 
-    void appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&);
+    void appendActiveStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
     void appendActiveStyleSheet(CSSStyleSheet*);
     void appendSheetForList(StyleSheet*);
 
+    bool hasVisited(Document* document) const { return m_visitedDocuments.contains(document); }
+    void willVisit(Document* document) { m_visitedDocuments.add(document); }
+
 private:
-    Vector<RefPtr<StyleSheet> >& m_styleSheetsForStyleSheetList;
-    Vector<RefPtr<CSSStyleSheet> >& m_activeAuthorStyleSheets;
+    WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& m_styleSheetsForStyleSheetList;
+    WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& m_activeAuthorStyleSheets;
+    HashSet<Document*>& m_visitedDocuments;
 };
 
 class ActiveDocumentStyleSheetCollector FINAL : public DocumentStyleSheetCollector {
 public:
     ActiveDocumentStyleSheetCollector(StyleSheetCollection&);
+private:
+    HashSet<Document*> m_visitedDocuments;
 };
 
 class ImportedDocumentStyleSheetCollector FINAL : public DocumentStyleSheetCollector {
 public:
-    ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector&, Vector<RefPtr<StyleSheet> >&);
+    ImportedDocumentStyleSheetCollector(DocumentStyleSheetCollector&, WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >&);
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/DocumentType.cpp b/Source/core/dom/DocumentType.cpp
index 7c392a7..e4b02d8 100644
--- a/Source/core/dom/DocumentType.cpp
+++ b/Source/core/dom/DocumentType.cpp
@@ -71,7 +71,7 @@
 
 void DocumentType::removedFrom(ContainerNode* insertionPoint)
 {
-    document().setDoctype(0);
+    document().setDoctype(nullptr);
     Node::removedFrom(insertionPoint);
 }
 
diff --git a/Source/core/dom/DocumentType.idl b/Source/core/dom/DocumentType.idl
index 330aa72..bafdfc7 100644
--- a/Source/core/dom/DocumentType.idl
+++ b/Source/core/dom/DocumentType.idl
@@ -25,8 +25,8 @@
 
     // DOM Level 2
 
-    [TreatReturnedNullStringAs=Null] readonly attribute DOMString publicId;
-    [TreatReturnedNullStringAs=Null] readonly attribute DOMString systemId;
+    readonly attribute DOMString publicId;
+    readonly attribute DOMString systemId;
     [TreatReturnedNullStringAs=Null, MeasureAs=DocumentTypeInternalSubset] readonly attribute DOMString internalSubset; // Removed from DOM4.
 };
 
diff --git a/Source/core/dom/Element.cpp b/Source/core/dom/Element.cpp
index 5f2ae80..1b88ddb 100644
--- a/Source/core/dom/Element.cpp
+++ b/Source/core/dom/Element.cpp
@@ -31,10 +31,12 @@
 #include "SVGNames.h"
 #include "XMLNames.h"
 #include "bindings/v8/Dictionary.h"
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "core/accessibility/AXObjectCache.h"
 #include "core/animation/DocumentTimeline.h"
 #include "core/animation/css/CSSAnimations.h"
+#include "core/css/CSSImageValue.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/CSSValuePool.h"
 #include "core/css/PropertySetCSSStyleDeclaration.h"
@@ -61,6 +63,7 @@
 #include "core/dom/RenderTreeBuilder.h"
 #include "core/dom/ScriptableDocumentParser.h"
 #include "core/dom/SelectorQuery.h"
+#include "core/dom/SiblingRuleHelper.h"
 #include "core/dom/Text.h"
 #include "core/dom/custom/CustomElement.h"
 #include "core/dom/custom/CustomElementRegistrationContext.h"
@@ -72,10 +75,10 @@
 #include "core/editing/markup.h"
 #include "core/events/EventDispatcher.h"
 #include "core/events/FocusEvent.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/ClassList.h"
 #include "core/html/HTMLCollection.h"
 #include "core/html/HTMLDocument.h"
@@ -208,7 +211,7 @@
         detachAllAttrNodesFromElement();
 
     if (hasPendingResources()) {
-        document().accessSVGExtensions()->removeElementFromPendingResources(this);
+        document().accessSVGExtensions().removeElementFromPendingResources(this);
         ASSERT(!hasPendingResources());
     }
 }
@@ -306,12 +309,12 @@
 PassRefPtr<Attr> Element::detachAttribute(size_t index)
 {
     ASSERT(elementData());
-    const Attribute* attribute = elementData()->attributeItem(index);
-    RefPtr<Attr> attrNode = attrIfExists(attribute->name());
+    const Attribute& attribute = elementData()->attributeItem(index);
+    RefPtr<Attr> attrNode = attrIfExists(attribute.name());
     if (attrNode)
         detachAttrNodeAtIndex(attrNode.get(), index);
     else {
-        attrNode = Attr::create(document(), attribute->name(), attribute->value());
+        attrNode = Attr::create(document(), attribute.name(), attribute.value());
         removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
     }
     return attrNode.release();
@@ -322,10 +325,9 @@
     ASSERT(attr);
     ASSERT(elementData());
 
-    const Attribute* attribute = elementData()->attributeItem(index);
-    ASSERT(attribute);
-    ASSERT(attribute->name() == attr->qualifiedName());
-    detachAttrNodeFromElementWithValue(attr, attribute->value());
+    const Attribute& attribute = elementData()->attributeItem(index);
+    ASSERT(attribute.name() == attr->qualifiedName());
+    detachAttrNodeFromElementWithValue(attr, attribute.value());
     removeAttributeInternal(index, NotInSynchronizationOfLazyAttribute);
 }
 
@@ -366,12 +368,12 @@
     return 0;
 }
 
-ActiveAnimations* Element::ensureActiveAnimations()
+ActiveAnimations& Element::ensureActiveAnimations()
 {
     ElementRareData& rareData = ensureElementRareData();
     if (!rareData.activeAnimations())
         rareData.setActiveAnimations(adoptPtr(new ActiveAnimations()));
-    return rareData.activeAnimations();
+    return *rareData.activeAnimations();
 }
 
 bool Element::hasActiveAnimations() const
@@ -554,7 +556,7 @@
 
 int Element::offsetLeft()
 {
-    document().partialUpdateLayoutIgnorePendingStylesheets(this);
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustForLocalZoom(renderer->pixelSnappedOffsetLeft(), *renderer);
     return 0;
@@ -562,7 +564,7 @@
 
 int Element::offsetTop()
 {
-    document().partialUpdateLayoutIgnorePendingStylesheets(this);
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustForLocalZoom(renderer->pixelSnappedOffsetTop(), *renderer);
     return 0;
@@ -577,7 +579,7 @@
             return adjustLayoutUnitForAbsoluteZoom(renderer->fixedOffsetWidth(), *renderer).round();
     }
 
-    document().partialUpdateLayoutIgnorePendingStylesheets(this);
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetWidth(), *renderer).round();
     return 0;
@@ -585,7 +587,7 @@
 
 int Element::offsetHeight()
 {
-    document().partialUpdateLayoutIgnorePendingStylesheets(this);
+    document().updateLayoutIgnorePendingStylesheets();
     if (RenderBoxModelObject* renderer = renderBoxModelObject())
         return adjustLayoutUnitForAbsoluteZoom(renderer->pixelSnappedOffsetHeight(), *renderer).round();
     return 0;
@@ -726,7 +728,7 @@
         if (document().inQuirksMode())
             return;
 
-        Frame* frame = document().frame();
+        LocalFrame* frame = document().frame();
         if (!frame)
             return;
         FrameView* view = frame->view();
@@ -772,7 +774,7 @@
         if (document().inQuirksMode())
             return;
 
-        Frame* frame = document().frame();
+        LocalFrame* frame = document().frame();
         if (!frame)
             return;
         FrameView* view = frame->view();
@@ -932,7 +934,7 @@
     const AtomicString& caseAdjustedLocalName = shouldIgnoreAttributeCase() ? localName.lower() : localName;
 
     size_t index = elementData() ? elementData()->getAttributeItemIndex(caseAdjustedLocalName, false) : kNotFound;
-    const QualifiedName& qName = index != kNotFound ? attributeItem(index)->name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
+    const QualifiedName& qName = index != kNotFound ? attributeItem(index).name() : QualifiedName(nullAtom, caseAdjustedLocalName, nullAtom);
     setAttributeInternal(index, qName, value, NotInSynchronizationOfLazyAttribute);
 }
 
@@ -962,20 +964,20 @@
         return;
     }
 
-    const Attribute* existingAttribute = attributeItem(index);
-    QualifiedName existingAttributeName = existingAttribute->name();
+    const Attribute& existingAttribute = attributeItem(index);
+    QualifiedName existingAttributeName = existingAttribute.name();
 
     if (!inSynchronizationOfLazyAttribute)
-        willModifyAttribute(existingAttributeName, existingAttribute->value(), newValue);
+        willModifyAttribute(existingAttributeName, existingAttribute.value(), newValue);
 
-    if (newValue != existingAttribute->value()) {
+    if (newValue != existingAttribute.value()) {
         // If there is an Attr node hooked to this attribute, the Attr::setValue() call below
         // will write into the ElementData.
         // FIXME: Refactor this so it makes some sense.
-        if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? 0 : attrIfExists(existingAttributeName))
+        if (RefPtr<Attr> attrNode = inSynchronizationOfLazyAttribute ? nullptr : attrIfExists(existingAttributeName))
             attrNode->setValue(newValue);
         else
-            ensureUniqueElementData()->attributeItem(index)->setValue(newValue);
+            ensureUniqueElementData().attributeItem(index).setValue(newValue);
     }
 
     if (!inSynchronizationOfLazyAttribute)
@@ -1026,12 +1028,14 @@
         AtomicString newId = makeIdForStyleResolution(newValue, document().inQuirksMode());
         if (newId != oldId) {
             elementData()->setIdForStyleResolution(newId);
-            shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ensureRuleFeatureSet());
+            shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForIdChange(oldId, newId, styleResolver->ensureUpdatedRuleFeatureSet());
         }
     } else if (name == classAttr) {
         classAttributeChanged(newValue);
     } else if (name == HTMLNames::nameAttr) {
         setHasName(!newValue.isNull());
+    } else if (name == HTMLNames::pseudoAttr) {
+        shouldInvalidateStyle |= testShouldInvalidateStyle && isInShadowTree();
     }
 
     invalidateNodeListCachesInAncestors(&name, this);
@@ -1085,17 +1089,18 @@
     StyleResolver* styleResolver = document().styleResolver();
     bool testShouldInvalidateStyle = inActiveDocument() && styleResolver && styleChangeType() < SubtreeStyleChange;
 
+    ASSERT(elementData());
     if (classStringHasClassName(newClassString)) {
         const bool shouldFoldCase = document().inQuirksMode();
         const SpaceSplitString oldClasses = elementData()->classNames();
         elementData()->setClass(newClassString, shouldFoldCase);
         const SpaceSplitString& newClasses = elementData()->classNames();
         if (testShouldInvalidateStyle)
-            styleResolver->ensureRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, newClasses, this);
+            styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, newClasses, this);
     } else {
         const SpaceSplitString& oldClasses = elementData()->classNames();
         if (testShouldInvalidateStyle)
-            styleResolver->ensureRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, this);
+            styleResolver->ensureUpdatedRuleFeatureSet().scheduleStyleInvalidationForClassChange(oldClasses, this);
         elementData()->clearClass();
     }
 
@@ -1246,11 +1251,12 @@
         return prefix();
 
     if (hasAttributes()) {
-        for (unsigned i = 0; i < attributeCount(); i++) {
-            const Attribute* attr = attributeItem(i);
+        unsigned attributeCount = this->attributeCount();
+        for (unsigned i = 0; i < attributeCount; ++i) {
+            const Attribute& attr = attributeItem(i);
 
-            if (attr->prefix() == xmlnsAtom && attr->value() == namespaceToLocate)
-                return attr->localName();
+            if (attr.prefix() == xmlnsAtom && attr.value() == namespaceToLocate)
+                return attr.localName();
         }
     }
 
@@ -1325,7 +1331,7 @@
     if (!nameValue.isNull())
         updateName(nullAtom, nameValue);
 
-    if (hasTagName(labelTag)) {
+    if (isHTMLLabelElement(*this)) {
         if (scope.shouldCacheLabelsByForAttribute())
             updateLabel(scope, nullAtom, fastGetAttribute(forAttr));
     }
@@ -1359,7 +1365,7 @@
         if (!nameValue.isNull())
             updateName(nameValue, nullAtom);
 
-        if (hasTagName(labelTag)) {
+        if (isHTMLLabelElement(*this)) {
             TreeScope& treeScope = insertionPoint->treeScope();
             if (treeScope.shouldCacheLabelsByForAttribute())
                 updateLabel(treeScope, fastGetAttribute(forAttr), nullAtom);
@@ -1369,7 +1375,7 @@
     ContainerNode::removedFrom(insertionPoint);
     if (wasInDocument) {
         if (hasPendingResources())
-            document().accessSVGExtensions()->removeElementFromPendingResources(this);
+            document().accessSVGExtensions().removeElementFromPendingResources(this);
 
         if (isUpgradedCustomElement())
             CustomElement::didLeaveDocument(this, insertionPoint->document());
@@ -1592,8 +1598,11 @@
     if (localChange == Reattach) {
         AttachContext reattachContext;
         reattachContext.resolvedStyle = newStyle.get();
+        bool rendererWillChange = needsAttach() || renderer();
         reattach(reattachContext);
-        return Reattach;
+        if (rendererWillChange || renderer())
+            return Reattach;
+        return ReattachNoRenderer;
     }
 
     ASSERT(oldStyle);
@@ -1647,7 +1656,7 @@
     updatePseudoElement(BEFORE, change);
 
     if (change < Force && hasRareData() && childNeedsStyleRecalc())
-        checkForChildrenAdjacentRuleChanges();
+        SiblingRuleHelper(this).checkForChildrenAdjacentRuleChanges();
 
     if (change > UpdatePseudoElements || childNeedsStyleRecalc()) {
         // This loop is deliberately backwards because we use insertBefore in the rendering tree, and want to avoid
@@ -1678,36 +1687,6 @@
     updatePseudoElement(BACKDROP, change);
 }
 
-void Element::checkForChildrenAdjacentRuleChanges()
-{
-    bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
-    bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
-
-    if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
-        return;
-
-    unsigned forceCheckOfNextElementCount = 0;
-    bool forceCheckOfAnyElementSibling = false;
-
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (!child->isElementNode())
-            continue;
-        Element* element = toElement(child);
-        bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() >= SubtreeStyleChange;
-
-        if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
-            element->setNeedsStyleRecalc(SubtreeStyleChange);
-
-        if (forceCheckOfNextElementCount)
-            forceCheckOfNextElementCount--;
-
-        if (childRulesChanged && hasDirectAdjacentRules)
-            forceCheckOfNextElementCount = document().styleEngine()->maxDirectAdjacentSelectors();
-
-        forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
-    }
-}
-
 void Element::updateCallbackSelectors(RenderStyle* oldStyle, RenderStyle* newStyle)
 {
     Vector<String> emptyVector;
@@ -1771,7 +1750,7 @@
     // flag is provided for testing how author shadows interact on these elements.
     if (!areAuthorShadowsAllowed() && !RuntimeEnabledFeatures::authorShadowDOMForAnyElementEnabled()) {
         exceptionState.throwDOMException(HierarchyRequestError, "Author-created shadow roots are disabled for this element.");
-        return 0;
+        return nullptr;
     }
 
     return PassRefPtr<ShadowRoot>(ensureShadow().addShadowRoot(*this, ShadowRoot::AuthorShadowRoot));
@@ -1833,7 +1812,7 @@
     if (!style && !styleAffectedByEmpty())
         return;
 
-    if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildNodes())))
+    if (!style || (styleAffectedByEmpty() && (!style->emptyState() || hasChildren())))
         setNeedsStyleRecalc(SubtreeStyleChange);
 }
 
@@ -1973,8 +1952,8 @@
 PassRefPtr<Attr> Element::setAttributeNode(Attr* attrNode, ExceptionState& exceptionState)
 {
     if (!attrNode) {
-        exceptionState.throwDOMException(TypeMismatchError, "The node provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+        return nullptr;
     }
 
     RefPtr<Attr> oldAttrNode = attrIfExists(attrNode->qualifiedName());
@@ -1985,18 +1964,18 @@
     // The DOM user must explicitly clone Attr nodes to re-use them in other elements.
     if (attrNode->ownerElement()) {
         exceptionState.throwDOMException(InUseAttributeError, "The node provided is an attribute node that is already an attribute of another Element; attribute nodes must be explicitly cloned.");
-        return 0;
+        return nullptr;
     }
 
     synchronizeAllAttributes();
-    UniqueElementData* elementData = ensureUniqueElementData();
+    UniqueElementData& elementData = ensureUniqueElementData();
 
-    size_t index = elementData->getAttributeItemIndex(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
+    size_t index = elementData.getAttributeItemIndex(attrNode->qualifiedName(), shouldIgnoreAttributeCase());
     if (index != kNotFound) {
         if (oldAttrNode)
-            detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData->attributeItem(index)->value());
+            detachAttrNodeFromElementWithValue(oldAttrNode.get(), elementData.attributeItem(index).value());
         else
-            oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData->attributeItem(index)->value());
+            oldAttrNode = Attr::create(document(), attrNode->qualifiedName(), elementData.attributeItem(index).value());
     }
 
     setAttributeInternal(index, attrNode->qualifiedName(), attrNode->value(), NotInSynchronizationOfLazyAttribute);
@@ -2011,12 +1990,12 @@
 PassRefPtr<Attr> Element::removeAttributeNode(Attr* attr, ExceptionState& exceptionState)
 {
     if (!attr) {
-        exceptionState.throwDOMException(TypeMismatchError, "The node provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Attr"));
+        return nullptr;
     }
     if (attr->ownerElement() != this) {
         exceptionState.throwDOMException(NotFoundError, "The node provided is owned by another element.");
-        return 0;
+        return nullptr;
     }
 
     ASSERT(document() == attr->document());
@@ -2026,7 +2005,7 @@
     size_t index = elementData()->getAttrIndex(attr);
     if (index == kNotFound) {
         exceptionState.throwDOMException(NotFoundError, "The attribute was not found on this element.");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<Attr> guard(attr);
@@ -2064,10 +2043,10 @@
 {
     ASSERT_WITH_SECURITY_IMPLICATION(index < attributeCount());
 
-    UniqueElementData* elementData = ensureUniqueElementData();
+    UniqueElementData& elementData = ensureUniqueElementData();
 
-    QualifiedName name = elementData->attributeItem(index)->name();
-    AtomicString valueBeingRemoved = elementData->attributeItem(index)->value();
+    QualifiedName name = elementData.attributeItem(index).name();
+    AtomicString valueBeingRemoved = elementData.attributeItem(index).value();
 
     if (!inSynchronizationOfLazyAttribute) {
         if (!valueBeingRemoved.isNull())
@@ -2075,9 +2054,9 @@
     }
 
     if (RefPtr<Attr> attrNode = attrIfExists(name))
-        detachAttrNodeFromElementWithValue(attrNode.get(), elementData->attributeItem(index)->value());
+        detachAttrNodeFromElementWithValue(attrNode.get(), elementData.attributeItem(index).value());
 
-    elementData->removeAttribute(index);
+    elementData.removeAttribute(index);
 
     if (!inSynchronizationOfLazyAttribute)
         didRemoveAttribute(name);
@@ -2087,7 +2066,7 @@
 {
     if (!inSynchronizationOfLazyAttribute)
         willModifyAttribute(name, nullAtom, value);
-    ensureUniqueElementData()->addAttribute(name, value);
+    ensureUniqueElementData().addAttribute(name, value);
     if (!inSynchronizationOfLazyAttribute)
         didAddAttribute(name, value);
 }
@@ -2116,23 +2095,23 @@
 PassRefPtr<Attr> Element::getAttributeNode(const AtomicString& localName)
 {
     if (!elementData())
-        return 0;
+        return nullptr;
     synchronizeAttribute(localName);
     const Attribute* attribute = elementData()->getAttributeItem(localName, shouldIgnoreAttributeCase());
     if (!attribute)
-        return 0;
+        return nullptr;
     return ensureAttr(attribute->name());
 }
 
 PassRefPtr<Attr> Element::getAttributeNodeNS(const AtomicString& namespaceURI, const AtomicString& localName)
 {
     if (!elementData())
-        return 0;
+        return nullptr;
     QualifiedName qName(nullAtom, localName, namespaceURI);
     synchronizeAttribute(qName);
     const Attribute* attribute = elementData()->getAttributeItem(qName);
     if (!attribute)
-        return 0;
+        return nullptr;
     return ensureAttr(attribute->name());
 }
 
@@ -2199,7 +2178,7 @@
 void Element::updateFocusAppearance(bool /*restorePreviousSelection*/)
 {
     if (isRootEditableElement()) {
-        Frame* frame = document().frame();
+        LocalFrame* frame = document().frame();
         if (!frame)
             return;
 
@@ -2223,7 +2202,7 @@
         if (doc.page())
             doc.page()->focusController().setFocusedElement(0, doc.frame());
         else
-            doc.setFocusedElement(0);
+            doc.setFocusedElement(nullptr);
     }
 }
 
@@ -2282,7 +2261,7 @@
 {
     if (RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(html, this, AllowScriptingContent, "innerHTML", exceptionState)) {
         ContainerNode* container = this;
-        if (hasTagName(templateTag))
+        if (isHTMLTemplateElement(*this))
             container = toHTMLTemplateElement(this)->content();
         replaceChildrenWithFragment(container, fragment.release(), exceptionState);
     }
@@ -2461,16 +2440,11 @@
 
 const AtomicString& Element::shadowPseudoId() const
 {
-    if (ShadowRoot* root = containingShadowRoot()) {
-        if (root->type() == ShadowRoot::UserAgentShadowRoot)
-            return fastGetAttribute(pseudoAttr);
-    }
-    return nullAtom;
+    return getAttribute(pseudoAttr);
 }
 
 void Element::setShadowPseudoId(const AtomicString& id)
 {
-    ASSERT(CSSSelector::parsePseudoType(id) == CSSSelector::PseudoWebKitCustomElement || CSSSelector::parsePseudoType(id) == CSSSelector::PseudoUserAgentCustomElement);
     setAttribute(pseudoAttr, id);
 }
 
@@ -2719,8 +2693,10 @@
 {
     if (!hasAttributes())
         return;
+    // attributeCount() cannot be cached before the loop because the attributes
+    // list is altered while iterating.
     for (unsigned i = 0; i < attributeCount(); ++i) {
-        if (RefPtr<Attr> attr = attrIfExists(attributeItem(i)->name()))
+        if (RefPtr<Attr> attr = attrIfExists(attributeItem(i).name()))
             attr->normalize();
     }
 }
@@ -2746,7 +2722,7 @@
         // when RenderObject::isChildAllowed on our parent returns false for the
         // PseudoElement's renderer for each style recalc.
         if (!renderer() || !pseudoElementRendererIsNeeded(renderer()->getCachedPseudoStyle(pseudoId)))
-            elementRareData()->setPseudoElement(pseudoId, 0);
+            elementRareData()->setPseudoElement(pseudoId, nullptr);
     } else if (change >= UpdatePseudoElements) {
         createPseudoElementIfNeeded(pseudoId);
     }
@@ -2791,20 +2767,20 @@
     return selectorQuery->matches(*this);
 }
 
-DOMTokenList* Element::classList()
+DOMTokenList& Element::classList()
 {
     ElementRareData& rareData = ensureElementRareData();
     if (!rareData.classList())
         rareData.setClassList(ClassList::create(this));
-    return rareData.classList();
+    return *rareData.classList();
 }
 
-DOMStringMap* Element::dataset()
+DOMStringMap& Element::dataset()
 {
     ElementRareData& rareData = ensureElementRareData();
     if (!rareData.dataset())
         rareData.setDataset(DatasetDOMStringMap::create(this));
-    return rareData.dataset();
+    return *rareData.dataset();
 }
 
 KURL Element::getURLAttribute(const QualifiedName& name) const
@@ -2869,12 +2845,12 @@
 
 void Element::webkitRequestFullscreen()
 {
-    FullscreenElementStack::from(&document())->requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+    FullscreenElementStack::from(document()).requestFullScreenForElement(this, ALLOW_KEYBOARD_INPUT, FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
 }
 
 void Element::webkitRequestFullScreen(unsigned short flags)
 {
-    FullscreenElementStack::from(&document())->requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
+    FullscreenElementStack::from(document()).requestFullScreenForElement(this, (flags | LEGACY_MOZILLA_REQUEST), FullscreenElementStack::EnforceIFrameAllowFullScreenRequirement);
 }
 
 bool Element::containsFullScreenElement() const
@@ -3011,7 +2987,7 @@
 
 void Element::updateLabel(TreeScope& scope, const AtomicString& oldForAttributeValue, const AtomicString& newForAttributeValue)
 {
-    ASSERT(hasTagName(labelTag));
+    ASSERT(isHTMLLabelElement(this));
 
     if (!inDocument())
         return;
@@ -3027,16 +3003,16 @@
 
 static bool hasSelectorForAttribute(Document* document, const AtomicString& localName)
 {
-    return document->ensureStyleResolver().ensureRuleFeatureSet().hasSelectorForAttribute(localName);
+    return document->ensureStyleResolver().ensureUpdatedRuleFeatureSet().hasSelectorForAttribute(localName);
 }
 
 void Element::willModifyAttribute(const QualifiedName& name, const AtomicString& oldValue, const AtomicString& newValue)
 {
-    if (isIdAttributeName(name))
+    if (isIdAttributeName(name)) {
         updateId(oldValue, newValue);
-    else if (name == HTMLNames::nameAttr)
+    } else if (name == HTMLNames::nameAttr) {
         updateName(oldValue, newValue);
-    else if (name == HTMLNames::forAttr && hasTagName(labelTag)) {
+    } else if (name == HTMLNames::forAttr && isHTMLLabelElement(*this)) {
         TreeScope& scope = treeScope();
         if (scope.shouldCacheLabelsByForAttribute())
             updateLabel(scope, oldValue, newValue);
@@ -3077,6 +3053,33 @@
     dispatchSubtreeModifiedEvent();
 }
 
+static bool needsURLResolutionForInlineStyle(const Element& element, const Document& oldDocument, const Document& newDocument)
+{
+    if (oldDocument == newDocument)
+        return false;
+    if (oldDocument.baseURL() == newDocument.baseURL())
+        return false;
+    const StylePropertySet* style = element.inlineStyle();
+    if (!style)
+        return false;
+    for (unsigned i = 0; i < style->propertyCount(); ++i) {
+        // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+        if (style->propertyAt(i).value()->isImageValue())
+            return true;
+    }
+    return false;
+}
+
+static void reResolveURLsInInlineStyle(const Document& document, MutableStylePropertySet& style)
+{
+    for (unsigned i = 0; i < style.propertyCount(); ++i) {
+        StylePropertySet::PropertyReference property = style.propertyAt(i);
+        // FIXME: Should handle all URL-based properties: CSSImageSetValue, CSSCursorImageValue, etc.
+        if (property.value()->isImageValue())
+            toCSSImageValue(property.value())->reResolveURL(document);
+    }
+}
+
 void Element::didMoveToNewDocument(Document& oldDocument)
 {
     Node::didMoveToNewDocument(oldDocument);
@@ -3090,6 +3093,9 @@
         if (hasClass())
             setAttribute(HTMLNames::classAttr, getClassAttribute());
     }
+
+    if (needsURLResolutionForInlineStyle(*this, oldDocument, document()))
+        reResolveURLsInInlineStyle(document(), ensureMutableInlineStyle());
 }
 
 void Element::updateNamedItemRegistration(const AtomicString& oldName, const AtomicString& newName)
@@ -3122,16 +3128,16 @@
         return collection;
 
     if (type == TableRows) {
-        ASSERT(hasTagName(tableTag));
-        return ensureRareData().ensureNodeLists().addCache<HTMLTableRowsCollection>(this, type);
+        ASSERT(isHTMLTableElement(this));
+        return ensureRareData().ensureNodeLists().addCache<HTMLTableRowsCollection>(*this, type);
     } else if (type == SelectOptions) {
-        ASSERT(hasTagName(selectTag));
-        return ensureRareData().ensureNodeLists().addCache<HTMLOptionsCollection>(this, type);
+        ASSERT(isHTMLSelectElement(this));
+        return ensureRareData().ensureNodeLists().addCache<HTMLOptionsCollection>(*this, type);
     } else if (type == FormControls) {
-        ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag));
-        return ensureRareData().ensureNodeLists().addCache<HTMLFormControlsCollection>(this, type);
+        ASSERT(isHTMLFormElement(this) || isHTMLFieldSetElement(this));
+        return ensureRareData().ensureNodeLists().addCache<HTMLFormControlsCollection>(*this, type);
     }
-    return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(this, type);
+    return ensureRareData().ensureNodeLists().addCache<HTMLCollection>(*this, type);
 }
 
 static void scheduleLayerUpdateCallback(Node* node)
@@ -3170,7 +3176,7 @@
 {
     if (AttrNodeList* attrNodeList = attrNodeListForElement(this))
         return findAttrNodeInList(*attrNodeList, name);
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<Attr> Element::ensureAttr(const QualifiedName& name)
@@ -3207,10 +3213,11 @@
     AttrNodeList* attrNodeList = attrNodeListForElement(this);
     ASSERT(attrNodeList);
 
-    for (unsigned i = 0; i < attributeCount(); ++i) {
-        const Attribute* attribute = attributeItem(i);
-        if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute->name()))
-            attrNode->detachFromElementWithValue(attribute->value());
+    unsigned attributeCount = this->attributeCount();
+    for (unsigned i = 0; i < attributeCount; ++i) {
+        const Attribute& attribute = attributeItem(i);
+        if (RefPtr<Attr> attrNode = findAttrNodeInList(*attrNodeList, attribute.name()))
+            attrNode->detachFromElementWithValue(attribute.value());
     }
 
     removeAttrNodeListForElement(this);
@@ -3230,7 +3237,7 @@
 PassRefPtr<RenderStyle> Element::customStyleForRenderer()
 {
     ASSERT(hasCustomStyleCallbacks());
-    return 0;
+    return nullptr;
 }
 
 void Element::cloneAttributesFromElement(const Element& other)
@@ -3269,14 +3276,15 @@
         && !other.m_elementData->presentationAttributeStyle())
         const_cast<Element&>(other).m_elementData = static_cast<const UniqueElementData*>(other.m_elementData.get())->makeShareableCopy();
 
-    if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity)
+    if (!other.m_elementData->isUnique() && !ownerDocumentsHaveDifferentCaseSensitivity && !needsURLResolutionForInlineStyle(other, other.document(), document()))
         m_elementData = other.m_elementData;
     else
         m_elementData = other.m_elementData->makeUniqueCopy();
 
-    for (unsigned i = 0; i < m_elementData->length(); ++i) {
-        const Attribute* attribute = const_cast<const ElementData*>(m_elementData.get())->attributeItem(i);
-        attributeChangedFromParserOrByCloning(attribute->name(), attribute->value(), ModifiedByCloning);
+    unsigned length = m_elementData->length();
+    for (unsigned i = 0; i < length; ++i) {
+        const Attribute& attribute = m_elementData->attributeItem(i);
+        attributeChangedFromParserOrByCloning(attribute.name(), attribute.value(), ModifiedByCloning);
     }
 }
 
@@ -3296,7 +3304,7 @@
     }
 }
 
-InputMethodContext* Element::inputMethodContext()
+InputMethodContext& Element::inputMethodContext()
 {
     return ensureElementRareData().ensureInputMethodContext(toHTMLElement(this));
 }
@@ -3336,26 +3344,26 @@
 {
     if (!isStyledElement())
         return 0;
-    return ensureElementRareData().ensureInlineCSSStyleDeclaration(this);
+    return &ensureElementRareData().ensureInlineCSSStyleDeclaration(this);
 }
 
-MutableStylePropertySet* Element::ensureMutableInlineStyle()
+MutableStylePropertySet& Element::ensureMutableInlineStyle()
 {
     ASSERT(isStyledElement());
-    RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData()->m_inlineStyle;
+    RefPtr<StylePropertySet>& inlineStyle = ensureUniqueElementData().m_inlineStyle;
     if (!inlineStyle) {
         CSSParserMode mode = (!isHTMLElement() || document().inQuirksMode()) ? HTMLQuirksMode : HTMLStandardMode;
         inlineStyle = MutableStylePropertySet::create(mode);
     } else if (!inlineStyle->isMutable()) {
         inlineStyle = inlineStyle->mutableCopy();
     }
-    return toMutableStylePropertySet(inlineStyle);
+    return *toMutableStylePropertySet(inlineStyle);
 }
 
 void Element::clearMutableInlineStyleIfEmpty()
 {
-    if (ensureMutableInlineStyle()->isEmpty()) {
-        ensureUniqueElementData()->m_inlineStyle.clear();
+    if (ensureMutableInlineStyle().isEmpty()) {
+        ensureUniqueElementData().m_inlineStyle.clear();
     }
 }
 
@@ -3377,7 +3385,7 @@
         inlineStyle = BisonCSSParser::parseInlineStyleDeclaration(newStyleString, this);
     } else {
         ASSERT(inlineStyle->isMutable());
-        static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet()->contents());
+        static_pointer_cast<MutableStylePropertySet>(inlineStyle)->parseDeclaration(newStyleString, document().elementSheet().contents());
     }
 }
 
@@ -3389,7 +3397,7 @@
         startLineNumber = document().scriptableDocumentParser()->lineNumber();
 
     if (newStyleString.isNull()) {
-        ensureUniqueElementData()->m_inlineStyle.clear();
+        ensureUniqueElementData().m_inlineStyle.clear();
     } else if (modificationReason == ModifiedByCloning || document().contentSecurityPolicy()->allowInlineStyle(document().url(), startLineNumber)) {
         setInlineStyleFromString(newStyleString);
     }
@@ -3412,7 +3420,7 @@
 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSValueID identifier, bool important)
 {
     ASSERT(isStyledElement());
-    ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+    ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
     inlineStyleChanged();
     return true;
 }
@@ -3420,7 +3428,7 @@
 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, CSSPropertyID identifier, bool important)
 {
     ASSERT(isStyledElement());
-    ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
+    ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important);
     inlineStyleChanged();
     return true;
 }
@@ -3428,7 +3436,7 @@
 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important)
 {
     ASSERT(isStyledElement());
-    ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createValue(value, unit), important);
+    ensureMutableInlineStyle().setProperty(propertyID, cssValuePool().createValue(value, unit), important);
     inlineStyleChanged();
     return true;
 }
@@ -3436,7 +3444,7 @@
 bool Element::setInlineStyleProperty(CSSPropertyID propertyID, const String& value, bool important)
 {
     ASSERT(isStyledElement());
-    bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document().elementSheet()->contents());
+    bool changes = ensureMutableInlineStyle().setProperty(propertyID, value, important, document().elementSheet().contents());
     if (changes)
         inlineStyleChanged();
     return changes;
@@ -3447,7 +3455,7 @@
     ASSERT(isStyledElement());
     if (!inlineStyle())
         return false;
-    bool changes = ensureMutableInlineStyle()->removeProperty(propertyID);
+    bool changes = ensureMutableInlineStyle().removeProperty(propertyID);
     if (changes)
         inlineStyleChanged();
     return changes;
@@ -3458,16 +3466,16 @@
     ASSERT(isStyledElement());
     if (!inlineStyle())
         return;
-    ensureMutableInlineStyle()->clear();
+    ensureMutableInlineStyle().clear();
     inlineStyleChanged();
 }
 
 void Element::updatePresentationAttributeStyle()
 {
     // ShareableElementData doesn't store presentation attribute style, so make sure we have a UniqueElementData.
-    UniqueElementData* elementData = ensureUniqueElementData();
-    elementData->m_presentationAttributeStyleIsDirty = false;
-    elementData->m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
+    UniqueElementData& elementData = ensureUniqueElementData();
+    elementData.m_presentationAttributeStyleIsDirty = false;
+    elementData.m_presentationAttributeStyle = computePresentationAttributeStyle(*this);
 }
 
 void Element::addPropertyToPresentationAttributeStyle(MutableStylePropertySet* style, CSSPropertyID propertyID, CSSValueID identifier)
@@ -3521,17 +3529,17 @@
     // Turn off style sharing for elements that can gain layers for reasons outside of the style system.
     // See comments in RenderObject::setStyle().
     // FIXME: Why does gaining a layer from outside the style system require disabling sharing?
-    if (hasTagName(iframeTag)
-        || hasTagName(frameTag)
-        || hasTagName(embedTag)
-        || hasTagName(objectTag)
-        || hasTagName(appletTag)
-        || hasTagName(canvasTag))
+    if (isHTMLIFrameElement(*this)
+        || isHTMLFrameElement(*this)
+        || isHTMLEmbedElement(*this)
+        || isHTMLObjectElement(*this)
+        || isHTMLAppletElement(*this)
+        || isHTMLCanvasElement(*this))
         return false;
     // FIXME: We should share style for option and optgroup whenever possible.
     // Before doing so, we need to resolve issues in HTMLSelectElement::recalcListItems
     // and RenderMenuList::setText. See also https://bugs.webkit.org/show_bug.cgi?id=88405
-    if (hasTagName(optionTag) || hasTagName(optgroupTag))
+    if (isHTMLOptionElement(*this) || isHTMLOptGroupElement(*this))
         return false;
     if (FullscreenElementStack::isActiveFullScreenElement(this))
         return false;
diff --git a/Source/core/dom/Element.h b/Source/core/dom/Element.h
index 742ebf4..ff846f4 100644
--- a/Source/core/dom/Element.h
+++ b/Source/core/dom/Element.h
@@ -154,9 +154,10 @@
     const AtomicString& idForStyleResolution() const;
 
     // Internal methods that assume the existence of attribute storage, one should use hasAttributes()
-    // before calling them.
+    // before calling them. This is not a trivial getter and its return value should be cached for
+    // performance.
     size_t attributeCount() const;
-    const Attribute* attributeItem(unsigned index) const;
+    const Attribute& attributeItem(unsigned index) const;
     const Attribute* getAttributeItem(const QualifiedName&) const;
     size_t getAttributeItemIndex(const QualifiedName& name) const { return elementData()->getAttributeItemIndex(name); }
     size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const { return elementData()->getAttributeItemIndex(name, shouldIgnoreAttributeCase); }
@@ -284,7 +285,7 @@
     void stripScriptingAttributes(Vector<Attribute>&) const;
 
     const ElementData* elementData() const { return m_elementData.get(); }
-    UniqueElementData* ensureUniqueElementData();
+    UniqueElementData& ensureUniqueElementData();
 
     void synchronizeAllAttributes() const;
 
@@ -403,6 +404,8 @@
 
     virtual String title() const { return String(); }
 
+    virtual const AtomicString& pseudo() const { return shadowPseudoId(); }
+    void setPseudo(const AtomicString& value) { setShadowPseudoId(value); }
     virtual const AtomicString& shadowPseudoId() const;
     void setShadowPseudoId(const AtomicString&);
 
@@ -432,11 +435,9 @@
     bool matches(const String& selectors, ExceptionState&);
     virtual bool shouldAppearIndeterminate() const { return false; }
 
-    DOMTokenList* classList();
+    DOMTokenList& classList();
 
-    DOMStringMap* dataset();
-
-    virtual bool isMediaElement() const { return false; }
+    DOMStringMap& dataset();
 
 #if ENABLE(INPUT_SPEECH)
     virtual bool isInputFieldSpeechButtonElement() const { return false; }
@@ -503,17 +504,17 @@
     void setSavedLayerScrollOffset(const IntSize&);
 
     ActiveAnimations* activeAnimations() const;
-    ActiveAnimations* ensureActiveAnimations();
+    ActiveAnimations& ensureActiveAnimations();
     bool hasActiveAnimations() const;
 
-    InputMethodContext* inputMethodContext();
+    InputMethodContext& inputMethodContext();
     bool hasInputMethodContext() const;
 
     void setPrefix(const AtomicString&, ExceptionState&);
 
     void synchronizeAttribute(const AtomicString& localName) const;
 
-    MutableStylePropertySet* ensureMutableInlineStyle();
+    MutableStylePropertySet& ensureMutableInlineStyle();
     void clearMutableInlineStyleIfEmpty();
 
 protected:
@@ -575,7 +576,6 @@
 
     // FIXME: These methods should all be renamed to something better than "check",
     // since it's not clear that they alter the style bits of siblings and children.
-    void checkForChildrenAdjacentRuleChanges();
     void checkForSiblingStyleChanges(bool finishedParsingCallback, Node* beforeChange, Node* afterChange, int childCountDelta);
     inline void checkForEmptyStyleChange(RenderStyle*);
 
@@ -669,6 +669,32 @@
 };
 
 DEFINE_NODE_TYPE_CASTS(Element, isElementNode());
+template <typename T> bool isElementOfType(const Element&);
+template <typename T> inline bool isElementOfType(const Node& node) { return node.isElementNode() && isElementOfType<const T>(toElement(node)); }
+template <> inline bool isElementOfType<const Element>(const Element&) { return true; }
+
+// Type casting.
+template<typename T> inline T& toElement(Node& node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+    return static_cast<T&>(node);
+}
+template<typename T> inline T* toElement(Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+    return static_cast<T*>(node);
+}
+template<typename T> inline const T& toElement(const Node& node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(isElementOfType<const T>(node));
+    return static_cast<const T&>(node);
+}
+template<typename T> inline const T* toElement(const Node* node)
+{
+    ASSERT_WITH_SECURITY_IMPLICATION(!node || isElementOfType<const T>(*node));
+    return static_cast<const T*>(node);
+}
+template<typename T, typename U> inline T* toElement(const RefPtr<U>& node) { return toElement<T>(node.get()); }
 
 inline bool isDisabledFormControl(const Node* node)
 {
@@ -764,7 +790,7 @@
     return elementData()->length();
 }
 
-inline const Attribute* Element::attributeItem(unsigned index) const
+inline const Attribute& Element::attributeItem(unsigned index) const
 {
     ASSERT(elementData());
     return elementData()->attributeItem(index);
@@ -786,11 +812,11 @@
     return elementData() && elementData()->hasClass();
 }
 
-inline UniqueElementData* Element::ensureUniqueElementData()
+inline UniqueElementData& Element::ensureUniqueElementData()
 {
     if (!elementData() || !elementData()->isUnique())
         createUniqueElementData();
-    return static_cast<UniqueElementData*>(m_elementData.get());
+    return static_cast<UniqueElementData&>(*m_elementData);
 }
 
 // Put here to make them inline.
@@ -860,6 +886,16 @@
     return element && element->shadow();
 }
 
+// These macros do the same as their NODE equivalents but additionally provide a template specialization
+// for isElementOfType<>() so that the Traversal<> API works for these Element types.
+#define DEFINE_ELEMENT_TYPE_CASTS(thisType, predicate) \
+    template <> inline bool isElementOfType<const thisType>(const Element& element) { return element.predicate; } \
+    DEFINE_NODE_TYPE_CASTS(thisType, predicate)
+
+#define DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(thisType) \
+    template <> inline bool isElementOfType<const thisType>(const Element& element) { return is##thisType(element); } \
+    DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(thisType)
+
 } // namespace
 
 #endif
diff --git a/Source/core/dom/Element.idl b/Source/core/dom/Element.idl
index a715874..4a3c23b 100644
--- a/Source/core/dom/Element.idl
+++ b/Source/core/dom/Element.idl
@@ -96,7 +96,7 @@
 
     [RaisesException, CustomElementCallbacks, MeasureAs=InsertAdjacentElement] Element insertAdjacentElement(DOMString where, Element element);
     [RaisesException, MeasureAs=InsertAdjacentText] void insertAdjacentText(DOMString where, DOMString text);
-    [CustomElementCallbacks, RaisesException] void insertAdjacentHTML(DOMString where, DOMString html);
+    [CustomElementCallbacks, RaisesException, MeasureAs=InsertAdjacentHTML] void insertAdjacentHTML(DOMString where, DOMString html);
 
     [Reflect=class, PerWorldBindings] attribute DOMString className;
     [PerWorldBindings] readonly attribute DOMTokenList classList;
@@ -111,6 +111,7 @@
     [RaisesException, ImplementedAs=matches, MeasureAs=ElementPrefixedMatchesSelector] boolean webkitMatchesSelector(DOMString selectors);
 
     // Shadow DOM API
+    [RuntimeEnabled=ShadowDOM, Reflect, TreatNullAs=NullString, PerWorldBindings] attribute DOMString pseudo;
     [RuntimeEnabled=ShadowDOM, RaisesException] ShadowRoot createShadowRoot();
     [RuntimeEnabled=ShadowDOM, PerWorldBindings] readonly attribute ShadowRoot shadowRoot;
     [RuntimeEnabled=ShadowDOM, PerWorldBindings] NodeList getDestinationInsertionPoints();
@@ -125,10 +126,10 @@
 
     // Mozilla version
     const unsigned short ALLOW_KEYBOARD_INPUT = 1;
-    [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
+    [PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullScreen] void webkitRequestFullScreen([Default=Undefined] optional unsigned short flags);
 
     // W3C version
-    [RuntimeEnabled=Fullscreen, PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen();
+    [PerWorldBindings, ActivityLogging=ForAllWorlds, MeasureAs=PrefixedElementRequestFullscreen] void webkitRequestFullscreen();
 
     void webkitRequestPointerLock();
 
diff --git a/Source/core/dom/ElementData.cpp b/Source/core/dom/ElementData.cpp
index 82c7712..dbd47f0 100644
--- a/Source/core/dom/ElementData.cpp
+++ b/Source/core/dom/ElementData.cpp
@@ -100,14 +100,14 @@
     if (!other)
         return isEmpty();
 
-    unsigned len = length();
-    if (len != other->length())
+    unsigned length = this->length();
+    if (length != other->length())
         return false;
 
-    for (unsigned i = 0; i < len; i++) {
-        const Attribute* attribute = attributeItem(i);
-        const Attribute* otherAttr = other->getAttributeItem(attribute->name());
-        if (!otherAttr || attribute->value() != otherAttr->value())
+    for (unsigned i = 0; i < length; ++i) {
+        const Attribute& attribute = attributeItem(i);
+        const Attribute* otherAttr = other->getAttributeItem(attribute.name());
+        if (!otherAttr || attribute.value() != otherAttr->value())
             return false;
     }
 
@@ -117,8 +117,9 @@
 size_t ElementData::getAttrIndex(Attr* attr) const
 {
     // This relies on the fact that Attr's QualifiedName == the Attribute's name.
-    for (unsigned i = 0; i < length(); ++i) {
-        if (attributeItem(i)->name() == attr->qualifiedName())
+    unsigned length = this->length();
+    for (unsigned i = 0; i < length; ++i) {
+        if (attributeItem(i).name() == attr->qualifiedName())
             return i;
     }
     return kNotFound;
@@ -127,18 +128,19 @@
 size_t ElementData::getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const
 {
     // Continue to checking case-insensitively and/or full namespaced names if necessary:
-    for (unsigned i = 0; i < length(); ++i) {
-        const Attribute* attribute = attributeItem(i);
+    unsigned length = this->length();
+    for (unsigned i = 0; i < length; ++i) {
+        const Attribute& attribute = attributeItem(i);
         // FIXME: Why check the prefix? Namespace is all that should matter
         // and all HTML/SVG attributes have a null namespace!
-        if (!attribute->name().hasPrefix()) {
-            if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute->localName()))
+        if (!attribute.name().hasPrefix()) {
+            if (shouldIgnoreAttributeCase && equalIgnoringCase(name, attribute.localName()))
                 return i;
         } else {
             // FIXME: Would be faster to do this comparison without calling toString, which
             // generates a temporary string by concatenation. But this branch is only reached
             // if the attribute name has a prefix, which is rare in HTML.
-            if (equalPossiblyIgnoringCase(name, attribute->name().toString(), shouldIgnoreAttributeCase))
+            if (equalPossiblyIgnoringCase(name, attribute.name().toString(), shouldIgnoreAttributeCase))
                 return i;
         }
     }
@@ -186,7 +188,7 @@
     , m_presentationAttributeStyle(other.m_presentationAttributeStyle)
     , m_attributeVector(other.m_attributeVector)
 {
-    m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : 0;
+    m_inlineStyle = other.m_inlineStyle ? other.m_inlineStyle->mutableCopy() : nullptr;
 }
 
 UniqueElementData::UniqueElementData(const ShareableElementData& other)
@@ -196,8 +198,9 @@
     ASSERT(!other.m_inlineStyle || !other.m_inlineStyle->isMutable());
     m_inlineStyle = other.m_inlineStyle;
 
-    m_attributeVector.reserveCapacity(other.length());
-    for (unsigned i = 0; i < other.length(); ++i)
+    unsigned length = other.length();
+    m_attributeVector.reserveCapacity(length);
+    for (unsigned i = 0; i < length; ++i)
         m_attributeVector.uncheckedAppend(other.m_attributeArray[i]);
 }
 
@@ -214,7 +217,8 @@
 
 Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name)
 {
-    for (unsigned i = 0; i < length(); ++i) {
+    unsigned length = this->length();
+    for (unsigned i = 0; i < length; ++i) {
         if (m_attributeVector.at(i).name().matches(name))
             return &m_attributeVector.at(i);
     }
diff --git a/Source/core/dom/ElementData.h b/Source/core/dom/ElementData.h
index 76451f8..e209f7f 100644
--- a/Source/core/dom/ElementData.h
+++ b/Source/core/dom/ElementData.h
@@ -62,10 +62,11 @@
 
     const StylePropertySet* presentationAttributeStyle() const;
 
+    // This is not a trivial getter and its return value should be cached for performance.
     size_t length() const;
     bool isEmpty() const { return !length(); }
 
-    const Attribute* attributeItem(unsigned index) const;
+    const Attribute& attributeItem(unsigned index) const;
     const Attribute* getAttributeItem(const QualifiedName&) const;
     size_t getAttributeItemIndex(const QualifiedName&, bool shouldIgnoreCase = false) const;
     size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const;
@@ -148,7 +149,7 @@
     void addAttribute(const QualifiedName&, const AtomicString&);
     void removeAttribute(size_t index);
 
-    Attribute* attributeItem(unsigned index);
+    Attribute& attributeItem(unsigned index);
     Attribute* getAttributeItem(const QualifiedName&);
 
     UniqueElementData();
@@ -188,7 +189,7 @@
 {
     size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
     if (index != kNotFound)
-        return attributeItem(index);
+        return &attributeItem(index);
     return 0;
 }
 
@@ -203,8 +204,8 @@
 {
     const Attribute* begin = attributeBase();
     // Cache length for performance as ElementData::length() contains a conditional branch.
-    unsigned len = length();
-    for (unsigned i = 0; i < len; ++i) {
+    unsigned length = this->length();
+    for (unsigned i = 0; i < length; ++i) {
         const Attribute& attribute = begin[i];
         if (attribute.name().matchesPossiblyIgnoringCase(name, shouldIgnoreCase))
             return i;
@@ -217,12 +218,12 @@
 inline size_t ElementData::getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const
 {
     // Cache length for performance as ElementData::length() contains a conditional branch.
-    unsigned len = length();
+    unsigned length = this->length();
     bool doSlowCheck = shouldIgnoreAttributeCase;
 
     // Optimize for the case where the attribute exists and its name exactly matches.
     const Attribute* begin = attributeBase();
-    for (unsigned i = 0; i < len; ++i) {
+    for (unsigned i = 0; i < length; ++i) {
         const Attribute& attribute = begin[i];
         // FIXME: Why check the prefix? Namespaces should be all that matter.
         // Most attributes (all of HTML and CSS) have no namespace.
@@ -242,7 +243,8 @@
 inline const Attribute* ElementData::getAttributeItem(const QualifiedName& name) const
 {
     const Attribute* begin = attributeBase();
-    for (unsigned i = 0; i < length(); ++i) {
+    unsigned length = this->length();
+    for (unsigned i = 0; i < length; ++i) {
         const Attribute& attribute = begin[i];
         if (attribute.name().matches(name))
             return &attribute;
@@ -250,10 +252,11 @@
     return 0;
 }
 
-inline const Attribute* ElementData::attributeItem(unsigned index) const
+inline const Attribute& ElementData::attributeItem(unsigned index) const
 {
     RELEASE_ASSERT(index < length());
-    return attributeBase() + index;
+    ASSERT(attributeBase() + index);
+    return *(attributeBase() + index);
 }
 
 inline void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value)
@@ -266,9 +269,9 @@
     m_attributeVector.remove(index);
 }
 
-inline Attribute* UniqueElementData::attributeItem(unsigned index)
+inline Attribute& UniqueElementData::attributeItem(unsigned index)
 {
-    return &m_attributeVector.at(index);
+    return m_attributeVector.at(index);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/ElementDataCache.cpp b/Source/core/dom/ElementDataCache.cpp
index 1b3cf32..8bdbf92 100644
--- a/Source/core/dom/ElementDataCache.cpp
+++ b/Source/core/dom/ElementDataCache.cpp
@@ -47,7 +47,7 @@
 {
     ASSERT(!attributes.isEmpty());
 
-    ShareableElementDataCache::ValueType* it = m_shareableElementDataCache.add(attributeHash(attributes), 0).storedValue;
+    ShareableElementDataCache::ValueType* it = m_shareableElementDataCache.add(attributeHash(attributes), nullptr).storedValue;
 
     // FIXME: This prevents sharing when there's a hash collision.
     if (it->value && !hasSameAttributes(attributes, *it->value))
diff --git a/Source/core/dom/ElementRareData.cpp b/Source/core/dom/ElementRareData.cpp
index 85889c3..8512151 100644
--- a/Source/core/dom/ElementRareData.cpp
+++ b/Source/core/dom/ElementRareData.cpp
@@ -43,11 +43,11 @@
     void* pointers[11];
 };
 
-CSSStyleDeclaration* ElementRareData::ensureInlineCSSStyleDeclaration(Element* ownerElement)
+CSSStyleDeclaration& ElementRareData::ensureInlineCSSStyleDeclaration(Element* ownerElement)
 {
     if (!m_cssomWrapper)
         m_cssomWrapper = adoptPtr(new InlineCSSStyleDeclaration(ownerElement));
-    return m_cssomWrapper.get();
+    return *m_cssomWrapper;
 }
 
 
diff --git a/Source/core/dom/ElementRareData.h b/Source/core/dom/ElementRareData.h
index a492285..40942a5 100644
--- a/Source/core/dom/ElementRareData.h
+++ b/Source/core/dom/ElementRareData.h
@@ -91,7 +91,7 @@
     unsigned childIndex() const { return m_childIndex; }
     void setChildIndex(unsigned index) { m_childIndex = index; }
 
-    CSSStyleDeclaration* ensureInlineCSSStyleDeclaration(Element* ownerElement);
+    CSSStyleDeclaration& ensureInlineCSSStyleDeclaration(Element* ownerElement);
 
     void clearShadow() { m_shadow = nullptr; }
     ElementShadow* shadow() const { return m_shadow.get(); }
@@ -107,7 +107,7 @@
 
     RenderStyle* computedStyle() const { return m_computedStyle.get(); }
     void setComputedStyle(PassRefPtr<RenderStyle> computedStyle) { m_computedStyle = computedStyle; }
-    void clearComputedStyle() { m_computedStyle = 0; }
+    void clearComputedStyle() { m_computedStyle = nullptr; }
 
     ClassList* classList() const { return m_classList.get(); }
     void setClassList(PassOwnPtr<ClassList> classList) { m_classList = classList; }
@@ -137,11 +137,11 @@
     void setHasPendingResources(bool has) { m_hasPendingResources = has; }
 
     bool hasInputMethodContext() const { return m_inputMethodContext; }
-    InputMethodContext* ensureInputMethodContext(HTMLElement* element)
+    InputMethodContext& ensureInputMethodContext(HTMLElement* element)
     {
         if (!m_inputMethodContext)
             m_inputMethodContext = InputMethodContext::create(element);
-        return m_inputMethodContext.get();
+        return *m_inputMethodContext;
     }
 
     bool hasPseudoElements() const;
@@ -233,9 +233,9 @@
 
 inline void ElementRareData::clearPseudoElements()
 {
-    setPseudoElement(BEFORE, 0);
-    setPseudoElement(AFTER, 0);
-    setPseudoElement(BACKDROP, 0);
+    setPseudoElement(BEFORE, nullptr);
+    setPseudoElement(AFTER, nullptr);
+    setPseudoElement(BACKDROP, nullptr);
 }
 
 inline void ElementRareData::setPseudoElement(PseudoId pseudoId, PassRefPtr<PseudoElement> element)
diff --git a/Source/core/dom/ElementTraversal.h b/Source/core/dom/ElementTraversal.h
index 6bcf1d1..6705f04 100644
--- a/Source/core/dom/ElementTraversal.h
+++ b/Source/core/dom/ElementTraversal.h
@@ -2,8 +2,9 @@
  * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
  *           (C) 1999 Antti Koivisto (koivisto@kde.org)
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -30,155 +31,285 @@
 
 namespace WebCore {
 
-namespace ElementTraversal {
+template <class ElementType>
+class Traversal {
+public:
+    // First or last ElementType child of the node.
+    static ElementType* firstChild(const ContainerNode& current) { return firstChildTemplate(current); }
+    static ElementType* firstChild(const Node& current) { return firstChildTemplate(current); }
+    static ElementType* lastChild(const ContainerNode& current) { return lastChildTemplate(current); }
+    static ElementType* lastChild(const Node& current) { return lastChildTemplate(current); }
 
-// First / Last element child of the node.
-Element* firstWithin(const Node&);
-Element* firstWithin(const ContainerNode&);
-Element* lastWithin(const Node&);
-Element* lastWithin(const ContainerNode&);
+    // First or last ElementType descendant of the node.
+    // For Elements firstWithin() is always the same as firstChild().
+    static ElementType* firstWithin(const ContainerNode& current) { return firstWithinTemplate(current); }
+    static ElementType* firstWithin(const Node& current) { return firstWithinTemplate(current); }
+    static ElementType* lastWithin(const ContainerNode& current) { return lastWithinTemplate(current); }
+    static ElementType* lastWithin(const Node& current) { return lastWithinTemplate(current); }
 
-// Pre-order traversal skipping non-element nodes.
-Element* next(const Node&);
-Element* next(const Node&, const Node* stayWithin);
-Element* next(const ContainerNode&);
-Element* next(const ContainerNode&, const Node* stayWithin);
+    // Pre-order traversal skipping non-element nodes.
+    static ElementType* next(const ContainerNode& current) { return nextTemplate(current); }
+    static ElementType* next(const Node& current) { return nextTemplate(current); }
+    static ElementType* next(const ContainerNode& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
+    static ElementType* next(const Node& current, const Node* stayWithin) { return nextTemplate(current, stayWithin); }
+    static ElementType* previous(const ContainerNode& current) { return previousTemplate(current); }
+    static ElementType* previous(const Node& current) { return previousTemplate(current); }
+    static ElementType* previous(const ContainerNode& current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
+    static ElementType* previous(const Node& current, const Node* stayWithin) { return previousTemplate(current, stayWithin); }
 
-// Like next, but skips children.
-Element* nextSkippingChildren(const Node&);
-Element* nextSkippingChildren(const Node&, const Node* stayWithin);
-Element* nextSkippingChildren(const ContainerNode&);
-Element* nextSkippingChildren(const ContainerNode&, const Node* stayWithin);
+    // Like next, but skips children.
+    static ElementType* nextSkippingChildren(const ContainerNode& current) { return nextSkippingChildrenTemplate(current); }
+    static ElementType* nextSkippingChildren(const Node& current) { return nextSkippingChildrenTemplate(current); }
+    static ElementType* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
+    static ElementType* nextSkippingChildren(const Node& current, const Node* stayWithin) { return nextSkippingChildrenTemplate(current, stayWithin); }
 
-// Pre-order traversal including the pseudo-elements.
-Element* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Element* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Element* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+    // Pre-order traversal including the pseudo-elements.
+    static ElementType* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
+    static ElementType* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
+    static ElementType* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
 
-// Utility function to traverse only the element and pseudo-element siblings of a node.
-Element* pseudoAwarePreviousSibling(const Node&);
+    // Utility function to traverse only the element and pseudo-element siblings of a node.
+    static ElementType* pseudoAwarePreviousSibling(const Node&);
 
-// Previous / Next sibling.
-Element* previousSibling(const Node&);
-Element* nextSibling(const Node&);
+    // Previous / Next sibling.
+    static ElementType* previousSibling(const Node&);
+    static ElementType* nextSibling(const Node&);
 
+private:
+    template <class NodeType>
+    static ElementType* firstChildTemplate(NodeType&);
+    template <class NodeType>
+    static ElementType* lastChildTemplate(NodeType&);
+    template <class NodeType>
+    static ElementType* firstWithinTemplate(NodeType&);
+    template <class NodeType>
+    static ElementType* lastWithinTemplate(NodeType&);
+    template <class NodeType>
+    static ElementType* nextTemplate(NodeType&);
+    template <class NodeType>
+    static ElementType* nextTemplate(NodeType&, const Node* stayWithin);
+    template <class NodeType>
+    static ElementType* previousTemplate(NodeType&);
+    template <class NodeType>
+    static ElementType* previousTemplate(NodeType&, const Node* stayWithin);
+    template <class NodeType>
+    static ElementType* nextSkippingChildrenTemplate(NodeType&);
+    template <class NodeType>
+    static ElementType* nextSkippingChildrenTemplate(NodeType&, const Node* stayWithin);
+};
+
+typedef Traversal<Element> ElementTraversal;
+
+// Specialized for pure Element to exploit the fact that Elements parent is always either another Element or the root.
+template <>
 template <class NodeType>
-inline Element* firstElementWithinTemplate(NodeType& current)
+inline Element* Traversal<Element>::firstWithinTemplate(NodeType& current)
 {
-    // Except for the root containers, only elements can have element children.
-    Node* node = current.firstChild();
-    while (node && !node->isElementNode())
-        node = node->nextSibling();
-    return toElement(node);
+    return firstChildTemplate(current);
 }
-inline Element* firstWithin(const ContainerNode& current) { return firstElementWithinTemplate(current); }
-inline Element* firstWithin(const Node& current) { return firstElementWithinTemplate(current); }
 
+template <>
 template <class NodeType>
-inline Element* lastWithinTemplate(NodeType& current)
+inline Element* Traversal<Element>::lastWithinTemplate(NodeType& current)
 {
-    Node* node = current.lastChild();
-    while (node && !node->isElementNode())
-        node = node->previousSibling();
-    return toElement(node);
+    return lastChildTemplate(current);
 }
-inline Element* lastWithin(const ContainerNode& current) { return lastWithinTemplate(current); }
-inline Element* lastWithin(const Node& current) { return lastWithinTemplate(current); }
 
+template <>
 template <class NodeType>
-inline Element* traverseNextElementTemplate(NodeType& current)
+inline Element* Traversal<Element>::nextTemplate(NodeType& current)
 {
     Node* node = NodeTraversal::next(current);
     while (node && !node->isElementNode())
         node = NodeTraversal::nextSkippingChildren(*node);
     return toElement(node);
 }
-inline Element* next(const ContainerNode& current) { return traverseNextElementTemplate(current); }
-inline Element* next(const Node& current) { return traverseNextElementTemplate(current); }
 
+template <>
 template <class NodeType>
-inline Element* traverseNextElementTemplate(NodeType& current, const Node* stayWithin)
+inline Element* Traversal<Element>::nextTemplate(NodeType& current, const Node* stayWithin)
 {
     Node* node = NodeTraversal::next(current, stayWithin);
     while (node && !node->isElementNode())
         node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
     return toElement(node);
 }
-inline Element* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextElementTemplate(current, stayWithin); }
-inline Element* next(const Node& current, const Node* stayWithin) { return traverseNextElementTemplate(current, stayWithin); }
 
+template <>
 template <class NodeType>
-inline Element* traverseNextElementSkippingChildrenTemplate(NodeType& current)
+inline Element* Traversal<Element>::previousTemplate(NodeType& current)
+{
+    Node* node = NodeTraversal::previous(current);
+    while (node && !node->isElementNode())
+        node = NodeTraversal::previous(*node);
+    return toElement(node);
+}
+
+template <>
+template <class NodeType>
+inline Element* Traversal<Element>::previousTemplate(NodeType& current, const Node* stayWithin)
+{
+    Node* node = NodeTraversal::previous(current, stayWithin);
+    while (node && !node->isElementNode())
+        node = NodeTraversal::previous(*node, stayWithin);
+    return toElement(node);
+}
+
+// Generic versions.
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstChildTemplate(NodeType& current)
+{
+    Node* node = current.firstChild();
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = node->nextSibling();
+    return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::lastChildTemplate(NodeType& current)
+{
+    Node* node = current.lastChild();
+    while (node && !isElementOfType<const ElementType>(*node))
+        node = node->previousSibling();
+    return toElement<ElementType>(node);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::firstWithinTemplate(NodeType& current)
+{
+    Element* element = Traversal<Element>::firstWithin(current);
+    while (element && !isElementOfType<const ElementType>(*element))
+        element = Traversal<Element>::next(*element, &current);
+    return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::lastWithinTemplate(NodeType& current)
+{
+    Element* element = Traversal<Element>::lastWithin(current);
+    while (element && !isElementOfType<const ElementType>(*element))
+        element = Traversal<Element>::previous(element, &current);
+    return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current)
+{
+    Element* element = Traversal<Element>::next(current);
+    while (element && !isElementOfType<const ElementType>(*element))
+        element = Traversal<Element>::next(*element);
+    return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextTemplate(NodeType& current, const Node* stayWithin)
+{
+    Element* element = Traversal<Element>::next(current, stayWithin);
+    while (element && !isElementOfType<const ElementType>(*element))
+        element = Traversal<Element>::next(*element, stayWithin);
+    return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current)
+{
+    Element* element = Traversal<Element>::previous(current);
+    while (element && !isElementOfType<const ElementType>(*element))
+        element = Traversal<Element>::previous(*element);
+    return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::previousTemplate(NodeType& current, const Node* stayWithin)
+{
+    Element* element = Traversal<Element>::previous(current, stayWithin);
+    while (element && !isElementOfType<const ElementType>(*element))
+        element = Traversal<Element>::previous(*element, stayWithin);
+    return toElement<ElementType>(element);
+}
+
+template <class ElementType>
+template <class NodeType>
+inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current)
 {
     Node* node = NodeTraversal::nextSkippingChildren(current);
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = NodeTraversal::nextSkippingChildren(*node);
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
-inline Element* nextSkippingChildren(const ContainerNode& current) { return traverseNextElementSkippingChildrenTemplate(current); }
-inline Element* nextSkippingChildren(const Node& current) { return traverseNextElementSkippingChildrenTemplate(current); }
 
+template <class ElementType>
 template <class NodeType>
-inline Element* traverseNextElementSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+inline ElementType* Traversal<ElementType>::nextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
 {
     Node* node = NodeTraversal::nextSkippingChildren(current, stayWithin);
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = NodeTraversal::nextSkippingChildren(*node, stayWithin);
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
-inline Element* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); }
-inline Element* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextElementSkippingChildrenTemplate(current, stayWithin); }
 
-inline Element* previousIncludingPseudo(const Node& current, const Node* stayWithin)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::previousIncludingPseudo(const Node& current, const Node* stayWithin)
 {
     Node* node = NodeTraversal::previousIncludingPseudo(current, stayWithin);
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = NodeTraversal::previousIncludingPseudo(*node, stayWithin);
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
 
-inline Element* nextIncludingPseudo(const Node& current, const Node* stayWithin)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextIncludingPseudo(const Node& current, const Node* stayWithin)
 {
     Node* node = NodeTraversal::nextIncludingPseudo(current, stayWithin);
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = NodeTraversal::nextIncludingPseudo(*node, stayWithin);
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
 
-inline Element* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
 {
     Node* node = NodeTraversal::nextIncludingPseudoSkippingChildren(current, stayWithin);
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = NodeTraversal::nextIncludingPseudoSkippingChildren(*node, stayWithin);
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
 
-inline Element* pseudoAwarePreviousSibling(const Node& current)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::pseudoAwarePreviousSibling(const Node& current)
 {
     Node* node = current.pseudoAwarePreviousSibling();
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = node->pseudoAwarePreviousSibling();
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
 
-inline Element* previousSibling(const Node& current)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::previousSibling(const Node& current)
 {
     Node* node = current.previousSibling();
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = node->previousSibling();
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
 
-inline Element* nextSibling(const Node& current)
+template <class ElementType>
+inline ElementType* Traversal<ElementType>::nextSibling(const Node& current)
 {
     Node* node = current.nextSibling();
-    while (node && !node->isElementNode())
+    while (node && !isElementOfType<const ElementType>(*node))
         node = node->nextSibling();
-    return toElement(node);
+    return toElement<ElementType>(node);
 }
 
-}
-
-}
+} // namespace WebCore
 
 #endif
diff --git a/Source/core/dom/EmptyNodeList.cpp b/Source/core/dom/EmptyNodeList.cpp
index 8705936..26104fb 100644
--- a/Source/core/dom/EmptyNodeList.cpp
+++ b/Source/core/dom/EmptyNodeList.cpp
@@ -44,7 +44,7 @@
 
 Node* EmptyNodeList::virtualOwnerNode() const
 {
-    return ownerNode();
+    return &ownerNode();
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/EmptyNodeList.h b/Source/core/dom/EmptyNodeList.h
index 06f895f..fd7c5a6 100644
--- a/Source/core/dom/EmptyNodeList.h
+++ b/Source/core/dom/EmptyNodeList.h
@@ -33,21 +33,22 @@
 #define EmptyNodeList_h
 
 #include "core/dom/NodeList.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
 class EmptyNodeList FINAL : public NodeList {
 public:
-    static PassRefPtr<EmptyNodeList> create(Node* rootNode)
+    static PassRefPtr<EmptyNodeList> create(Node& rootNode)
     {
         return adoptRef(new EmptyNodeList(rootNode));
     }
     virtual ~EmptyNodeList();
 
-    Node* ownerNode() const { return m_owner.get(); }
+    Node& ownerNode() const { return *m_owner; }
 
 private:
-    explicit EmptyNodeList(Node* rootNode) : m_owner(rootNode) { }
+    explicit EmptyNodeList(Node& rootNode) : m_owner(rootNode) { }
 
     virtual unsigned length() const OVERRIDE { return 0; }
     virtual Node* item(unsigned) const OVERRIDE { return 0; }
diff --git a/Source/core/dom/ExecutionContext.cpp b/Source/core/dom/ExecutionContext.cpp
index 0740d82..a0b8914 100644
--- a/Source/core/dom/ExecutionContext.cpp
+++ b/Source/core/dom/ExecutionContext.cpp
@@ -96,6 +96,11 @@
     lifecycleNotifier().notifyStoppingActiveDOMObjects();
 }
 
+unsigned ExecutionContext::activeDOMObjectCount()
+{
+    return lifecycleNotifier().activeDOMObjects().size();
+}
+
 void ExecutionContext::suspendScheduledTasks()
 {
     suspendActiveDOMObjects();
diff --git a/Source/core/dom/ExecutionContext.h b/Source/core/dom/ExecutionContext.h
index 3fb01bb..9cc3926 100644
--- a/Source/core/dom/ExecutionContext.h
+++ b/Source/core/dom/ExecutionContext.h
@@ -95,6 +95,7 @@
     void suspendActiveDOMObjects();
     void resumeActiveDOMObjects();
     void stopActiveDOMObjects();
+    unsigned activeDOMObjectCount();
 
     virtual void suspendScheduledTasks();
     virtual void resumeScheduledTasks();
diff --git a/Source/core/dom/ExecutionContextTask.cpp b/Source/core/dom/ExecutionContextTask.cpp
deleted file mode 100644
index 124a5ac..0000000
--- a/Source/core/dom/ExecutionContextTask.cpp
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ExecutionContextTask_h
-#define ExecutionContextTask_h
-
-#include "config.h"
-#include "core/dom/ExecutionContextTask.h"
-
-namespace WebCore {
-
-
-} // namespace
-
-#endif
diff --git a/Source/core/dom/FullscreenElementStack.cpp b/Source/core/dom/FullscreenElementStack.cpp
index 635639b..fc56e7b 100644
--- a/Source/core/dom/FullscreenElementStack.cpp
+++ b/Source/core/dom/FullscreenElementStack.cpp
@@ -31,10 +31,11 @@
 #include "HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/events/Event.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameOwnerElement.h"
+#include "core/html/HTMLMediaElement.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
 #include "core/rendering/RenderFullScreen.h"
@@ -60,7 +61,7 @@
     return "FullscreenElementStack";
 }
 
-FullscreenElementStack* FullscreenElementStack::from(Document* document)
+FullscreenElementStack& FullscreenElementStack::from(Document& document)
 {
     FullscreenElementStack* fullscreen = fromIfExists(document);
     if (!fullscreen) {
@@ -68,42 +69,42 @@
         DocumentSupplement::provideTo(document, supplementName(), adoptPtr(fullscreen));
     }
 
-    return fullscreen;
+    return *fullscreen;
 }
 
-FullscreenElementStack* FullscreenElementStack::fromIfExistsSlow(Document* document)
+FullscreenElementStack* FullscreenElementStack::fromIfExistsSlow(Document& document)
 {
     return static_cast<FullscreenElementStack*>(DocumentSupplement::from(document, supplementName()));
 }
 
-Element* FullscreenElementStack::fullscreenElementFrom(Document* document)
+Element* FullscreenElementStack::fullscreenElementFrom(Document& document)
 {
     if (FullscreenElementStack* found = fromIfExists(document))
         return found->webkitFullscreenElement();
     return 0;
 }
 
-Element* FullscreenElementStack::currentFullScreenElementFrom(Document* document)
+Element* FullscreenElementStack::currentFullScreenElementFrom(Document& document)
 {
     if (FullscreenElementStack* found = fromIfExists(document))
         return found->webkitCurrentFullScreenElement();
     return 0;
 }
 
-bool FullscreenElementStack::isFullScreen(Document* document)
+bool FullscreenElementStack::isFullScreen(Document& document)
 {
     if (FullscreenElementStack* found = fromIfExists(document))
         return found->webkitIsFullScreen();
     return false;
 }
 
-FullscreenElementStack::FullscreenElementStack(Document* document)
-    : DocumentLifecycleObserver(document)
+FullscreenElementStack::FullscreenElementStack(Document& document)
+    : DocumentLifecycleObserver(&document)
     , m_areKeysEnabledInFullScreen(false)
     , m_fullScreenRenderer(0)
     , m_fullScreenChangeDelayTimer(this, &FullscreenElementStack::fullScreenChangeDelayTimerFired)
 {
-    document->setHasFullscreenElementStack();
+    document.setHasFullscreenElementStack();
 }
 
 FullscreenElementStack::~FullscreenElementStack()
@@ -126,7 +127,7 @@
 
 void FullscreenElementStack::documentWasDisposed()
 {
-    m_fullScreenElement = 0;
+    m_fullScreenElement = nullptr;
     m_fullScreenElementStack.clear();
 }
 
@@ -138,6 +139,10 @@
 
 void FullscreenElementStack::requestFullScreenForElement(Element* element, unsigned short flags, FullScreenCheckType checkType)
 {
+    // Ignore this request if the document is not in a live frame.
+    if (!document()->isActive())
+        return;
+
     // The Mozilla Full Screen API <https://wiki.mozilla.org/Gecko:FullScreenAPI> has different requirements
     // for full screen mode, and do not have the concept of a full screen element stack.
     bool inLegacyMozillaMode = (flags & Element::LEGACY_MOZILLA_REQUEST);
@@ -170,8 +175,9 @@
 
         // A descendant browsing context's document has a non-empty fullscreen element stack.
         bool descendentHasNonEmptyStack = false;
-        for (Frame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
-            if (fullscreenElementFrom(descendant->document())) {
+        for (LocalFrame* descendant = document()->frame() ? document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
+            ASSERT(descendant->document());
+            if (fullscreenElementFrom(*descendant->document())) {
                 descendentHasNonEmptyStack = true;
                 break;
             }
@@ -184,7 +190,7 @@
         //   - an activation behavior is currently being processed whose click event was trusted, or
         //   - the event listener for a trusted click event is being handled.
         // FIXME: Does this need to null-check settings()?
-        if (!UserGestureIndicator::processingUserGesture() && (!element->isMediaElement() || document()->settings()->mediaFullscreenRequiresUserGesture()))
+        if (!UserGestureIndicator::processingUserGesture() && (!isHTMLMediaElement(*element) || document()->settings()->mediaFullscreenRequiresUserGesture()))
             break;
 
         // There is a previously-established user preference, security risk, or platform limitation.
@@ -217,19 +223,19 @@
             // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
             // set to true on the document.
             if (!followingDoc) {
-                from(currentDoc)->pushFullscreenElementStack(element);
+                from(*currentDoc).pushFullscreenElementStack(element);
                 addDocumentToFullScreenChangeEventQueue(currentDoc);
                 continue;
             }
 
             // 3. Otherwise, if document's fullscreen element stack is either empty or its top element
             // is not following document's browsing context container,
-            Element* topElement = fullscreenElementFrom(currentDoc);
+            Element* topElement = fullscreenElementFrom(*currentDoc);
             if (!topElement || topElement != followingDoc->ownerElement()) {
                 // ...push following document's browsing context container on document's fullscreen element
                 // stack, and queue a task to fire an event named fullscreenchange with its bubbles attribute
                 // set to true on document.
-                from(currentDoc)->pushFullscreenElementStack(followingDoc->ownerElement());
+                from(*currentDoc).pushFullscreenElementStack(followingDoc->ownerElement());
                 addDocumentToFullScreenChangeEventQueue(currentDoc);
                 continue;
             }
@@ -247,7 +253,7 @@
     } while (0);
 
     m_fullScreenErrorEventTargetQueue.append(element ? element : document()->documentElement());
-    m_fullScreenChangeDelayTimer.startOneShot(0);
+    m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
 }
 
 void FullscreenElementStack::webkitCancelFullScreen()
@@ -263,9 +269,9 @@
     // calling webkitExitFullscreen():
     Vector<RefPtr<Element> > replacementFullscreenElementStack;
     replacementFullscreenElementStack.append(fullscreenElementFrom(document()->topDocument()));
-    FullscreenElementStack* topFullscreenElementStack = from(document()->topDocument());
-    topFullscreenElementStack->m_fullScreenElementStack.swap(replacementFullscreenElementStack);
-    topFullscreenElementStack->webkitExitFullscreen();
+    FullscreenElementStack& topFullscreenElementStack = from(document()->topDocument());
+    topFullscreenElementStack.m_fullScreenElementStack.swap(replacementFullscreenElementStack);
+    topFullscreenElementStack.webkitExitFullscreen();
 }
 
 void FullscreenElementStack::webkitExitFullscreen()
@@ -284,15 +290,17 @@
     // element stack (if any), ordered so that the child of the doc is last and the document furthest
     // away from the doc is first.
     Deque<RefPtr<Document> > descendants;
-    for (Frame* descendant = document()->frame() ?  document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
-        if (fullscreenElementFrom(descendant->document()))
+    for (LocalFrame* descendant = document()->frame() ?  document()->frame()->tree().traverseNext() : 0; descendant; descendant = descendant->tree().traverseNext()) {
+        ASSERT(descendant->document());
+        if (fullscreenElementFrom(*descendant->document()))
             descendants.prepend(descendant->document());
     }
 
     // 4. For each descendant in descendants, empty descendant's fullscreen element stack, and queue a
     // task to fire an event named fullscreenchange with its bubbles attribute set to true on descendant.
     for (Deque<RefPtr<Document> >::iterator i = descendants.begin(); i != descendants.end(); ++i) {
-        from(i->get())->clearFullscreenElementStack();
+        ASSERT(*i);
+        from(**i).clearFullscreenElementStack();
         addDocumentToFullScreenChangeEventQueue(i->get());
     }
 
@@ -300,11 +308,11 @@
     Element* newTop = 0;
     while (currentDoc) {
         // 1. Pop the top element of doc's fullscreen element stack.
-        from(currentDoc)->popFullscreenElementStack();
+        from(*currentDoc).popFullscreenElementStack();
 
         //    If doc's fullscreen element stack is non-empty and the element now at the top is either
         //    not in a document or its node document is not doc, repeat this substep.
-        newTop = fullscreenElementFrom(currentDoc);
+        newTop = fullscreenElementFrom(*currentDoc);
         if (newTop && (!newTop->inDocument() || newTop->document() != currentDoc))
             continue;
 
@@ -345,13 +353,13 @@
     host->chrome().client().enterFullScreenForElement(newTop);
 }
 
-bool FullscreenElementStack::webkitFullscreenEnabled(Document* document)
+bool FullscreenElementStack::webkitFullscreenEnabled(Document& document)
 {
     // 4. The fullscreenEnabled attribute must return true if the context object and all ancestor
     // browsing context's documents have their fullscreen enabled flag set, or false otherwise.
 
     // Top-level browsing contexts are implied to have their allowFullScreen attribute set.
-    return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, document->ownerElement());
+    return isAttributeOnAllOwners(allowfullscreenAttr, webkitallowfullscreenAttr, document.ownerElement());
 
 }
 
@@ -400,7 +408,7 @@
 
     m_fullScreenElement->didBecomeFullscreenElement();
 
-    m_fullScreenChangeDelayTimer.startOneShot(0);
+    m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
 }
 
 void FullscreenElementStack::webkitWillExitFullScreenForElement(Element*)
@@ -429,7 +437,7 @@
     if (m_fullScreenRenderer)
         m_fullScreenRenderer->unwrapRenderer();
 
-    m_fullScreenElement = 0;
+    m_fullScreenElement = nullptr;
     document()->setNeedsStyleRecalc(SubtreeStyleChange);
 
     // When webkitCancelFullScreen is called, we call webkitExitFullScreen on the topDocument(). That
@@ -437,8 +445,9 @@
     // the exiting document.
     Document* exitingDocument = document();
     if (m_fullScreenChangeEventTargetQueue.isEmpty() && m_fullScreenErrorEventTargetQueue.isEmpty())
-        exitingDocument = document()->topDocument();
-    from(exitingDocument)->m_fullScreenChangeDelayTimer.startOneShot(0);
+        exitingDocument = &document()->topDocument();
+    ASSERT(exitingDocument);
+    from(*exitingDocument).m_fullScreenChangeDelayTimer.startOneShot(0, FROM_HERE);
 }
 
 void FullscreenElementStack::setFullScreenRenderer(RenderFullScreen* renderer)
@@ -557,7 +566,7 @@
     ASSERT(doc);
 
     Node* target = 0;
-    if (FullscreenElementStack* fullscreen = fromIfExists(doc)) {
+    if (FullscreenElementStack* fullscreen = fromIfExists(*doc)) {
         target = fullscreen->webkitFullscreenElement();
         if (!target)
             target = fullscreen->webkitCurrentFullScreenElement();
diff --git a/Source/core/dom/FullscreenElementStack.h b/Source/core/dom/FullscreenElementStack.h
index 346ea1e..71ac402 100644
--- a/Source/core/dom/FullscreenElementStack.h
+++ b/Source/core/dom/FullscreenElementStack.h
@@ -52,11 +52,11 @@
 public:
     virtual ~FullscreenElementStack();
     static const char* supplementName();
-    static FullscreenElementStack* from(Document*);
-    static FullscreenElementStack* fromIfExists(Document*);
-    static Element* fullscreenElementFrom(Document*);
-    static Element* currentFullScreenElementFrom(Document*);
-    static bool isFullScreen(Document*);
+    static FullscreenElementStack& from(Document&);
+    static FullscreenElementStack* fromIfExists(Document&);
+    static Element* fullscreenElementFrom(Document&);
+    static Element* currentFullScreenElementFrom(Document&);
+    static bool isFullScreen(Document&);
     static bool isActiveFullScreenElement(const Element*);
 
     enum FullScreenCheckType {
@@ -86,7 +86,7 @@
     void removeFullScreenElementOfSubtree(Node*, bool amongChildrenOnly = false);
 
     // W3C API
-    static bool webkitFullscreenEnabled(Document*);
+    static bool webkitFullscreenEnabled(Document&);
     Element* webkitFullscreenElement() const { return !m_fullScreenElementStack.isEmpty() ? m_fullScreenElementStack.last().get() : 0; }
     void webkitExitFullscreen();
 
@@ -98,9 +98,9 @@
     virtual void documentWasDisposed() OVERRIDE;
 
 private:
-    static FullscreenElementStack* fromIfExistsSlow(Document*);
+    static FullscreenElementStack* fromIfExistsSlow(Document&);
 
-    explicit FullscreenElementStack(Document*);
+    explicit FullscreenElementStack(Document&);
 
     Document* document();
     void fullScreenChangeDelayTimerFired(Timer<FullscreenElementStack>*);
@@ -118,15 +118,15 @@
 
 inline bool FullscreenElementStack::isActiveFullScreenElement(const Element* element)
 {
-    FullscreenElementStack* controller = fromIfExists(&element->document());
+    FullscreenElementStack* controller = fromIfExists(element->document());
     if (!controller)
         return false;
     return controller->webkitIsFullScreen() && controller->webkitCurrentFullScreenElement() == element;
 }
 
-inline FullscreenElementStack* FullscreenElementStack::fromIfExists(Document* document)
+inline FullscreenElementStack* FullscreenElementStack::fromIfExists(Document& document)
 {
-    if (!document->hasFullscreenElementStack())
+    if (!document.hasFullscreenElementStack())
         return 0;
     return fromIfExistsSlow(document);
 }
diff --git a/Source/core/dom/IdTargetObserver.cpp b/Source/core/dom/IdTargetObserver.cpp
index 6957995..af185a0 100644
--- a/Source/core/dom/IdTargetObserver.cpp
+++ b/Source/core/dom/IdTargetObserver.cpp
@@ -31,16 +31,15 @@
 namespace WebCore {
 
 IdTargetObserver::IdTargetObserver(IdTargetObserverRegistry& registry, const AtomicString& id)
-    : m_registry(&registry)
+    : m_registry(registry)
     , m_id(id)
 {
-    m_registry->addObserver(m_id, this);
+    m_registry.addObserver(m_id, this);
 }
 
 IdTargetObserver::~IdTargetObserver()
 {
-    if (m_registry)
-        m_registry->removeObserver(m_id, this);
+    m_registry.removeObserver(m_id, this);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/IdTargetObserver.h b/Source/core/dom/IdTargetObserver.h
index e76b8a5..22f26bf 100644
--- a/Source/core/dom/IdTargetObserver.h
+++ b/Source/core/dom/IdTargetObserver.h
@@ -41,7 +41,7 @@
     IdTargetObserver(IdTargetObserverRegistry&, const AtomicString& id);
 
 private:
-    IdTargetObserverRegistry* m_registry;
+    IdTargetObserverRegistry& m_registry;
     AtomicString m_id;
 };
 
diff --git a/Source/core/dom/IdTargetObserverRegistry.h b/Source/core/dom/IdTargetObserverRegistry.h
index b60af69..2f047ec 100644
--- a/Source/core/dom/IdTargetObserverRegistry.h
+++ b/Source/core/dom/IdTargetObserverRegistry.h
@@ -37,7 +37,7 @@
 class IdTargetObserver;
 
 class IdTargetObserverRegistry {
-    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(IdTargetObserverRegistry); WTF_MAKE_FAST_ALLOCATED;
     friend class IdTargetObserver;
 public:
     static PassOwnPtr<IdTargetObserverRegistry> create();
diff --git a/Source/core/dom/LiveNodeList.cpp b/Source/core/dom/LiveNodeList.cpp
index d43ce2f..d079fb0 100644
--- a/Source/core/dom/LiveNodeList.cpp
+++ b/Source/core/dom/LiveNodeList.cpp
@@ -23,34 +23,16 @@
 #include "config.h"
 #include "core/dom/LiveNodeList.h"
 
-#include "core/dom/Element.h"
-#include "core/html/HTMLCollection.h"
-
 namespace WebCore {
 
-ContainerNode& LiveNodeListBase::rootNode() const
+static inline bool isMatchingElement(const LiveNodeList& nodeList, const Element& element)
 {
-    if (isRootedAtDocument() && m_ownerNode->inDocument())
-        return m_ownerNode->document();
-    return *m_ownerNode;
-}
-
-void LiveNodeListBase::didMoveToDocument(Document& oldDocument, Document& newDocument)
-{
-    invalidateCache(&oldDocument);
-    oldDocument.unregisterNodeList(this);
-    newDocument.registerNodeList(this);
-}
-
-void LiveNodeListBase::invalidateIdNameCacheMaps() const
-{
-    ASSERT(hasIdNameCache());
-    static_cast<const HTMLCollection*>(this)->invalidateIdNameCacheMaps();
+    return nodeList.elementMatches(element);
 }
 
 Node* LiveNodeList::virtualOwnerNode() const
 {
-    return ownerNode();
+    return &ownerNode();
 }
 
 void LiveNodeList::invalidateCache(Document*) const
@@ -58,4 +40,19 @@
     m_collectionIndexCache.invalidate();
 }
 
+Element* LiveNodeList::itemBefore(const Element* previous) const
+{
+    return LiveNodeListBase::itemBefore(*this, previous);
+}
+
+Element* LiveNodeList::traverseToFirstElement(const ContainerNode& root) const
+{
+    return firstMatchingElement(*this, root);
+}
+
+Element* LiveNodeList::traverseForwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset, const ContainerNode& root) const
+{
+    return traverseMatchingElementsForwardToOffset(*this, offset, currentNode, currentOffset, root);
+}
+
 } // namespace WebCore
diff --git a/Source/core/dom/LiveNodeList.h b/Source/core/dom/LiveNodeList.h
index 422e6bc..b9128e4 100644
--- a/Source/core/dom/LiveNodeList.h
+++ b/Source/core/dom/LiveNodeList.h
@@ -24,118 +24,26 @@
 #ifndef LiveNodeList_h
 #define LiveNodeList_h
 
-#include "HTMLNames.h"
-#include "core/dom/Document.h"
+#include "core/dom/LiveNodeListBase.h"
 #include "core/dom/NodeList.h"
 #include "core/html/CollectionIndexCache.h"
 #include "core/html/CollectionType.h"
-#include "wtf/Forward.h"
-#include "wtf/RefPtr.h"
+#include "wtf/PassRefPtr.h"
 
 namespace WebCore {
 
 class Element;
 
-enum NodeListRootType {
-    NodeListIsRootedAtNode,
-    NodeListIsRootedAtDocument,
-    NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr,
-};
-
-class LiveNodeListBase {
-public:
-    LiveNodeListBase(ContainerNode* ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType,
-        CollectionType collectionType)
-        : m_ownerNode(ownerNode)
-        , m_rootType(rootType)
-        , m_invalidationType(invalidationType)
-        , m_collectionType(collectionType)
-    {
-        ASSERT(m_ownerNode);
-        ASSERT(m_rootType == static_cast<unsigned>(rootType));
-        ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
-        ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
-
-        document().registerNodeList(this);
-    }
-
-    virtual ~LiveNodeListBase()
-    {
-        document().unregisterNodeList(this);
-    }
-
-    ContainerNode& rootNode() const;
-
-    void didMoveToDocument(Document& oldDocument, Document& newDocument);
-    ALWAYS_INLINE bool hasIdNameCache() const { return !isLiveNodeListType(type()); }
-    ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument || m_rootType == NodeListIsRootedAtDocumentIfOwnerHasItemrefAttr; }
-    ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
-    ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
-    ContainerNode* ownerNode() const { return m_ownerNode.get(); }
-    ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const
-    {
-        if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
-            invalidateCache();
-        else if (hasIdNameCache() && (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr))
-            invalidateIdNameCacheMaps();
-    }
-    virtual void invalidateCache(Document* oldDocument = 0) const = 0;
-
-    static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
-
-protected:
-    Document& document() const { return m_ownerNode->document(); }
-
-    ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
-
-    template <typename Collection>
-    static Element* iterateForPreviousNode(const Collection&, Node* current);
-    template <typename Collection>
-    static Element* itemBefore(const Collection&, const Element* previousItem);
-
-private:
-    void invalidateIdNameCacheMaps() const;
-
-    RefPtr<ContainerNode> m_ownerNode; // Cannot be null.
-    const unsigned m_rootType : 2;
-    const unsigned m_invalidationType : 4;
-    const unsigned m_collectionType : 5;
-};
-
-ALWAYS_INLINE bool LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName)
-{
-    switch (type) {
-    case InvalidateOnClassAttrChange:
-        return attrName == HTMLNames::classAttr;
-    case InvalidateOnNameAttrChange:
-        return attrName == HTMLNames::nameAttr;
-    case InvalidateOnIdNameAttrChange:
-        return attrName == HTMLNames::idAttr || attrName == HTMLNames::nameAttr;
-    case InvalidateOnForAttrChange:
-        return attrName == HTMLNames::forAttr;
-    case InvalidateForFormControls:
-        return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr
-            || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr;
-    case InvalidateOnHRefAttrChange:
-        return attrName == HTMLNames::hrefAttr;
-    case DoNotInvalidateOnAttributeChanges:
-        return false;
-    case InvalidateOnAnyAttrChange:
-        return true;
-    }
-    return false;
-}
-
 class LiveNodeList : public NodeList, public LiveNodeListBase {
 public:
-    LiveNodeList(PassRefPtr<ContainerNode> ownerNode, CollectionType collectionType, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
-        : LiveNodeListBase(ownerNode.get(), rootType, invalidationType,
+    LiveNodeList(ContainerNode& ownerNode, CollectionType collectionType, NodeListInvalidationType invalidationType, NodeListRootType rootType = NodeListIsRootedAtNode)
+        : LiveNodeListBase(ownerNode, rootType, invalidationType,
         collectionType)
     { }
 
     virtual unsigned length() const OVERRIDE FINAL { return m_collectionIndexCache.nodeCount(*this); }
     virtual Node* item(unsigned offset) const OVERRIDE FINAL { return m_collectionIndexCache.nodeAt(*this, offset); }
-    virtual bool nodeMatches(const Element&) const = 0;
+    virtual bool elementMatches(const Element&) const = 0;
 
     virtual void invalidateCache(Document* oldDocument) const OVERRIDE FINAL;
     bool shouldOnlyIncludeDirectChildren() const { return false; }
diff --git a/Source/core/dom/LiveNodeListBase.cpp b/Source/core/dom/LiveNodeListBase.cpp
new file mode 100644
index 0000000..a4b1202
--- /dev/null
+++ b/Source/core/dom/LiveNodeListBase.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/dom/LiveNodeListBase.h"
+
+#include "core/html/HTMLCollection.h"
+
+namespace WebCore {
+
+ContainerNode& LiveNodeListBase::rootNode() const
+{
+    if (isRootedAtDocument() && m_ownerNode->inDocument())
+        return m_ownerNode->document();
+    return *m_ownerNode;
+}
+
+void LiveNodeListBase::didMoveToDocument(Document& oldDocument, Document& newDocument)
+{
+    invalidateCache(&oldDocument);
+    oldDocument.unregisterNodeList(this);
+    newDocument.registerNodeList(this);
+}
+
+void LiveNodeListBase::invalidateIdNameCacheMaps() const
+{
+    ASSERT(hasIdNameCache());
+    static_cast<const HTMLCollection*>(this)->invalidateIdNameCacheMaps();
+}
+
+} // namespace WebCore
diff --git a/Source/core/dom/LiveNodeListBase.h b/Source/core/dom/LiveNodeListBase.h
new file mode 100644
index 0000000..ecc1730
--- /dev/null
+++ b/Source/core/dom/LiveNodeListBase.h
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2001 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2004, 2006, 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef LiveNodeListBase_h
+#define LiveNodeListBase_h
+
+#include "HTMLNames.h"
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/dom/NodeTraversal.h"
+#include "core/html/CollectionType.h"
+
+namespace WebCore {
+
+enum NodeListRootType {
+    NodeListIsRootedAtNode,
+    NodeListIsRootedAtDocument
+};
+
+class LiveNodeListBase {
+public:
+    LiveNodeListBase(ContainerNode& ownerNode, NodeListRootType rootType, NodeListInvalidationType invalidationType,
+        CollectionType collectionType)
+        : m_ownerNode(ownerNode)
+        , m_rootType(rootType)
+        , m_invalidationType(invalidationType)
+        , m_collectionType(collectionType)
+    {
+        ASSERT(m_rootType == static_cast<unsigned>(rootType));
+        ASSERT(m_invalidationType == static_cast<unsigned>(invalidationType));
+        ASSERT(m_collectionType == static_cast<unsigned>(collectionType));
+
+        document().registerNodeList(this);
+    }
+
+    virtual ~LiveNodeListBase()
+    {
+        document().unregisterNodeList(this);
+    }
+
+    ContainerNode& rootNode() const;
+
+    void didMoveToDocument(Document& oldDocument, Document& newDocument);
+    ALWAYS_INLINE bool hasIdNameCache() const { return !isLiveNodeListType(type()); }
+    ALWAYS_INLINE bool isRootedAtDocument() const { return m_rootType == NodeListIsRootedAtDocument; }
+    ALWAYS_INLINE NodeListInvalidationType invalidationType() const { return static_cast<NodeListInvalidationType>(m_invalidationType); }
+    ALWAYS_INLINE CollectionType type() const { return static_cast<CollectionType>(m_collectionType); }
+    ContainerNode& ownerNode() const { return *m_ownerNode; }
+    ALWAYS_INLINE void invalidateCache(const QualifiedName* attrName) const
+    {
+        if (!attrName || shouldInvalidateTypeOnAttributeChange(invalidationType(), *attrName))
+            invalidateCache();
+        else if (hasIdNameCache() && (*attrName == HTMLNames::idAttr || *attrName == HTMLNames::nameAttr))
+            invalidateIdNameCacheMaps();
+    }
+    virtual void invalidateCache(Document* oldDocument = 0) const = 0;
+
+    static bool shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType, const QualifiedName&);
+
+protected:
+    Document& document() const { return m_ownerNode->document(); }
+
+    ALWAYS_INLINE NodeListRootType rootType() const { return static_cast<NodeListRootType>(m_rootType); }
+
+    template <typename Collection>
+    static Element* itemBefore(const Collection&, const Element* previousItem);
+    template <class NodeListType>
+    static Element* firstMatchingElement(const NodeListType&, const ContainerNode&);
+    template <class NodeListType>
+    static Element* nextMatchingElement(const NodeListType&, Element& current, const ContainerNode& root);
+    template <class NodeListType>
+    static Element* traverseMatchingElementsForwardToOffset(const NodeListType&, unsigned offset, Element& currentElement, unsigned& currentOffset, const ContainerNode& root);
+
+private:
+    void invalidateIdNameCacheMaps() const;
+    template <typename Collection>
+    static Element* iterateForPreviousNode(const Collection&, Node* current);
+    static Node* previousNode(const ContainerNode&, const Node& previous, bool onlyIncludeDirectChildren);
+    static Node* lastDescendant(const ContainerNode&);
+    static Node* lastNode(const ContainerNode&, bool onlyIncludeDirectChildren);
+
+    RefPtr<ContainerNode> m_ownerNode; // Cannot be null.
+    const unsigned m_rootType : 1;
+    const unsigned m_invalidationType : 4;
+    const unsigned m_collectionType : 5;
+};
+
+ALWAYS_INLINE bool LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(NodeListInvalidationType type, const QualifiedName& attrName)
+{
+    switch (type) {
+    case InvalidateOnClassAttrChange:
+        return attrName == HTMLNames::classAttr;
+    case InvalidateOnNameAttrChange:
+        return attrName == HTMLNames::nameAttr;
+    case InvalidateOnIdNameAttrChange:
+        return attrName == HTMLNames::idAttr || attrName == HTMLNames::nameAttr;
+    case InvalidateOnForAttrChange:
+        return attrName == HTMLNames::forAttr;
+    case InvalidateForFormControls:
+        return attrName == HTMLNames::nameAttr || attrName == HTMLNames::idAttr || attrName == HTMLNames::forAttr
+            || attrName == HTMLNames::formAttr || attrName == HTMLNames::typeAttr;
+    case InvalidateOnHRefAttrChange:
+        return attrName == HTMLNames::hrefAttr;
+    case DoNotInvalidateOnAttributeChanges:
+        return false;
+    case InvalidateOnAnyAttrChange:
+        return true;
+    }
+    return false;
+}
+
+inline Node* LiveNodeListBase::previousNode(const ContainerNode& base, const Node& previous, bool onlyIncludeDirectChildren)
+{
+    return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversal::previous(previous, &base);
+}
+
+inline Node* LiveNodeListBase::lastDescendant(const ContainerNode& node)
+{
+    Node* descendant = node.lastChild();
+    for (Node* current = descendant; current; current = current->lastChild())
+        descendant = current;
+    return descendant;
+}
+
+inline Node* LiveNodeListBase::lastNode(const ContainerNode& rootNode, bool onlyIncludeDirectChildren)
+{
+    return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendant(rootNode);
+}
+
+template <typename Collection>
+Element* LiveNodeListBase::iterateForPreviousNode(const Collection& collection, Node* current)
+{
+    bool onlyIncludeDirectChildren = collection.shouldOnlyIncludeDirectChildren();
+    ContainerNode& rootNode = collection.rootNode();
+    for (; current; current = previousNode(rootNode, *current, onlyIncludeDirectChildren)) {
+        if (current->isElementNode() && isMatchingElement(collection, toElement(*current)))
+            return toElement(current);
+    }
+    return 0;
+}
+
+template <typename Collection>
+Element* LiveNodeListBase::itemBefore(const Collection& collection, const Element* previous)
+{
+    Node* current;
+    if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower.
+        current = previousNode(collection.rootNode(), *previous, collection.shouldOnlyIncludeDirectChildren());
+    else
+        current = lastNode(collection.rootNode(), collection.shouldOnlyIncludeDirectChildren());
+
+    return iterateForPreviousNode(collection, current);
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::firstMatchingElement(const NodeListType& nodeList, const ContainerNode& root)
+{
+    Element* element = ElementTraversal::firstWithin(root);
+    while (element && !isMatchingElement(nodeList, *element))
+        element = ElementTraversal::next(*element, &root);
+    return element;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::nextMatchingElement(const NodeListType& nodeList, Element& current, const ContainerNode& root)
+{
+    Element* next = &current;
+    do {
+        next = ElementTraversal::next(*next, &root);
+    } while (next && !isMatchingElement(nodeList, *next));
+    return next;
+}
+
+template <class NodeListType>
+Element* LiveNodeListBase::traverseMatchingElementsForwardToOffset(const NodeListType& nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset, const ContainerNode& root)
+{
+    ASSERT(currentOffset < offset);
+    Element* next = &currentElement;
+    while ((next = nextMatchingElement(nodeList, *next, root))) {
+        if (++currentOffset == offset)
+            return next;
+    }
+    return 0;
+}
+
+} // namespace WebCore
+
+#endif // LiveNodeListBase_h
diff --git a/Source/core/dom/MainThreadTaskRunner.cpp b/Source/core/dom/MainThreadTaskRunner.cpp
index 976d971..d8b5310 100644
--- a/Source/core/dom/MainThreadTaskRunner.cpp
+++ b/Source/core/dom/MainThreadTaskRunner.cpp
@@ -99,7 +99,7 @@
 {
     ASSERT(m_suspended);
     if (!m_pendingTasks.isEmpty())
-        m_pendingTasksTimer.startOneShot(0);
+        m_pendingTasksTimer.startOneShot(0, FROM_HERE);
 
     m_suspended = false;
 }
diff --git a/Source/core/dom/MessagePort.cpp b/Source/core/dom/MessagePort.cpp
index 769a4ef..b5e1714 100644
--- a/Source/core/dom/MessagePort.cpp
+++ b/Source/core/dom/MessagePort.cpp
@@ -188,9 +188,7 @@
 {
     // The spec says that entangled message ports should always be treated as if they have a strong reference.
     // We'll also stipulate that the queue needs to be open (if the app drops its reference to the port before start()-ing it, then it's not really entangled as it's unreachable).
-    if (m_started && m_entangledChannel)
-        return true;
-    return isEntangled();
+    return m_started && isEntangled();
 }
 
 PassOwnPtr<MessagePortChannelArray> MessagePort::disentanglePorts(const MessagePortArray* ports, ExceptionState& exceptionState)
diff --git a/Source/core/dom/MessagePort.h b/Source/core/dom/MessagePort.h
index 65e0cba..8c4ab2a 100644
--- a/Source/core/dom/MessagePort.h
+++ b/Source/core/dom/MessagePort.h
@@ -45,7 +45,7 @@
 
 class Event;
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class MessagePort;
 class ExecutionContext;
 class SerializedScriptValue;
diff --git a/Source/core/dom/MutationObserver.cpp b/Source/core/dom/MutationObserver.cpp
index 21bdd69..6f4fb9e 100644
--- a/Source/core/dom/MutationObserver.cpp
+++ b/Source/core/dom/MutationObserver.cpp
@@ -119,25 +119,25 @@
 
     if (!(options & Attributes)) {
         if (options & AttributeOldValue) {
-            exceptionState.throwDOMException(TypeError, "The options object may only set 'attributeOldValue' to true when 'attributes' is true or not present.");
+            exceptionState.throwTypeError("The options object may only set 'attributeOldValue' to true when 'attributes' is true or not present.");
             return;
         }
         if (options & AttributeFilter) {
-            exceptionState.throwDOMException(TypeError, "The options object may only set 'attributeFilter' when 'attributes' is true or not present.");
+            exceptionState.throwTypeError("The options object may only set 'attributeFilter' when 'attributes' is true or not present.");
             return;
         }
     }
     if (!((options & CharacterData) || !(options & CharacterDataOldValue))) {
-        exceptionState.throwDOMException(TypeError, "The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.");
+        exceptionState.throwTypeError("The options object may only set 'characterDataOldValue' to true when 'characterData' is true or not present.");
         return;
     }
 
     if (!(options & (Attributes | CharacterData | ChildList))) {
-        exceptionState.throwDOMException(TypeError, "The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.");
+        exceptionState.throwTypeError("The options object must set at least one of 'attributes', 'characterData', or 'childList' to true.");
         return;
     }
 
-    node->registerMutationObserver(this, options, attributeFilter);
+    node->registerMutationObserver(*this, options, attributeFilter);
 }
 
 Vector<RefPtr<MutationRecord> > MutationObserver::takeRecords()
diff --git a/Source/core/dom/MutationObserver.h b/Source/core/dom/MutationObserver.h
index a5f3aa3..086e600 100644
--- a/Source/core/dom/MutationObserver.h
+++ b/Source/core/dom/MutationObserver.h
@@ -33,6 +33,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "wtf/HashSet.h"
+#include "wtf/PassOwnPtr.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
diff --git a/Source/core/dom/MutationObserverRegistration.cpp b/Source/core/dom/MutationObserverRegistration.cpp
index 1ece4d1..2680bb7 100644
--- a/Source/core/dom/MutationObserverRegistration.cpp
+++ b/Source/core/dom/MutationObserverRegistration.cpp
@@ -37,12 +37,12 @@
 
 namespace WebCore {
 
-PassOwnPtr<MutationObserverRegistration> MutationObserverRegistration::create(PassRefPtr<MutationObserver> observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+PassOwnPtr<MutationObserverRegistration> MutationObserverRegistration::create(MutationObserver& observer, Node& registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
 {
     return adoptPtr(new MutationObserverRegistration(observer, registrationNode, options, attributeFilter));
 }
 
-MutationObserverRegistration::MutationObserverRegistration(PassRefPtr<MutationObserver> observer, Node* registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+MutationObserverRegistration::MutationObserverRegistration(MutationObserver& observer, Node& registrationNode, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
     : m_observer(observer)
     , m_registrationNode(registrationNode)
     , m_options(options)
@@ -64,21 +64,21 @@
     m_attributeFilter = attributeFilter;
 }
 
-void MutationObserverRegistration::observedSubtreeNodeWillDetach(Node* node)
+void MutationObserverRegistration::observedSubtreeNodeWillDetach(Node& node)
 {
     if (!isSubtree())
         return;
 
-    node->registerTransientMutationObserver(this);
+    node.registerTransientMutationObserver(this);
     m_observer->setHasTransientRegistration();
 
     if (!m_transientRegistrationNodes) {
         m_transientRegistrationNodes = adoptPtr(new NodeHashSet);
 
         ASSERT(!m_registrationNodeKeepAlive);
-        m_registrationNodeKeepAlive = m_registrationNode; // Balanced in clearTransientRegistrations.
+        m_registrationNodeKeepAlive = PassRefPtr<Node>(m_registrationNode); // Balanced in clearTransientRegistrations.
     }
-    m_transientRegistrationNodes->add(node);
+    m_transientRegistrationNodes->add(&node);
 }
 
 void MutationObserverRegistration::clearTransientRegistrations()
@@ -94,16 +94,16 @@
     m_transientRegistrationNodes.clear();
 
     ASSERT(m_registrationNodeKeepAlive);
-    m_registrationNodeKeepAlive = 0; // Balanced in observeSubtreeNodeWillDetach.
+    m_registrationNodeKeepAlive = nullptr; // Balanced in observeSubtreeNodeWillDetach.
 }
 
 void MutationObserverRegistration::unregister()
 {
-    m_registrationNode->unregisterMutationObserver(this);
+    m_registrationNode.unregisterMutationObserver(this);
     // The above line will cause this object to be deleted, so don't do any more in this function.
 }
 
-bool MutationObserverRegistration::shouldReceiveMutationFrom(Node* node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
+bool MutationObserverRegistration::shouldReceiveMutationFrom(Node& node, MutationObserver::MutationType type, const QualifiedName* attributeName) const
 {
     ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
     if (!(m_options & type))
@@ -123,7 +123,7 @@
 
 void MutationObserverRegistration::addRegistrationNodesToSet(HashSet<Node*>& nodes) const
 {
-    nodes.add(m_registrationNode);
+    nodes.add(&m_registrationNode);
     if (!m_transientRegistrationNodes)
         return;
     for (NodeHashSet::const_iterator iter = m_transientRegistrationNodes->begin(); iter != m_transientRegistrationNodes->end(); ++iter)
diff --git a/Source/core/dom/MutationObserverRegistration.h b/Source/core/dom/MutationObserverRegistration.h
index 7c0fb52..8bc80d4 100644
--- a/Source/core/dom/MutationObserverRegistration.h
+++ b/Source/core/dom/MutationObserverRegistration.h
@@ -42,29 +42,29 @@
 
 class MutationObserverRegistration {
 public:
-    static PassOwnPtr<MutationObserverRegistration> create(PassRefPtr<MutationObserver>, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+    static PassOwnPtr<MutationObserverRegistration> create(MutationObserver&, Node&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
     ~MutationObserverRegistration();
 
     void resetObservation(MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
-    void observedSubtreeNodeWillDetach(Node*);
+    void observedSubtreeNodeWillDetach(Node&);
     void clearTransientRegistrations();
     bool hasTransientRegistrations() const { return m_transientRegistrationNodes && !m_transientRegistrationNodes->isEmpty(); }
     void unregister();
 
-    bool shouldReceiveMutationFrom(Node*, MutationObserver::MutationType, const QualifiedName* attributeName) const;
+    bool shouldReceiveMutationFrom(Node&, MutationObserver::MutationType, const QualifiedName* attributeName) const;
     bool isSubtree() const { return m_options & MutationObserver::Subtree; }
 
-    MutationObserver* observer() const { return m_observer.get(); }
+    MutationObserver& observer() const { return *m_observer; }
     MutationRecordDeliveryOptions deliveryOptions() const { return m_options & (MutationObserver::AttributeOldValue | MutationObserver::CharacterDataOldValue); }
     MutationObserverOptions mutationTypes() const { return m_options & MutationObserver::AllMutationTypes; }
 
     void addRegistrationNodesToSet(HashSet<Node*>&) const;
 
 private:
-    MutationObserverRegistration(PassRefPtr<MutationObserver>, Node*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+    MutationObserverRegistration(MutationObserver&, Node&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
 
     RefPtr<MutationObserver> m_observer;
-    Node* m_registrationNode;
+    Node& m_registrationNode;
     RefPtr<Node> m_registrationNodeKeepAlive;
     typedef HashSet<RefPtr<Node> > NodeHashSet;
     OwnPtr<NodeHashSet> m_transientRegistrationNodes;
diff --git a/Source/core/dom/NameNodeList.cpp b/Source/core/dom/NameNodeList.cpp
index 6393eba..0c0e385 100644
--- a/Source/core/dom/NameNodeList.cpp
+++ b/Source/core/dom/NameNodeList.cpp
@@ -31,7 +31,7 @@
 
 using namespace HTMLNames;
 
-NameNodeList::NameNodeList(PassRefPtr<ContainerNode> rootNode, const AtomicString& name)
+NameNodeList::NameNodeList(ContainerNode& rootNode, const AtomicString& name)
     : LiveNodeList(rootNode, NameNodeListType, InvalidateOnNameAttrChange)
     , m_name(name)
 {
@@ -39,12 +39,12 @@
 
 NameNodeList::~NameNodeList()
 {
-    ownerNode()->nodeLists()->removeCache(this, NameNodeListType, m_name);
+    ownerNode().nodeLists()->removeCache(this, NameNodeListType, m_name);
 }
 
-bool NameNodeList::nodeMatches(const Element& testNode) const
+bool NameNodeList::elementMatches(const Element& element) const
 {
-    return testNode.getNameAttribute() == m_name;
+    return element.getNameAttribute() == m_name;
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/NameNodeList.h b/Source/core/dom/NameNodeList.h
index 2212fb1..438a164 100644
--- a/Source/core/dom/NameNodeList.h
+++ b/Source/core/dom/NameNodeList.h
@@ -33,7 +33,7 @@
 // NodeList which lists all Nodes in a Element with a given "name" attribute
 class NameNodeList FINAL : public LiveNodeList {
 public:
-    static PassRefPtr<NameNodeList> create(PassRefPtr<ContainerNode> rootNode, CollectionType type, const AtomicString& name)
+    static PassRefPtr<NameNodeList> create(ContainerNode& rootNode, CollectionType type, const AtomicString& name)
     {
         ASSERT_UNUSED(type, type == NameNodeListType);
         return adoptRef(new NameNodeList(rootNode, name));
@@ -42,9 +42,9 @@
     virtual ~NameNodeList();
 
 private:
-    NameNodeList(PassRefPtr<ContainerNode> rootNode, const AtomicString& name);
+    NameNodeList(ContainerNode& rootNode, const AtomicString& name);
 
-    virtual bool nodeMatches(const Element&) const OVERRIDE;
+    virtual bool elementMatches(const Element&) const OVERRIDE;
 
     AtomicString m_name;
 };
diff --git a/Source/core/dom/NamedNodeMap.cpp b/Source/core/dom/NamedNodeMap.cpp
index 499f7b6..00280fa 100644
--- a/Source/core/dom/NamedNodeMap.cpp
+++ b/Source/core/dom/NamedNodeMap.cpp
@@ -60,7 +60,7 @@
     size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(name, m_element->shouldIgnoreAttributeCase()) : kNotFound;
     if (index == kNotFound) {
         exceptionState.throwDOMException(NotFoundError, "No item with name '" + name + "' was found.");
-        return 0;
+        return nullptr;
     }
     return m_element->detachAttribute(index);
 }
@@ -70,7 +70,7 @@
     size_t index = m_element->hasAttributes() ? m_element->getAttributeItemIndex(QualifiedName(nullAtom, localName, namespaceURI)) : kNotFound;
     if (index == kNotFound) {
         exceptionState.throwDOMException(NotFoundError, "No item with name '" + namespaceURI + "::" + localName + "' was found.");
-        return 0;
+        return nullptr;
     }
     return m_element->detachAttribute(index);
 }
@@ -79,13 +79,13 @@
 {
     if (!node) {
         exceptionState.throwDOMException(NotFoundError, "The node provided was null.");
-        return 0;
+        return nullptr;
     }
 
     // Not mentioned in spec: throw a HIERARCHY_REQUEST_ERROR if the user passes in a non-attribute node
     if (!node->isAttributeNode()) {
         exceptionState.throwDOMException(HierarchyRequestError, "The node provided is not an attribute node.");
-        return 0;
+        return nullptr;
     }
 
     return m_element->setAttributeNode(toAttr(node), exceptionState);
@@ -99,8 +99,8 @@
 PassRefPtr<Node> NamedNodeMap::item(unsigned index) const
 {
     if (index >= length())
-        return 0;
-    return m_element->ensureAttr(m_element->attributeItem(index)->name());
+        return nullptr;
+    return m_element->ensureAttr(m_element->attributeItem(index).name());
 }
 
 size_t NamedNodeMap::length() const
diff --git a/Source/core/dom/Node.cpp b/Source/core/dom/Node.cpp
index 1671ca9..59a60dc 100644
--- a/Source/core/dom/Node.cpp
+++ b/Source/core/dom/Node.cpp
@@ -73,13 +73,13 @@
 #include "core/events/TouchEvent.h"
 #include "core/events/UIEvent.h"
 #include "core/events/WheelEvent.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLDialogElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLStyleElement.h"
 #include "core/page/ContextMenuController.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/FlowThreadController.h"
@@ -295,7 +295,7 @@
     if (AXObjectCache* cache = document.existingAXObjectCache())
         cache->remove(this);
 
-    document.markers()->removeMarkers(this);
+    document.markers().removeMarkers(this);
 }
 
 NodeRareData* Node::rareData() const
@@ -358,8 +358,8 @@
 PassRefPtr<NodeList> Node::childNodes()
 {
     if (isContainerNode())
-        return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(this));
-    return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(this);
+        return ensureRareData().ensureNodeLists().ensureChildNodeList(toContainerNode(*this));
+    return ensureRareData().ensureNodeLists().ensureEmptyChildNodeList(*this);
 }
 
 Node& Node::lastDescendant() const
@@ -648,7 +648,8 @@
 
 void Node::markAncestorsWithChildNeedsStyleInvalidation()
 {
-    for (Node* node = this; node && !node->childNeedsStyleInvalidation(); node = node->parentOrShadowHostNode())
+    Node* node = this;
+    for (; node && !node->childNeedsStyleInvalidation(); node = node->parentOrShadowHostNode())
         node->setChildNeedsStyleInvalidation();
     if (document().childNeedsStyleInvalidation())
         document().scheduleStyleRecalc();
@@ -814,40 +815,6 @@
     return count;
 }
 
-template<unsigned type>
-bool shouldInvalidateNodeListCachesForAttr(const unsigned nodeListCounts[], const QualifiedName& attrName)
-{
-    if (nodeListCounts[type] && LiveNodeListBase::shouldInvalidateTypeOnAttributeChange(static_cast<NodeListInvalidationType>(type), attrName))
-        return true;
-    return shouldInvalidateNodeListCachesForAttr<type + 1>(nodeListCounts, attrName);
-}
-
-template<>
-bool shouldInvalidateNodeListCachesForAttr<numNodeListInvalidationTypes>(const unsigned[], const QualifiedName&)
-{
-    return false;
-}
-
-bool Document::shouldInvalidateNodeListCaches(const QualifiedName* attrName) const
-{
-    if (attrName)
-        return shouldInvalidateNodeListCachesForAttr<DoNotInvalidateOnAttributeChanges + 1>(m_nodeListCounts, *attrName);
-
-    for (int type = 0; type < numNodeListInvalidationTypes; type++) {
-        if (m_nodeListCounts[type])
-            return true;
-    }
-
-    return false;
-}
-
-void Document::invalidateNodeListCaches(const QualifiedName* attrName)
-{
-    HashSet<LiveNodeListBase*>::iterator end = m_listsInvalidatedAtDocument.end();
-    for (HashSet<LiveNodeListBase*>::iterator it = m_listsInvalidatedAtDocument.begin(); it != end; ++it)
-        (*it)->invalidateCache(attrName);
-}
-
 void Node::invalidateNodeListCachesInAncestors(const QualifiedName* attrName, Element* attributeOwnerElement)
 {
     if (hasRareData() && (!attrName || isAttributeNode())) {
@@ -883,7 +850,7 @@
 bool Node::isDescendantOf(const Node *other) const
 {
     // Return true if other is an ancestor of this, otherwise false
-    if (!other || !other->hasChildNodes() || inDocument() != other->inDocument())
+    if (!other || !other->hasChildren() || inDocument() != other->inDocument())
         return false;
     if (other->treeScope() != treeScope())
         return false;
@@ -917,7 +884,7 @@
     if (inDocument() != node->inDocument())
         return false;
 
-    bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildNodes();
+    bool hasChildren = isContainerNode() && toContainerNode(this)->hasChildren();
     bool hasShadow = isElementNode() && toElement(this)->shadow();
     if (!hasChildren && !hasShadow)
         return false;
@@ -1039,6 +1006,8 @@
 
     setStyleChange(NeedsReattachStyleChange);
     setChildNeedsStyleRecalc();
+    if (StyleResolver* resolver = document().styleResolver())
+        resolver->ruleFeatureSet().clearStyleInvalidation(this);
 
 #ifndef NDEBUG
     detachingNode = 0;
@@ -1222,7 +1191,7 @@
         n = n->parentNode();
         if (!n)
             break;
-        if (n->isBlockFlowElement() || n->hasTagName(bodyTag))
+        if (n->isBlockFlowElement() || isHTMLBodyElement(*n))
             return toElement(n);
     }
     return 0;
@@ -1231,7 +1200,7 @@
 bool Node::isRootEditableElement() const
 {
     return rendererIsEditable() && isElementNode() && (!parentNode() || !parentNode()->rendererIsEditable()
-        || !parentNode()->isElementNode() || hasTagName(bodyTag));
+        || !parentNode()->isElementNode() || isHTMLBodyElement((*this)));
 }
 
 Element* Node::rootEditableElement(EditableType editableType) const
@@ -1250,7 +1219,7 @@
     for (Node* n = const_cast<Node*>(this); n && n->rendererIsEditable(); n = n->parentNode()) {
         if (n->isElementNode())
             result = toElement(n);
-        if (n->hasTagName(bodyTag))
+        if (isHTMLBodyElement(*n))
             break;
     }
     return result;
@@ -1341,11 +1310,12 @@
                 return elem->namespaceURI() == namespaceURI;
 
             if (elem->hasAttributes()) {
-                for (unsigned i = 0; i < elem->attributeCount(); i++) {
-                    const Attribute* attr = elem->attributeItem(i);
+                unsigned attributeCount = elem->attributeCount();
+                for (unsigned i = 0; i < attributeCount; ++i) {
+                    const Attribute& attr = elem->attributeItem(i);
 
-                    if (attr->localName() == xmlnsAtom)
-                        return attr->value() == namespaceURI;
+                    if (attr.localName() == xmlnsAtom)
+                        return attr.value() == namespaceURI;
                 }
             }
 
@@ -1426,17 +1396,19 @@
                 return elem->namespaceURI();
 
             if (elem->hasAttributes()) {
-                for (unsigned i = 0; i < elem->attributeCount(); i++) {
-                    const Attribute* attr = elem->attributeItem(i);
+                unsigned attributeCount = elem->attributeCount();
+                for (unsigned i = 0; i < attributeCount; ++i) {
+                    const Attribute& attr = elem->attributeItem(i);
 
-                    if (attr->prefix() == xmlnsAtom && attr->localName() == prefix) {
-                        if (!attr->value().isEmpty())
-                            return attr->value();
+                    if (attr.prefix() == xmlnsAtom && attr.localName() == prefix) {
+                        if (!attr.value().isEmpty())
+                            return attr.value();
 
                         return nullAtom;
-                    } else if (attr->localName() == xmlnsAtom && prefix.isNull()) {
-                        if (!attr->value().isEmpty())
-                            return attr->value();
+                    }
+                    if (attr.localName() == xmlnsAtom && prefix.isNull()) {
+                        if (!attr.value().isEmpty())
+                            return attr.value();
 
                         return nullAtom;
                     }
@@ -1483,7 +1455,7 @@
         break;
 
     case Node::ELEMENT_NODE:
-        if (node->hasTagName(brTag) && convertBRsToNewlines) {
+        if (isHTMLBRElement(*node) && convertBRsToNewlines) {
             isNullString = false;
             content.append('\n');
             break;
@@ -1590,10 +1562,10 @@
             // the same nodeType are inserted into or removed from the direct container. This would be the case, for example,
             // when comparing two attributes of the same element, and inserting or removing additional attributes might change
             // the order between existing attributes.
-            const Attribute* attribute = owner1->attributeItem(i);
-            if (attr1->qualifiedName() == attribute->name())
+            const Attribute& attribute = owner1->attributeItem(i);
+            if (attr1->qualifiedName() == attribute.name())
                 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_FOLLOWING;
-            if (attr2->qualifiedName() == attribute->name())
+            if (attr2->qualifiedName() == attribute.name())
                 return DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC | DOCUMENT_POSITION_PRECEDING;
         }
 
@@ -1737,7 +1709,9 @@
         return;
 
     stringBuilder.append(attrDesc);
+    stringBuilder.append("=\"");
     stringBuilder.append(attr);
+    stringBuilder.append("\"");
 }
 
 void Node::showNode(const char* prefix) const
@@ -1751,8 +1725,9 @@
         fprintf(stderr, "%s%s\t%p \"%s\"\n", prefix, nodeName().utf8().data(), this, value.utf8().data());
     } else {
         StringBuilder attrs;
-        appendAttributeDesc(this, attrs, classAttr, " CLASS=");
-        appendAttributeDesc(this, attrs, styleAttr, " STYLE=");
+        appendAttributeDesc(this, attrs, idAttr, " ID");
+        appendAttributeDesc(this, attrs, classAttr, " CLASS");
+        appendAttributeDesc(this, attrs, styleAttr, " STYLE");
         fprintf(stderr, "%s%s\t%p%s\n", prefix, nodeName().utf8().data(), this, attrs.toString().utf8().data());
     }
 }
@@ -1841,7 +1816,7 @@
 {
     const Node* rootNode;
     const Node* node = this;
-    while (node->parentOrShadowHostNode() && !node->hasTagName(bodyTag))
+    while (node->parentOrShadowHostNode() && !isHTMLBodyElement(*node))
         node = node->parentOrShadowHostNode();
     rootNode = node;
 
@@ -1908,7 +1883,7 @@
         // For imagemaps, the enclosing link node is the associated area element not the image itself.
         // So we don't let images be the enclosingLinkNode, even though isLink sometimes returns true
         // for them.
-        if (node->isLink() && !node->hasTagName(imgTag))
+        if (node->isLink() && !isHTMLImageElement(*node))
             return node;
     }
 
@@ -1944,17 +1919,17 @@
     }
 
     const EventListenerVector& mousewheelListeners = getEventListeners(EventTypeNames::mousewheel);
-    WheelController* oldController = WheelController::from(&oldDocument);
-    WheelController* newController = WheelController::from(&document());
+    WheelController* oldController = WheelController::from(oldDocument);
+    WheelController* newController = WheelController::from(document());
     for (size_t i = 0; i < mousewheelListeners.size(); ++i) {
-        oldController->didRemoveWheelEventHandler(&oldDocument);
-        newController->didAddWheelEventHandler(&document());
+        oldController->didRemoveWheelEventHandler(oldDocument);
+        newController->didAddWheelEventHandler(document());
     }
 
     const EventListenerVector& wheelListeners = getEventListeners(EventTypeNames::wheel);
     for (size_t i = 0; i < wheelListeners.size(); ++i) {
-        oldController->didRemoveWheelEventHandler(&oldDocument);
-        newController->didAddWheelEventHandler(&document());
+        oldController->didRemoveWheelEventHandler(oldDocument);
+        newController->didAddWheelEventHandler(document());
     }
 
     if (const TouchEventTargetSet* touchHandlers = oldDocument.touchEventTargets()) {
@@ -1985,7 +1960,7 @@
     Document& document = targetNode->document();
     document.addListenerTypeIfNeeded(eventType);
     if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
-        WheelController::from(&document)->didAddWheelEventHandler(&document);
+        WheelController::from(document)->didAddWheelEventHandler(document);
     else if (isTouchEventType(eventType))
         document.didAddTouchEventHandler(targetNode);
 
@@ -2006,7 +1981,7 @@
     // listeners for each type, not just a bool - see https://bugs.webkit.org/show_bug.cgi?id=33861
     Document& document = targetNode->document();
     if (eventType == EventTypeNames::wheel || eventType == EventTypeNames::mousewheel)
-        WheelController::from(&document)->didAddWheelEventHandler(&document);
+        WheelController::from(document)->didRemoveWheelEventHandler(document);
     else if (isTouchEventType(eventType))
         document.didRemoveTouchEventHandler(targetNode);
 
@@ -2073,7 +2048,7 @@
 }
 
 template<typename Registry>
-static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Registry* registry, Node* target, MutationObserver::MutationType type, const QualifiedName* attributeName)
+static inline void collectMatchingObserversForMutation(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, Registry* registry, Node& target, MutationObserver::MutationType type, const QualifiedName* attributeName)
 {
     if (!registry)
         return;
@@ -2081,7 +2056,7 @@
         const MutationObserverRegistration& registration = **iter;
         if (registration.shouldReceiveMutationFrom(target, type, attributeName)) {
             MutationRecordDeliveryOptions deliveryOptions = registration.deliveryOptions();
-            HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(registration.observer(), deliveryOptions);
+            HashMap<MutationObserver*, MutationRecordDeliveryOptions>::AddResult result = observers.add(&registration.observer(), deliveryOptions);
             if (!result.isNewEntry)
                 result.storedValue->value |= deliveryOptions;
         }
@@ -2091,27 +2066,27 @@
 void Node::getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>& observers, MutationObserver::MutationType type, const QualifiedName* attributeName)
 {
     ASSERT((type == MutationObserver::Attributes && attributeName) || !attributeName);
-    collectMatchingObserversForMutation(observers, mutationObserverRegistry(), this, type, attributeName);
-    collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), this, type, attributeName);
+    collectMatchingObserversForMutation(observers, mutationObserverRegistry(), *this, type, attributeName);
+    collectMatchingObserversForMutation(observers, transientMutationObserverRegistry(), *this, type, attributeName);
     for (Node* node = parentNode(); node; node = node->parentNode()) {
-        collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), this, type, attributeName);
-        collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), this, type, attributeName);
+        collectMatchingObserversForMutation(observers, node->mutationObserverRegistry(), *this, type, attributeName);
+        collectMatchingObserversForMutation(observers, node->transientMutationObserverRegistry(), *this, type, attributeName);
     }
 }
 
-void Node::registerMutationObserver(MutationObserver* observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
+void Node::registerMutationObserver(MutationObserver& observer, MutationObserverOptions options, const HashSet<AtomicString>& attributeFilter)
 {
     MutationObserverRegistration* registration = 0;
     Vector<OwnPtr<MutationObserverRegistration> >& registry = ensureRareData().ensureMutationObserverData().registry;
     for (size_t i = 0; i < registry.size(); ++i) {
-        if (registry[i]->observer() == observer) {
+        if (&registry[i]->observer() == &observer) {
             registration = registry[i].get();
             registration->resetObservation(options, attributeFilter);
         }
     }
 
     if (!registration) {
-        registry.append(MutationObserverRegistration::create(observer, this, options, attributeFilter));
+        registry.append(MutationObserverRegistration::create(observer, *this, options, attributeFilter));
         registration = registry.last().get();
     }
 
@@ -2162,12 +2137,12 @@
         if (Vector<OwnPtr<MutationObserverRegistration> >* registry = node->mutationObserverRegistry()) {
             const size_t size = registry->size();
             for (size_t i = 0; i < size; ++i)
-                registry->at(i)->observedSubtreeNodeWillDetach(this);
+                registry->at(i)->observedSubtreeNodeWillDetach(*this);
         }
 
         if (HashSet<MutationObserverRegistration*>* transientRegistry = node->transientMutationObserverRegistry()) {
             for (HashSet<MutationObserverRegistration*>::iterator iter = transientRegistry->begin(); iter != transientRegistry->end(); ++iter)
-                (*iter)->observedSubtreeNodeWillDetach(this);
+                (*iter)->observedSubtreeNodeWillDetach(*this);
         }
     }
 }
@@ -2284,7 +2259,7 @@
     const AtomicString& eventType = event->type();
     if (eventType == EventTypeNames::keydown || eventType == EventTypeNames::keypress) {
         if (event->isKeyboardEvent()) {
-            if (Frame* frame = document().frame())
+            if (LocalFrame* frame = document().frame())
                 frame->eventHandler().defaultKeyboardEventHandler(toKeyboardEvent(event));
         }
     } else if (eventType == EventTypeNames::click) {
@@ -2296,7 +2271,7 @@
             page->contextMenuController().handleContextMenuEvent(event);
     } else if (eventType == EventTypeNames::textInput) {
         if (event->hasInterface(EventNames::TextEvent)) {
-            if (Frame* frame = document().frame())
+            if (LocalFrame* frame = document().frame())
                 frame->eventHandler().defaultTextInputEventHandler(toTextEvent(event));
         }
 #if OS(WIN)
@@ -2311,7 +2286,7 @@
                 renderer = renderer->parent();
 
             if (renderer) {
-                if (Frame* frame = document().frame())
+                if (LocalFrame* frame = document().frame())
                     frame->eventHandler().startPanScrolling(renderer);
             }
         }
@@ -2326,7 +2301,7 @@
             startNode = startNode->parentOrShadowHostNode();
 
         if (startNode && startNode->renderer()) {
-            if (Frame* frame = document().frame())
+            if (LocalFrame* frame = document().frame())
                 frame->eventHandler().defaultWheelEventHandler(startNode, wheelEvent);
         }
     } else if (event->type() == EventTypeNames::webkitEditableContentChanged) {
@@ -2471,9 +2446,9 @@
 size_t Node::numberOfScopedHTMLStyleChildren() const
 {
     size_t count = 0;
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(HTMLNames::styleTag) && toHTMLStyleElement(child)->isRegisteredAsScoped())
-            count++;
+    for (HTMLStyleElement* style = Traversal<HTMLStyleElement>::firstChild(*this); style; style = Traversal<HTMLStyleElement>::nextSibling(*style)) {
+        if (style->isRegisteredAsScoped())
+            ++count;
     }
 
     return count;
@@ -2548,6 +2523,12 @@
 
 #ifndef NDEBUG
 
+void showNode(const WebCore::Node* node)
+{
+    if (node)
+        node->showNode("");
+}
+
 void showTree(const WebCore::Node* node)
 {
     if (node)
diff --git a/Source/core/dom/Node.h b/Source/core/dom/Node.h
index 3ee5488..33d1ff2 100644
--- a/Source/core/dom/Node.h
+++ b/Source/core/dom/Node.h
@@ -57,7 +57,7 @@
 class EventListener;
 class ExceptionState;
 class FloatPoint;
-class Frame;
+class LocalFrame;
 class HTMLInputElement;
 class IntRect;
 class KeyboardEvent;
@@ -172,6 +172,7 @@
     virtual NodeType nodeType() const = 0;
     ContainerNode* parentNode() const;
     Element* parentElement() const;
+    Node* parentElementOrShadowRoot() const;
     Node* previousSibling() const { return m_previous; }
     Node* nextSibling() const { return m_next; }
     PassRefPtr<NodeList> childNodes();
@@ -194,7 +195,7 @@
     void removeChild(Node* child, ExceptionState&);
     void appendChild(PassRefPtr<Node> newChild, ExceptionState& = ASSERT_NO_EXCEPTION);
 
-    bool hasChildNodes() const { return firstChild(); }
+    bool hasChildren() const { return firstChild(); }
     virtual PassRefPtr<Node> cloneNode(bool deep = false) = 0;
     virtual const AtomicString& localName() const;
     virtual const AtomicString& namespaceURI() const;
@@ -282,7 +283,7 @@
     ContainerNode* parentOrShadowHostNode() const;
     Element* parentOrShadowHostElement() const;
     void setParentOrShadowHostNode(ContainerNode*);
-    Node* highestAncestor() const;
+    Node& highestAncestor() const;
 
     // Knows about all kinds of hosts.
     ContainerNode* parentOrShadowHostOrTemplateHostNode() const;
@@ -370,6 +371,7 @@
     void clearChildNeedsStyleInvalidation()  { clearFlag(ChildNeedsStyleInvalidation); }
     void markAncestorsWithChildNeedsStyleInvalidation();
     bool needsStyleInvalidation() { return getFlag(NeedsStyleInvalidation); }
+    void clearNeedsStyleInvalidation() { clearFlag(NeedsStyleInvalidation); }
     void setNeedsStyleInvalidation();
 
     void recalcDistribution();
@@ -473,8 +475,8 @@
 
     bool isDocumentTypeNode() const { return nodeType() == DOCUMENT_TYPE_NODE; }
     virtual bool childTypeAllowed(NodeType) const { return false; }
-    unsigned childNodeCount() const;
-    Node* childNode(unsigned index) const;
+    unsigned countChildren() const;
+    Node* traverseToChildAt(unsigned index) const;
 
     bool isDescendantOf(const Node*) const;
     bool contains(const Node*) const;
@@ -560,7 +562,7 @@
     //
     // There are another callback named didNotifySubtreeInsertionsToDocument(), which is called after all the descendant is notified,
     // if this node was inserted into the document tree. Only a few subclasses actually need this. To utilize this, the node should
-    // return InsertionShouldCallDidNotifySubtreeInsertions from insrtedInto().
+    // return InsertionShouldCallDidNotifySubtreeInsertions from insertedInto().
     //
     enum InsertionNotificationRequest {
         InsertionDone,
@@ -650,7 +652,7 @@
     virtual EventTargetData& ensureEventTargetData() OVERRIDE;
 
     void getRegisteredMutationObserversOfType(HashMap<MutationObserver*, MutationRecordDeliveryOptions>&, MutationObserver::MutationType, const QualifiedName* attributeName);
-    void registerMutationObserver(MutationObserver*, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
+    void registerMutationObserver(MutationObserver&, MutationObserverOptions, const HashSet<AtomicString>& attributeFilter);
     void unregisterMutationObserver(MutationObserverRegistration*);
     void registerTransientMutationObserver(MutationObserverRegistration*);
     void unregisterTransientMutationObserver(MutationObserverRegistration*);
@@ -907,6 +909,7 @@
 
 #ifndef NDEBUG
 // Outside the WebCore namespace for ease of invocation from gdb.
+void showNode(const WebCore::Node*);
 void showTree(const WebCore::Node*);
 void showNodePath(const WebCore::Node*);
 #endif
diff --git a/Source/core/dom/Node.idl b/Source/core/dom/Node.idl
index 690190d..ed2c8aa 100644
--- a/Source/core/dom/Node.idl
+++ b/Source/core/dom/Node.idl
@@ -54,7 +54,7 @@
     [Custom, CustomElementCallbacks, PerWorldBindings, RaisesException] Node removeChild(Node oldChild);
     [Custom, CustomElementCallbacks, PerWorldBindings, ActivityLogging=ForIsolatedWorlds, RaisesException] Node appendChild(Node newChild);
 
-    boolean            hasChildNodes();
+    [ImplementedAs=hasChildren] boolean hasChildNodes();
     [CustomElementCallbacks, PerWorldBindings]
     Node               cloneNode(optional boolean deep);
     [CustomElementCallbacks] void normalize();
@@ -85,7 +85,7 @@
     unsigned short compareDocumentPosition(Node other);
 
     // Introduced in DOM4
-    [ImplementedAs=containsIncludingShadowDOM] boolean contains(Node other);
+    boolean contains(Node other);
 
     // IE extensions
     [PerWorldBindings] readonly attribute Element parentElement;
diff --git a/Source/core/dom/NodeFilter.idl b/Source/core/dom/NodeFilter.idl
index 58ac22e..36d5e82 100644
--- a/Source/core/dom/NodeFilter.idl
+++ b/Source/core/dom/NodeFilter.idl
@@ -19,7 +19,7 @@
  */
 
 [
-    DependentLifetime
+    DependentLifetime,
 ] interface NodeFilter {
     // Constants returned by acceptNode
     const short               FILTER_ACCEPT                  = 1;
@@ -44,4 +44,3 @@
     [CallWith=ScriptState] short acceptNode([Default=Undefined] optional Node n);
 
 };
-
diff --git a/Source/core/dom/NodeIterator.cpp b/Source/core/dom/NodeIterator.cpp
index 35c912f..6127231 100644
--- a/Source/core/dom/NodeIterator.cpp
+++ b/Source/core/dom/NodeIterator.cpp
@@ -73,7 +73,7 @@
 }
 
 NodeIterator::NodeIterator(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
-    : Traversal(rootNode, whatToShow, filter)
+    : NodeIteratorBase(rootNode, whatToShow, filter)
     , m_referenceNode(root(), true)
     , m_detached(false)
 {
@@ -90,7 +90,7 @@
 {
     if (m_detached) {
         exceptionState.throwDOMException(InvalidStateError, "The iterator is detached.");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<Node> result;
@@ -119,7 +119,7 @@
 {
     if (m_detached) {
         exceptionState.throwDOMException(InvalidStateError, "The iterator is detached.");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<Node> result;
diff --git a/Source/core/dom/NodeIterator.h b/Source/core/dom/NodeIterator.h
index 1f06a57..fcbe77b 100644
--- a/Source/core/dom/NodeIterator.h
+++ b/Source/core/dom/NodeIterator.h
@@ -27,7 +27,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/NodeFilter.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
@@ -35,7 +35,7 @@
 
 class ExceptionState;
 
-class NodeIterator : public ScriptWrappable, public RefCounted<NodeIterator>, public Traversal {
+class NodeIterator : public ScriptWrappable, public RefCounted<NodeIterator>, public NodeIteratorBase {
 public:
     static PassRefPtr<NodeIterator> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
     {
diff --git a/Source/core/dom/NodeIterator.idl b/Source/core/dom/NodeIterator.idl
index c47c809..8da36f6 100644
--- a/Source/core/dom/NodeIterator.idl
+++ b/Source/core/dom/NodeIterator.idl
@@ -18,9 +18,9 @@
  * Boston, MA 02110-1301, USA.
  */
 
-// Introduced in DOM Level 2:
+// Introduced in DOM Level 2
 [
-    SetWrapperReferenceTo(NodeFilter filter)
+    SetWrapperReferenceTo(NodeFilter filter),
 ] interface NodeIterator {
     readonly attribute Node root;
     readonly attribute unsigned long whatToShow;
@@ -33,4 +33,3 @@
     [CallWith=ScriptState, RaisesException] Node previousNode();
     void detach();
 };
-
diff --git a/Source/core/dom/Traversal.cpp b/Source/core/dom/NodeIteratorBase.cpp
similarity index 87%
rename from Source/core/dom/Traversal.cpp
rename to Source/core/dom/NodeIteratorBase.cpp
index a9262cc..aa450fe 100644
--- a/Source/core/dom/Traversal.cpp
+++ b/Source/core/dom/NodeIteratorBase.cpp
@@ -23,21 +23,21 @@
  */
 
 #include "config.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
 
 #include "core/dom/Node.h"
 #include "core/dom/NodeFilter.h"
 
 namespace WebCore {
 
-Traversal::Traversal(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter)
+NodeIteratorBase::NodeIteratorBase(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> nodeFilter)
     : m_root(rootNode)
     , m_whatToShow(whatToShow)
     , m_filter(nodeFilter)
 {
 }
 
-short Traversal::acceptNode(ScriptState* state, Node* node) const
+short NodeIteratorBase::acceptNode(ScriptState* state, Node* node) const
 {
     // The bit twiddling here is done to map DOM node types, which are given as integers from
     // 1 through 14, to whatToShow bit masks.
diff --git a/Source/core/dom/NodeIteratorBase.h b/Source/core/dom/NodeIteratorBase.h
new file mode 100644
index 0000000..0118e3e
--- /dev/null
+++ b/Source/core/dom/NodeIteratorBase.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
+ * Copyright (C) 2001 Peter Kelly (pmk@post.com)
+ * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
+ * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef NodeIteratorBase_h
+#define NodeIteratorBase_h
+
+#include "bindings/v8/ScriptState.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class Node;
+class NodeFilter;
+
+class NodeIteratorBase {
+public:
+    Node* root() const { return m_root.get(); }
+    unsigned whatToShow() const { return m_whatToShow; }
+    NodeFilter* filter() const { return m_filter.get(); }
+    // |expandEntityReferences| first appeared in "DOM Level 2 Traversal and Range". However, this argument was
+    // never implemented, and, in DOM4, the function argument |expandEntityReferences| is removed from
+    // Document.createNodeIterator() and Document.createTreeWalker().
+    bool expandEntityReferences() const { return false; }
+
+protected:
+    NodeIteratorBase(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
+    short acceptNode(ScriptState*, Node*) const;
+
+private:
+    RefPtr<Node> m_root;
+    unsigned m_whatToShow;
+    RefPtr<NodeFilter> m_filter;
+};
+
+} // namespace WebCore
+
+#endif // NodeIteratorBase_h
diff --git a/Source/core/dom/NodeRareData.h b/Source/core/dom/NodeRareData.h
index 3572d14..b127e7e 100644
--- a/Source/core/dom/NodeRareData.h
+++ b/Source/core/dom/NodeRareData.h
@@ -50,7 +50,7 @@
             toChildNodeList(m_childNodeList)->invalidateCache();
     }
 
-    PassRefPtr<ChildNodeList> ensureChildNodeList(ContainerNode* node)
+    PassRefPtr<ChildNodeList> ensureChildNodeList(ContainerNode& node)
     {
         if (m_childNodeList)
             return toChildNodeList(m_childNodeList);
@@ -59,7 +59,7 @@
         return list.release();
     }
 
-    PassRefPtr<EmptyNodeList> ensureEmptyChildNodeList(Node* node)
+    PassRefPtr<EmptyNodeList> ensureEmptyChildNodeList(Node& node)
     {
         if (m_childNodeList)
             return toEmptyNodeList(m_childNodeList);
@@ -97,7 +97,7 @@
     typedef HashMap<QualifiedName, TagCollection*> TagCollectionCacheNS;
 
     template<typename T>
-    PassRefPtr<T> addCache(ContainerNode* node, CollectionType collectionType, const AtomicString& name)
+    PassRefPtr<T> addCache(ContainerNode& node, CollectionType collectionType, const AtomicString& name)
     {
         NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, name), 0);
         if (!result.isNewEntry)
@@ -109,7 +109,7 @@
     }
 
     template<typename T>
-    PassRefPtr<T> addCache(ContainerNode* node, CollectionType collectionType)
+    PassRefPtr<T> addCache(ContainerNode& node, CollectionType collectionType)
     {
         NodeListAtomicNameCacheMap::AddResult result = m_atomicNameCaches.add(namedNodeListKey(collectionType, starAtom), 0);
         if (!result.isNewEntry)
@@ -126,7 +126,7 @@
         return static_cast<T*>(m_atomicNameCaches.get(namedNodeListKey(collectionType, starAtom)));
     }
 
-    PassRefPtr<TagCollection> addCache(ContainerNode* node, const AtomicString& namespaceURI, const AtomicString& localName)
+    PassRefPtr<TagCollection> addCache(ContainerNode& node, const AtomicString& namespaceURI, const AtomicString& localName)
     {
         QualifiedName name(nullAtom, localName, namespaceURI);
         TagCollectionCacheNS::AddResult result = m_tagCollectionCacheNS.add(name, 0);
@@ -201,7 +201,7 @@
         return std::pair<unsigned char, StringImpl*>(type, name.impl());
     }
 
-    bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node*);
+    bool deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node&);
 
     // Can be a ChildNodeList or an EmptyNodeList.
     NodeList* m_childNodeList;
@@ -268,13 +268,12 @@
     OwnPtr<NodeMutationObserverData> m_mutationObserverData;
 };
 
-inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node* ownerNode)
+inline bool NodeListsNodeData::deleteThisAndUpdateNodeRareDataIfAboutToRemoveLastList(Node& ownerNode)
 {
-    ASSERT(ownerNode);
-    ASSERT(ownerNode->nodeLists() == this);
+    ASSERT(ownerNode.nodeLists() == this);
     if ((m_childNodeList ? 1 : 0) + m_atomicNameCaches.size() + m_tagCollectionCacheNS.size() != 1)
         return false;
-    ownerNode->clearNodeLists();
+    ownerNode.clearNodeLists();
     return true;
 }
 
diff --git a/Source/core/dom/NodeRenderStyle.h b/Source/core/dom/NodeRenderStyle.h
index deef2fd..96b9fab 100644
--- a/Source/core/dom/NodeRenderStyle.h
+++ b/Source/core/dom/NodeRenderStyle.h
@@ -25,9 +25,9 @@
 #ifndef NodeRenderStyle_h
 #define NodeRenderStyle_h
 
-#include "HTMLNames.h"
 #include "core/dom/Node.h"
 #include "core/dom/NodeRenderingTraversal.h"
+#include "core/html/HTMLOptGroupElement.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/style/RenderStyle.h"
 
@@ -40,7 +40,7 @@
     // <option> and <optgroup> can be styled even though they never get renderers,
     // so they store their style internally and return it through nonRendererStyle().
     // We check here explicitly to avoid the virtual call in the common case.
-    if (hasTagName(HTMLNames::optgroupTag) || hasTagName(HTMLNames::optionTag))
+    if (isHTMLOptGroupElement(*this) || isHTMLOptionElement(this))
         return nonRendererStyle();
     return 0;
 }
diff --git a/Source/core/dom/NodeRenderingTraversal.cpp b/Source/core/dom/NodeRenderingTraversal.cpp
index b6f1db3..496413e 100644
--- a/Source/core/dom/NodeRenderingTraversal.cpp
+++ b/Source/core/dom/NodeRenderingTraversal.cpp
@@ -118,6 +118,115 @@
     return 0;
 }
 
+static Node* lastChild(const Node* node)
+{
+    ComposedTreeWalker walker(node);
+    walker.lastChild();
+    return walker.get();
+}
+
+static Node* pseudoAwarePreviousSibling(const Node* node)
+{
+    Node* previousNode = previousSibling(node);
+    Node* parentNode = parent(node);
+
+    if (parentNode && parentNode->isElementNode() && !previousNode) {
+        if (node->isAfterPseudoElement()) {
+            if (Node* child = lastChild(parentNode))
+                return child;
+        }
+        if (!node->isBeforePseudoElement())
+            return toElement(parentNode)->pseudoElement(BEFORE);
+    }
+    return previousNode;
+}
+
+static Node* pseudoAwareLastChild(const Node* node)
+{
+    if (node->isElementNode()) {
+        const Element* currentElement = toElement(node);
+        Node* last = currentElement->pseudoElement(AFTER);
+        if (last)
+            return last;
+
+        last = lastChild(currentElement);
+        if (!last)
+            last = currentElement->pseudoElement(BEFORE);
+        return last;
+    }
+
+    return lastChild(node);
+}
+
+Node* previous(const Node* node, const Node* stayWithin)
+{
+    if (node == stayWithin)
+        return 0;
+
+    if (Node* previousNode = pseudoAwarePreviousSibling(node)) {
+        while (Node* previousLastChild = pseudoAwareLastChild(previousNode))
+            previousNode = previousLastChild;
+        return previousNode;
+    }
+    return parent(node);
+}
+
+static Node* firstChild(const Node* node)
+{
+    ComposedTreeWalker walker(node);
+    walker.firstChild();
+    return walker.get();
+}
+
+static Node* pseudoAwareNextSibling(const Node* node)
+{
+    Node* parentNode = parent(node);
+    Node* nextNode = nextSibling(node);
+
+    if (parentNode && parentNode->isElementNode() && !nextNode) {
+        if (node->isBeforePseudoElement()) {
+            if (Node* child = firstChild(parentNode))
+                return child;
+        }
+        if (!node->isAfterPseudoElement())
+            return toElement(parentNode)->pseudoElement(AFTER);
+    }
+    return nextNode;
+}
+
+static Node* pseudoAwareFirstChild(const Node* node)
+{
+    if (node->isElementNode()) {
+        const Element* currentElement = toElement(node);
+        Node* first = currentElement->pseudoElement(BEFORE);
+        if (first)
+            return first;
+        first = firstChild(currentElement);
+        if (!first)
+            first = currentElement->pseudoElement(AFTER);
+        return first;
+    }
+
+    return firstChild(node);
+}
+
+Node* next(const Node* node, const Node* stayWithin)
+{
+    if (Node* child = pseudoAwareFirstChild(node))
+        return child;
+    if (node == stayWithin)
+        return 0;
+    if (Node* nextNode = pseudoAwareNextSibling(node))
+        return nextNode;
+    for (Node* parentNode = parent(node); parentNode; parentNode = parent(parentNode)) {
+        if (parentNode == stayWithin)
+            return 0;
+        if (Node* nextNode = pseudoAwareNextSibling(parentNode))
+            return nextNode;
+    }
+    return 0;
+}
+
 RenderObject* nextSiblingRenderer(const Node* node)
 {
     for (Node* sibling = NodeRenderingTraversal::nextSibling(node); sibling; sibling = NodeRenderingTraversal::nextSibling(sibling)) {
diff --git a/Source/core/dom/NodeRenderingTraversal.h b/Source/core/dom/NodeRenderingTraversal.h
index fab1bc3..2d96b25 100644
--- a/Source/core/dom/NodeRenderingTraversal.h
+++ b/Source/core/dom/NodeRenderingTraversal.h
@@ -65,6 +65,8 @@
 bool contains(const ContainerNode*, const Node*);
 Node* nextSibling(const Node*);
 Node* previousSibling(const Node*);
+Node* previous(const Node*, const Node* stayWithin);
+Node* next(const Node*, const Node* stayWithin);
 RenderObject* nextSiblingRenderer(const Node*);
 RenderObject* previousSiblingRenderer(const Node*);
 RenderObject* nextInTopLayer(const Element*);
diff --git a/Source/core/dom/NodeTraversal.cpp b/Source/core/dom/NodeTraversal.cpp
index b5eba51..37e37cc 100644
--- a/Source/core/dom/NodeTraversal.cpp
+++ b/Source/core/dom/NodeTraversal.cpp
@@ -28,9 +28,8 @@
 #include "core/dom/ContainerNode.h"
 
 namespace WebCore {
-namespace NodeTraversal {
 
-Node* previousIncludingPseudo(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousIncludingPseudo(const Node& current, const Node* stayWithin)
 {
     if (current == stayWithin)
         return 0;
@@ -42,7 +41,7 @@
     return current.parentNode();
 }
 
-Node* nextIncludingPseudo(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextIncludingPseudo(const Node& current, const Node* stayWithin)
 {
     if (Node* next = current.pseudoAwareFirstChild())
         return next;
@@ -59,7 +58,7 @@
     return 0;
 }
 
-Node* nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextIncludingPseudoSkippingChildren(const Node& current, const Node* stayWithin)
 {
     if (current == stayWithin)
         return 0;
@@ -74,7 +73,7 @@
     return 0;
 }
 
-Node* nextAncestorSibling(const Node& current)
+Node* NodeTraversal::nextAncestorSibling(const Node& current)
 {
     ASSERT(!current.nextSibling());
     for (Node* parent = current.parentNode(); parent; parent = parent->parentNode()) {
@@ -84,7 +83,7 @@
     return 0;
 }
 
-Node* nextAncestorSibling(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextAncestorSibling(const Node& current, const Node* stayWithin)
 {
     ASSERT(!current.nextSibling());
     ASSERT(current != stayWithin);
@@ -97,7 +96,7 @@
     return 0;
 }
 
-Node* previous(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previous(const Node& current, const Node* stayWithin)
 {
     if (current == stayWithin)
         return 0;
@@ -110,7 +109,7 @@
     return current.parentNode();
 }
 
-Node* previousSkippingChildren(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousSkippingChildren(const Node& current, const Node* stayWithin)
 {
     if (current == stayWithin)
         return 0;
@@ -125,7 +124,7 @@
     return 0;
 }
 
-Node* nextPostOrder(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::nextPostOrder(const Node& current, const Node* stayWithin)
 {
     if (current == stayWithin)
         return 0;
@@ -149,7 +148,7 @@
     return 0;
 }
 
-Node* previousPostOrder(const Node& current, const Node* stayWithin)
+Node* NodeTraversal::previousPostOrder(const Node& current, const Node* stayWithin)
 {
     if (current.lastChild())
         return current.lastChild();
@@ -160,5 +159,4 @@
     return previousAncestorSiblingPostOrder(current, stayWithin);
 }
 
-}
-}
+} // namespace WebCore
diff --git a/Source/core/dom/NodeTraversal.h b/Source/core/dom/NodeTraversal.h
index 995613a..41017f8 100644
--- a/Source/core/dom/NodeTraversal.h
+++ b/Source/core/dom/NodeTraversal.h
@@ -4,6 +4,7 @@
  *           (C) 2001 Dirk Mueller (mueller@kde.org)
  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
  * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2014 Samsung Electronics. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -29,45 +30,56 @@
 
 namespace WebCore {
 
-namespace NodeTraversal {
+class NodeTraversal {
+public:
+    // Does a pre-order traversal of the tree to find the next node after this one.
+    // This uses the same order that tags appear in the source file. If the stayWithin
+    // argument is non-null, the traversal will stop once the specified node is reached.
+    // This can be used to restrict traversal to a particular sub-tree.
+    static Node* next(const Node& current) { return traverseNextTemplate(current); }
+    static Node* next(const ContainerNode& current) { return traverseNextTemplate(current); }
+    static Node* next(const Node& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
+    static Node* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
 
-// Does a pre-order traversal of the tree to find the next node after this one.
-// This uses the same order that tags appear in the source file. If the stayWithin
-// argument is non-null, the traversal will stop once the specified node is reached.
-// This can be used to restrict traversal to a particular sub-tree.
-Node* next(const Node&);
-Node* next(const Node&, const Node* stayWithin);
-Node* next(const ContainerNode&);
-Node* next(const ContainerNode&, const Node* stayWithin);
+    // Like next, but skips children and starts with the next sibling.
+    static Node* nextSkippingChildren(const Node& current) { return traverseNextSkippingChildrenTemplate(current); }
+    static Node* nextSkippingChildren(const ContainerNode& current) { return traverseNextSkippingChildrenTemplate(current); }
+    static Node* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
+    static Node* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
 
-// Like next, but skips children and starts with the next sibling.
-Node* nextSkippingChildren(const Node&);
-Node* nextSkippingChildren(const Node&, const Node* stayWithin);
-Node* nextSkippingChildren(const ContainerNode&);
-Node* nextSkippingChildren(const ContainerNode&, const Node* stayWithin);
+    // Does a reverse pre-order traversal to find the node that comes before the current one in document order
+    static Node* previous(const Node&, const Node* stayWithin = 0);
 
-// Does a reverse pre-order traversal to find the node that comes before the current one in document order
-Node* previous(const Node&, const Node* stayWithin = 0);
+    // Like previous, but skips children and starts with the next sibling.
+    static Node* previousSkippingChildren(const Node&, const Node* stayWithin = 0);
 
-// Like previous, but skips children and starts with the next sibling.
-Node* previousSkippingChildren(const Node&, const Node* stayWithin = 0);
+    // Like next, but visits parents after their children.
+    static Node* nextPostOrder(const Node&, const Node* stayWithin = 0);
 
-// Like next, but visits parents after their children.
-Node* nextPostOrder(const Node&, const Node* stayWithin = 0);
+    // Like previous, but visits parents before their children.
+    static Node* previousPostOrder(const Node&, const Node* stayWithin = 0);
 
-// Like previous, but visits parents before their children.
-Node* previousPostOrder(const Node&, const Node* stayWithin = 0);
+    // Pre-order traversal including the pseudo-elements.
+    static Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
+    static Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
+    static Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
 
-// Pre-order traversal including the pseudo-elements.
-Node* previousIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Node* nextIncludingPseudo(const Node&, const Node* stayWithin = 0);
-Node* nextIncludingPseudoSkippingChildren(const Node&, const Node* stayWithin = 0);
+    static Node* nextAncestorSibling(const Node&);
+    static Node* nextAncestorSibling(const Node&, const Node* stayWithin);
 
-Node* nextAncestorSibling(const Node&);
-Node* nextAncestorSibling(const Node&, const Node* stayWithin);
+private:
+    template <class NodeType>
+    static Node* traverseNextTemplate(NodeType&);
+    template <class NodeType>
+    static Node* traverseNextTemplate(NodeType&, const Node* stayWithin);
+    template <class NodeType>
+    static Node* traverseNextSkippingChildrenTemplate(NodeType&);
+    template <class NodeType>
+    static Node* traverseNextSkippingChildrenTemplate(NodeType&, const Node* stayWithin);
+};
 
 template <class NodeType>
-inline Node* traverseNextTemplate(NodeType& current)
+inline Node* NodeTraversal::traverseNextTemplate(NodeType& current)
 {
     if (current.firstChild())
         return current.firstChild();
@@ -75,11 +87,9 @@
         return current.nextSibling();
     return nextAncestorSibling(current);
 }
-inline Node* next(const Node& current) { return traverseNextTemplate(current); }
-inline Node* next(const ContainerNode& current) { return traverseNextTemplate(current); }
 
 template <class NodeType>
-inline Node* traverseNextTemplate(NodeType& current, const Node* stayWithin)
+inline Node* NodeTraversal::traverseNextTemplate(NodeType& current, const Node* stayWithin)
 {
     if (current.firstChild())
         return current.firstChild();
@@ -89,21 +99,17 @@
         return current.nextSibling();
     return nextAncestorSibling(current, stayWithin);
 }
-inline Node* next(const Node& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
-inline Node* next(const ContainerNode& current, const Node* stayWithin) { return traverseNextTemplate(current, stayWithin); }
 
 template <class NodeType>
-inline Node* traverseNextSkippingChildrenTemplate(NodeType& current)
+inline Node* NodeTraversal::traverseNextSkippingChildrenTemplate(NodeType& current)
 {
     if (current.nextSibling())
         return current.nextSibling();
     return nextAncestorSibling(current);
 }
-inline Node* nextSkippingChildren(const Node& current) { return traverseNextSkippingChildrenTemplate(current); }
-inline Node* nextSkippingChildren(const ContainerNode& current) { return traverseNextSkippingChildrenTemplate(current); }
 
 template <class NodeType>
-inline Node* traverseNextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
+inline Node* NodeTraversal::traverseNextSkippingChildrenTemplate(NodeType& current, const Node* stayWithin)
 {
     if (current == stayWithin)
         return 0;
@@ -111,11 +117,7 @@
         return current.nextSibling();
     return nextAncestorSibling(current, stayWithin);
 }
-inline Node* nextSkippingChildren(const Node& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
-inline Node* nextSkippingChildren(const ContainerNode& current, const Node* stayWithin) { return traverseNextSkippingChildrenTemplate(current, stayWithin); }
 
-}
-
-}
+} // namespace WebCore
 
 #endif
diff --git a/Source/core/dom/NodeWithIndex.h b/Source/core/dom/NodeWithIndex.h
index 8c75ccc..02b6d33 100644
--- a/Source/core/dom/NodeWithIndex.h
+++ b/Source/core/dom/NodeWithIndex.h
@@ -34,27 +34,26 @@
 // only want to walk the child list to figure out the index once.
 class NodeWithIndex {
 public:
-    explicit NodeWithIndex(Node* node)
+    explicit NodeWithIndex(Node& node)
         : m_node(node)
         , m_haveIndex(false)
     {
-        ASSERT(node);
     }
 
-    Node* node() const { return m_node; }
+    Node& node() const { return m_node; }
 
     int index() const
     {
         if (!m_haveIndex) {
-            m_index = m_node->nodeIndex();
+            m_index = m_node.nodeIndex();
             m_haveIndex = true;
         }
-        ASSERT(m_index == static_cast<int>(m_node->nodeIndex()));
+        ASSERT(m_index == static_cast<int>(m_node.nodeIndex()));
         return m_index;
     }
 
 private:
-    Node* m_node;
+    Node& m_node;
     mutable bool m_haveIndex;
     mutable int m_index;
 };
diff --git a/Source/core/dom/ParentNode.h b/Source/core/dom/ParentNode.h
index 45f146c..dda6a8a 100644
--- a/Source/core/dom/ParentNode.h
+++ b/Source/core/dom/ParentNode.h
@@ -38,28 +38,25 @@
 
 class ParentNode {
 public:
-    static PassRefPtr<HTMLCollection> children(ContainerNode* node)
+    static PassRefPtr<HTMLCollection> children(ContainerNode& node)
     {
-        return node->children();
+        return node.children();
     }
 
-    static Element* firstElementChild(ContainerNode* node)
+    static Element* firstElementChild(ContainerNode& node)
     {
-        ASSERT(node);
-        return ElementTraversal::firstWithin(*node);
+        return ElementTraversal::firstWithin(node);
     }
 
-    static Element* lastElementChild(ContainerNode* node)
+    static Element* lastElementChild(ContainerNode& node)
     {
-        ASSERT(node);
-        return ElementTraversal::lastWithin(*node);
+        return ElementTraversal::lastWithin(node);
     }
 
-    static unsigned childElementCount(ContainerNode* node)
+    static unsigned childElementCount(ContainerNode& node)
     {
-        ASSERT(node);
         unsigned count = 0;
-        for (Element* child = ElementTraversal::firstWithin(*node); child; child = ElementTraversal::nextSibling(*child))
+        for (Element* child = ElementTraversal::firstWithin(node); child; child = ElementTraversal::nextSibling(*child))
             ++count;
         return count;
     }
diff --git a/Source/core/dom/Position.cpp b/Source/core/dom/Position.cpp
index 91832ed..2bdca34 100644
--- a/Source/core/dom/Position.cpp
+++ b/Source/core/dom/Position.cpp
@@ -35,14 +35,15 @@
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
-#include "platform/Logging.h"
+#include "core/html/HTMLTableElement.h"
 #include "core/rendering/InlineIterator.h"
 #include "core/rendering/InlineTextBox.h"
 #include "core/rendering/RenderBlock.h"
 #include "core/rendering/RenderInline.h"
 #include "core/rendering/RenderText.h"
+#include "platform/Logging.h"
 #include "wtf/text/CString.h"
 #include "wtf/unicode/CharacterNames.h"
 
@@ -210,14 +211,14 @@
     // FIXME: This should only be necessary for legacy positions, but is also needed for positions before and after Tables
     if (m_offset <= 0 && (m_anchorType != PositionIsAfterAnchor && m_anchorType != PositionIsAfterChildren)) {
         if (m_anchorNode->parentNode() && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTableElement(m_anchorNode.get())))
-            return positionInParentBeforeNode(m_anchorNode.get());
+            return positionInParentBeforeNode(*m_anchorNode);
         return Position(m_anchorNode.get(), 0, PositionIsOffsetInAnchor);
     }
     if (!m_anchorNode->offsetInCharacters()
-        && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->childNodeCount())
+        && (m_anchorType == PositionIsAfterAnchor || m_anchorType == PositionIsAfterChildren || static_cast<unsigned>(m_offset) == m_anchorNode->countChildren())
         && (editingIgnoresContent(m_anchorNode.get()) || isRenderedTableElement(m_anchorNode.get()))
         && containerNode()) {
-        return positionInParentAfterNode(m_anchorNode.get());
+        return positionInParentAfterNode(*m_anchorNode);
     }
 
     return Position(containerNode(), computeOffsetInContainerNode(), PositionIsOffsetInAnchor);
@@ -234,7 +235,7 @@
     case PositionIsAfterChildren:
         return m_anchorNode->lastChild();
     case PositionIsOffsetInAnchor:
-        return m_anchorNode->childNode(m_offset - 1); // -1 converts to childNode((unsigned)-1) and returns null.
+        return m_anchorNode->traverseToChildAt(m_offset - 1); // -1 converts to traverseToChildAt((unsigned)-1) and returns null.
     case PositionIsBeforeAnchor:
         return m_anchorNode->previousSibling();
     case PositionIsAfterAnchor:
@@ -255,7 +256,7 @@
     case PositionIsAfterChildren:
         return 0;
     case PositionIsOffsetInAnchor:
-        return m_anchorNode->childNode(m_offset);
+        return m_anchorNode->traverseToChildAt(m_offset);
     case PositionIsBeforeAnchor:
         return m_anchorNode.get();
     case PositionIsAfterAnchor:
@@ -288,7 +289,7 @@
 {
     Element* elem = element();
     if (!elem)
-        return 0;
+        return nullptr;
     return CSSComputedStyleDeclaration::create(elem);
 }
 
@@ -303,7 +304,7 @@
     ASSERT(offset >= 0);
 
     if (offset > 0) {
-        if (Node* child = node->childNode(offset - 1))
+        if (Node* child = node->traverseToChildAt(offset - 1))
             return lastPositionInOrAfterNode(child);
 
         // There are two reasons child might be 0:
@@ -338,10 +339,10 @@
     // FIXME: Negative offsets shouldn't be allowed. We should catch this earlier.
     ASSERT(offset >= 0);
 
-    if (Node* child = node->childNode(offset))
+    if (Node* child = node->traverseToChildAt(offset))
         return firstPositionInOrBeforeNode(child);
 
-    if (!node->hasChildNodes() && offset < lastOffsetForEditing(node)) {
+    if (!node->hasChildren() && offset < lastOffsetForEditing(node)) {
         // There are two reasons child might be 0:
         //   1) The node is node like a text node that is not an element, and therefore has no children.
         //      Going forward one character at a time is correct.
@@ -544,9 +545,14 @@
         return true;
 
     // Don't include inline tables.
-    if (node->hasTagName(tableTag))
+    if (isHTMLTableElement(*node))
         return false;
 
+    // A Marquee elements are moving so we should assume their ends are always
+    // visibily distinct.
+    if (isHTMLMarqueeElement(*node))
+        return true;
+
     // There is a VisiblePosition inside an empty inline-block container.
     return node->renderer()->isReplaced() && canHaveChildrenForEditing(node) && toRenderBox(node->renderer())->height() != 0 && !node->firstChild();
 }
@@ -734,7 +740,7 @@
 
         // stop before going above the body, up into the head
         // return the last visible streamer position
-        if (currentNode->hasTagName(bodyTag) && currentPos.atEndOfNode())
+        if (isHTMLBodyElement(*currentNode) && currentPos.atEndOfNode())
             break;
 
         // Do not move to a visually distinct position.
@@ -890,17 +896,17 @@
     if (isRenderedTableElement(deprecatedNode()) || editingIgnoresContent(deprecatedNode()))
         return (atFirstEditingPositionForNode() || atLastEditingPositionForNode()) && !nodeIsUserSelectNone(deprecatedNode()->parentNode());
 
-    if (m_anchorNode->hasTagName(htmlTag))
+    if (isHTMLHtmlElement(*m_anchorNode))
         return false;
 
     if (renderer->isRenderBlockFlow()) {
-        if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
+        if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anchorNode)) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
                 return atFirstEditingPositionForNode() && !Position::nodeIsUserSelectNone(deprecatedNode());
             return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
         }
     } else {
-        Frame* frame = m_anchorNode->document().frame();
+        LocalFrame* frame = m_anchorNode->document().frame();
         bool caretBrowsing = frame->settings() && frame->settings()->caretBrowsingEnabled();
         return (caretBrowsing || m_anchorNode->rendererIsEditable()) && !Position::nodeIsUserSelectNone(deprecatedNode()) && atEditingBoundary();
     }
@@ -975,7 +981,7 @@
         return false;
 
     if (deprecatedNode() == pos.deprecatedNode()) {
-        if (deprecatedNode()->hasTagName(brTag))
+        if (isHTMLBRElement(*deprecatedNode()))
             return false;
 
         if (m_offset == pos.deprecatedEditingOffset())
@@ -987,10 +993,10 @@
         }
     }
 
-    if (deprecatedNode()->hasTagName(brTag) && pos.isCandidate())
+    if (isHTMLBRElement(*deprecatedNode()) && pos.isCandidate())
         return true;
 
-    if (pos.deprecatedNode()->hasTagName(brTag) && isCandidate())
+    if (isHTMLBRElement(*pos.deprecatedNode()) && isCandidate())
         return true;
 
     if (deprecatedNode()->enclosingBlockFlowElement() != pos.deprecatedNode()->enclosingBlockFlowElement())
@@ -1050,7 +1056,7 @@
     if (isNull())
         return Position();
 
-    if (upstream().deprecatedNode()->hasTagName(brTag))
+    if (isHTMLBRElement(*upstream().deprecatedNode()))
         return Position();
 
     Position prev = previousCharacterPosition(affinity);
diff --git a/Source/core/dom/Position.h b/Source/core/dom/Position.h
index eea78f6..643ba2b 100644
--- a/Source/core/dom/Position.h
+++ b/Source/core/dom/Position.h
@@ -244,19 +244,19 @@
 // These are inline to prevent ref-churn when returning a Position object.
 // If we ever add a PassPosition we can make these non-inline.
 
-inline Position positionInParentBeforeNode(const Node* node)
+inline Position positionInParentBeforeNode(const Node& node)
 {
-    // FIXME: This should ASSERT(node->parentNode())
+    // FIXME: This should ASSERT(node.parentNode())
     // At least one caller currently hits this ASSERT though, which indicates
     // that the caller is trying to make a position relative to a disconnected node (which is likely an error)
     // Specifically, editing/deleting/delete-ligature-001.html crashes with ASSERT(node->parentNode())
-    return Position(node->parentNode(), node->nodeIndex(), Position::PositionIsOffsetInAnchor);
+    return Position(node.parentNode(), node.nodeIndex(), Position::PositionIsOffsetInAnchor);
 }
 
-inline Position positionInParentAfterNode(const Node* node)
+inline Position positionInParentAfterNode(const Node& node)
 {
-    ASSERT(node->parentNode());
-    return Position(node->parentNode(), node->nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
+    ASSERT(node.parentNode());
+    return Position(node.parentNode(), node.nodeIndex() + 1, Position::PositionIsOffsetInAnchor);
 }
 
 // positionBeforeNode and positionAfterNode return neighbor-anchored positions, construction is O(1)
@@ -274,10 +274,10 @@
 
 inline int lastOffsetInNode(Node* node)
 {
-    return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast<int>(node->childNodeCount());
+    return node->offsetInCharacters() ? node->maxCharacterOffset() : static_cast<int>(node->countChildren());
 }
 
-// firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to childNodeCount()
+// firstPositionInNode and lastPositionInNode return parent-anchored positions, lastPositionInNode construction is O(n) due to countChildren()
 inline Position firstPositionInNode(Node* anchorNode)
 {
     if (anchorNode->isTextNode())
diff --git a/Source/core/dom/PositionIterator.cpp b/Source/core/dom/PositionIterator.cpp
index d99beaa..c6a3ca2 100644
--- a/Source/core/dom/PositionIterator.cpp
+++ b/Source/core/dom/PositionIterator.cpp
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "core/dom/PositionIterator.h"
 
-#include "HTMLNames.h"
 #include "core/editing/htmlediting.h"
+#include "core/html/HTMLHtmlElement.h"
 #include "core/rendering/RenderBlock.h"
 
 namespace WebCore {
@@ -41,9 +41,9 @@
         // FIXME: This check is inadaquete because any ancestor could be ignored by editing
         if (editingIgnoresContent(m_nodeAfterPositionInAnchor->parentNode()))
             return positionBeforeNode(m_anchorNode);
-        return positionInParentBeforeNode(m_nodeAfterPositionInAnchor);
+        return positionInParentBeforeNode(*m_nodeAfterPositionInAnchor);
     }
-    if (m_anchorNode->hasChildNodes())
+    if (m_anchorNode->hasChildren())
         return lastPositionInOrAfterNode(m_anchorNode);
     return createLegacyEditingPosition(m_anchorNode, m_offsetInAnchor);
 }
@@ -60,7 +60,7 @@
         return;
     }
 
-    if (!m_anchorNode->hasChildNodes() && m_offsetInAnchor < lastOffsetForEditing(m_anchorNode))
+    if (!m_anchorNode->hasChildren() && m_offsetInAnchor < lastOffsetForEditing(m_anchorNode))
         m_offsetInAnchor = Position::uncheckedNextOffset(m_anchorNode, m_offsetInAnchor);
     else {
         m_nodeAfterPositionInAnchor = m_anchorNode;
@@ -79,7 +79,7 @@
         m_anchorNode = m_nodeAfterPositionInAnchor->previousSibling();
         if (m_anchorNode) {
             m_nodeAfterPositionInAnchor = 0;
-            m_offsetInAnchor = m_anchorNode->hasChildNodes() ? 0 : lastOffsetForEditing(m_anchorNode);
+            m_offsetInAnchor = m_anchorNode->hasChildren() ? 0 : lastOffsetForEditing(m_anchorNode);
         } else {
             m_nodeAfterPositionInAnchor = m_nodeAfterPositionInAnchor->parentNode();
             m_anchorNode = m_nodeAfterPositionInAnchor->parentNode();
@@ -88,9 +88,9 @@
         return;
     }
 
-    if (m_anchorNode->hasChildNodes()) {
+    if (m_anchorNode->hasChildren()) {
         m_anchorNode = m_anchorNode->lastChild();
-        m_offsetInAnchor = m_anchorNode->hasChildNodes()? 0: lastOffsetForEditing(m_anchorNode);
+        m_offsetInAnchor = m_anchorNode->hasChildren()? 0: lastOffsetForEditing(m_anchorNode);
     } else {
         if (m_offsetInAnchor)
             m_offsetInAnchor = Position::uncheckedPreviousOffset(m_anchorNode, m_offsetInAnchor);
@@ -107,7 +107,7 @@
         return true;
     if (m_anchorNode->parentNode())
         return false;
-    return (!m_anchorNode->hasChildNodes() && !m_offsetInAnchor) || (m_nodeAfterPositionInAnchor && !m_nodeAfterPositionInAnchor->previousSibling());
+    return (!m_anchorNode->hasChildren() && !m_offsetInAnchor) || (m_nodeAfterPositionInAnchor && !m_nodeAfterPositionInAnchor->previousSibling());
 }
 
 bool PositionIterator::atEnd() const
@@ -116,7 +116,7 @@
         return true;
     if (m_nodeAfterPositionInAnchor)
         return false;
-    return !m_anchorNode->parentNode() && (m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode));
+    return !m_anchorNode->parentNode() && (m_anchorNode->hasChildren() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode));
 }
 
 bool PositionIterator::atStartOfNode() const
@@ -124,7 +124,7 @@
     if (!m_anchorNode)
         return true;
     if (!m_nodeAfterPositionInAnchor)
-        return !m_anchorNode->hasChildNodes() && !m_offsetInAnchor;
+        return !m_anchorNode->hasChildren() && !m_offsetInAnchor;
     return !m_nodeAfterPositionInAnchor->previousSibling();
 }
 
@@ -134,7 +134,7 @@
         return true;
     if (m_nodeAfterPositionInAnchor)
         return false;
-    return m_anchorNode->hasChildNodes() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode);
+    return m_anchorNode->hasChildren() || m_offsetInAnchor >= lastOffsetForEditing(m_anchorNode);
 }
 
 bool PositionIterator::isCandidate() const
@@ -149,17 +149,27 @@
     if (renderer->style()->visibility() != VISIBLE)
         return false;
 
-    if (renderer->isBR())
-        return !m_offsetInAnchor && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
-
+    if (renderer->isBR()) {
+        // For br element, the condition
+        // |(!m_anchorNode->hasChildren() || m_nodeAfterPositionInAnchor)|
+        // corresponds to the condition
+        // |m_anchorType != PositionIsAfterAnchor| in Position.isCandaite.
+        // Both conditions say this position is not in tail of the element.
+        // If conditions lose consitency, VisiblePosition::canonicalPosition
+        // will fail on |canonicalizeCandidate(previousCandidate(position))|,
+        // because previousCandidate returns a Position converted from
+        // a "Candidate" PositionIterator and cannonicalizeCandidate(Position)
+        // assumes the Position is "Candidate".
+        return !m_offsetInAnchor && (!m_anchorNode->hasChildren() || m_nodeAfterPositionInAnchor) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
+    }
     if (renderer->isText())
         return !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).inRenderedText();
 
     if (isRenderedTableElement(m_anchorNode) || editingIgnoresContent(m_anchorNode))
         return (atStartOfNode() || atEndOfNode()) && !Position::nodeIsUserSelectNone(m_anchorNode->parentNode());
 
-    if (!m_anchorNode->hasTagName(htmlTag) && renderer->isRenderBlockFlow()) {
-        if (toRenderBlock(renderer)->logicalHeight() || m_anchorNode->hasTagName(bodyTag)) {
+    if (!isHTMLHtmlElement(*m_anchorNode) && renderer->isRenderBlockFlow()) {
+        if (toRenderBlock(renderer)->logicalHeight() || isHTMLBodyElement(*m_anchorNode)) {
             if (!Position::hasRenderedNonAnonymousDescendantsWithHeight(renderer))
                 return atStartOfNode() && !Position::nodeIsUserSelectNone(m_anchorNode);
             return m_anchorNode->rendererIsEditable() && !Position::nodeIsUserSelectNone(m_anchorNode) && Position(*this).atEditingBoundary();
diff --git a/Source/core/dom/PositionIterator.h b/Source/core/dom/PositionIterator.h
index 6587f7e..4d81cd1 100644
--- a/Source/core/dom/PositionIterator.h
+++ b/Source/core/dom/PositionIterator.h
@@ -45,7 +45,7 @@
 
     PositionIterator(const Position& pos)
         : m_anchorNode(pos.anchorNode())
-        , m_nodeAfterPositionInAnchor(m_anchorNode->childNode(pos.deprecatedEditingOffset()))
+        , m_nodeAfterPositionInAnchor(m_anchorNode->traverseToChildAt(pos.deprecatedEditingOffset()))
         , m_offsetInAnchor(m_nodeAfterPositionInAnchor ? 0 : pos.deprecatedEditingOffset())
     {
     }
diff --git a/Source/core/dom/PresentationAttributeStyle.cpp b/Source/core/dom/PresentationAttributeStyle.cpp
index ce45b4b..3d9a3e3 100644
--- a/Source/core/dom/PresentationAttributeStyle.cpp
+++ b/Source/core/dom/PresentationAttributeStyle.cpp
@@ -31,10 +31,10 @@
 #include "config.h"
 #include "core/dom/PresentationAttributeStyle.h"
 
-#include "HTMLNames.h"
 #include "core/css/StylePropertySet.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/Element.h"
+#include "core/html/HTMLInputElement.h"
 #include "wtf/HashFunctions.h"
 #include "wtf/HashMap.h"
 #include "wtf/text/CString.h"
@@ -87,7 +87,7 @@
         m_hitCount++;
 
         if (!m_cleanTimer.isActive())
-            m_cleanTimer.startOneShot(presentationAttributeCacheCleanTimeInSeconds);
+            m_cleanTimer.startOneShot(presentationAttributeCacheCleanTimeInSeconds, FROM_HERE);
     }
 
 private:
@@ -121,19 +121,19 @@
     if (!element.isHTMLElement())
         return;
     // Interpretation of the size attributes on <input> depends on the type attribute.
-    if (element.hasTagName(inputTag))
+    if (isHTMLInputElement(element))
         return;
     unsigned size = element.attributeCount();
     for (unsigned i = 0; i < size; ++i) {
-        const Attribute* attribute = element.attributeItem(i);
-        if (!element.isPresentationAttribute(attribute->name()))
+        const Attribute& attribute = element.attributeItem(i);
+        if (!element.isPresentationAttribute(attribute.name()))
             continue;
-        if (!attribute->namespaceURI().isNull())
+        if (!attribute.namespaceURI().isNull())
             return;
         // FIXME: Background URL may depend on the base URL and can't be shared. Disallow caching.
-        if (attribute->name() == backgroundAttr)
+        if (attribute.name() == backgroundAttr)
             return;
-        result.attributesAndValues.append(std::make_pair(attribute->localName().impl(), attribute->value()));
+        result.attributesAndValues.append(std::make_pair(attribute.localName().impl(), attribute.value()));
     }
     if (result.attributesAndValues.isEmpty())
         return;
@@ -180,8 +180,8 @@
         style = MutableStylePropertySet::create(element.isSVGElement() ? SVGAttributeMode : HTMLAttributeMode);
         unsigned size = element.attributeCount();
         for (unsigned i = 0; i < size; ++i) {
-            const Attribute* attribute = element.attributeItem(i);
-            element.collectStyleForPresentationAttribute(attribute->name(), attribute->value(), toMutableStylePropertySet(style));
+            const Attribute& attribute = element.attributeItem(i);
+            element.collectStyleForPresentationAttribute(attribute.name(), attribute.value(), toMutableStylePropertySet(style));
         }
     }
 
diff --git a/Source/core/dom/ProcessingInstruction.cpp b/Source/core/dom/ProcessingInstruction.cpp
index ab493bf..ad3d494 100644
--- a/Source/core/dom/ProcessingInstruction.cpp
+++ b/Source/core/dom/ProcessingInstruction.cpp
@@ -174,7 +174,7 @@
     ASSERT(m_isCSS);
     CSSParserContext parserContext(document(), 0, baseURL, charset);
 
-    RefPtr<StyleSheetContents> newSheet = StyleSheetContents::create(href, parserContext);
+    RefPtrWillBeRawPtr<StyleSheetContents> newSheet = StyleSheetContents::create(href, parserContext);
 
     RefPtr<CSSStyleSheet> cssSheet = CSSStyleSheet::create(newSheet, this);
     cssSheet->setDisabled(m_alternate);
@@ -244,7 +244,7 @@
     if (m_sheet) {
         ASSERT(m_sheet->ownerNode() == this);
         m_sheet->clearOwnerNode();
-        m_sheet = 0;
+        m_sheet = nullptr;
     }
 
     // If we're in document teardown, then we don't need to do any notification of our sheet's removal.
diff --git a/Source/core/dom/PseudoElement.h b/Source/core/dom/PseudoElement.h
index 8fbd1da..be135ee 100644
--- a/Source/core/dom/PseudoElement.h
+++ b/Source/core/dom/PseudoElement.h
@@ -67,7 +67,7 @@
     return style && style->display() != NONE && (style->styleType() == BACKDROP || style->contentData());
 }
 
-DEFINE_NODE_TYPE_CASTS(PseudoElement, isPseudoElement());
+DEFINE_ELEMENT_TYPE_CASTS(PseudoElement, isPseudoElement());
 
 } // namespace
 
diff --git a/Source/core/dom/Range.cpp b/Source/core/dom/Range.cpp
index 9c9ac34..39bf7d6 100644
--- a/Source/core/dom/Range.cpp
+++ b/Source/core/dom/Range.cpp
@@ -120,15 +120,15 @@
     ASSERT(m_ownerDocument);
     m_ownerDocument->detachRange(this);
     m_ownerDocument = &document;
-    m_start.setToStartOfNode(&document);
-    m_end.setToStartOfNode(&document);
+    m_start.setToStartOfNode(document);
+    m_end.setToStartOfNode(document);
     m_ownerDocument->attachRange(this);
 }
 
 Node* Range::startContainer(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -138,7 +138,7 @@
 int Range::startOffset(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -148,7 +148,7 @@
 Node* Range::endContainer(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -158,7 +158,7 @@
 int Range::endOffset(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -168,7 +168,7 @@
 Node* Range::commonAncestorContainer(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -189,7 +189,7 @@
 bool Range::collapsed(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -211,7 +211,7 @@
 void Range::setStart(PassRefPtr<Node> refNode, int offset, ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -239,7 +239,7 @@
 void Range::setEnd(PassRefPtr<Node> refNode, int offset, ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -279,7 +279,7 @@
 void Range::collapse(bool toStart, ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -292,7 +292,7 @@
 bool Range::isPointInRange(Node* refNode, int offset, ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return false;
     }
 
@@ -320,7 +320,7 @@
     // refNode node and an offset within the node is before, same as, or after the range respectively.
 
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -408,7 +408,7 @@
 short Range::compareBoundaryPoints(CompareHow how, const Range* sourceRange, ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return 0;
     }
 
@@ -575,7 +575,7 @@
 
     // Throw exception if the range is already detached.
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return false;
     }
     if (!refNode) {
@@ -657,9 +657,10 @@
     case Node::ELEMENT_NODE:
     case Node::ATTRIBUTE_NODE:
     case Node::DOCUMENT_NODE:
-    case Node::DOCUMENT_TYPE_NODE:
     case Node::DOCUMENT_FRAGMENT_NODE:
-        return node->childNodeCount();
+        return toContainerNode(node)->countChildren();
+    case Node::DOCUMENT_TYPE_NODE:
+        return 0;
     }
     ASSERT_NOT_REACHED();
     return 0;
@@ -676,11 +677,11 @@
     if (collapsed(exceptionState))
         return fragment.release();
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     RefPtr<Node> commonRoot = commonAncestorContainer(exceptionState);
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
     ASSERT(commonRoot);
 
     if (m_start.container() == m_end.container()) {
@@ -718,13 +719,13 @@
 
     RefPtr<Node> leftContents;
     if (originalStart.container() != commonRoot && commonRoot->contains(originalStart.container())) {
-        leftContents = processContentsBetweenOffsets(action, 0, originalStart.container(), originalStart.offset(), lengthOfContentsInNode(originalStart.container()), exceptionState);
+        leftContents = processContentsBetweenOffsets(action, nullptr, originalStart.container(), originalStart.offset(), lengthOfContentsInNode(originalStart.container()), exceptionState);
         leftContents = processAncestorsAndTheirSiblings(action, originalStart.container(), ProcessContentsForward, leftContents, commonRoot.get(), exceptionState);
     }
 
     RefPtr<Node> rightContents;
     if (m_end.container() != commonRoot && commonRoot->contains(originalEnd.container())) {
-        rightContents = processContentsBetweenOffsets(action, 0, originalEnd.container(), 0, originalEnd.offset(), exceptionState);
+        rightContents = processContentsBetweenOffsets(action, nullptr, originalEnd.container(), 0, originalEnd.offset(), exceptionState);
         rightContents = processAncestorsAndTheirSiblings(action, originalEnd.container(), ProcessContentsBackward, rightContents, commonRoot.get(), exceptionState);
     }
 
@@ -746,7 +747,7 @@
             setStart(partialEnd->parentNode(), partialEnd->nodeIndex(), exceptionState);
         }
         if (exceptionState.hadException())
-            return 0;
+            return nullptr;
         m_end = m_start;
     }
 
@@ -900,7 +901,10 @@
             Node* child = it->get();
             switch (action) {
             case DELETE_CONTENTS:
-                ancestor->removeChild(child, exceptionState);
+                // Prior call of ancestor->removeChild() may cause a tree change due to DOMSubtreeModified event.
+                // Therefore, we need to make sure |ancestor| is still |child|'s parent.
+                if (ancestor == child->parentNode())
+                    ancestor->removeChild(child, exceptionState);
                 break;
             case EXTRACT_CONTENTS: // will remove child from ancestor
                 if (direction == ProcessContentsForward)
@@ -926,7 +930,7 @@
 {
     checkDeleteExtract(exceptionState);
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     return processContents(EXTRACT_CONTENTS, exceptionState);
 }
@@ -934,8 +938,8 @@
 PassRefPtr<DocumentFragment> Range::cloneContents(ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
-        return 0;
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
+        return nullptr;
     }
 
     return processContents(CLONE_CONTENTS, exceptionState);
@@ -946,7 +950,7 @@
     RefPtr<Node> newNode = prpNewNode;
 
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -1042,7 +1046,7 @@
         }
 
         container = m_start.container();
-        container->insertBefore(newNode.release(), container->childNode(m_start.offset()), exceptionState);
+        container->insertBefore(newNode.release(), container->traverseToChildAt(m_start.offset()), exceptionState);
         if (exceptionState.hadException())
             return;
 
@@ -1056,7 +1060,7 @@
 String Range::toString(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return String();
     }
 
@@ -1096,19 +1100,19 @@
 PassRefPtr<DocumentFragment> Range::createContextualFragment(const String& markup, ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
-        return 0;
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
+        return nullptr;
     }
 
     Node* element = m_start.container()->isElementNode() ? m_start.container() : m_start.container()->parentNode();
     if (!element || !element->isHTMLElement()) {
         exceptionState.throwDOMException(NotSupportedError, "The range's container must be an HTML element.");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<DocumentFragment> fragment = WebCore::createContextualFragment(markup, toHTMLElement(element), AllowScriptingContentAndDoNotMarkAlreadyStarted, exceptionState);
     if (!fragment)
-        return 0;
+        return nullptr;
 
     return fragment.release();
 }
@@ -1118,7 +1122,7 @@
 {
     // Check first to see if we've already detached:
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -1150,7 +1154,7 @@
         case Node::ELEMENT_NODE: {
             if (!offset)
                 return 0;
-            Node* childBefore = n->childNode(offset - 1);
+            Node* childBefore = n->traverseToChildAt(offset - 1);
             if (!childBefore)
                 exceptionState.throwDOMException(IndexSizeError, "There is no child at offset " + String::number(offset) + ".");
             return childBefore;
@@ -1163,7 +1167,7 @@
 void Range::checkNodeBA(Node* n, ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -1219,8 +1223,8 @@
 PassRefPtr<Range> Range::cloneRange(ExceptionState& exceptionState) const
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
-        return 0;
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
+        return nullptr;
     }
 
     return Range::create(*m_ownerDocument.get(), m_start.container(), m_start.offset(), m_end.container(), m_end.offset());
@@ -1256,7 +1260,7 @@
 void Range::selectNode(Node* refNode, ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -1315,7 +1319,7 @@
 void Range::selectNodeContents(Node* refNode, ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -1346,8 +1350,8 @@
     if (m_ownerDocument != refNode->document())
         setDocument(refNode->document());
 
-    m_start.setToStartOfNode(refNode);
-    m_end.setToEndOfNode(refNode);
+    m_start.setToStartOfNode(*refNode);
+    m_end.setToEndOfNode(*refNode);
 }
 
 void Range::surroundContents(PassRefPtr<Node> passNewParent, ExceptionState& exceptionState)
@@ -1355,7 +1359,7 @@
     RefPtr<Node> newParent = passNewParent;
 
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
@@ -1449,10 +1453,12 @@
 void Range::checkDeleteExtract(ExceptionState& exceptionState)
 {
     if (!m_start.container()) {
-        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detatch()' has been invoked on this object?");
+        exceptionState.throwDOMException(InvalidStateError, "The range has no container. Perhaps 'detach()' has been invoked on this object?");
         return;
     }
 
+    ASSERT(boundaryPointsValid());
+
     if (!commonAncestorContainer(exceptionState) || exceptionState.hadException())
         return;
 
@@ -1471,7 +1477,7 @@
         return 0;
     if (m_start.container()->offsetInCharacters())
         return m_start.container();
-    if (Node* child = m_start.container()->childNode(m_start.offset()))
+    if (Node* child = m_start.container()->traverseToChildAt(m_start.offset()))
         return child;
     if (!m_start.offset())
         return m_start.container();
@@ -1489,7 +1495,7 @@
         return 0;
     if (m_end.container()->offsetInCharacters())
         return NodeTraversal::nextSkippingChildren(*m_end.container());
-    if (Node* child = m_end.container()->childNode(m_end.offset()))
+    if (Node* child = m_end.container()->traverseToChildAt(m_end.offset()))
         return child;
     return NodeTraversal::nextSkippingChildren(*m_end.container());
 }
@@ -1618,7 +1624,7 @@
     if (!m_start.container())
         return 0;
     if (!m_start.container()->offsetInCharacters())
-        return m_start.container()->childNodeCount();
+        return m_start.container()->countChildren();
     return m_start.container()->maxCharacterOffset();
 }
 
@@ -1627,7 +1633,7 @@
     if (!m_end.container())
         return 0;
     if (!m_end.container()->offsetInCharacters())
-        return m_end.container()->childNodeCount();
+        return m_end.container()->countChildren();
     return m_end.container()->maxCharacterOffset();
 }
 
@@ -1648,9 +1654,9 @@
     boundaryNodeChildrenChanged(m_end, container);
 }
 
-static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode* container)
+static inline void boundaryNodeChildrenWillBeRemoved(RangeBoundaryPoint& boundary, ContainerNode& container)
 {
-    for (Node* nodeToBeRemoved = container->firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
+    for (Node* nodeToBeRemoved = container.firstChild(); nodeToBeRemoved; nodeToBeRemoved = nodeToBeRemoved->nextSibling()) {
         if (boundary.childBefore() == nodeToBeRemoved) {
             boundary.setToStartOfNode(container);
             return;
@@ -1665,10 +1671,9 @@
     }
 }
 
-void Range::nodeChildrenWillBeRemoved(ContainerNode* container)
+void Range::nodeChildrenWillBeRemoved(ContainerNode& container)
 {
-    ASSERT(container);
-    ASSERT(container->document() == m_ownerDocument);
+    ASSERT(container.document() == m_ownerDocument);
     boundaryNodeChildrenWillBeRemoved(m_start, container);
     boundaryNodeChildrenWillBeRemoved(m_end, container);
 }
@@ -1740,46 +1745,45 @@
     boundaryTextRemoved(m_end, text, offset, length);
 }
 
-static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, NodeWithIndex& oldNode, unsigned offset)
+static inline void boundaryTextNodesMerged(RangeBoundaryPoint& boundary, const NodeWithIndex& oldNode, unsigned offset)
 {
     if (boundary.container() == oldNode.node())
-        boundary.set(oldNode.node()->previousSibling(), boundary.offset() + offset, 0);
-    else if (boundary.container() == oldNode.node()->parentNode() && boundary.offset() == oldNode.index())
-        boundary.set(oldNode.node()->previousSibling(), offset, 0);
+        boundary.set(oldNode.node().previousSibling(), boundary.offset() + offset, 0);
+    else if (boundary.container() == oldNode.node().parentNode() && boundary.offset() == oldNode.index())
+        boundary.set(oldNode.node().previousSibling(), offset, 0);
 }
 
-void Range::didMergeTextNodes(NodeWithIndex& oldNode, unsigned offset)
+void Range::didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset)
 {
-    ASSERT(oldNode.node());
-    ASSERT(oldNode.node()->document() == m_ownerDocument);
-    ASSERT(oldNode.node()->parentNode());
-    ASSERT(oldNode.node()->isTextNode());
-    ASSERT(oldNode.node()->previousSibling());
-    ASSERT(oldNode.node()->previousSibling()->isTextNode());
+    ASSERT(oldNode.node().document() == m_ownerDocument);
+    ASSERT(oldNode.node().parentNode());
+    ASSERT(oldNode.node().isTextNode());
+    ASSERT(oldNode.node().previousSibling());
+    ASSERT(oldNode.node().previousSibling()->isTextNode());
     boundaryTextNodesMerged(m_start, oldNode, offset);
     boundaryTextNodesMerged(m_end, oldNode, offset);
 }
 
-static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text* oldNode)
+static inline void boundaryTextNodeSplit(RangeBoundaryPoint& boundary, Text& oldNode)
 {
-    if (boundary.container() != oldNode)
-        return;
+    Node* boundaryContainer = boundary.container();
     unsigned boundaryOffset = boundary.offset();
-    if (boundaryOffset <= oldNode->length())
-        return;
-    boundary.set(oldNode->nextSibling(), boundaryOffset - oldNode->length(), 0);
+    if (boundary.childBefore() == &oldNode)
+        boundary.set(boundaryContainer, boundaryOffset + 1, oldNode.nextSibling());
+    else if (boundary.container() == &oldNode && boundaryOffset > oldNode.length())
+        boundary.set(oldNode.nextSibling(), boundaryOffset - oldNode.length(), 0);
 }
 
-void Range::didSplitTextNode(Text* oldNode)
+void Range::didSplitTextNode(Text& oldNode)
 {
-    ASSERT(oldNode);
-    ASSERT(oldNode->document() == m_ownerDocument);
-    ASSERT(oldNode->parentNode());
-    ASSERT(oldNode->isTextNode());
-    ASSERT(oldNode->nextSibling());
-    ASSERT(oldNode->nextSibling()->isTextNode());
+    ASSERT(oldNode.document() == m_ownerDocument);
+    ASSERT(oldNode.parentNode());
+    ASSERT(oldNode.isTextNode());
+    ASSERT(oldNode.nextSibling());
+    ASSERT(oldNode.nextSibling()->isTextNode());
     boundaryTextNodeSplit(m_start, oldNode);
     boundaryTextNodeSplit(m_end, oldNode);
+    ASSERT(boundaryPointsValid());
 }
 
 void Range::expand(const String& unit, ExceptionState& exceptionState)
@@ -1842,7 +1846,7 @@
                     renderBoxModelObject->absoluteQuads(elementQuads);
                     m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(elementQuads, *renderBoxModelObject);
 
-                    quads.append(elementQuads);
+                    quads.appendVector(elementQuads);
                 }
             }
         } else if (node->isTextNode()) {
@@ -1855,7 +1859,7 @@
                 renderText.absoluteQuadsForRange(textQuads, startOffset, endOffset);
                 m_ownerDocument->adjustFloatQuadsForScrollAndAbsoluteZoom(textQuads, renderText);
 
-                quads.append(textQuads);
+                quads.appendVector(textQuads);
             }
         }
     }
diff --git a/Source/core/dom/Range.h b/Source/core/dom/Range.h
index 3a662f1..6f50ba5 100644
--- a/Source/core/dom/Range.h
+++ b/Source/core/dom/Range.h
@@ -129,13 +129,13 @@
     FloatRect boundingRect() const;
 
     void nodeChildrenChanged(ContainerNode*);
-    void nodeChildrenWillBeRemoved(ContainerNode*);
+    void nodeChildrenWillBeRemoved(ContainerNode&);
     void nodeWillBeRemoved(Node&);
 
     void didInsertText(Node*, unsigned offset, unsigned length);
     void didRemoveText(Node*, unsigned offset, unsigned length);
-    void didMergeTextNodes(NodeWithIndex& oldNode, unsigned offset);
-    void didSplitTextNode(Text* oldNode);
+    void didMergeTextNodes(const NodeWithIndex& oldNode, unsigned offset);
+    void didSplitTextNode(Text& oldNode);
 
     // Expand range to a unit (word or sentence or block or document) boundary.
     // Please refer to https://bugs.webkit.org/show_bug.cgi?id=27632 comment #5
diff --git a/Source/core/dom/RangeBoundaryPoint.h b/Source/core/dom/RangeBoundaryPoint.h
index 7574a89..2f7235b 100644
--- a/Source/core/dom/RangeBoundaryPoint.h
+++ b/Source/core/dom/RangeBoundaryPoint.h
@@ -49,8 +49,8 @@
     void setOffset(int offset);
 
     void setToBeforeChild(Node&);
-    void setToStartOfNode(PassRefPtr<Node>);
-    void setToEndOfNode(PassRefPtr<Node>);
+    void setToStartOfNode(Node&);
+    void setToEndOfNode(Node&);
 
     void childBeforeWillBeRemoved();
     void invalidateOffset() const;
@@ -67,7 +67,7 @@
 inline RangeBoundaryPoint::RangeBoundaryPoint(PassRefPtr<Node> container)
     : m_containerNode(container)
     , m_offsetInContainer(0)
-    , m_childBeforeBoundary(0)
+    , m_childBeforeBoundary(nullptr)
 {
     ASSERT(m_containerNode);
 }
@@ -114,14 +114,14 @@
 {
     m_containerNode.clear();
     m_offsetInContainer = 0;
-    m_childBeforeBoundary = 0;
+    m_childBeforeBoundary = nullptr;
 }
 
 inline void RangeBoundaryPoint::set(PassRefPtr<Node> container, int offset, Node* childBefore)
 {
     ASSERT(container);
     ASSERT(offset >= 0);
-    ASSERT(childBefore == (offset ? container->childNode(offset - 1) : 0));
+    ASSERT(childBefore == (offset ? container->traverseToChildAt(offset - 1) : 0));
     m_containerNode = container;
     m_offsetInContainer = offset;
     m_childBeforeBoundary = childBefore;
@@ -144,21 +144,19 @@
     m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
 }
 
-inline void RangeBoundaryPoint::setToStartOfNode(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToStartOfNode(Node& container)
 {
-    ASSERT(container);
-    m_containerNode = container;
+    m_containerNode = PassRefPtr<Node>(container);
     m_offsetInContainer = 0;
-    m_childBeforeBoundary = 0;
+    m_childBeforeBoundary = nullptr;
 }
 
-inline void RangeBoundaryPoint::setToEndOfNode(PassRefPtr<Node> container)
+inline void RangeBoundaryPoint::setToEndOfNode(Node& container)
 {
-    ASSERT(container);
-    m_containerNode = container;
+    m_containerNode = PassRefPtr<Node>(container);
     if (m_containerNode->offsetInCharacters()) {
         m_offsetInContainer = m_containerNode->maxCharacterOffset();
-        m_childBeforeBoundary = 0;
+        m_childBeforeBoundary = nullptr;
     } else {
         m_childBeforeBoundary = m_containerNode->lastChild();
         m_offsetInContainer = m_childBeforeBoundary ? invalidOffset : 0;
diff --git a/Source/core/dom/RangeTest.cpp b/Source/core/dom/RangeTest.cpp
new file mode 100644
index 0000000..a4ac883
--- /dev/null
+++ b/Source/core/dom/RangeTest.cpp
@@ -0,0 +1,142 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/Range.h"
+
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/Element.h"
+#include "core/dom/Text.h"
+#include "core/html/HTMLBodyElement.h"
+#include "core/html/HTMLDocument.h"
+#include "core/html/HTMLElement.h"
+#include "core/html/HTMLHtmlElement.h"
+#include "wtf/Compiler.h"
+#include "wtf/RefPtr.h"
+#include "wtf/text/AtomicString.h"
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+class RangeTest : public ::testing::Test {
+protected:
+    virtual void SetUp() OVERRIDE;
+
+    HTMLDocument& document() const;
+
+private:
+    RefPtr<HTMLDocument> m_document;
+};
+
+void RangeTest::SetUp()
+{
+    m_document = HTMLDocument::create();
+    RefPtr<HTMLHtmlElement> html = HTMLHtmlElement::create(*m_document);
+    html->appendChild(HTMLBodyElement::create(*m_document));
+    m_document->appendChild(html.release());
+}
+
+HTMLDocument& RangeTest::document() const
+{
+    return *m_document;
+}
+
+TEST_F(RangeTest, SplitTextNodeRangeWithinText)
+{
+    document().body()->setInnerHTML("1234", ASSERT_NO_EXCEPTION);
+    Text* oldText = toText(document().body()->firstChild());
+
+    RefPtr<Range> range04 = Range::create(document(), oldText, 0, oldText, 4);
+    RefPtr<Range> range02 = Range::create(document(), oldText, 0, oldText, 2);
+    RefPtr<Range> range22 = Range::create(document(), oldText, 2, oldText, 2);
+    RefPtr<Range> range24 = Range::create(document(), oldText, 2, oldText, 4);
+
+    oldText->splitText(2, ASSERT_NO_EXCEPTION);
+    Text* newText = toText(oldText->nextSibling());
+
+    EXPECT_TRUE(range04->boundaryPointsValid());
+    EXPECT_EQ(oldText, range04->startContainer());
+    EXPECT_EQ(0, range04->startOffset());
+    EXPECT_EQ(newText, range04->endContainer());
+    EXPECT_EQ(2, range04->endOffset());
+
+    EXPECT_TRUE(range02->boundaryPointsValid());
+    EXPECT_EQ(oldText, range02->startContainer());
+    EXPECT_EQ(0, range02->startOffset());
+    EXPECT_EQ(oldText, range02->endContainer());
+    EXPECT_EQ(2, range02->endOffset());
+
+    // Our implementation always moves the boundary point at the separation point to the end of the original text node.
+    EXPECT_TRUE(range22->boundaryPointsValid());
+    EXPECT_EQ(oldText, range22->startContainer());
+    EXPECT_EQ(2, range22->startOffset());
+    EXPECT_EQ(oldText, range22->endContainer());
+    EXPECT_EQ(2, range22->endOffset());
+
+    EXPECT_TRUE(range24->boundaryPointsValid());
+    EXPECT_EQ(oldText, range24->startContainer());
+    EXPECT_EQ(2, range24->startOffset());
+    EXPECT_EQ(newText, range24->endContainer());
+    EXPECT_EQ(2, range24->endOffset());
+}
+
+TEST_F(RangeTest, SplitTextNodeRangeOutsideText)
+{
+    document().body()->setInnerHTML("<span id=\"outer\">0<span id=\"inner-left\">1</span>SPLITME<span id=\"inner-right\">2</span>3</span>", ASSERT_NO_EXCEPTION);
+
+    Element* outer = document().getElementById(AtomicString::fromUTF8("outer"));
+    Element* innerLeft = document().getElementById(AtomicString::fromUTF8("inner-left"));
+    Element* innerRight = document().getElementById(AtomicString::fromUTF8("inner-right"));
+    Text* oldText = toText(outer->childNodes()->item(2));
+
+    RefPtr<Range> rangeOuterOutside = Range::create(document(), outer, 0, outer, 5);
+    RefPtr<Range> rangeOuterInside = Range::create(document(), outer, 1, outer, 4);
+    RefPtr<Range> rangeOuterSurroundingText = Range::create(document(), outer, 2, outer, 3);
+    RefPtr<Range> rangeInnerLeft = Range::create(document(), innerLeft, 0, innerLeft, 1);
+    RefPtr<Range> rangeInnerRight = Range::create(document(), innerRight, 0, innerRight, 1);
+    RefPtr<Range> rangeFromTextToMiddleOfElement = Range::create(document(), oldText, 6, outer, 3);
+
+    oldText->splitText(3, ASSERT_NO_EXCEPTION);
+    Text* newText = toText(oldText->nextSibling());
+
+    EXPECT_TRUE(rangeOuterOutside->boundaryPointsValid());
+    EXPECT_EQ(outer, rangeOuterOutside->startContainer());
+    EXPECT_EQ(0, rangeOuterOutside->startOffset());
+    EXPECT_EQ(outer, rangeOuterOutside->endContainer());
+    EXPECT_EQ(6, rangeOuterOutside->endOffset()); // Increased by 1 since a new node is inserted.
+
+    EXPECT_TRUE(rangeOuterInside->boundaryPointsValid());
+    EXPECT_EQ(outer, rangeOuterInside->startContainer());
+    EXPECT_EQ(1, rangeOuterInside->startOffset());
+    EXPECT_EQ(outer, rangeOuterInside->endContainer());
+    EXPECT_EQ(5, rangeOuterInside->endOffset());
+
+    EXPECT_TRUE(rangeOuterSurroundingText->boundaryPointsValid());
+    EXPECT_EQ(outer, rangeOuterSurroundingText->startContainer());
+    EXPECT_EQ(2, rangeOuterSurroundingText->startOffset());
+    EXPECT_EQ(outer, rangeOuterSurroundingText->endContainer());
+    EXPECT_EQ(4, rangeOuterSurroundingText->endOffset());
+
+    EXPECT_TRUE(rangeInnerLeft->boundaryPointsValid());
+    EXPECT_EQ(innerLeft, rangeInnerLeft->startContainer());
+    EXPECT_EQ(0, rangeInnerLeft->startOffset());
+    EXPECT_EQ(innerLeft, rangeInnerLeft->endContainer());
+    EXPECT_EQ(1, rangeInnerLeft->endOffset());
+
+    EXPECT_TRUE(rangeInnerRight->boundaryPointsValid());
+    EXPECT_EQ(innerRight, rangeInnerRight->startContainer());
+    EXPECT_EQ(0, rangeInnerRight->startOffset());
+    EXPECT_EQ(innerRight, rangeInnerRight->endContainer());
+    EXPECT_EQ(1, rangeInnerRight->endOffset());
+
+    EXPECT_TRUE(rangeFromTextToMiddleOfElement->boundaryPointsValid());
+    EXPECT_EQ(newText, rangeFromTextToMiddleOfElement->startContainer());
+    EXPECT_EQ(3, rangeFromTextToMiddleOfElement->startOffset());
+    EXPECT_EQ(outer, rangeFromTextToMiddleOfElement->endContainer());
+    EXPECT_EQ(4, rangeFromTextToMiddleOfElement->endOffset());
+}
+
+}
diff --git a/Source/core/dom/RenderTreeBuilder.cpp b/Source/core/dom/RenderTreeBuilder.cpp
index 168fcce..bb52e93 100644
--- a/Source/core/dom/RenderTreeBuilder.cpp
+++ b/Source/core/dom/RenderTreeBuilder.cpp
@@ -80,7 +80,7 @@
         return false;
     if (m_node->isSVGElement()) {
         // SVG elements only render when inside <svg>, or if the element is an <svg> itself.
-        if (!m_node->hasTagName(SVGNames::svgTag) && !m_renderingParent->isSVGElement())
+        if (!isSVGSVGElement(*m_node) && !m_renderingParent->isSVGElement())
             return false;
         if (!toSVGElement(m_node)->isValid())
             return false;
diff --git a/Source/core/dom/ScriptLoader.cpp b/Source/core/dom/ScriptLoader.cpp
index ac91a97..faba258 100644
--- a/Source/core/dom/ScriptLoader.cpp
+++ b/Source/core/dom/ScriptLoader.cpp
@@ -38,11 +38,11 @@
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ScriptResource.h"
-#include "core/html/HTMLImport.h"
 #include "core/html/HTMLScriptElement.h"
+#include "core/html/imports/HTMLImport.h"
 #include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/svg/SVGScriptElement.h"
 #include "platform/MIMETypeRegistry.h"
 #include "platform/weborigin/SecurityOrigin.h"
@@ -115,7 +115,6 @@
     DEFINE_STATIC_LOCAL(LanguageSet, languages, ());
     if (languages.isEmpty()) {
         languages.add("javascript");
-        languages.add("javascript");
         languages.add("javascript1.0");
         languages.add("javascript1.1");
         languages.add("javascript1.2");
@@ -282,12 +281,14 @@
 
 bool isHTMLScriptLoader(Element* element)
 {
-    return element->hasTagName(HTMLNames::scriptTag);
+    ASSERT(element);
+    return isHTMLScriptElement(*element);
 }
 
 bool isSVGScriptLoader(Element* element)
 {
-    return element->hasTagName(SVGNames::scriptTag);
+    ASSERT(element);
+    return isSVGScriptElement(*element);
 }
 
 void ScriptLoader::executeScript(const ScriptSourceCode& sourceCode)
@@ -302,26 +303,32 @@
     if (!contextDocument)
         return;
 
-    Frame* frame = contextDocument->frame();
+    LocalFrame* frame = contextDocument->frame();
 
     bool shouldBypassMainWorldContentSecurityPolicy = (frame && frame->script().shouldBypassMainWorldContentSecurityPolicy()) || elementDocument->contentSecurityPolicy()->allowScriptNonce(m_element->fastGetAttribute(HTMLNames::nonceAttr)) || elementDocument->contentSecurityPolicy()->allowScriptHash(sourceCode.source());
 
     if (!m_isExternalScript && (!shouldBypassMainWorldContentSecurityPolicy && !elementDocument->contentSecurityPolicy()->allowInlineScript(elementDocument->url(), m_startLineNumber)))
         return;
 
-    if (m_isExternalScript && m_resource && !m_resource->mimeTypeAllowedByNosniff()) {
-        contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + m_resource->url().elidedString() + "' because its MIME type ('" + m_resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
-        return;
+    if (m_isExternalScript) {
+        ScriptResource* resource = m_resource ? m_resource.get() : sourceCode.resource();
+        if (resource && !resource->mimeTypeAllowedByNosniff()) {
+            contextDocument->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Refused to execute script from '" + resource->url().elidedString() + "' because its MIME type ('" + resource->mimeType() + "') is not executable, and strict MIME type checking is enabled.");
+            return;
+        }
     }
 
     if (frame) {
-        IgnoreDestructiveWriteCountIncrementer ignoreDesctructiveWriteCountIncrementer(m_isExternalScript ? contextDocument.get() : 0);
+        const bool isImportedScript = contextDocument != elementDocument;
+        // http://www.whatwg.org/specs/web-apps/current-work/#execute-the-script-block step 2.3
+        // with additional support for HTML imports.
+        IgnoreDestructiveWriteCountIncrementer ignoreDestructiveWriteCountIncrementer(m_isExternalScript || isImportedScript ? contextDocument.get() : 0);
 
         if (isHTMLScriptLoader(m_element))
             contextDocument->pushCurrentScript(toHTMLScriptElement(m_element));
 
         AccessControlStatus corsCheck = NotSharableCrossOrigin;
-        if (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin()))
+        if (!m_isExternalScript || (sourceCode.resource() && sourceCode.resource()->passesAccessControlCheck(m_element->document().securityOrigin())))
             corsCheck = SharableCrossOrigin;
 
         // Create a script from the script element node, using the script
diff --git a/Source/core/dom/ScriptRunner.cpp b/Source/core/dom/ScriptRunner.cpp
index 2fbf959..d33ea6e 100644
--- a/Source/core/dom/ScriptRunner.cpp
+++ b/Source/core/dom/ScriptRunner.cpp
@@ -81,7 +81,7 @@
 void ScriptRunner::resume()
 {
     if (hasPendingScripts())
-        m_timer.startOneShot(0);
+        m_timer.startOneShot(0, FROM_HERE);
 }
 
 void ScriptRunner::notifyScriptReady(ScriptLoader* scriptLoader, ExecutionType executionType)
@@ -96,7 +96,7 @@
         ASSERT(!m_scriptsToExecuteInOrder.isEmpty());
         break;
     }
-    m_timer.startOneShot(0);
+    m_timer.startOneShot(0, FROM_HERE);
 }
 
 void ScriptRunner::notifyScriptLoadError(ScriptLoader* scriptLoader, ExecutionType executionType)
diff --git a/Source/core/dom/ScriptedAnimationController.cpp b/Source/core/dom/ScriptedAnimationController.cpp
index 27a7f6b..29ed5b8 100644
--- a/Source/core/dom/ScriptedAnimationController.cpp
+++ b/Source/core/dom/ScriptedAnimationController.cpp
@@ -110,7 +110,7 @@
         // special casting window.
         // FIXME: We should not fire events for nodes that are no longer in the tree.
         if (DOMWindow* window = eventTarget->toDOMWindow())
-            window->dispatchEvent(events[i], 0);
+            window->dispatchEvent(events[i], nullptr);
         else
             eventTarget->dispatchEvent(events[i]);
     }
diff --git a/Source/core/dom/SecurityContext.cpp b/Source/core/dom/SecurityContext.cpp
index d0c3530..9767bf1 100644
--- a/Source/core/dom/SecurityContext.cpp
+++ b/Source/core/dom/SecurityContext.cpp
@@ -27,7 +27,7 @@
 #include "config.h"
 #include "core/dom/SecurityContext.h"
 
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace WebCore {
@@ -47,7 +47,7 @@
     m_haveInitializedSecurityOrigin = true;
 }
 
-void SecurityContext::setContentSecurityPolicy(PassOwnPtr<ContentSecurityPolicy> contentSecurityPolicy)
+void SecurityContext::setContentSecurityPolicy(PassRefPtr<ContentSecurityPolicy> contentSecurityPolicy)
 {
     m_contentSecurityPolicy = contentSecurityPolicy;
 }
diff --git a/Source/core/dom/SecurityContext.h b/Source/core/dom/SecurityContext.h
index b47c6f4..07f62ad 100644
--- a/Source/core/dom/SecurityContext.h
+++ b/Source/core/dom/SecurityContext.h
@@ -53,7 +53,7 @@
     SecurityContext();
     virtual ~SecurityContext();
 
-    void setContentSecurityPolicy(PassOwnPtr<ContentSecurityPolicy>);
+    void setContentSecurityPolicy(PassRefPtr<ContentSecurityPolicy>);
 
     void didFailToInitializeSecurityOrigin() { m_haveInitializedSecurityOrigin = false; }
     bool haveInitializedSecurityOrigin() const { return m_haveInitializedSecurityOrigin; }
@@ -61,7 +61,7 @@
 private:
     bool m_haveInitializedSecurityOrigin;
     RefPtr<SecurityOrigin> m_securityOrigin;
-    OwnPtr<ContentSecurityPolicy> m_contentSecurityPolicy;
+    RefPtr<ContentSecurityPolicy> m_contentSecurityPolicy;
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/SelectorQuery.cpp b/Source/core/dom/SelectorQuery.cpp
index e43511f..a139843 100644
--- a/Source/core/dom/SelectorQuery.cpp
+++ b/Source/core/dom/SelectorQuery.cpp
@@ -36,6 +36,8 @@
 #include "core/dom/ElementTraversal.h"
 #include "core/dom/Node.h"
 #include "core/dom/StaticNodeList.h"
+#include "core/dom/shadow/ElementShadow.h"
+#include "core/dom/shadow/ShadowRoot.h"
 
 namespace WebCore {
 
@@ -104,9 +106,13 @@
     for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector))
         selectorCount++;
 
+    m_crossesTreeBoundary = false;
     m_selectors.reserveInitialCapacity(selectorCount);
-    for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector))
+    unsigned index = 0;
+    for (const CSSSelector* selector = selectorList.first(); selector; selector = CSSSelectorList::next(*selector), ++index) {
         m_selectors.uncheckedAppend(SelectorData(*selector, SelectorCheckerFastPath::canUse(*selector)));
+        m_crossesTreeBoundary |= selectorList.hasCombinatorCrossingTreeBoundaryAt(index);
+    }
 }
 
 inline bool SelectorDataList::selectorMatches(const SelectorData& selectorData, Element& element, const ContainerNode& rootNode) const
@@ -176,7 +182,7 @@
 
 inline bool SelectorDataList::canUseFastQuery(const ContainerNode& rootNode) const
 {
-    return m_selectors.size() == 1 && rootNode.inDocument() && !rootNode.document().inQuirksMode();
+    return m_selectors.size() == 1 && !m_crossesTreeBoundary && rootNode.inDocument() && !rootNode.document().inQuirksMode();
 }
 
 inline bool ancestorHasClassName(ContainerNode& rootNode, const AtomicString& className)
@@ -312,17 +318,81 @@
 }
 
 template <typename SelectorQueryTrait>
+bool SelectorDataList::selectorListMatches(ContainerNode& rootNode, Element& element, typename SelectorQueryTrait::OutputType& output) const
+{
+    for (unsigned i = 0; i < m_selectors.size(); ++i) {
+        if (selectorMatches(m_selectors[i], element, rootNode)) {
+            SelectorQueryTrait::appendElement(output, element);
+            return true;
+        }
+    }
+    return false;
+}
+
+template <typename SelectorQueryTrait>
 void SelectorDataList::executeSlow(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
 {
     for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(*element, &rootNode)) {
-        for (unsigned i = 0; i < m_selectors.size(); ++i) {
-            if (selectorMatches(m_selectors[i], *element, rootNode)) {
-                SelectorQueryTrait::appendElement(output, *element);
-                if (SelectorQueryTrait::shouldOnlyMatchFirstElement)
-                    return;
-                break;
-            }
-        }
+        if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output) && SelectorQueryTrait::shouldOnlyMatchFirstElement)
+            return;
+    }
+}
+
+// FIXME: Move the following helper functions, authorShadowRootOf, firstWithinTraversingShadowTree,
+// nextTraversingShadowTree to the best place, e.g. NodeTraversal.
+static ShadowRoot* authorShadowRootOf(const ContainerNode& node)
+{
+    if (!node.isElementNode() || !isShadowHost(&node))
+        return 0;
+
+    ElementShadow* shadow = toElement(node).shadow();
+    ASSERT(shadow);
+    for (ShadowRoot* shadowRoot = shadow->oldestShadowRoot(); shadowRoot; shadowRoot = shadowRoot->youngerShadowRoot()) {
+        if (shadowRoot->type() == ShadowRoot::AuthorShadowRoot)
+            return shadowRoot;
+    }
+    return 0;
+}
+
+static ContainerNode* firstWithinTraversingShadowTree(const ContainerNode& rootNode)
+{
+    if (ShadowRoot* shadowRoot = authorShadowRootOf(rootNode))
+        return shadowRoot;
+    return ElementTraversal::firstWithin(rootNode);
+}
+
+static ContainerNode* nextTraversingShadowTree(const ContainerNode& node, const ContainerNode* rootNode)
+{
+    if (ShadowRoot* shadowRoot = authorShadowRootOf(node))
+        return shadowRoot;
+
+    if (Element* next = ElementTraversal::next(node, rootNode))
+        return next;
+
+    if (!node.isInShadowTree())
+        return 0;
+
+    ShadowRoot* shadowRoot = node.containingShadowRoot();
+    if (shadowRoot == rootNode)
+        return 0;
+    if (ShadowRoot* youngerShadowRoot = shadowRoot->youngerShadowRoot()) {
+        // Should not obtain any elements in user-agent shadow root.
+        ASSERT(youngerShadowRoot->type() == ShadowRoot::AuthorShadowRoot);
+        return youngerShadowRoot;
+    }
+    Element* shadowHost = shadowRoot->host();
+    return ElementTraversal::next(*shadowHost, rootNode);
+}
+
+template <typename SelectorQueryTrait>
+void SelectorDataList::executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
+{
+    for (ContainerNode* node = firstWithinTraversingShadowTree(rootNode); node; node = nextTraversingShadowTree(*node, &rootNode)) {
+        if (!node->isElementNode())
+            continue;
+        Element* element = toElement(node);
+        if (selectorListMatches<SelectorQueryTrait>(rootNode, *element, output) && SelectorQueryTrait::shouldOnlyMatchFirstElement)
+            return;
     }
 }
 
@@ -341,7 +411,10 @@
 void SelectorDataList::execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType& output) const
 {
     if (!canUseFastQuery(rootNode)) {
-        executeSlow<SelectorQueryTrait>(rootNode, output);
+        if (m_crossesTreeBoundary)
+            executeSlowTraversingShadowTree<SelectorQueryTrait>(rootNode, output);
+        else
+            executeSlow<SelectorQueryTrait>(rootNode, output);
         return;
     }
 
diff --git a/Source/core/dom/SelectorQuery.h b/Source/core/dom/SelectorQuery.h
index c413f3a..726b677 100644
--- a/Source/core/dom/SelectorQuery.h
+++ b/Source/core/dom/SelectorQuery.h
@@ -76,12 +76,17 @@
     void executeForTraverseRoots(const SelectorData&, SimpleElementListType& traverseRoots, MatchTraverseRootState, ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
 
     template <typename SelectorQueryTrait>
+    bool selectorListMatches(ContainerNode& rootNode, Element&, typename SelectorQueryTrait::OutputType&) const;
+    template <typename SelectorQueryTrait>
     void executeSlow(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
     template <typename SelectorQueryTrait>
+    void executeSlowTraversingShadowTree(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
+    template <typename SelectorQueryTrait>
     void execute(ContainerNode& rootNode, typename SelectorQueryTrait::OutputType&) const;
     const CSSSelector* selectorForIdLookup(const CSSSelector&) const;
 
     Vector<SelectorData> m_selectors;
+    bool m_crossesTreeBoundary;
 };
 
 class SelectorQuery {
diff --git a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
index 6a74608..3e81992 100644
--- a/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
+++ b/Source/core/dom/ShadowTreeStyleSheetCollection.cpp
@@ -53,14 +53,14 @@
         StyleSheet* sheet = 0;
         CSSStyleSheet* activeSheet = 0;
 
-        if (!node->isHTMLElement() || !node->hasTagName(styleTag))
+        if (!isHTMLStyleElement(*node))
             continue;
 
-        Element* element = toElement(node);
+        HTMLStyleElement* element = toHTMLStyleElement(node);
         const AtomicString& title = element->fastGetAttribute(titleAttr);
         bool enabledViaScript = false;
 
-        sheet = toHTMLStyleElement(node)->sheet();
+        sheet = element->sheet();
         if (sheet && !sheet->disabled() && sheet->isCSSStyleSheet())
             activeSheet = toCSSStyleSheet(sheet);
 
diff --git a/Source/core/dom/SiblingRuleHelper.cpp b/Source/core/dom/SiblingRuleHelper.cpp
new file mode 100644
index 0000000..7ebc4ca
--- /dev/null
+++ b/Source/core/dom/SiblingRuleHelper.cpp
@@ -0,0 +1,130 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/dom/SiblingRuleHelper.h"
+
+#include "core/dom/Document.h"
+#include "core/dom/Element.h"
+#include "core/dom/StyleEngine.h"
+#include "core/dom/shadow/ShadowRoot.h"
+
+namespace WebCore {
+
+bool SiblingRuleHelper::isFinishedParsingChildren()
+{
+    if (m_node->isElementNode())
+        return toElement(m_node)->isFinishedParsingChildren();
+
+    return toShadowRoot(m_node)->isFinishedParsingChildren();
+}
+
+void SiblingRuleHelper::setChildrenAffectedByDirectAdjacentRules()
+{
+    if (m_node->isElementNode())
+        toElement(m_node)->setChildrenAffectedByDirectAdjacentRules();
+    else
+        toShadowRoot(m_node)->setChildrenAffectedByDirectAdjacentRules();
+}
+
+void SiblingRuleHelper::setChildrenAffectedByForwardPositionalRules()
+{
+    if (m_node->isElementNode())
+        toElement(m_node)->setChildrenAffectedByForwardPositionalRules();
+    else
+        toShadowRoot(m_node)->setChildrenAffectedByForwardPositionalRules();
+}
+
+void SiblingRuleHelper::setChildrenAffectedByBackwardPositionalRules()
+{
+    if (m_node->isElementNode())
+        toElement(m_node)->setChildrenAffectedByBackwardPositionalRules();
+    else
+        toShadowRoot(m_node)->setChildrenAffectedByBackwardPositionalRules();
+}
+
+void SiblingRuleHelper::setChildrenAffectedByFirstChildRules()
+{
+    if (m_node->isElementNode())
+        toElement(m_node)->setChildrenAffectedByFirstChildRules();
+    else
+        toShadowRoot(m_node)->setChildrenAffectedByFirstChildRules();
+}
+
+void SiblingRuleHelper::setChildrenAffectedByLastChildRules()
+{
+    if (m_node->isElementNode())
+        toElement(m_node)->setChildrenAffectedByLastChildRules();
+    else
+        toShadowRoot(m_node)->setChildrenAffectedByLastChildRules();
+}
+
+bool SiblingRuleHelper::childrenAffectedByPositionalRules() const
+{
+    return m_node->isElementNode() ? toElement(m_node)->childrenAffectedByPositionalRules() : toShadowRoot(m_node)->childrenAffectedByPositionalRules();
+}
+
+bool SiblingRuleHelper::childrenAffectedByFirstChildRules() const
+{
+    return m_node->isElementNode() ? toElement(m_node)->childrenAffectedByFirstChildRules() : toShadowRoot(m_node)->childrenAffectedByFirstChildRules();
+}
+
+bool SiblingRuleHelper::childrenAffectedByLastChildRules() const
+{
+    return m_node->isElementNode() ? toElement(m_node)->childrenAffectedByLastChildRules() : toShadowRoot(m_node)->childrenAffectedByLastChildRules();
+}
+
+bool SiblingRuleHelper::childrenAffectedByDirectAdjacentRules() const
+{
+    return m_node->isElementNode() ? toElement(m_node)->childrenAffectedByDirectAdjacentRules() : toShadowRoot(m_node)->childrenAffectedByDirectAdjacentRules();
+}
+
+bool SiblingRuleHelper::childrenAffectedByForwardPositionalRules() const
+{
+    return m_node->isElementNode() ? toElement(m_node)->childrenAffectedByForwardPositionalRules() : toShadowRoot(m_node)->childrenAffectedByForwardPositionalRules();
+}
+
+bool SiblingRuleHelper::childrenAffectedByBackwardPositionalRules() const
+{
+    return m_node->isElementNode() ? toElement(m_node)->childrenAffectedByBackwardPositionalRules() : toShadowRoot(m_node)->childrenAffectedByBackwardPositionalRules();
+}
+
+void SiblingRuleHelper::checkForChildrenAdjacentRuleChanges()
+{
+    bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules();
+    bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules();
+
+    if (!hasDirectAdjacentRules && !hasIndirectAdjacentRules)
+        return;
+
+    unsigned forceCheckOfNextElementCount = 0;
+    bool forceCheckOfAnyElementSibling = false;
+    Document& document = m_node->document();
+
+    for (Node* child = m_node->firstChild(); child; child = child->nextSibling()) {
+        if (!child->isElementNode())
+            continue;
+        Element* element = toElement(child);
+        bool childRulesChanged = element->needsStyleRecalc() && element->styleChangeType() >= SubtreeStyleChange;
+
+        if (forceCheckOfNextElementCount || forceCheckOfAnyElementSibling)
+            element->setNeedsStyleRecalc(SubtreeStyleChange);
+
+        if (forceCheckOfNextElementCount)
+            forceCheckOfNextElementCount--;
+
+        if (childRulesChanged && hasDirectAdjacentRules)
+            forceCheckOfNextElementCount = document.styleEngine()->maxDirectAdjacentSelectors();
+
+        forceCheckOfAnyElementSibling = forceCheckOfAnyElementSibling || (childRulesChanged && hasIndirectAdjacentRules);
+    }
+}
+
+bool SiblingRuleHelper::childrenSupportStyleSharing()
+{
+    return m_node->isElementNode() ? toElement(m_node)->childrenSupportStyleSharing() : toShadowRoot(m_node)->childrenSupportStyleSharing();
+}
+
+} // namespace WebCore
+
diff --git a/Source/core/dom/SiblingRuleHelper.h b/Source/core/dom/SiblingRuleHelper.h
new file mode 100644
index 0000000..1ae2d9c
--- /dev/null
+++ b/Source/core/dom/SiblingRuleHelper.h
@@ -0,0 +1,45 @@
+// Copyright (c) 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SiblingRuleHelper_h
+#define SiblingRuleHelper_h
+
+#include "core/dom/Node.h"
+
+namespace WebCore {
+
+class SiblingRuleHelper {
+public:
+    SiblingRuleHelper(Node* node) : m_node(node)
+    {
+        ASSERT(node);
+        ASSERT(node->isElementNode() || node->isShadowRoot());
+    }
+
+    void checkForChildrenAdjacentRuleChanges();
+
+    void setChildrenAffectedByDirectAdjacentRules();
+    void setChildrenAffectedByForwardPositionalRules();
+    void setChildrenAffectedByBackwardPositionalRules();
+    void setChildrenAffectedByFirstChildRules();
+    void setChildrenAffectedByLastChildRules();
+
+    bool isFinishedParsingChildren();
+
+    bool childrenSupportStyleSharing();
+
+private:
+    bool childrenAffectedByPositionalRules() const;
+    bool childrenAffectedByFirstChildRules() const;
+    bool childrenAffectedByLastChildRules() const;
+    bool childrenAffectedByDirectAdjacentRules() const;
+    bool childrenAffectedByForwardPositionalRules() const;
+    bool childrenAffectedByBackwardPositionalRules() const;
+
+    Node* m_node;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/core/dom/StyleElement.cpp b/Source/core/dom/StyleElement.cpp
index e744c9b..5d377b8 100644
--- a/Source/core/dom/StyleElement.cpp
+++ b/Source/core/dom/StyleElement.cpp
@@ -28,8 +28,9 @@
 #include "core/dom/Element.h"
 #include "core/dom/ScriptableDocumentParser.h"
 #include "core/dom/StyleEngine.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/HTMLStyleElement.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "platform/TraceEvent.h"
 #include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
@@ -56,6 +57,7 @@
 
 void StyleElement::processStyleSheet(Document& document, Element* element)
 {
+    TRACE_EVENT0("webkit", "StyleElement::processStyleSheet");
     ASSERT(element);
     document.styleEngine()->addStyleSheetCandidateNode(element, m_createdByParser);
     if (m_createdByParser)
@@ -64,15 +66,20 @@
     process(element);
 }
 
-void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode)
+void StyleElement::removedFromDocument(Document& document, Element* element)
+{
+    removedFromDocument(document, element, 0, document);
+}
+
+void StyleElement::removedFromDocument(Document& document, Element* element, ContainerNode* scopingNode, TreeScope& treeScope)
 {
     ASSERT(element);
-    document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode);
+    document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
 
     RefPtr<StyleSheet> removedSheet = m_sheet;
 
     if (m_sheet)
-        clearSheet();
+        clearSheet(element);
 
     document.removedStyleSheet(removedSheet.get(), RecalcStyleDeferred, AnalyzedStyleUpdate);
 }
@@ -82,8 +89,11 @@
     if (m_sheet)
         m_sheet->clearOwnerNode();
 
-    if (element->inDocument())
-        document.styleEngine()->removeStyleSheetCandidateNode(element, element->hasTagName(HTMLNames::styleTag) ? toHTMLStyleElement(element)->scopingNode() :  0);
+    if (element->inDocument()) {
+        ContainerNode* scopingNode = isHTMLStyleElement(element) ? toHTMLStyleElement(element)->scopingNode() :  0;
+        TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : element->treeScope();
+        document.styleEngine()->removeStyleSheetCandidateNode(element, scopingNode, treeScope);
+    }
 }
 
 void StyleElement::childrenChanged(Element* element)
@@ -109,9 +119,13 @@
     createSheet(element, element->textFromChildren());
 }
 
-void StyleElement::clearSheet()
+void StyleElement::clearSheet(Element* ownerElement)
 {
     ASSERT(m_sheet);
+
+    if (ownerElement && m_sheet->isLoading())
+        ownerElement->document().styleEngine()->removePendingSheet(ownerElement);
+
     m_sheet.release()->clearOwnerNode();
 }
 
@@ -120,17 +134,14 @@
     ASSERT(e);
     ASSERT(e->inDocument());
     Document& document = e->document();
-    if (m_sheet) {
-        if (m_sheet->isLoading())
-            document.styleEngine()->removePendingSheet(e);
-        clearSheet();
-    }
+    if (m_sheet)
+        clearSheet(e);
 
     // If type is empty or CSS, this is a CSS style sheet.
     const AtomicString& type = this->type();
     bool passesContentSecurityPolicyChecks = document.contentSecurityPolicy()->allowStyleHash(text) || document.contentSecurityPolicy()->allowStyleNonce(e->fastGetAttribute(HTMLNames::nonceAttr)) || document.contentSecurityPolicy()->allowInlineStyle(e->document().url(), m_startPosition.m_line);
     if (isCSS(e, type) && passesContentSecurityPolicyChecks) {
-        RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());
+        RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(media());
 
         MediaQueryEvaluator screenEval("screen", true);
         MediaQueryEvaluator printEval("print", true);
diff --git a/Source/core/dom/StyleElement.h b/Source/core/dom/StyleElement.h
index a26f5a5..b10337e 100644
--- a/Source/core/dom/StyleElement.h
+++ b/Source/core/dom/StyleElement.h
@@ -29,6 +29,7 @@
 class ContainerNode;
 class Document;
 class Element;
+class TreeScope;
 
 class StyleElement {
 public:
@@ -46,7 +47,8 @@
     void startLoadingDynamicSheet(Document&);
 
     void processStyleSheet(Document&, Element*);
-    void removedFromDocument(Document&, Element*, ContainerNode* scopingNode = 0);
+    void removedFromDocument(Document&, Element*);
+    void removedFromDocument(Document&, Element*, ContainerNode* scopingNode, TreeScope&);
     void clearDocumentData(Document&, Element*);
     void childrenChanged(Element*);
     void finishParsingChildren(Element*);
@@ -56,7 +58,7 @@
 private:
     void createSheet(Element*, const String& text = String());
     void process(Element*);
-    void clearSheet();
+    void clearSheet(Element* ownerElement = 0);
 
     bool m_createdByParser;
     bool m_loading;
diff --git a/Source/core/dom/StyleEngine.cpp b/Source/core/dom/StyleEngine.cpp
index 8f329f8..756d3cc 100644
--- a/Source/core/dom/StyleEngine.cpp
+++ b/Source/core/dom/StyleEngine.cpp
@@ -41,11 +41,11 @@
 #include "core/dom/ShadowTreeStyleSheetCollection.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/html/HTMLIFrameElement.h"
-#include "core/html/HTMLImport.h"
 #include "core/html/HTMLLinkElement.h"
+#include "core/html/imports/HTMLImport.h"
 #include "core/inspector/InspectorInstrumentation.h"
+#include "core/page/InjectedStyleSheets.h"
 #include "core/page/Page.h"
-#include "core/page/PageGroup.h"
 #include "core/frame/Settings.h"
 #include "core/svg/SVGStyleElement.h"
 #include "platform/URLPatternMatcher.h"
@@ -54,18 +54,28 @@
 
 using namespace HTMLNames;
 
-static HashMap<AtomicString, StyleSheetContents*>& textToSheetCache()
+static WillBeHeapHashMap<AtomicString, RawPtrWillBeWeakMember<StyleSheetContents> >& textToSheetCache()
 {
-    typedef HashMap<AtomicString, StyleSheetContents*> TextToSheetCache;
+    typedef WillBeHeapHashMap<AtomicString, RawPtrWillBeWeakMember<StyleSheetContents> > TextToSheetCache;
+#if ENABLE(OILPAN)
+    DEFINE_STATIC_LOCAL(Persistent<TextToSheetCache>, cache, (new TextToSheetCache));
+    return *cache;
+#else
     DEFINE_STATIC_LOCAL(TextToSheetCache, cache, ());
     return cache;
+#endif
 }
 
-static HashMap<StyleSheetContents*, AtomicString>& sheetToTextCache()
+static WillBeHeapHashMap<RawPtrWillBeWeakMember<StyleSheetContents>, AtomicString>& sheetToTextCache()
 {
-    typedef HashMap<StyleSheetContents*, AtomicString> SheetToTextCache;
+    typedef WillBeHeapHashMap<RawPtrWillBeWeakMember<StyleSheetContents>, AtomicString> SheetToTextCache;
+#if ENABLE(OILPAN)
+    DEFINE_STATIC_LOCAL(Persistent<SheetToTextCache>, cache, (new SheetToTextCache));
+    return *cache;
+#else
     DEFINE_STATIC_LOCAL(SheetToTextCache, cache, ());
     return cache;
+#endif
 }
 
 StyleEngine::StyleEngine(Document& document)
@@ -85,12 +95,19 @@
     , m_didCalculateResolver(false)
     // We don't need to create CSSFontSelector for imported document or
     // HTMLTemplateElement's document, because those documents have no frame.
-    , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : 0)
+    , m_fontSelector(document.frame() ? CSSFontSelector::create(&document) : nullptr)
 {
 }
 
 StyleEngine::~StyleEngine()
 {
+}
+
+void StyleEngine::detachFromDocument()
+{
+    // Cleanup is performed eagerly when the StyleEngine is removed from the
+    // document. The StyleEngine is unreachable after this, since only the
+    // document has a reference to it.
     for (unsigned i = 0; i < m_injectedAuthorStyleSheets.size(); ++i)
         m_injectedAuthorStyleSheets[i]->clearOwnerNode();
     for (unsigned i = 0; i < m_authorStyleSheets.size(); ++i)
@@ -101,6 +118,11 @@
         if (m_resolver)
             m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
     }
+
+    // Decrement reference counts for things we could be keeping alive.
+    m_fontSelector.clear();
+    m_resolver.clear();
+    m_styleSheetCollectionMap.clear();
 }
 
 inline Document* StyleEngine::master()
@@ -162,7 +184,7 @@
     return it->value.get();
 }
 
-const Vector<RefPtr<StyleSheet> >& StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope)
+const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& StyleEngine::styleSheetsForStyleSheetList(TreeScope& treeScope)
 {
     if (treeScope == m_document)
         return m_documentStyleSheetCollection.styleSheetsForStyleSheetList();
@@ -170,7 +192,7 @@
     return ensureStyleSheetCollectionFor(treeScope)->styleSheetsForStyleSheetList();
 }
 
-const Vector<RefPtr<CSSStyleSheet> >& StyleEngine::activeAuthorStyleSheets() const
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& StyleEngine::activeAuthorStyleSheets() const
 {
     return m_documentStyleSheetCollection.activeAuthorStyleSheets();
 }
@@ -190,7 +212,7 @@
     m_maxDirectAdjacentSelectors = features.maxDirectAdjacentSelectors();
 }
 
-const Vector<RefPtr<CSSStyleSheet> >& StyleEngine::injectedAuthorStyleSheets() const
+const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& StyleEngine::injectedAuthorStyleSheets() const
 {
     updateInjectedStyleSheetCache();
     return m_injectedAuthorStyleSheets;
@@ -214,7 +236,7 @@
             continue;
         if (!URLPatternMatcher::matchesPatterns(m_document.url(), entry->whitelist()))
             continue;
-        RefPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(&m_document), KURL());
+        RefPtrWillBeRawPtr<CSSStyleSheet> groupSheet = CSSStyleSheet::createInline(const_cast<Document*>(&m_document), KURL());
         m_injectedAuthorStyleSheets.append(groupSheet);
         groupSheet->contents()->parseString(entry->source());
     }
@@ -229,7 +251,7 @@
     m_document.styleResolverChanged(RecalcStyleDeferred);
 }
 
-void StyleEngine::addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet)
+void StyleEngine::addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet)
 {
     m_authorStyleSheets.append(CSSStyleSheet::create(authorSheet, &m_document));
     m_document.addedStyleSheet(m_authorStyleSheets.last().get(), RecalcStyleImmediately);
@@ -238,26 +260,16 @@
 
 void StyleEngine::addPendingSheet()
 {
-    master()->styleEngine()->notifyPendingStyleSheetAdded();
+    m_pendingStylesheets++;
 }
 
 // This method is called whenever a top-level stylesheet has finished loading.
 void StyleEngine::removePendingSheet(Node* styleSheetCandidateNode, RemovePendingSheetNotificationType notification)
 {
-    TreeScope* treeScope = styleSheetCandidateNode->hasTagName(styleTag) ? &styleSheetCandidateNode->treeScope() : &m_document;
+    ASSERT(styleSheetCandidateNode);
+    TreeScope* treeScope = isHTMLStyleElement(*styleSheetCandidateNode) ? &styleSheetCandidateNode->treeScope() : &m_document;
     markTreeScopeDirty(*treeScope);
-    master()->styleEngine()->notifyPendingStyleSheetRemoved(notification);
-}
 
-void StyleEngine::notifyPendingStyleSheetAdded()
-{
-    ASSERT(isMaster());
-    m_pendingStylesheets++;
-}
-
-void StyleEngine::notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType notification)
-{
-    ASSERT(isMaster());
     // Make sure we knew this sheet was pending, and that our count isn't out of sync.
     ASSERT(m_pendingStylesheets > 0);
 
@@ -284,8 +296,8 @@
     if (!node || !node->inDocument())
         return;
 
-    TreeScope& treeScope = node->hasTagName(styleTag) ? node->treeScope() : m_document;
-    ASSERT(node->hasTagName(styleTag) || treeScope == m_document);
+    TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : m_document;
+    ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
 
     markTreeScopeDirty(treeScope);
 }
@@ -295,8 +307,8 @@
     if (!node->inDocument())
         return;
 
-    TreeScope& treeScope = node->hasTagName(styleTag) ? node->treeScope() : m_document;
-    ASSERT(node->hasTagName(styleTag) || treeScope == m_document);
+    TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : m_document;
+    ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
 
     TreeScopeStyleSheetCollection* collection = ensureStyleSheetCollectionFor(treeScope);
     ASSERT(collection);
@@ -307,10 +319,14 @@
         insertTreeScopeInDocumentOrder(m_activeTreeScopes, &treeScope);
 }
 
-void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode)
+void StyleEngine::removeStyleSheetCandidateNode(Node* node)
 {
-    TreeScope& treeScope = scopingNode ? scopingNode->treeScope() : m_document;
-    ASSERT(node->hasTagName(styleTag) || treeScope == m_document);
+    removeStyleSheetCandidateNode(node, 0, m_document);
+}
+
+void StyleEngine::removeStyleSheetCandidateNode(Node* node, ContainerNode* scopingNode, TreeScope& treeScope)
+{
+    ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
 
     TreeScopeStyleSheetCollection* collection = styleSheetCollectionFor(treeScope);
     ASSERT(collection);
@@ -325,8 +341,8 @@
     if (!node->inDocument())
         return;
 
-    TreeScope& treeScope = node->hasTagName(styleTag) ? node->treeScope() : m_document;
-    ASSERT(node->hasTagName(styleTag) || treeScope == m_document);
+    TreeScope& treeScope = isHTMLStyleElement(*node) ? node->treeScope() : m_document;
+    ASSERT(isHTMLStyleElement(node) || treeScope == m_document);
     markTreeScopeDirty(treeScope);
 }
 
@@ -356,7 +372,7 @@
 void StyleEngine::updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector)
 {
     ASSERT(!isMaster());
-    Vector<RefPtr<StyleSheet> > sheetsForList;
+    WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > sheetsForList;
     ImportedDocumentStyleSheetCollector subcollector(parentCollector, sheetsForList);
     m_documentStyleSheetCollection.collectStyleSheets(this, subcollector);
     m_documentStyleSheetCollection.swapSheetsForSheetList(sheetsForList);
@@ -401,20 +417,20 @@
     return requiresFullStyleRecalc;
 }
 
-const Vector<RefPtr<StyleSheet> > StyleEngine::activeStyleSheetsForInspector() const
+const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > StyleEngine::activeStyleSheetsForInspector() const
 {
     if (m_activeTreeScopes.isEmpty())
         return m_documentStyleSheetCollection.styleSheetsForStyleSheetList();
 
-    Vector<RefPtr<StyleSheet> > activeStyleSheets;
+    WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > activeStyleSheets;
 
-    activeStyleSheets.append(m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
+    activeStyleSheets.appendVector(m_documentStyleSheetCollection.styleSheetsForStyleSheetList());
 
     TreeScopeSet::const_iterator begin = m_activeTreeScopes.begin();
     TreeScopeSet::const_iterator end = m_activeTreeScopes.end();
     for (TreeScopeSet::const_iterator it = begin; it != end; ++it) {
         if (TreeScopeStyleSheetCollection* collection = m_styleSheetCollectionMap.get(*it))
-            activeStyleSheets.append(collection->styleSheetsForStyleSheetList());
+            activeStyleSheets.appendVector(collection->styleSheetsForStyleSheetList());
     }
 
     // FIXME: Inspector needs a vector which has all active stylesheets.
@@ -459,7 +475,7 @@
     m_resolver = adoptPtr(new StyleResolver(m_document));
     appendActiveAuthorStyleSheets();
     m_fontSelector->registerForInvalidationCallbacks(m_resolver.get());
-    combineCSSFeatureFlags(m_resolver->ensureRuleFeatureSet());
+    combineCSSFeatureFlags(m_resolver->ensureUpdatedRuleFeatureSet());
 }
 
 void StyleEngine::clearResolver()
@@ -467,8 +483,10 @@
     ASSERT(!m_document.inStyleRecalc());
     ASSERT(isMaster() || !m_resolver);
     ASSERT(m_fontSelector || !m_resolver);
-    if (m_resolver)
+    if (m_resolver) {
+        m_document.updateStyleInvalidationIfNeeded();
         m_fontSelector->unregisterForInvalidationCallbacks(m_resolver.get());
+    }
     m_resolver.clear();
 }
 
@@ -539,7 +557,7 @@
         m_resolver->invalidateMatchedPropertiesCache();
 }
 
-void StyleEngine::removeFontFaceRules(const Vector<const StyleRuleFontFace*>& fontFaceRules)
+void StyleEngine::removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
 {
     if (!m_fontSelector)
         return;
@@ -577,16 +595,16 @@
     if (!e->document().inQuirksMode()) {
         AtomicString textContent(text);
 
-        HashMap<AtomicString, StyleSheetContents*>::AddResult result = textToSheetCache().add(textContent, 0);
-        if (result.isNewEntry || !result.storedValue->value) {
+        WillBeHeapHashMap<AtomicString, RawPtrWillBeWeakMember<StyleSheetContents> >::iterator it = textToSheetCache().find(textContent);
+        if (it == textToSheetCache().end()) {
             styleSheet = StyleEngine::parseSheet(e, text, startPosition, createdByParser);
-            if (result.isNewEntry && styleSheet->contents()->maybeCacheable()) {
-                result.storedValue->value = styleSheet->contents();
+            if (styleSheet->contents()->maybeCacheable()) {
+                textToSheetCache().add(textContent, styleSheet->contents());
                 sheetToTextCache().add(styleSheet->contents(), textContent);
             }
         } else {
-            ASSERT(result.storedValue->value->maybeCacheable());
-            styleSheet = CSSStyleSheet::createInline(result.storedValue->value, e, startPosition);
+            ASSERT(it->value->maybeCacheable());
+            styleSheet = CSSStyleSheet::createInline(it->value, e, startPosition);
         }
     } else {
         // FIXME: currently we don't cache StyleSheetContents inQuirksMode.
@@ -608,7 +626,7 @@
 
 void StyleEngine::removeSheet(StyleSheetContents* contents)
 {
-    HashMap<StyleSheetContents*, AtomicString>::iterator it = sheetToTextCache().find(contents);
+    WillBeHeapHashMap<RawPtrWillBeWeakMember<StyleSheetContents>, AtomicString>::iterator it = sheetToTextCache().find(contents);
     if (it == sheetToTextCache().end())
         return;
 
@@ -616,4 +634,10 @@
     sheetToTextCache().remove(contents);
 }
 
+void StyleEngine::trace(Visitor* visitor)
+{
+    visitor->trace(m_injectedAuthorStyleSheets);
+    visitor->trace(m_authorStyleSheets);
+}
+
 }
diff --git a/Source/core/dom/StyleEngine.h b/Source/core/dom/StyleEngine.h
index d924848..57daab1 100644
--- a/Source/core/dom/StyleEngine.h
+++ b/Source/core/dom/StyleEngine.h
@@ -71,8 +71,8 @@
     bool m_needsStyleRecalc;
 };
 
-class StyleEngine {
-    WTF_MAKE_FAST_ALLOCATED;
+class StyleEngine : public NoBaseWillBeGarbageCollectedFinalized<StyleEngine> {
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
 
     class IgnoringPendingStylesheet : public TemporaryChange<bool> {
@@ -85,27 +85,30 @@
 
     friend class IgnoringPendingStylesheet;
 
-    static PassOwnPtr<StyleEngine> create(Document& document) { return adoptPtr(new StyleEngine(document)); }
+    static PassOwnPtrWillBeRawPtr<StyleEngine> create(Document& document) { return adoptPtrWillBeNoop(new StyleEngine(document)); }
 
     ~StyleEngine();
 
-    const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
-    const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const;
+    void detachFromDocument();
 
-    const Vector<RefPtr<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
-    const Vector<RefPtr<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+    const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList(TreeScope&);
+    const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const;
 
-    const Vector<RefPtr<StyleSheet> > activeStyleSheetsForInspector() const;
+    const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& documentAuthorStyleSheets() const { return m_authorStyleSheets; }
+    const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& injectedAuthorStyleSheets() const;
+
+    const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > activeStyleSheetsForInspector() const;
 
     void modifiedStyleSheet(StyleSheet*);
     void addStyleSheetCandidateNode(Node*, bool createdByParser);
-    void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode = 0);
+    void removeStyleSheetCandidateNode(Node*);
+    void removeStyleSheetCandidateNode(Node*, ContainerNode* scopingNode, TreeScope&);
     void modifiedStyleSheetCandidateNode(Node*);
 
     void invalidateInjectedStyleSheetCache();
     void updateInjectedStyleSheetCache() const;
 
-    void addAuthorSheet(PassRefPtr<StyleSheetContents> authorSheet);
+    void addAuthorSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> authorSheet);
 
     void clearMediaQueryRuleSetStyleSheets();
     void updateStyleSheetsInImport(DocumentStyleSheetCollector& parentCollector);
@@ -169,7 +172,7 @@
     void clearMasterResolver();
 
     CSSFontSelector* fontSelector() { return m_fontSelector.get(); }
-    void removeFontFaceRules(const Vector<const StyleRuleFontFace*>&);
+    void removeFontFaceRules(const WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >&);
     void clearFontCache();
     // updateGenericFontFamilySettings is used from WebSettingsImpl.
     void updateGenericFontFamilySettings();
@@ -184,6 +187,8 @@
     static PassRefPtr<CSSStyleSheet> createSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
     static void removeSheet(StyleSheetContents*);
 
+    void trace(Visitor*);
+
 private:
     StyleEngine(Document&);
 
@@ -202,9 +207,6 @@
 
     void createResolver();
 
-    void notifyPendingStyleSheetAdded();
-    void notifyPendingStyleSheetRemoved(RemovePendingSheetNotificationType);
-
     static PassRefPtr<CSSStyleSheet> parseSheet(Element*, const String& text, TextPosition startPosition, bool createdByParser);
 
     Document& m_document;
@@ -216,10 +218,10 @@
     // elements and when it is safe to execute scripts.
     int m_pendingStylesheets;
 
-    mutable Vector<RefPtr<CSSStyleSheet> > m_injectedAuthorStyleSheets;
+    mutable WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_injectedAuthorStyleSheets;
     mutable bool m_injectedStyleSheetCacheValid;
 
-    Vector<RefPtr<CSSStyleSheet> > m_authorStyleSheets;
+    WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_authorStyleSheets;
 
     DocumentStyleSheetCollection m_documentStyleSheetCollection;
     HashMap<TreeScope*, OwnPtr<TreeScopeStyleSheetCollection> > m_styleSheetCollectionMap;
diff --git a/Source/core/dom/StyleSheetCandidate.cpp b/Source/core/dom/StyleSheetCandidate.cpp
index f090e25..e9bad97 100644
--- a/Source/core/dom/StyleSheetCandidate.cpp
+++ b/Source/core/dom/StyleSheetCandidate.cpp
@@ -31,9 +31,9 @@
 #include "core/dom/Element.h"
 #include "core/dom/ProcessingInstruction.h"
 #include "core/dom/StyleEngine.h"
-#include "core/html/HTMLImport.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/html/HTMLStyleElement.h"
+#include "core/html/imports/HTMLImport.h"
 #include "core/svg/SVGStyleElement.h"
 
 namespace WebCore {
@@ -58,12 +58,7 @@
 Document* StyleSheetCandidate::importedDocument() const
 {
     ASSERT(isImport());
-    // The stylesheet update traversal shouldn't go into shared import
-    // to prevent it from stepping into cycle.
-    HTMLLinkElement& element = toHTMLLinkElement(m_node);
-    if (!element.importOwnsLoader())
-        return 0;
-    return element.import();
+    return toHTMLLinkElement(m_node).import();
 }
 
 bool StyleSheetCandidate::isAlternate() const
@@ -109,16 +104,16 @@
         return Pi;
 
     if (node.isHTMLElement()) {
-        if (node.hasTagName(linkTag))
+        if (isHTMLLinkElement(node))
             return HTMLLink;
-        if (node.hasTagName(styleTag))
+        if (isHTMLStyleElement(node))
             return HTMLStyle;
 
         ASSERT_NOT_REACHED();
         return HTMLStyle;
     }
 
-    if (node.isSVGElement() && node.hasTagName(SVGNames::styleTag))
+    if (isSVGStyleElement(node))
         return SVGStyle;
 
     ASSERT_NOT_REACHED();
diff --git a/Source/core/dom/StyleSheetCollection.cpp b/Source/core/dom/StyleSheetCollection.cpp
index 8603903..9187d67 100644
--- a/Source/core/dom/StyleSheetCollection.cpp
+++ b/Source/core/dom/StyleSheetCollection.cpp
@@ -45,16 +45,16 @@
     m_activeAuthorStyleSheets.swap(other.m_activeAuthorStyleSheets);
 }
 
-void StyleSheetCollection::swapSheetsForSheetList(Vector<RefPtr<StyleSheet> >& sheets)
+void StyleSheetCollection::swapSheetsForSheetList(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& sheets)
 {
     // Only called for collection of HTML Imports that never has active sheets.
     ASSERT(m_activeAuthorStyleSheets.isEmpty());
     m_styleSheetsForStyleSheetList.swap(sheets);
 }
 
-void StyleSheetCollection::appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& sheets)
+void StyleSheetCollection::appendActiveStyleSheets(const WillBePersistentHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
 {
-    m_activeAuthorStyleSheets.append(sheets);
+    m_activeAuthorStyleSheets.appendVector(sheets);
 }
 
 void StyleSheetCollection::appendActiveStyleSheet(CSSStyleSheet* sheet)
diff --git a/Source/core/dom/StyleSheetCollection.h b/Source/core/dom/StyleSheetCollection.h
index 47b89ce..7f0da11 100644
--- a/Source/core/dom/StyleSheetCollection.h
+++ b/Source/core/dom/StyleSheetCollection.h
@@ -28,6 +28,7 @@
 #ifndef StyleSheetCollection_h
 #define StyleSheetCollection_h
 
+#include "heap/Handle.h"
 #include "wtf/FastAllocBase.h"
 #include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
@@ -46,20 +47,20 @@
     StyleSheetCollection();
     ~StyleSheetCollection();
 
-    Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
-    Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() { return m_styleSheetsForStyleSheetList; }
-    const Vector<RefPtr<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
-    const Vector<RefPtr<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
+    WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() { return m_activeAuthorStyleSheets; }
+    WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList() { return m_styleSheetsForStyleSheetList; }
+    const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& activeAuthorStyleSheets() const { return m_activeAuthorStyleSheets; }
+    const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >& styleSheetsForStyleSheetList() const { return m_styleSheetsForStyleSheetList; }
 
     void swap(StyleSheetCollection&);
-    void swapSheetsForSheetList(Vector<RefPtr<StyleSheet> >&);
-    void appendActiveStyleSheets(const Vector<RefPtr<CSSStyleSheet> >&);
+    void swapSheetsForSheetList(WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >&);
+    void appendActiveStyleSheets(const WillBePersistentHeapVector<RefPtrWillBeMember<CSSStyleSheet> >&);
     void appendActiveStyleSheet(CSSStyleSheet*);
     void appendSheetForList(StyleSheet*);
 
 protected:
-    Vector<RefPtr<StyleSheet> > m_styleSheetsForStyleSheetList;
-    Vector<RefPtr<CSSStyleSheet> > m_activeAuthorStyleSheets;
+    WillBePersistentHeapVector<RefPtrWillBeMember<StyleSheet> > m_styleSheetsForStyleSheetList;
+    WillBePersistentHeapVector<RefPtrWillBeMember<CSSStyleSheet> > m_activeAuthorStyleSheets;
 };
 
 }
diff --git a/Source/core/dom/TagCollection.cpp b/Source/core/dom/TagCollection.cpp
index 275d942..98bd3e4 100644
--- a/Source/core/dom/TagCollection.cpp
+++ b/Source/core/dom/TagCollection.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-TagCollection::TagCollection(ContainerNode* rootNode, CollectionType type, const AtomicString& namespaceURI, const AtomicString& localName)
+TagCollection::TagCollection(ContainerNode& rootNode, CollectionType type, const AtomicString& namespaceURI, const AtomicString& localName)
     : HTMLCollection(rootNode, type, DoesNotOverrideItemAfter)
     , m_namespaceURI(namespaceURI)
     , m_localName(localName)
@@ -40,9 +40,9 @@
 TagCollection::~TagCollection()
 {
     if (m_namespaceURI == starAtom)
-        ownerNode()->nodeLists()->removeCache(this, type(), m_localName);
+        ownerNode().nodeLists()->removeCache(this, type(), m_localName);
     else
-        ownerNode()->nodeLists()->removeCache(this, m_namespaceURI, m_localName);
+        ownerNode().nodeLists()->removeCache(this, m_namespaceURI, m_localName);
 }
 
 bool TagCollection::elementMatches(const Element& testNode) const
@@ -54,7 +54,7 @@
     return m_namespaceURI == starAtom || m_namespaceURI == testNode.namespaceURI();
 }
 
-HTMLTagCollection::HTMLTagCollection(ContainerNode* rootNode, const AtomicString& localName)
+HTMLTagCollection::HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName)
     : TagCollection(rootNode, HTMLTagCollectionType, starAtom, localName)
     , m_loweredLocalName(localName.lower())
 {
diff --git a/Source/core/dom/TagCollection.h b/Source/core/dom/TagCollection.h
index 393741e..7d4782a 100644
--- a/Source/core/dom/TagCollection.h
+++ b/Source/core/dom/TagCollection.h
@@ -33,13 +33,13 @@
 // Collection that limits to a particular tag.
 class TagCollection : public HTMLCollection {
 public:
-    static PassRefPtr<TagCollection> create(ContainerNode* rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
+    static PassRefPtr<TagCollection> create(ContainerNode& rootNode, const AtomicString& namespaceURI, const AtomicString& localName)
     {
         ASSERT(namespaceURI != starAtom);
         return adoptRef(new TagCollection(rootNode, TagCollectionType, namespaceURI, localName));
     }
 
-    static PassRefPtr<TagCollection> create(ContainerNode* rootNode, CollectionType type, const AtomicString& localName)
+    static PassRefPtr<TagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
     {
         ASSERT_UNUSED(type, type == TagCollectionType);
         return adoptRef(new TagCollection(rootNode, TagCollectionType, starAtom, localName));
@@ -50,7 +50,7 @@
     bool elementMatches(const Element&) const;
 
 protected:
-    TagCollection(ContainerNode* rootNode, CollectionType, const AtomicString& namespaceURI, const AtomicString& localName);
+    TagCollection(ContainerNode& rootNode, CollectionType, const AtomicString& namespaceURI, const AtomicString& localName);
 
     AtomicString m_namespaceURI;
     AtomicString m_localName;
@@ -58,7 +58,7 @@
 
 class HTMLTagCollection FINAL : public TagCollection {
 public:
-    static PassRefPtr<HTMLTagCollection> create(ContainerNode* rootNode, CollectionType type, const AtomicString& localName)
+    static PassRefPtr<HTMLTagCollection> create(ContainerNode& rootNode, CollectionType type, const AtomicString& localName)
     {
         ASSERT_UNUSED(type, type == HTMLTagCollectionType);
         return adoptRef(new HTMLTagCollection(rootNode, localName));
@@ -67,7 +67,7 @@
     bool elementMatches(const Element&) const;
 
 private:
-    HTMLTagCollection(ContainerNode* rootNode, const AtomicString& localName);
+    HTMLTagCollection(ContainerNode& rootNode, const AtomicString& localName);
 
     AtomicString m_loweredLocalName;
 };
diff --git a/Source/core/dom/Text.cpp b/Source/core/dom/Text.cpp
index cf67098..d799418 100644
--- a/Source/core/dom/Text.cpp
+++ b/Source/core/dom/Text.cpp
@@ -36,6 +36,7 @@
 #include "core/rendering/RenderCombineText.h"
 #include "core/rendering/RenderText.h"
 #include "core/rendering/svg/RenderSVGInlineText.h"
+#include "core/svg/SVGForeignObjectElement.h"
 #include "wtf/text/CString.h"
 #include "wtf/text/StringBuilder.h"
 
@@ -89,7 +90,7 @@
         nextText->setDataWithoutUpdate(emptyString());
         nextText->updateTextRenderer(0, nextTextData.length());
 
-        document().didMergeTextNodes(nextText.get(), offset);
+        document().didMergeTextNodes(*nextText, offset);
 
         // Restore nextText for mutation event.
         nextText->setDataWithoutUpdate(nextTextData);
@@ -109,7 +110,7 @@
     // the number of 16-bit units in data.
     if (offset > length()) {
         exceptionState.throwDOMException(IndexSizeError, "The offset " + String::number(offset) + " is larger than the Text node's length.");
-        return 0;
+        return nullptr;
     }
 
     EventQueueScope scope;
@@ -122,13 +123,13 @@
     if (parentNode())
         parentNode()->insertBefore(newText.get(), nextSibling(), exceptionState);
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     if (renderer())
         toRenderText(renderer())->setTextWithOffset(dataImpl(), 0, oldStr.length());
 
     if (parentNode())
-        document().didSplitTextNode(this);
+        document().didSplitTextNode(*this);
 
     return newText.release();
 }
@@ -218,7 +219,7 @@
     if (newText.isEmpty()) {
         if (parent && parentNode() == parent)
             parent->removeChild(this, IGNORE_EXCEPTION);
-        return 0;
+        return nullptr;
     }
 
     setData(newText);
@@ -290,7 +291,8 @@
 static bool isSVGText(Text* text)
 {
     Node* parentOrShadowHostNode = text->parentOrShadowHostNode();
-    return parentOrShadowHostNode->isSVGElement() && !parentOrShadowHostNode->hasTagName(SVGNames::foreignObjectTag);
+    ASSERT(parentOrShadowHostNode);
+    return parentOrShadowHostNode->isSVGElement() && !isSVGForeignObjectElement(*parentOrShadowHostNode);
 }
 
 RenderText* Text::createTextRenderer(RenderStyle* style)
diff --git a/Source/core/dom/Touch.cpp b/Source/core/dom/Touch.cpp
index a955bab..18f2734 100644
--- a/Source/core/dom/Touch.cpp
+++ b/Source/core/dom/Touch.cpp
@@ -27,12 +27,12 @@
 
 #include "core/dom/Touch.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
-static int contentsX(Frame* frame)
+static int contentsX(LocalFrame* frame)
 {
     if (!frame)
         return 0;
@@ -42,7 +42,7 @@
     return frameView->scrollX() / frame->pageZoomFactor();
 }
 
-static int contentsY(Frame* frame)
+static int contentsY(LocalFrame* frame)
 {
     if (!frame)
         return 0;
@@ -52,7 +52,7 @@
     return frameView->scrollY() / frame->pageZoomFactor();
 }
 
-Touch::Touch(Frame* frame, EventTarget* target, unsigned identifier, int screenX, int screenY, int pageX, int pageY, int radiusX, int radiusY, float rotationAngle, float force)
+Touch::Touch(LocalFrame* frame, EventTarget* target, unsigned identifier, int screenX, int screenY, int pageX, int pageY, int radiusX, int radiusY, float rotationAngle, float force)
     : m_target(target)
     , m_identifier(identifier)
     , m_clientX(pageX - contentsX(frame))
@@ -91,9 +91,9 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<Touch> Touch::cloneWithNewTarget(EventTarget* eventTarget) const
+PassRefPtrWillBeRawPtr<Touch> Touch::cloneWithNewTarget(EventTarget* eventTarget) const
 {
-    return adoptRef(new Touch(eventTarget, m_identifier, m_clientX, m_clientY, m_screenX, m_screenY, m_pageX, m_pageY, m_radiusX, m_radiusY, m_rotationAngle, m_force, m_absoluteLocation));
+    return adoptRefWillBeNoop(new Touch(eventTarget, m_identifier, m_clientX, m_clientY, m_screenX, m_screenY, m_pageX, m_pageY, m_radiusX, m_radiusY, m_rotationAngle, m_force, m_absoluteLocation));
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/Touch.h b/Source/core/dom/Touch.h
index 220d4cf..d4f253b 100644
--- a/Source/core/dom/Touch.h
+++ b/Source/core/dom/Touch.h
@@ -28,6 +28,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/events/EventTarget.h"
+#include "heap/Handle.h"
 #include "platform/geometry/LayoutPoint.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -35,15 +36,15 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 
-class Touch : public RefCounted<Touch>, public ScriptWrappable {
+class Touch : public RefCountedWillBeGarbageCollectedFinalized<Touch>, public ScriptWrappable {
 public:
-    static PassRefPtr<Touch> create(Frame* frame, EventTarget* target,
+    static PassRefPtrWillBeRawPtr<Touch> create(LocalFrame* frame, EventTarget* target,
             unsigned identifier, int screenX, int screenY, int pageX, int pageY,
             int radiusX, int radiusY, float rotationAngle, float force)
     {
-        return adoptRef(new Touch(frame, target, identifier, screenX,
+        return adoptRefWillBeNoop(new Touch(frame, target, identifier, screenX,
                 screenY, pageX, pageY, radiusX, radiusY, rotationAngle, force));
     }
 
@@ -60,10 +61,12 @@
     float webkitRotationAngle() const { return m_rotationAngle; }
     float webkitForce() const { return m_force; }
     const LayoutPoint& absoluteLocation() const { return m_absoluteLocation; }
-    PassRefPtr<Touch> cloneWithNewTarget(EventTarget*) const;
+    PassRefPtrWillBeRawPtr<Touch> cloneWithNewTarget(EventTarget*) const;
+
+    void trace(Visitor*) { }
 
 private:
-    Touch(Frame* frame, EventTarget* target, unsigned identifier,
+    Touch(LocalFrame* frame, EventTarget* target, unsigned identifier,
             int screenX, int screenY, int pageX, int pageY,
             int radiusX, int radiusY, float rotationAngle, float force);
 
diff --git a/Source/core/dom/Touch.idl b/Source/core/dom/Touch.idl
index c748ec8..06e93d9 100644
--- a/Source/core/dom/Touch.idl
+++ b/Source/core/dom/Touch.idl
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface Touch {
+[
+    WillBeGarbageCollected,
+] interface Touch {
     readonly attribute long             clientX;
     readonly attribute long             clientY;
     readonly attribute long             screenX;
diff --git a/Source/core/dom/TouchList.cpp b/Source/core/dom/TouchList.cpp
index 3653a2e..b636f20 100644
--- a/Source/core/dom/TouchList.cpp
+++ b/Source/core/dom/TouchList.cpp
@@ -41,4 +41,9 @@
     return const_cast<TouchList*>(this)->item(index);
 }
 
+void TouchList::trace(Visitor* visitor)
+{
+    visitor->trace(m_values);
+}
+
 } // namespace WebCore
diff --git a/Source/core/dom/TouchList.h b/Source/core/dom/TouchList.h
index 6d5f2bf..68b5341 100644
--- a/Source/core/dom/TouchList.h
+++ b/Source/core/dom/TouchList.h
@@ -28,21 +28,22 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/Touch.h"
+#include "heap/Handle.h"
 #include "wtf/RefCounted.h"
 #include "wtf/Vector.h"
 
 namespace WebCore {
 
-class TouchList : public RefCounted<TouchList>, public ScriptWrappable {
+class TouchList : public RefCountedWillBeGarbageCollectedFinalized<TouchList>, public ScriptWrappable {
 public:
-    static PassRefPtr<TouchList> create()
+    static PassRefPtrWillBeRawPtr<TouchList> create()
     {
-        return adoptRef(new TouchList);
+        return adoptRefWillBeNoop(new TouchList);
     }
 
-    static PassRefPtr<TouchList> create(Vector<RefPtr<Touch> >& touches)
+    static PassRefPtrWillBeRawPtr<TouchList> create(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches)
     {
-        return adoptRef(new TouchList(touches));
+        return adoptRefWillBeNoop(new TouchList(touches));
     }
 
     unsigned length() const { return m_values.size(); }
@@ -50,7 +51,9 @@
     Touch* item(unsigned);
     const Touch* item(unsigned) const;
 
-    void append(const PassRefPtr<Touch> touch) { m_values.append(touch); }
+    void append(const PassRefPtrWillBeRawPtr<Touch> touch) { m_values.append(touch); }
+
+    void trace(Visitor*);
 
 private:
     TouchList()
@@ -58,13 +61,13 @@
         ScriptWrappable::init(this);
     }
 
-    TouchList(Vector<RefPtr<Touch> >& touches)
+    TouchList(WillBeHeapVector<RefPtrWillBeMember<Touch> >& touches)
     {
         m_values.swap(touches);
         ScriptWrappable::init(this);
     }
 
-    Vector<RefPtr<Touch> > m_values;
+    WillBeHeapVector<RefPtrWillBeMember<Touch> > m_values;
 };
 
 } // namespace WebCore
diff --git a/Source/core/dom/TouchList.idl b/Source/core/dom/TouchList.idl
index 351a59c..516946d 100644
--- a/Source/core/dom/TouchList.idl
+++ b/Source/core/dom/TouchList.idl
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface TouchList {
+[
+    WillBeGarbageCollected,
+] interface TouchList {
     readonly attribute unsigned long length;
 
     getter Touch item(unsigned long index);
diff --git a/Source/core/dom/Traversal.h b/Source/core/dom/Traversal.h
deleted file mode 100644
index 58ef152..0000000
--- a/Source/core/dom/Traversal.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- * Copyright (C) 2000 Frederik Holljen (frederik.holljen@hig.no)
- * Copyright (C) 2001 Peter Kelly (pmk@post.com)
- * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- * Copyright (C) 2004, 2008 Apple Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef Traversal_h
-#define Traversal_h
-
-#include "bindings/v8/ScriptState.h"
-#include "wtf/RefPtr.h"
-
-namespace WebCore {
-
-    class Node;
-    class NodeFilter;
-
-    class Traversal {
-    public:
-        Node* root() const { return m_root.get(); }
-        unsigned whatToShow() const { return m_whatToShow; }
-        NodeFilter* filter() const { return m_filter.get(); }
-        // |expandEntityReferences| first appeared in "DOM Level 2 Traversal and Range". However, this argument was
-        // never implemented, and, in DOM4, the function argument |expandEntityReferences| is removed from
-        // Document.createNodeIterator() and Document.createTreeWalker().
-        bool expandEntityReferences() const { return false; }
-
-    protected:
-        Traversal(PassRefPtr<Node>, unsigned whatToShow, PassRefPtr<NodeFilter>);
-        short acceptNode(ScriptState*, Node*) const;
-
-    private:
-        RefPtr<Node> m_root;
-        unsigned m_whatToShow;
-        RefPtr<NodeFilter> m_filter;
-    };
-
-} // namespace WebCore
-
-#endif // Traversal_h
diff --git a/Source/core/dom/TreeScope.cpp b/Source/core/dom/TreeScope.cpp
index bd2bcb4..ed11d7e 100644
--- a/Source/core/dom/TreeScope.cpp
+++ b/Source/core/dom/TreeScope.cpp
@@ -38,14 +38,14 @@
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/events/EventPath.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLLabelElement.h"
 #include "core/html/HTMLMapElement.h"
 #include "core/page/DOMSelection.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/RenderView.h"
@@ -84,7 +84,7 @@
 
     if (m_selection) {
         m_selection->clearTreeScope();
-        m_selection = 0;
+        m_selection = nullptr;
     }
 
     if (m_parentTreeScope)
@@ -217,7 +217,7 @@
 
 HitTestResult hitTestInDocument(const Document* document, int x, int y)
 {
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
 
     if (!frame)
         return HitTestResult();
@@ -272,13 +272,10 @@
     if (!m_labelsByForAttribute) {
         // Populate the map on first access.
         m_labelsByForAttribute = adoptPtr(new DocumentOrderedMap);
-        for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::next(*element)) {
-            if (element->hasTagName(labelTag)) {
-                HTMLLabelElement* label = toHTMLLabelElement(element);
-                const AtomicString& forValue = label->fastGetAttribute(forAttr);
-                if (!forValue.isEmpty())
-                    addLabel(forValue, label);
-            }
+        for (HTMLLabelElement* label = Traversal<HTMLLabelElement>::firstWithin(rootNode()); label; label = Traversal<HTMLLabelElement>::next(*label)) {
+            const AtomicString& forValue = label->fastGetAttribute(forAttr);
+            if (!forValue.isEmpty())
+                addLabel(forValue, label);
         }
     }
 
@@ -306,18 +303,15 @@
         return 0;
     if (Element* element = getElementById(AtomicString(name)))
         return element;
-    for (Element* element = ElementTraversal::firstWithin(rootNode()); element; element = ElementTraversal::next(*element)) {
-        if (element->hasTagName(aTag)) {
-            HTMLAnchorElement* anchor = toHTMLAnchorElement(element);
-            if (rootNode().document().inQuirksMode()) {
-                // Quirks mode, case insensitive comparison of names.
-                if (equalIgnoringCase(anchor->name(), name))
-                    return anchor;
-            } else {
-                // Strict mode, names need to match exactly.
-                if (anchor->name() == name)
-                    return anchor;
-            }
+    for (HTMLAnchorElement* anchor = Traversal<HTMLAnchorElement>::firstWithin(rootNode()); anchor; anchor = Traversal<HTMLAnchorElement>::next(*anchor)) {
+        if (rootNode().document().inQuirksMode()) {
+            // Quirks mode, case insensitive comparison of names.
+            if (equalIgnoringCase(anchor->name(), name))
+                return anchor;
+        } else {
+            // Strict mode, names need to match exactly.
+            if (anchor->name() == name)
+                return anchor;
         }
     }
     return 0;
@@ -338,7 +332,7 @@
         adopter.execute();
 }
 
-static Element* focusedFrameOwnerElement(Frame* focusedFrame, Frame* currentFrame)
+static Element* focusedFrameOwnerElement(LocalFrame* focusedFrame, LocalFrame* currentFrame)
 {
     for (; focusedFrame; focusedFrame = focusedFrame->tree().parent()) {
         if (focusedFrame->tree().parent() == currentFrame)
diff --git a/Source/core/dom/TreeScope.h b/Source/core/dom/TreeScope.h
index 6a7703a..cdb299b 100644
--- a/Source/core/dom/TreeScope.h
+++ b/Source/core/dom/TreeScope.h
@@ -28,6 +28,7 @@
 #define TreeScope_h
 
 #include "core/dom/DocumentOrderedMap.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/text/AtomicString.h"
 
@@ -167,7 +168,7 @@
 
     OwnPtr<IdTargetObserverRegistry> m_idTargetObserverRegistry;
 
-    mutable RefPtr<DOMSelection> m_selection;
+    mutable RefPtrWillBePersistent<DOMSelection> m_selection;
 };
 
 inline bool TreeScope::hasElementWithId(StringImpl* id) const
diff --git a/Source/core/dom/TreeScopeStyleSheetCollection.cpp b/Source/core/dom/TreeScopeStyleSheetCollection.cpp
index ea7eef7..2daa165 100644
--- a/Source/core/dom/TreeScopeStyleSheetCollection.cpp
+++ b/Source/core/dom/TreeScopeStyleSheetCollection.cpp
@@ -59,10 +59,10 @@
     else
         m_styleSheetCandidateNodes.add(node);
 
-    if (!node->hasTagName(HTMLNames::styleTag))
+    if (!isHTMLStyleElement(*node))
         return;
 
-    ContainerNode* scopingNode = toHTMLStyleElement(node)->scopingNode();
+    ContainerNode* scopingNode = toHTMLStyleElement(*node).scopingNode();
     if (!isTreeScopeRoot(scopingNode))
         m_scopingNodesForStyleScoped.add(scopingNode);
 }
@@ -75,7 +75,7 @@
         m_scopingNodesForStyleScoped.remove(scopingNode);
 }
 
-TreeScopeStyleSheetCollection::StyleResolverUpdateType TreeScopeStyleSheetCollection::compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets)
+TreeScopeStyleSheetCollection::StyleResolverUpdateType TreeScopeStyleSheetCollection::compareStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& oldStyleSheets, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStylesheets, WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& addedSheets)
 {
     unsigned newStyleSheetCount = newStylesheets.size();
     unsigned oldStyleSheetCount = oldStyleSheets.size();
@@ -104,7 +104,7 @@
     return hasInsertions ? Reset : Additive;
 }
 
-bool TreeScopeStyleSheetCollection::activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets)
+bool TreeScopeStyleSheetCollection::activeLoadingStyleSheetLoaded(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStyleSheets)
 {
     // StyleSheets of <style> elements that @import stylesheets are active but loading. We need to trigger a full recalc when such loads are done.
     bool hasActiveLoadingStylesheet = false;
@@ -121,7 +121,7 @@
     return false;
 }
 
-static bool findFontFaceRulesFromStyleSheetContents(Vector<StyleSheetContents*> sheets, Vector<const StyleRuleFontFace*>& fontFaceRules)
+static bool findFontFaceRulesFromStyleSheetContents(const WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& sheets, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> >& fontFaceRules)
 {
     bool hasFontFaceRule = false;
 
@@ -145,7 +145,7 @@
         return;
 
     // Find out which stylesheets are new.
-    Vector<StyleSheetContents*> addedSheets;
+    WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> > addedSheets;
     if (m_activeAuthorStyleSheets.size() <= newCollection.activeAuthorStyleSheets().size()) {
         change.styleResolverUpdateType = compareStyleSheets(m_activeAuthorStyleSheets, newCollection.activeAuthorStyleSheets(), addedSheets);
     } else {
@@ -204,7 +204,7 @@
     styleResolver->resetAuthorStyle(toContainerNode(&m_treeScope.rootNode()));
 }
 
-static bool styleSheetsUseRemUnits(const Vector<RefPtr<CSSStyleSheet> >& sheets)
+static bool styleSheetsUseRemUnits(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& sheets)
 {
     for (unsigned i = 0; i < sheets.size(); ++i) {
         if (sheets[i]->contents()->usesRemUnits())
diff --git a/Source/core/dom/TreeScopeStyleSheetCollection.h b/Source/core/dom/TreeScopeStyleSheetCollection.h
index 6d24219..f2141c3 100644
--- a/Source/core/dom/TreeScopeStyleSheetCollection.h
+++ b/Source/core/dom/TreeScopeStyleSheetCollection.h
@@ -76,10 +76,12 @@
         Additive
     };
 
-    struct StyleSheetChange {
+    class StyleSheetChange {
+        STACK_ALLOCATED();
+    public:
         StyleResolverUpdateType styleResolverUpdateType;
         bool requiresFullStyleRecalc;
-        Vector<const StyleRuleFontFace*> fontFaceRulesToRemove;
+        WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFontFace> > fontFaceRulesToRemove;
 
         StyleSheetChange()
             : styleResolverUpdateType(Reconstruct)
@@ -91,8 +93,8 @@
     void updateUsesRemUnits();
 
 private:
-    static StyleResolverUpdateType compareStyleSheets(const Vector<RefPtr<CSSStyleSheet> >& oldStyleSheets, const Vector<RefPtr<CSSStyleSheet> >& newStylesheets, Vector<StyleSheetContents*>& addedSheets);
-    bool activeLoadingStyleSheetLoaded(const Vector<RefPtr<CSSStyleSheet> >& newStyleSheets);
+    static StyleResolverUpdateType compareStyleSheets(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& oldStyleSheets, const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStylesheets, WillBeHeapVector<RawPtrWillBeMember<StyleSheetContents> >& addedSheets);
+    bool activeLoadingStyleSheetLoaded(const WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> >& newStyleSheets);
 
 protected:
     TreeScope& m_treeScope;
diff --git a/Source/core/dom/TreeWalker.cpp b/Source/core/dom/TreeWalker.cpp
index fa09981..0bd000f 100644
--- a/Source/core/dom/TreeWalker.cpp
+++ b/Source/core/dom/TreeWalker.cpp
@@ -25,6 +25,7 @@
 #include "config.h"
 #include "core/dom/TreeWalker.h"
 
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ScriptState.h"
 #include "core/dom/ContainerNode.h"
@@ -34,7 +35,7 @@
 namespace WebCore {
 
 TreeWalker::TreeWalker(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
-    : Traversal(rootNode, whatToShow, filter)
+    : NodeIteratorBase(rootNode, whatToShow, filter)
     , m_current(root())
 {
     ScriptWrappable::init(this);
@@ -43,7 +44,7 @@
 void TreeWalker::setCurrentNode(PassRefPtr<Node> node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(NotSupportedError, "The Node provided is invalid.");
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return;
     }
     m_current = node;
diff --git a/Source/core/dom/TreeWalker.h b/Source/core/dom/TreeWalker.h
index 354e449..e1a512f 100644
--- a/Source/core/dom/TreeWalker.h
+++ b/Source/core/dom/TreeWalker.h
@@ -27,7 +27,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/NodeFilter.h"
-#include "core/dom/Traversal.h"
+#include "core/dom/NodeIteratorBase.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
@@ -35,7 +35,7 @@
 
 class ExceptionState;
 
-class TreeWalker : public ScriptWrappable, public RefCounted<TreeWalker>, public Traversal {
+class TreeWalker : public ScriptWrappable, public RefCounted<TreeWalker>, public NodeIteratorBase {
 public:
     static PassRefPtr<TreeWalker> create(PassRefPtr<Node> rootNode, unsigned whatToShow, PassRefPtr<NodeFilter> filter)
     {
diff --git a/Source/core/dom/TreeWalker.idl b/Source/core/dom/TreeWalker.idl
index eecb1ed..efd5cfb 100644
--- a/Source/core/dom/TreeWalker.idl
+++ b/Source/core/dom/TreeWalker.idl
@@ -18,9 +18,9 @@
  * Boston, MA 02110-1301, USA.
  */
 
-// Introduced in DOM Level 2:
+// Introduced in DOM Level 2
 [
-    SetWrapperReferenceTo(NodeFilter filter)
+    SetWrapperReferenceTo(NodeFilter filter),
 ] interface TreeWalker {
     readonly attribute Node root;
     readonly attribute unsigned long whatToShow;
@@ -36,4 +36,3 @@
     [CallWith=ScriptState] Node previousNode();
     [CallWith=ScriptState] Node nextNode();
 };
-
diff --git a/Source/core/dom/URL.idl b/Source/core/dom/URL.idl
index 67dbb1e..f5bf93f 100644
--- a/Source/core/dom/URL.idl
+++ b/Source/core/dom/URL.idl
@@ -30,9 +30,10 @@
     Constructor(DOMString url),
     Constructor(DOMString url, URL base),
     Constructor(DOMString url, DOMString base),
-    ImplementedAs=DOMURL
+    ImplementedAs=DOMURL,
+    WillBeGarbageCollected
 ] interface URL {
-    [CallWith=ExecutionContext,TreatReturnedNullStringAs=Null] static DOMString createObjectURL(Blob? blob);
+    [RaisesException, CallWith=ExecutionContext,TreatReturnedNullStringAs=Null] static DOMString createObjectURL(Blob? blob);
     [CallWith=ExecutionContext] static void revokeObjectURL(DOMString url);
 };
 
diff --git a/Source/core/dom/VisitedLinkState.cpp b/Source/core/dom/VisitedLinkState.cpp
index d134243..1973511 100644
--- a/Source/core/dom/VisitedLinkState.cpp
+++ b/Source/core/dom/VisitedLinkState.cpp
@@ -49,7 +49,7 @@
 static inline LinkHash linkHashForElement(const Element& element, const AtomicString& attribute = AtomicString())
 {
     ASSERT(attribute.isNull() || linkAttribute(element) == attribute);
-    if (element.hasTagName(HTMLNames::aTag))
+    if (isHTMLAnchorElement(element))
         return toHTMLAnchorElement(element).visitedLinkHash();
     return visitedLinkHash(element.document().baseURL(), attribute.isNull() ? linkAttribute(element) : attribute);
 }
diff --git a/Source/core/dom/WheelController.cpp b/Source/core/dom/WheelController.cpp
index 68d5b18..b241ad5 100644
--- a/Source/core/dom/WheelController.cpp
+++ b/Source/core/dom/WheelController.cpp
@@ -29,14 +29,14 @@
 #include "core/dom/Document.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/events/WheelEvent.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
 
 namespace WebCore {
 
-WheelController::WheelController(Document* document)
-    : DOMWindowLifecycleObserver(document->domWindow())
+WheelController::WheelController(Document& document)
+    : DOMWindowLifecycleObserver(document.domWindow())
     , m_wheelEventHandlerCount(0)
 {
 }
@@ -50,7 +50,7 @@
     return "WheelController";
 }
 
-WheelController* WheelController::from(Document* document)
+WheelController* WheelController::from(Document& document)
 {
     WheelController* controller = static_cast<WheelController*>(DocumentSupplement::from(document, supplementName()));
     if (!controller) {
@@ -60,9 +60,9 @@
     return controller;
 }
 
-static void wheelEventHandlerCountChanged(Document* document)
+static void wheelEventHandlerCountChanged(Document& document)
 {
-    Page* page = document->page();
+    Page* page = document.page();
     if (!page)
         return;
 
@@ -70,30 +70,30 @@
     if (!scrollingCoordinator)
         return;
 
-    FrameView* frameView = document->view();
+    FrameView* frameView = document.view();
     if (!frameView)
         return;
 
     scrollingCoordinator->frameViewWheelEventHandlerCountChanged(frameView);
 }
 
-void WheelController::didAddWheelEventHandler(Document* document)
+void WheelController::didAddWheelEventHandler(Document& document)
 {
     ++m_wheelEventHandlerCount;
-    Page* page = document->page();
-    Frame* mainFrame = page ? page->mainFrame() : 0;
+    Page* page = document.page();
+    LocalFrame* mainFrame = page ? page->mainFrame() : 0;
     if (mainFrame)
         mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
 
     wheelEventHandlerCountChanged(document);
 }
 
-void WheelController::didRemoveWheelEventHandler(Document* document)
+void WheelController::didRemoveWheelEventHandler(Document& document)
 {
     ASSERT(m_wheelEventHandlerCount > 0);
     --m_wheelEventHandlerCount;
-    Page* page = document->page();
-    Frame* mainFrame = page ? page->mainFrame() : 0;
+    Page* page = document.page();
+    LocalFrame* mainFrame = page ? page->mainFrame() : 0;
     if (mainFrame)
         mainFrame->notifyChromeClientWheelEventHandlerCountChanged();
 
@@ -106,7 +106,8 @@
         return;
 
     Document* document = window->document();
-    didAddWheelEventHandler(document);
+    ASSERT(document);
+    didAddWheelEventHandler(*document);
 }
 
 void WheelController::didRemoveEventListener(DOMWindow* window, const AtomicString& eventType)
@@ -115,7 +116,8 @@
         return;
 
     Document* document = window->document();
-    didRemoveWheelEventHandler(document);
+    ASSERT(document);
+    didRemoveWheelEventHandler(*document);
 }
 
 } // namespace WebCore
diff --git a/Source/core/dom/WheelController.h b/Source/core/dom/WheelController.h
index 5f25f98..49879f4 100644
--- a/Source/core/dom/WheelController.h
+++ b/Source/core/dom/WheelController.h
@@ -41,19 +41,19 @@
     virtual ~WheelController();
 
     static const char* supplementName();
-    static WheelController* from(Document*);
+    static WheelController* from(Document&);
 
     unsigned wheelEventHandlerCount() { return m_wheelEventHandlerCount; }
 
-    void didAddWheelEventHandler(Document*);
-    void didRemoveWheelEventHandler(Document*);
+    void didAddWheelEventHandler(Document&);
+    void didRemoveWheelEventHandler(Document&);
 
     // Inherited from DOMWindowLifecycleObserver
     virtual void didAddEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
     virtual void didRemoveEventListener(DOMWindow*, const AtomicString&) OVERRIDE;
 
 private:
-    explicit WheelController(Document*);
+    explicit WheelController(Document&);
 
     unsigned m_wheelEventHandlerCount;
 };
diff --git a/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp b/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp
index a569ad2..5337da3 100644
--- a/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp
+++ b/Source/core/dom/custom/CustomElementMicrotaskDispatcher.cpp
@@ -10,7 +10,7 @@
 #include "core/dom/custom/CustomElementCallbackQueue.h"
 #include "core/dom/custom/CustomElementMicrotaskImportStep.h"
 #include "core/dom/custom/CustomElementScheduler.h"
-#include "core/html/HTMLImport.h"
+#include "core/html/imports/HTMLImport.h"
 #include "wtf/MainThread.h"
 
 namespace WebCore {
diff --git a/Source/core/dom/custom/CustomElementScheduler.cpp b/Source/core/dom/custom/CustomElementScheduler.cpp
index f0ba5cf..40f7235 100644
--- a/Source/core/dom/custom/CustomElementScheduler.cpp
+++ b/Source/core/dom/custom/CustomElementScheduler.cpp
@@ -40,7 +40,7 @@
 #include "core/dom/custom/CustomElementMicrotaskImportStep.h"
 #include "core/dom/custom/CustomElementMicrotaskResolutionStep.h"
 #include "core/dom/custom/CustomElementRegistrationContext.h"
-#include "core/html/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportChild.h"
 
 namespace WebCore {
 
diff --git a/Source/core/dom/shadow/ComposedTreeWalker.cpp b/Source/core/dom/shadow/ComposedTreeWalker.cpp
index 3ffc70c..55390f6 100644
--- a/Source/core/dom/shadow/ComposedTreeWalker.cpp
+++ b/Source/core/dom/shadow/ComposedTreeWalker.cpp
@@ -30,7 +30,7 @@
 
 #include "core/dom/Element.h"
 #include "core/dom/shadow/ElementShadow.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLShadowElement.h"
 
 namespace WebCore {
 
@@ -72,7 +72,7 @@
     const InsertionPoint* insertionPoint = toInsertionPoint(node);
     if (Node* found = traverseDistributedNodes(direction == TraversalDirectionForward ? insertionPoint->first() : insertionPoint->last(), insertionPoint, direction))
         return found;
-    ASSERT(node->hasTagName(HTMLNames::shadowTag) || (node->hasTagName(HTMLNames::contentTag) && !node->hasChildNodes()));
+    ASSERT(isHTMLShadowElement(node) || (isHTMLContentElement(node) && !node->hasChildren()));
     return 0;
 }
 
diff --git a/Source/core/dom/shadow/ElementShadow.cpp b/Source/core/dom/shadow/ElementShadow.cpp
index 17ee8ba..8c94e95 100644
--- a/Source/core/dom/shadow/ElementShadow.cpp
+++ b/Source/core/dom/shadow/ElementShadow.cpp
@@ -33,8 +33,8 @@
 #include "core/dom/ElementTraversal.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/shadow/ContentDistribution.h"
-#include "core/html/shadow/HTMLContentElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLContentElement.h"
+#include "core/html/HTMLShadowElement.h"
 
 namespace WebCore {
 
@@ -88,7 +88,7 @@
         if (m_distributed[i])
             continue;
 
-        if (insertionPoint->hasTagName(HTMLNames::contentTag) && !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i))
+        if (isHTMLContentElement(*insertionPoint) && !toHTMLContentElement(insertionPoint)->canSelectNode(m_nodes, i))
             continue;
 
         Node* node = m_nodes[i];
@@ -302,7 +302,7 @@
             InsertionPoint* point = insertionPoints[i].get();
             if (!point->isActive())
                 continue;
-            if (point->hasTagName(HTMLNames::shadowTag)) {
+            if (isHTMLShadowElement(*point)) {
                 ASSERT(!shadowInsertionPoint);
                 shadowInsertionPoint = toHTMLShadowElement(point);
                 shadowInsertionPoints.append(shadowInsertionPoint);
@@ -358,9 +358,9 @@
     for (Element* element = ElementTraversal::firstWithin(root); element; element = ElementTraversal::next(*element, &root)) {
         if (ElementShadow* shadow = element->shadow())
             m_selectFeatures.add(shadow->ensureSelectFeatureSet());
-        if (!element->hasTagName(HTMLNames::contentTag))
+        if (!isHTMLContentElement(*element))
             continue;
-        const CSSSelectorList& list = toHTMLContentElement(element)->selectorList();
+        const CSSSelectorList& list = toHTMLContentElement(*element).selectorList();
         for (const CSSSelector* selector = list.first(); selector; selector = CSSSelectorList::next(*selector)) {
             for (const CSSSelector* component = selector; component; component = component->tagHistory())
                 m_selectFeatures.collectFeaturesFromSelector(*component);
@@ -389,7 +389,7 @@
     m_nodeToInsertionPoints.clear();
 
     for (ShadowRoot* root = youngestShadowRoot(); root; root = root->olderShadowRoot())
-        root->setShadowInsertionPointOfYoungerShadowRoot(0);
+        root->setShadowInsertionPointOfYoungerShadowRoot(nullptr);
 }
 
 } // namespace
diff --git a/Source/core/dom/shadow/InsertionPoint.cpp b/Source/core/dom/shadow/InsertionPoint.cpp
index 4099b88..690cb8e 100644
--- a/Source/core/dom/shadow/InsertionPoint.cpp
+++ b/Source/core/dom/shadow/InsertionPoint.cpp
@@ -148,14 +148,14 @@
     ShadowRoot* shadowRoot = containingShadowRoot();
     if (!shadowRoot)
         return false;
-    if (!hasTagName(shadowTag) || shadowRoot->descendantShadowElementCount() <= 1)
+    if (!isHTMLShadowElement(*this) || shadowRoot->descendantShadowElementCount() <= 1)
         return true;
 
     // Slow path only when there are more than one shadow elements in a shadow tree. That should be a rare case.
     const Vector<RefPtr<InsertionPoint> >& insertionPoints = shadowRoot->descendantInsertionPoints();
     for (size_t i = 0; i < insertionPoints.size(); ++i) {
         InsertionPoint* point = insertionPoints[i].get();
-        if (point->hasTagName(shadowTag))
+        if (isHTMLShadowElement(*point))
             return point == this;
     }
     return true;
@@ -163,12 +163,12 @@
 
 bool InsertionPoint::isShadowInsertionPoint() const
 {
-    return hasTagName(shadowTag) && isActive();
+    return isHTMLShadowElement(*this) && isActive();
 }
 
 bool InsertionPoint::isContentInsertionPoint() const
 {
-    return hasTagName(contentTag) && isActive();
+    return isHTMLContentElement(*this) && isActive();
 }
 
 PassRefPtr<NodeList> InsertionPoint::getDistributedNodes()
diff --git a/Source/core/dom/shadow/InsertionPoint.h b/Source/core/dom/shadow/InsertionPoint.h
index 05f2ac9..75cc3c5 100644
--- a/Source/core/dom/shadow/InsertionPoint.h
+++ b/Source/core/dom/shadow/InsertionPoint.h
@@ -87,7 +87,7 @@
 
 typedef Vector<RefPtr<InsertionPoint> > DestinationInsertionPoints;
 
-DEFINE_NODE_TYPE_CASTS(InsertionPoint, isInsertionPoint());
+DEFINE_ELEMENT_TYPE_CASTS(InsertionPoint, isInsertionPoint());
 
 inline bool isActiveInsertionPoint(const Node& node)
 {
diff --git a/Source/core/dom/shadow/ShadowRoot.cpp b/Source/core/dom/shadow/ShadowRoot.cpp
index 80be155..c781db0 100644
--- a/Source/core/dom/shadow/ShadowRoot.cpp
+++ b/Source/core/dom/shadow/ShadowRoot.cpp
@@ -31,13 +31,14 @@
 #include "core/css/StyleSheetList.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/ElementTraversal.h"
+#include "core/dom/SiblingRuleHelper.h"
 #include "core/dom/StyleEngine.h"
 #include "core/dom/Text.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/InsertionPoint.h"
 #include "core/dom/shadow/ShadowRootRareData.h"
 #include "core/editing/markup.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLShadowElement.h"
 #include "public/platform/Platform.h"
 
 namespace WebCore {
@@ -49,12 +50,6 @@
 
 COMPILE_ASSERT(sizeof(ShadowRoot) == sizeof(SameSizeAsShadowRoot), shadowroot_should_stay_small);
 
-enum ShadowRootUsageOriginType {
-    ShadowRootUsageOriginWeb = 0,
-    ShadowRootUsageOriginNotWeb,
-    ShadowRootUsageOriginMax
-};
-
 ShadowRoot::ShadowRoot(Document& document, ShadowRootType type)
     : DocumentFragment(0, CreateShadowRoot)
     , TreeScope(*this, document)
@@ -68,11 +63,6 @@
     , m_descendantInsertionPointsIsValid(false)
 {
     ScriptWrappable::init(this);
-
-    if (type == ShadowRoot::AuthorShadowRoot) {
-        ShadowRootUsageOriginType usageType = document.url().protocolIsInHTTPFamily() ? ShadowRootUsageOriginWeb : ShadowRootUsageOriginNotWeb;
-        blink::Platform::current()->histogramEnumeration("WebCore.ShadowRoot.constructor", usageType, ShadowRootUsageOriginMax);
-    }
 }
 
 ShadowRoot::~ShadowRoot()
@@ -128,7 +118,7 @@
 PassRefPtr<Node> ShadowRoot::cloneNode(bool, ExceptionState& exceptionState)
 {
     exceptionState.throwDOMException(DataCloneError, "ShadowRoot nodes are not clonable.");
-    return 0;
+    return nullptr;
 }
 
 String ShadowRoot::innerHTML() const
@@ -163,6 +153,9 @@
     if (styleChangeType() >= SubtreeStyleChange)
         change = Force;
 
+    if (change < Force && childNeedsStyleRecalc())
+        SiblingRuleHelper(this).checkForChildrenAdjacentRuleChanges();
+
     // There's no style to update so just calling recalcStyle means we're updated.
     clearNeedsStyleRecalc();
 
@@ -411,4 +404,70 @@
     return m_shadowRootRareData->styleSheets();
 }
 
+bool ShadowRoot::childrenSupportStyleSharing() const
+{
+    if (!m_shadowRootRareData)
+        return false;
+    return !m_shadowRootRareData->childrenAffectedByFirstChildRules()
+        && !m_shadowRootRareData->childrenAffectedByLastChildRules()
+        && !m_shadowRootRareData->childrenAffectedByDirectAdjacentRules()
+        && !m_shadowRootRareData->childrenAffectedByForwardPositionalRules()
+        && !m_shadowRootRareData->childrenAffectedByBackwardPositionalRules();
+}
+
+bool ShadowRoot::childrenAffectedByPositionalRules() const
+{
+    return m_shadowRootRareData && (m_shadowRootRareData->childrenAffectedByForwardPositionalRules() || m_shadowRootRareData->childrenAffectedByBackwardPositionalRules());
+}
+
+bool ShadowRoot::childrenAffectedByFirstChildRules() const
+{
+    return m_shadowRootRareData && m_shadowRootRareData->childrenAffectedByFirstChildRules();
+}
+
+bool ShadowRoot::childrenAffectedByLastChildRules() const
+{
+    return m_shadowRootRareData && m_shadowRootRareData->childrenAffectedByLastChildRules();
+}
+
+bool ShadowRoot::childrenAffectedByDirectAdjacentRules() const
+{
+    return m_shadowRootRareData && m_shadowRootRareData->childrenAffectedByDirectAdjacentRules();
+}
+
+bool ShadowRoot::childrenAffectedByForwardPositionalRules() const
+{
+    return m_shadowRootRareData && m_shadowRootRareData->childrenAffectedByForwardPositionalRules();
+}
+
+bool ShadowRoot::childrenAffectedByBackwardPositionalRules() const
+{
+    return m_shadowRootRareData && m_shadowRootRareData->childrenAffectedByBackwardPositionalRules();
+}
+
+void ShadowRoot::setChildrenAffectedByForwardPositionalRules()
+{
+    ensureShadowRootRareData()->setChildrenAffectedByForwardPositionalRules(true);
+}
+
+void ShadowRoot::setChildrenAffectedByDirectAdjacentRules()
+{
+    ensureShadowRootRareData()->setChildrenAffectedByDirectAdjacentRules(true);
+}
+
+void ShadowRoot::setChildrenAffectedByBackwardPositionalRules()
+{
+    ensureShadowRootRareData()->setChildrenAffectedByBackwardPositionalRules(true);
+}
+
+void ShadowRoot::setChildrenAffectedByFirstChildRules()
+{
+    ensureShadowRootRareData()->setChildrenAffectedByFirstChildRules(true);
+}
+
+void ShadowRoot::setChildrenAffectedByLastChildRules()
+{
+    ensureShadowRootRareData()->setChildrenAffectedByLastChildRules(true);
+}
+
 }
diff --git a/Source/core/dom/shadow/ShadowRoot.h b/Source/core/dom/shadow/ShadowRoot.h
index 98ca4ce..43091ff 100644
--- a/Source/core/dom/shadow/ShadowRoot.h
+++ b/Source/core/dom/shadow/ShadowRoot.h
@@ -127,6 +127,22 @@
     StyleSheetList* styleSheets();
     bool isActiveForStyling() const;
 
+    bool childrenSupportStyleSharing() const;
+    bool childrenAffectedByPositionalRules() const;
+    bool childrenAffectedByFirstChildRules() const;
+    bool childrenAffectedByLastChildRules() const;
+    bool childrenAffectedByDirectAdjacentRules() const;
+    bool childrenAffectedByForwardPositionalRules() const;
+    bool childrenAffectedByBackwardPositionalRules() const;
+
+    void setChildrenAffectedByFirstChildRules();
+    void setChildrenAffectedByLastChildRules();
+    void setChildrenAffectedByDirectAdjacentRules();
+    void setChildrenAffectedByForwardPositionalRules();
+    void setChildrenAffectedByBackwardPositionalRules();
+
+    using Node::isFinishedParsingChildren; // make public for SelectorChecker
+
 private:
     ShadowRoot(Document&, ShadowRootType);
     virtual ~ShadowRoot();
@@ -141,7 +157,7 @@
     void invalidateDescendantInsertionPoints();
 
     // ShadowRoots should never be cloned.
-    virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return 0; }
+    virtual PassRefPtr<Node> cloneNode(bool) OVERRIDE { return nullptr; }
 
     // FIXME: This shouldn't happen. https://bugs.webkit.org/show_bug.cgi?id=88834
     bool isOrphan() const { return !host(); }
diff --git a/Source/core/dom/shadow/ShadowRootRareData.h b/Source/core/dom/shadow/ShadowRootRareData.h
index 7ad8ef6..051579a 100644
--- a/Source/core/dom/shadow/ShadowRootRareData.h
+++ b/Source/core/dom/shadow/ShadowRootRareData.h
@@ -43,6 +43,11 @@
         : m_descendantShadowElementCount(0)
         , m_descendantContentElementCount(0)
         , m_childShadowRootCount(0)
+        , m_childrenAffectedByDirectAdjacentRules(false)
+        , m_childrenAffectedByForwardPositionalRules(false)
+        , m_childrenAffectedByBackwardPositionalRules(false)
+        , m_childrenAffectedByFirstChildRules(false)
+        , m_childrenAffectedByLastChildRules(false)
     {
     }
 
@@ -68,7 +73,21 @@
     void clearDescendantInsertionPoints() { m_descendantInsertionPoints.clear(); }
 
     StyleSheetList* styleSheets() { return m_styleSheetList.get(); }
-    void setStyleSheets(PassRefPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
+    void setStyleSheets(PassRefPtrWillBeRawPtr<StyleSheetList> styleSheetList) { m_styleSheetList = styleSheetList; }
+
+    bool childrenAffectedByDirectAdjacentRules() const { return m_childrenAffectedByDirectAdjacentRules; }
+    void setChildrenAffectedByDirectAdjacentRules(bool value) { m_childrenAffectedByDirectAdjacentRules = value; }
+    bool childrenAffectedByForwardPositionalRules() const { return m_childrenAffectedByForwardPositionalRules; }
+    void setChildrenAffectedByForwardPositionalRules(bool value) { m_childrenAffectedByForwardPositionalRules = value; }
+
+    bool childrenAffectedByBackwardPositionalRules() const { return m_childrenAffectedByBackwardPositionalRules; }
+    void setChildrenAffectedByBackwardPositionalRules(bool value) { m_childrenAffectedByBackwardPositionalRules = value; }
+
+    bool childrenAffectedByFirstChildRules() const { return m_childrenAffectedByFirstChildRules; }
+    void setChildrenAffectedByFirstChildRules(bool value) { m_childrenAffectedByFirstChildRules = value; }
+
+    bool childrenAffectedByLastChildRules() const { return m_childrenAffectedByLastChildRules; }
+    void setChildrenAffectedByLastChildRules(bool value) { m_childrenAffectedByLastChildRules = value; }
 
 private:
     RefPtr<HTMLShadowElement> m_shadowInsertionPointOfYoungerShadowRoot;
@@ -76,14 +95,21 @@
     unsigned m_descendantContentElementCount;
     unsigned m_childShadowRootCount;
     Vector<RefPtr<InsertionPoint> > m_descendantInsertionPoints;
-    RefPtr<StyleSheetList> m_styleSheetList;
+    RefPtrWillBePersistent<StyleSheetList> m_styleSheetList;
+
+    unsigned m_childrenAffectedByDirectAdjacentRules : 1;
+    unsigned m_childrenAffectedByForwardPositionalRules : 1;
+    unsigned m_childrenAffectedByBackwardPositionalRules : 1;
+    unsigned m_childrenAffectedByFirstChildRules : 1;
+    unsigned m_childrenAffectedByLastChildRules : 1;
 };
 
 inline void ShadowRootRareData::didAddInsertionPoint(InsertionPoint* point)
 {
-    if (point->hasTagName(HTMLNames::shadowTag))
+    ASSERT(point);
+    if (isHTMLShadowElement(*point))
         ++m_descendantShadowElementCount;
-    else if (point->hasTagName(HTMLNames::contentTag))
+    else if (isHTMLContentElement(*point))
         ++m_descendantContentElementCount;
     else
         ASSERT_NOT_REACHED();
@@ -91,9 +117,10 @@
 
 inline void ShadowRootRareData::didRemoveInsertionPoint(InsertionPoint* point)
 {
-    if (point->hasTagName(HTMLNames::shadowTag))
+    ASSERT(point);
+    if (isHTMLShadowElement(*point))
         --m_descendantShadowElementCount;
-    else if (point->hasTagName(HTMLNames::contentTag))
+    else if (isHTMLContentElement(*point))
         --m_descendantContentElementCount;
     else
         ASSERT_NOT_REACHED();
diff --git a/Source/core/editing/ApplyBlockElementCommand.cpp b/Source/core/editing/ApplyBlockElementCommand.cpp
index 7049dac..8de6c16 100644
--- a/Source/core/editing/ApplyBlockElementCommand.cpp
+++ b/Source/core/editing/ApplyBlockElementCommand.cpp
@@ -128,7 +128,7 @@
             atEnd = true;
 
         rangeForParagraphSplittingTextNodesIfNeeded(endOfCurrentParagraph, start, end);
-        endOfCurrentParagraph = end;
+        endOfCurrentParagraph = VisiblePosition(end);
 
         Node* enclosingCell = enclosingNodeOfType(start, &isTableCell);
         VisiblePosition endOfNextParagraph = endOfNextParagrahSplittingTextNodesIfNeeded(endOfCurrentParagraph, start, end);
@@ -138,7 +138,7 @@
         // Don't put the next paragraph in the blockquote we just created for this paragraph unless
         // the next paragraph is in the same cell.
         if (enclosingCell && enclosingCell != enclosingNodeOfType(endOfNextParagraph.deepEquivalent(), &isTableCell))
-            blockquoteForNextIndent = 0;
+            blockquoteForNextIndent = nullptr;
 
         // indentIntoBlockquote could move more than one paragraph if the paragraph
         // is in a list item or a table. As a result, endAfterSelection could refer to a position
@@ -189,7 +189,7 @@
 
         // Avoid obtanining the start of next paragraph for start
         if (startStyle->preserveNewline() && isNewLineAtPosition(start) && !isNewLineAtPosition(start.previous()) && start.offsetInContainerNode() > 0)
-            start = startOfParagraph(end.previous()).deepEquivalent();
+            start = startOfParagraph(VisiblePosition(end.previous())).deepEquivalent();
 
         // If start is in the middle of a text node, split.
         if (!startStyle->collapseWhiteSpace() && start.offsetInContainerNode() > 0) {
@@ -273,7 +273,7 @@
             m_endOfLastParagraph = Position(text.get(), m_endOfLastParagraph.offsetInContainerNode() - 1);
     }
 
-    return Position(text.get(), position.offsetInContainerNode() - 1);
+    return VisiblePosition(Position(text.get(), position.offsetInContainerNode() - 1));
 }
 
 PassRefPtr<Element> ApplyBlockElementCommand::createBlockElement() const
diff --git a/Source/core/editing/ApplyStyleCommand.cpp b/Source/core/editing/ApplyStyleCommand.cpp
index bda5ae2..4d70f21 100644
--- a/Source/core/editing/ApplyStyleCommand.cpp
+++ b/Source/core/editing/ApplyStyleCommand.cpp
@@ -85,21 +85,21 @@
 
 bool isStyleSpanOrSpanWithOnlyStyleAttribute(const Element* element)
 {
-    if (!element || !element->hasTagName(spanTag))
+    if (!isHTMLSpanElement(element))
         return false;
     return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), AllowNonEmptyStyleAttribute);
 }
 
 static inline bool isSpanWithoutAttributesOrUnstyledStyleSpan(const Node* node)
 {
-    if (!node || !node->isHTMLElement() || !node->hasTagName(spanTag))
+    if (!isHTMLSpanElement(node))
         return false;
     return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(node), StyleAttributeShouldBeEmpty);
 }
 
 bool isEmptyFontTag(const Element* element, ShouldStyleAttributeBeEmpty shouldStyleAttributeBeEmpty)
 {
-    if (!element || !element->hasTagName(fontTag))
+    if (!isHTMLFontElement(element))
         return false;
 
     return hasNoAttributeOrOnlyStyleAttribute(toHTMLElement(element), shouldStyleAttributeBeEmpty);
@@ -125,7 +125,7 @@
     , m_start(endingSelection().start().downstream())
     , m_end(endingSelection().end().upstream())
     , m_useEndingSelection(true)
-    , m_styledInlineElement(0)
+    , m_styledInlineElement(nullptr)
     , m_removeOnly(false)
     , m_isInlineElementToRemoveFunction(0)
 {
@@ -139,7 +139,7 @@
     , m_start(start)
     , m_end(end)
     , m_useEndingSelection(false)
-    , m_styledInlineElement(0)
+    , m_styledInlineElement(nullptr)
     , m_removeOnly(false)
     , m_isInlineElementToRemoveFunction(0)
 {
@@ -167,7 +167,7 @@
     , m_start(endingSelection().start().downstream())
     , m_end(endingSelection().end().upstream())
     , m_useEndingSelection(true)
-    , m_styledInlineElement(0)
+    , m_styledInlineElement(nullptr)
     , m_removeOnly(true)
     , m_isInlineElementToRemoveFunction(isInlineElementToRemoveFunction)
 {
@@ -253,9 +253,9 @@
     // Save and restore the selection endpoints using their indices in the document, since
     // addBlockStyleIfNeeded may moveParagraphs, which can remove these endpoints.
     // Calculate start and end indices from the start of the tree that they're in.
-    Node* scope = visibleStart.deepEquivalent().deprecatedNode()->highestAncestor();
-    RefPtr<Range> startRange = Range::create(document(), firstPositionInNode(scope), visibleStart.deepEquivalent().parentAnchoredEquivalent());
-    RefPtr<Range> endRange = Range::create(document(), firstPositionInNode(scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
+    Node& scope = visibleStart.deepEquivalent().deprecatedNode()->highestAncestor();
+    RefPtr<Range> startRange = Range::create(document(), firstPositionInNode(&scope), visibleStart.deepEquivalent().parentAnchoredEquivalent());
+    RefPtr<Range> endRange = Range::create(document(), firstPositionInNode(&scope), visibleEnd.deepEquivalent().parentAnchoredEquivalent());
     int startIndex = TextIterator::rangeLength(startRange.get(), true);
     int endIndex = TextIterator::rangeLength(endRange.get(), true);
 
@@ -286,8 +286,8 @@
         nextParagraphStart = endOfParagraph(paragraphStart).next();
     }
 
-    startRange = PlainTextRange(startIndex).createRangeForSelection(*toContainerNode(scope));
-    endRange = PlainTextRange(endIndex).createRangeForSelection(*toContainerNode(scope));
+    startRange = PlainTextRange(startIndex).createRangeForSelection(toContainerNode(scope));
+    endRange = PlainTextRange(endIndex).createRangeForSelection(toContainerNode(scope));
     if (startRange && endRange)
         updateStartEnd(startRange->startPosition(), endRange->startPosition());
 }
@@ -349,7 +349,9 @@
     // Calculate loop end point.
     // If the end node is before the start node (can only happen if the end node is
     // an ancestor of the start node), we gather nodes up to the next sibling of the end node
-    Node *beyondEnd;
+    Node* beyondEnd;
+    ASSERT(start.deprecatedNode());
+    ASSERT(end.deprecatedNode());
     if (start.deprecatedNode()->isDescendantOf(end.deprecatedNode()))
         beyondEnd = NodeTraversal::nextSkippingChildren(*end.deprecatedNode());
     else
@@ -358,20 +360,29 @@
     start = start.upstream(); // Move upstream to ensure we do not add redundant spans.
     Node* startNode = start.deprecatedNode();
     ASSERT(startNode);
+
+    // Make sure we're not already at the end or the next NodeTraversal::next() will traverse
+    // past it.
+    if (startNode == beyondEnd)
+        return;
+
     if (startNode->isTextNode() && start.deprecatedEditingOffset() >= caretMaxOffset(startNode)) // Move out of text node if range does not include its characters.
         startNode = NodeTraversal::next(*startNode);
 
     // Store away font size before making any changes to the document.
     // This ensures that changes to one node won't effect another.
     HashMap<Node*, float> startingFontSizes;
-    for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(*node))
+    for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(*node)) {
+        ASSERT(node);
         startingFontSizes.set(node, computedFontSize(node));
+    }
 
     // These spans were added by us. If empty after font size changes, they can be removed.
     Vector<RefPtr<HTMLElement> > unstyledSpans;
 
     Node* lastStyledNode = 0;
     for (Node* node = startNode; node != beyondEnd; node = NodeTraversal::next(*node)) {
+        ASSERT(node);
         RefPtr<HTMLElement> element;
         if (node->isHTMLElement()) {
             // Only work on fully selected nodes.
@@ -393,7 +404,7 @@
         RefPtr<MutableStylePropertySet> inlineStyle = copyStyleOrCreateEmpty(element->inlineStyle());
         float currentFontSize = computedFontSize(node);
         float desiredFontSize = max(MinimumFontSize, startingFontSizes.get(node) + style->fontSizeDelta());
-        RefPtr<CSSValue> value = inlineStyle->getPropertyCSSValue(CSSPropertyFontSize);
+        RefPtrWillBeRawPtr<CSSValue> value = inlineStyle->getPropertyCSSValue(CSSPropertyFontSize);
         if (value) {
             element->removeInlineStyleProperty(CSSPropertyFontSize);
             currentFontSize = computedFontSize(node);
@@ -536,8 +547,8 @@
 
 void ApplyStyleCommand::applyInlineStyle(EditingStyle* style)
 {
-    RefPtr<Node> startDummySpanAncestor = 0;
-    RefPtr<Node> endDummySpanAncestor = 0;
+    RefPtr<Node> startDummySpanAncestor = nullptr;
+    RefPtr<Node> endDummySpanAncestor = nullptr;
 
     // update document layout once before removing styles
     // so that we avoid the expense of updating before each and every call
@@ -601,11 +612,11 @@
         // Avoid removing the dir attribute and the unicode-bidi and direction properties from the unsplit ancestors.
         Position embeddingRemoveStart = removeStart;
         if (startUnsplitAncestor && nodeFullySelected(startUnsplitAncestor, removeStart, end))
-            embeddingRemoveStart = positionInParentAfterNode(startUnsplitAncestor);
+            embeddingRemoveStart = positionInParentAfterNode(*startUnsplitAncestor);
 
         Position embeddingRemoveEnd = end;
         if (endUnsplitAncestor && nodeFullySelected(endUnsplitAncestor, removeStart, end))
-            embeddingRemoveEnd = positionInParentBeforeNode(endUnsplitAncestor).downstream();
+            embeddingRemoveEnd = positionInParentBeforeNode(*endUnsplitAncestor).downstream();
 
         if (embeddingRemoveEnd != removeStart || embeddingRemoveEnd != end) {
             styleWithoutEmbedding = style->copy();
@@ -645,8 +656,8 @@
         Node* embeddingEndNode = highestEmbeddingAncestor(end.deprecatedNode(), enclosingBlock(end.deprecatedNode()));
 
         if (embeddingStartNode || embeddingEndNode) {
-            Position embeddingApplyStart = embeddingStartNode ? positionInParentAfterNode(embeddingStartNode) : start;
-            Position embeddingApplyEnd = embeddingEndNode ? positionInParentBeforeNode(embeddingEndNode) : end;
+            Position embeddingApplyStart = embeddingStartNode ? positionInParentAfterNode(*embeddingStartNode) : start;
+            Position embeddingApplyEnd = embeddingEndNode ? positionInParentBeforeNode(*embeddingEndNode) : end;
             ASSERT(embeddingApplyStart.isNotNull() && embeddingApplyEnd.isNotNull());
 
             if (!embeddingStyle) {
@@ -684,7 +695,7 @@
 
     // FIXME: Callers should perform this operation on a Range that includes the br
     // if they want style applied to the empty line.
-    if (start == end && start.deprecatedNode()->hasTagName(brTag))
+    if (start == end && isHTMLBRElement(*start.deprecatedNode()))
         pastEndNode = NodeTraversal::next(*start.deprecatedNode());
 
     // Start from the highest fully selected ancestor so that we can modify the fully selected node.
@@ -693,7 +704,7 @@
     RefPtr<Range> range = Range::create(startNode->document(), start, end);
     Element* editableRoot = startNode->rootEditableElement();
     if (startNode != editableRoot) {
-        while (editableRoot && startNode->parentNode() != editableRoot && isNodeVisiblyContainedWithin(startNode->parentNode(), range.get()))
+        while (editableRoot && startNode->parentNode() != editableRoot && isNodeVisiblyContainedWithin(*startNode->parentNode(), *range))
             startNode = startNode->parentNode();
     }
 
@@ -771,7 +782,7 @@
         if (isBlock(node.get()))
             continue;
 
-        if (node->childNodeCount()) {
+        if (node->hasChildren()) {
             if (node->contains(pastEndNode.get()) || containsNonEditableRegion(*node) || !node->parentNode()->rendererIsEditable())
                 continue;
             if (editingIgnoresContent(node.get())) {
@@ -784,7 +795,7 @@
         Node* runEnd = node.get();
         Node* sibling = node->nextSibling();
         while (sibling && sibling != pastEndNode && !sibling->contains(pastEndNode.get())
-            && (!isBlock(sibling) || sibling->hasTagName(brTag))
+            && (!isBlock(sibling) || isHTMLBRElement(*sibling))
             && !containsNonEditableRegion(*sibling)) {
             runEnd = sibling;
             sibling = runEnd->nextSibling();
@@ -801,13 +812,16 @@
 
     for (size_t i = 0; i < runs.size(); i++) {
         removeConflictingInlineStyleFromRun(style, runs[i].start, runs[i].end, runs[i].pastEndNode);
-        runs[i].positionForStyleComputation = positionToComputeInlineStyleChange(runs[i].start, runs[i].dummyElement);
+        if (runs[i].startAndEndAreStillInDocument())
+            runs[i].positionForStyleComputation = positionToComputeInlineStyleChange(runs[i].start, runs[i].dummyElement);
     }
 
     document().updateLayoutIgnorePendingStylesheets();
 
-    for (size_t i = 0; i < runs.size(); i++)
-        runs[i].change = StyleChange(style, runs[i].positionForStyleComputation);
+    for (size_t i = 0; i < runs.size(); i++) {
+        if (runs[i].positionForStyleComputation.isNotNull())
+            runs[i].change = StyleChange(style, runs[i].positionForStyleComputation);
+    }
 
     for (size_t i = 0; i < runs.size(); i++) {
         InlineRunToApplyStyle& run = runs[i];
@@ -829,7 +843,7 @@
     ASSERT(style && runStart);
 
     for (Node* node = runStart; node && node != pastEndNode; node = NodeTraversal::next(*node)) {
-        if (node->childNodeCount())
+        if (node->hasChildren())
             continue;
         // We don't consider m_isInlineElementToRemoveFunction here because we never apply style when m_isInlineElementToRemoveFunction is specified
         if (!style->styleIsPresentInComputedStyleOfNode(node))
@@ -984,7 +998,7 @@
 
     node->document().updateStyleIfNeeded();
 
-    if (!style || style->isEmpty() || !node->renderer())
+    if (!style || style->isEmpty() || !node->renderer() || isHTMLIFrameElement(*node))
         return;
 
     RefPtr<EditingStyle> newInlineStyle = style;
@@ -995,7 +1009,7 @@
 
     // Since addInlineStyleIfNeeded can't add styles to block-flow render objects, add style attribute instead.
     // FIXME: applyInlineStyleToRange should be used here instead.
-    if ((node->renderer()->isRenderBlockFlow() || node->childNodeCount()) && node->isHTMLElement()) {
+    if ((node->renderer()->isRenderBlockFlow() || node->hasChildren()) && node->isHTMLElement()) {
         setNodeAttribute(toHTMLElement(node), styleAttr, AtomicString(newInlineStyle->style()->asText()));
         return;
     }
@@ -1290,7 +1304,7 @@
         endNode = end.deprecatedNode()->parentNode();
     }
 
-    if (!endNode->isElementNode() || endNode->hasTagName(brTag))
+    if (!endNode->isElementNode() || isHTMLBRElement(*endNode))
         return false;
 
     Node* nextSibling = endNode->nextSibling();
@@ -1406,11 +1420,14 @@
     HTMLElement* fontContainer = 0;
     HTMLElement* styleContainer = 0;
     for (Node* container = startNode.get(); container && startNode == endNode; container = container->firstChild()) {
-        if (container->isHTMLElement() && container->hasTagName(fontTag))
+        if (isHTMLFontElement(*container))
             fontContainer = toHTMLElement(container);
-        bool styleContainerIsNotSpan = !styleContainer || !styleContainer->hasTagName(spanTag);
-        if (container->isHTMLElement() && (container->hasTagName(spanTag) || (styleContainerIsNotSpan && container->childNodeCount())))
-            styleContainer = toHTMLElement(container);
+        bool styleContainerIsNotSpan = !isHTMLSpanElement(styleContainer);
+        if (container->isHTMLElement()) {
+            HTMLElement* containerElement = toHTMLElement(container);
+            if (isHTMLSpanElement(*containerElement) || (styleContainerIsNotSpan && containerElement->hasChildren()))
+                styleContainer = toHTMLElement(container);
+        }
         if (!container->firstChild())
             break;
         startNode = container->firstChild();
@@ -1488,8 +1505,7 @@
     if (!style)
         return 0;
 
-    // FIXME: oilpan: Change to RefPtrWillBeRawPtr when changing CSSValue.
-    RefPtr<CSSPrimitiveValue> value = static_pointer_cast<CSSPrimitiveValue>(style->getPropertyCSSValue(CSSPropertyFontSize));
+    RefPtrWillBeRawPtr<CSSPrimitiveValue> value = static_pointer_cast<CSSPrimitiveValue>(style->getPropertyCSSValue(CSSPropertyFontSize));
     if (!value)
         return 0;
 
diff --git a/Source/core/editing/BreakBlockquoteCommand.cpp b/Source/core/editing/BreakBlockquoteCommand.cpp
index 73f09d9..02b2eb1 100644
--- a/Source/core/editing/BreakBlockquoteCommand.cpp
+++ b/Source/core/editing/BreakBlockquoteCommand.cpp
@@ -116,7 +116,7 @@
         } else if (pos.deprecatedEditingOffset() > 0)
             splitTextNode(textNode, pos.deprecatedEditingOffset());
     } else if (pos.deprecatedEditingOffset() > 0) {
-        Node* childAtOffset = startNode->childNode(pos.deprecatedEditingOffset());
+        Node* childAtOffset = startNode->traverseToChildAt(pos.deprecatedEditingOffset());
         startNode = childAtOffset ? childAtOffset : NodeTraversal::next(*startNode);
         ASSERT(startNode);
     }
@@ -144,11 +144,11 @@
     for (size_t i = ancestors.size(); i != 0; --i) {
         RefPtr<Element> clonedChild = ancestors[i - 1]->cloneElementWithoutChildren();
         // Preserve list item numbering in cloned lists.
-        if (clonedChild->isElementNode() && clonedChild->hasTagName(olTag)) {
+        if (isHTMLOListElement(*clonedChild)) {
             Node* listChildNode = i > 1 ? ancestors[i - 2].get() : startNode;
             // The first child of the cloned list might not be a list item element,
             // find the first one so that we know where to start numbering.
-            while (listChildNode && !listChildNode->hasTagName(liTag))
+            while (listChildNode && !isHTMLLIElement(*listChildNode))
                 listChildNode = listChildNode->nextSibling();
             if (listChildNode && listChildNode->renderer() && listChildNode->renderer()->isListItem())
                 setNodeAttribute(clonedChild, startAttr, AtomicString::number(toRenderListItem(listChildNode->renderer())->value()));
@@ -174,7 +174,7 @@
 
         // If the startNode's original parent is now empty, remove it
         Node* originalParent = ancestors.first().get();
-        if (!originalParent->hasChildNodes())
+        if (!originalParent->hasChildren())
             removeNode(originalParent);
     }
 
diff --git a/Source/core/editing/Caret.cpp b/Source/core/editing/Caret.cpp
index 64f0508..ffe2ab6 100644
--- a/Source/core/editing/Caret.cpp
+++ b/Source/core/editing/Caret.cpp
@@ -28,7 +28,7 @@
 
 #include "core/dom/Document.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/RenderBlock.h"
 #include "core/rendering/RenderView.h"
@@ -198,7 +198,7 @@
     ASSERT(view);
     bool caretBrowsing = false;
     if (FrameView* frameView = view->frameView()) {
-        Frame& frame = frameView->frame(); // The frame where the selection started
+        LocalFrame& frame = frameView->frame(); // The frame where the selection started
         caretBrowsing = frame.settings() && frame.settings()->caretBrowsingEnabled();
     }
     return (caretBrowsing || isContentEditable);
@@ -256,7 +256,7 @@
     context->fillRect(caret, caretColor);
 }
 
-void DragCaretController::paintDragCaret(Frame* frame, GraphicsContext* p, const LayoutPoint& paintOffset, const LayoutRect& clipRect) const
+void DragCaretController::paintDragCaret(LocalFrame* frame, GraphicsContext* p, const LayoutPoint& paintOffset, const LayoutRect& clipRect) const
 {
     if (m_position.deepEquivalent().deprecatedNode()->document().frame() == frame)
         paintCaret(m_position.deepEquivalent().deprecatedNode(), p, paintOffset, clipRect);
diff --git a/Source/core/editing/Caret.h b/Source/core/editing/Caret.h
index 18c7421..3d9f9eb 100644
--- a/Source/core/editing/Caret.h
+++ b/Source/core/editing/Caret.h
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class GraphicsContext;
 class RenderObject;
 class RenderView;
@@ -78,7 +78,7 @@
     static PassOwnPtr<DragCaretController> create();
 
     RenderObject* caretRenderer() const;
-    void paintDragCaret(Frame*, GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
+    void paintDragCaret(LocalFrame*, GraphicsContext*, const LayoutPoint&, const LayoutRect& clipRect) const;
 
     bool isContentEditable() const { return m_position.rootEditableElement(); }
     bool isContentRichlyEditable() const;
diff --git a/Source/core/editing/CompositeEditCommand.cpp b/Source/core/editing/CompositeEditCommand.cpp
index 3f7dbda..6800411 100644
--- a/Source/core/editing/CompositeEditCommand.cpp
+++ b/Source/core/editing/CompositeEditCommand.cpp
@@ -62,8 +62,8 @@
 #include "core/editing/htmlediting.h"
 #include "core/editing/markup.h"
 #include "core/events/ScopedEventQueue.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/InlineTextBox.h"
 #include "core/rendering/RenderBlock.h"
 #include "core/rendering/RenderText.h"
@@ -90,7 +90,7 @@
 {
 }
 
-bool EditCommandComposition::belongsTo(const Frame& frame) const
+bool EditCommandComposition::belongsTo(const LocalFrame& frame) const
 {
     ASSERT(m_document);
     return m_document->frame() == &frame;
@@ -99,7 +99,7 @@
 void EditCommandComposition::unapply()
 {
     ASSERT(m_document);
-    RefPtr<Frame> frame = m_document->frame();
+    RefPtr<LocalFrame> frame = m_document->frame();
     ASSERT(frame);
 
     // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>.
@@ -119,7 +119,7 @@
 void EditCommandComposition::reapply()
 {
     ASSERT(m_document);
-    RefPtr<Frame> frame = m_document->frame();
+    RefPtr<LocalFrame> frame = m_document->frame();
     ASSERT(frame);
 
     // Changes to the document may have been made since the last editing operation that require a layout, as in <rdar://problem/5658603>.
@@ -186,7 +186,7 @@
     // if one is necessary (like for the creation of VisiblePositions).
     document().updateLayoutIgnorePendingStylesheets();
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     ASSERT(frame);
     {
         EventQueueScope eventQueueScope;
@@ -277,7 +277,8 @@
 
 bool CompositeEditCommand::isRemovableBlock(const Node* node)
 {
-    if (!node->hasTagName(divTag))
+    ASSERT(node);
+    if (!isHTMLDivElement(*node))
         return false;
 
     Node* parentNode = node->parentNode();
@@ -292,7 +293,7 @@
 
 void CompositeEditCommand::insertNodeBefore(PassRefPtr<Node> insertChild, PassRefPtr<Node> refChild, ShouldAssumeContentIsAlwaysEditable shouldAssumeContentIsAlwaysEditable)
 {
-    ASSERT(!refChild->hasTagName(bodyTag));
+    ASSERT(!isHTMLBodyElement(*refChild));
     applyCommandToComposite(InsertNodeBeforeCommand::create(insertChild, refChild, shouldAssumeContentIsAlwaysEditable));
 }
 
@@ -300,7 +301,7 @@
 {
     ASSERT(insertChild);
     ASSERT(refChild);
-    ASSERT(!refChild->hasTagName(bodyTag));
+    ASSERT(!isHTMLBodyElement(*refChild));
     ContainerNode* parent = refChild->parentNode();
     ASSERT(parent);
     ASSERT(!parent->isShadowRoot());
@@ -351,7 +352,7 @@
 void CompositeEditCommand::removeChildrenInRange(PassRefPtr<Node> node, unsigned from, unsigned to)
 {
     Vector<RefPtr<Node> > children;
-    Node* child = node->childNode(from);
+    Node* child = node->traverseToChildAt(from);
     for (unsigned i = from; child && i < to; i++, child = child->nextSibling())
         children.append(child);
 
@@ -394,7 +395,7 @@
     }
 }
 
-void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Position& position, Node* node)
+void CompositeEditCommand::updatePositionForNodeRemovalPreservingChildren(Position& position, Node& node)
 {
     int offset = (position.anchorType() == Position::PositionIsOffsetInAnchor) ? position.offsetInContainerNode() : 0;
     updatePositionForNodeRemoval(position, node);
@@ -497,13 +498,13 @@
 void CompositeEditCommand::replaceTextInNodePreservingMarkers(PassRefPtr<Text> prpNode, unsigned offset, unsigned count, const String& replacementText)
 {
     RefPtr<Text> node(prpNode);
-    DocumentMarkerController* markerController = document().markers();
+    DocumentMarkerController& markerController = document().markers();
     Vector<DocumentMarker> markers;
-    copyMarkers(markerController->markersInRange(Range::create(document(), node.get(), offset, node.get(), offset + count).get(), DocumentMarker::AllMarkers()), markers);
+    copyMarkers(markerController.markersInRange(Range::create(document(), node.get(), offset, node.get(), offset + count).get(), DocumentMarker::AllMarkers()), markers);
     replaceTextInNode(node, offset, count, replacementText);
     RefPtr<Range> newRange = Range::create(document(), node.get(), offset, node.get(), offset + replacementText.length());
     for (size_t i = 0; i < markers.size(); ++i)
-        markerController->addMarker(newRange.get(), markers[i].type(), markers[i].description());
+        markerController.addMarker(newRange.get(), markers[i].type(), markers[i].description());
 }
 
 Position CompositeEditCommand::positionOutsideTabSpan(const Position& pos)
@@ -519,21 +520,22 @@
     case Position::PositionIsOffsetInAnchor:
         break;
     case Position::PositionIsBeforeAnchor:
-        return positionInParentBeforeNode(pos.anchorNode());
+        return positionInParentBeforeNode(*pos.anchorNode());
     case Position::PositionIsAfterAnchor:
-        return positionInParentAfterNode(pos.anchorNode());
+        return positionInParentAfterNode(*pos.anchorNode());
     }
 
     Node* tabSpan = tabSpanNode(pos.containerNode());
+    ASSERT(tabSpan);
 
     if (pos.offsetInContainerNode() <= caretMinOffset(pos.containerNode()))
-        return positionInParentBeforeNode(tabSpan);
+        return positionInParentBeforeNode(*tabSpan);
 
     if (pos.offsetInContainerNode() >= caretMaxOffset(pos.containerNode()))
-        return positionInParentAfterNode(tabSpan);
+        return positionInParentAfterNode(*tabSpan);
 
     splitTextNodeContainingElement(toText(pos.containerNode()), pos.offsetInContainerNode());
-    return positionInParentBeforeNode(tabSpan);
+    return positionInParentBeforeNode(*tabSpan);
 }
 
 void CompositeEditCommand::insertNodeAtTabSpanPosition(PassRefPtr<Node> node, const Position& pos)
@@ -683,7 +685,7 @@
     if (!isCollapsibleWhitespace(visiblePosition.characterAfter()))
         return;
     Position pos = visiblePosition.deepEquivalent().downstream();
-    if (!pos.containerNode() || !pos.containerNode()->isTextNode() || pos.containerNode()->hasTagName(brTag))
+    if (!pos.containerNode() || !pos.containerNode()->isTextNode())
         return;
     replaceTextInNodePreservingMarkers(pos.containerText(), pos.offsetInContainerNode(), 1, nonBreakingSpaceString());
 }
@@ -812,7 +814,7 @@
 PassRefPtr<Node> CompositeEditCommand::appendBlockPlaceholder(PassRefPtr<Element> container)
 {
     if (!container)
-        return 0;
+        return nullptr;
 
     document().updateLayoutIgnorePendingStylesheets();
 
@@ -827,7 +829,7 @@
 PassRefPtr<Node> CompositeEditCommand::insertBlockPlaceholder(const Position& pos)
 {
     if (pos.isNull())
-        return 0;
+        return nullptr;
 
     // Should assert isRenderBlockFlow || isInlineFlow when deletion improves. See 4244964.
     ASSERT(pos.deprecatedNode()->renderer());
@@ -840,13 +842,13 @@
 PassRefPtr<Node> CompositeEditCommand::addBlockPlaceholderIfNeeded(Element* container)
 {
     if (!container)
-        return 0;
+        return nullptr;
 
     document().updateLayoutIgnorePendingStylesheets();
 
     RenderObject* renderer = container->renderer();
     if (!renderer || !renderer->isRenderBlockFlow())
-        return 0;
+        return nullptr;
 
     // append the placeholder to make sure it follows
     // any unrendered blocks
@@ -854,7 +856,7 @@
     if (block->height() == 0 || (block->isListItem() && block->isEmpty()))
         return appendBlockPlaceholder(container);
 
-    return 0;
+    return nullptr;
 }
 
 // Assumes that the position is at a placeholder and does the removal without much checking.
@@ -863,7 +865,7 @@
     ASSERT(lineBreakExistsAtPosition(p));
 
     // We are certain that the position is at a line break, but it may be a br or a preserved newline.
-    if (p.anchorNode()->hasTagName(brTag)) {
+    if (isHTMLBRElement(*p.anchorNode())) {
         removeNode(p.anchorNode());
         return;
     }
@@ -884,7 +886,7 @@
 PassRefPtr<Node> CompositeEditCommand::moveParagraphContentsToNewBlockIfNecessary(const Position& pos)
 {
     if (pos.isNull())
-        return 0;
+        return nullptr;
 
     document().updateLayoutIgnorePendingStylesheets();
 
@@ -902,7 +904,7 @@
     // If there are no VisiblePositions in the same block as pos then
     // upstreamStart will be outside the paragraph
     if (comparePositions(pos, upstreamStart) < 0)
-        return 0;
+        return nullptr;
 
     // Perform some checks to see if we need to perform work in this function.
     if (isBlock(upstreamStart.deprecatedNode())) {
@@ -917,26 +919,26 @@
             if (!upstreamEnd.deprecatedNode()->isDescendantOf(upstreamStart.deprecatedNode())) {
                 // If the paragraph end is a descendant of paragraph start, then we need to run
                 // the rest of this function. If not, we can bail here.
-                return 0;
+                return nullptr;
             }
         } else if (enclosingBlock(upstreamEnd.deprecatedNode()) != upstreamStart.deprecatedNode()) {
             // The visibleEnd.  It must be an ancestor of the paragraph start.
             // We can bail as we have a full block to work with.
             ASSERT(upstreamStart.deprecatedNode()->isDescendantOf(enclosingBlock(upstreamEnd.deprecatedNode())));
-            return 0;
+            return nullptr;
         } else if (isEndOfEditableOrNonEditableContent(visibleEnd)) {
             // At the end of the editable region. We can bail here as well.
-            return 0;
+            return nullptr;
         }
     }
 
     RefPtr<Node> newBlock = insertNewDefaultParagraphElementAt(upstreamStart);
 
-    bool endWasBr = visibleParagraphEnd.deepEquivalent().deprecatedNode()->hasTagName(brTag);
+    bool endWasBr = isHTMLBRElement(*visibleParagraphEnd.deepEquivalent().deprecatedNode());
 
     moveParagraphs(visibleParagraphStart, visibleParagraphEnd, VisiblePosition(firstPositionInNode(newBlock.get())));
 
-    if (newBlock->lastChild() && newBlock->lastChild()->hasTagName(brTag) && !endWasBr)
+    if (newBlock->lastChild() && isHTMLBRElement(*newBlock->lastChild()) && !endWasBr)
         removeNode(newBlock->lastChild());
 
     return newBlock.release();
@@ -959,8 +961,10 @@
 // Clone the paragraph between start and end under blockElement,
 // preserving the hierarchy up to outerNode.
 
-void CompositeEditCommand::cloneParagraphUnderNewElement(Position& start, Position& end, Node* passedOuterNode, Element* blockElement)
+void CompositeEditCommand::cloneParagraphUnderNewElement(const Position& start, const Position& end, Node* passedOuterNode, Element* blockElement)
 {
+    ASSERT(comparePositions(start, end) <= 0);
+
     // First we clone the outerNode
     RefPtr<Node> lastNode;
     RefPtr<Node> outerNode = passedOuterNode;
@@ -1045,7 +1049,7 @@
             return;
 
         // Normally deletion will leave a br as a placeholder.
-        if (node->hasTagName(brTag)) {
+        if (isHTMLBRElement(*node)) {
             removeNodeAndPruneAncestors(node, destinationNode);
 
             // If the selection to move was empty and in an empty block that
@@ -1090,7 +1094,7 @@
     // We upstream() the end and downstream() the start so that we don't include collapsed whitespace in the move.
     // When we paste a fragment, spaces after the end and before the start are treated as though they were rendered.
     Position start = startOfParagraphToMove.deepEquivalent().downstream();
-    Position end = endOfParagraphToMove.deepEquivalent().upstream();
+    Position end = startOfParagraphToMove == endOfParagraphToMove ? start : endOfParagraphToMove.deepEquivalent().upstream();
 
     cloneParagraphUnderNewElement(start, end, outerNode, blockElement);
 
@@ -1177,7 +1181,7 @@
     // FIXME: This is an inefficient way to preserve style on nodes in the paragraph to move. It
     // shouldn't matter though, since moved paragraphs will usually be quite small.
     RefPtr<DocumentFragment> fragment = startOfParagraphToMove != endOfParagraphToMove ?
-        createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotAnnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor), "") : 0;
+        createFragmentFromMarkup(document(), createMarkup(range.get(), 0, DoNotAnnotateForInterchange, true, DoNotResolveURLs, constrainingAncestor), "") : nullptr;
 
     // A non-empty paragraph's style is moved when we copy and move it.  We don't move
     // anything if we're given an empty paragraph, but an empty paragraph can have style
@@ -1234,15 +1238,17 @@
         applyStyle(styleInEmptyParagraph.get());
 
     if (preserveSelection && startIndex != -1) {
-        // Fragment creation (using createMarkup) incorrectly uses regular
-        // spaces instead of nbsps for some spaces that were rendered (11475), which
-        // causes spaces to be collapsed during the move operation.  This results
-        // in a call to rangeFromLocationAndLength with a location past the end
-        // of the document (which will return null).
-        RefPtr<Range> start = PlainTextRange(destinationIndex + startIndex).createRangeForSelection(*document().documentElement());
-        RefPtr<Range> end = PlainTextRange(destinationIndex + endIndex).createRangeForSelection(*document().documentElement());
-        if (start && end)
-            setEndingSelection(VisibleSelection(start->startPosition(), end->startPosition(), DOWNSTREAM, originalIsDirectional));
+        if (Element* documentElement = document().documentElement()) {
+            // Fragment creation (using createMarkup) incorrectly uses regular
+            // spaces instead of nbsps for some spaces that were rendered (11475), which
+            // causes spaces to be collapsed during the move operation. This results
+            // in a call to rangeFromLocationAndLength with a location past the end
+            // of the document (which will return null).
+            RefPtr<Range> start = PlainTextRange(destinationIndex + startIndex).createRangeForSelection(*documentElement);
+            RefPtr<Range> end = PlainTextRange(destinationIndex + endIndex).createRangeForSelection(*documentElement);
+            if (start && end)
+                setEndingSelection(VisibleSelection(start->startPosition(), end->startPosition(), DOWNSTREAM, originalIsDirectional));
+        }
     }
 }
 
@@ -1259,15 +1265,15 @@
     RefPtr<ContainerNode> listNode = emptyListItem->parentNode();
     // FIXME: Can't we do something better when the immediate parent wasn't a list node?
     if (!listNode
-        || (!listNode->hasTagName(ulTag) && !listNode->hasTagName(olTag))
+        || (!isHTMLUListElement(*listNode) && !isHTMLOListElement(*listNode))
         || !listNode->rendererIsEditable()
         || listNode == emptyListItem->rootEditableElement())
         return false;
 
-    RefPtr<Element> newBlock = 0;
+    RefPtr<Element> newBlock = nullptr;
     if (ContainerNode* blockEnclosingList = listNode->parentNode()) {
-        if (blockEnclosingList->hasTagName(liTag)) { // listNode is inside another list item
-            if (visiblePositionAfterNode(blockEnclosingList) == visiblePositionAfterNode(listNode.get())) {
+        if (isHTMLLIElement(*blockEnclosingList)) { // listNode is inside another list item
+            if (visiblePositionAfterNode(*blockEnclosingList) == visiblePositionAfterNode(*listNode)) {
                 // If listNode appears at the end of the outer list item, then move listNode outside of this list item
                 // e.g. <ul><li>hello <ul><li><br></li></ul> </li></ul> should become <ul><li>hello</li> <ul><li><br></li></ul> </ul> after this section
                 // If listNode does NOT appear at the end, then we should consider it as a regular paragraph.
@@ -1277,7 +1283,7 @@
                 newBlock = createListItemElement(document());
             }
             // If listNode does NOT appear at the end of the outer list item, then behave as if in a regular paragraph.
-        } else if (blockEnclosingList->hasTagName(olTag) || blockEnclosingList->hasTagName(ulTag)) {
+        } else if (isHTMLOListElement(*blockEnclosingList) || isHTMLUListElement(*blockEnclosingList)) {
             newBlock = createListItemElement(document());
         }
     }
@@ -1350,9 +1356,9 @@
 
     Position caretPos(caret.deepEquivalent().downstream());
     // A line break is either a br or a preserved newline.
-    ASSERT(caretPos.deprecatedNode()->hasTagName(brTag) || (caretPos.deprecatedNode()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveNewline()));
+    ASSERT(isHTMLBRElement(caretPos.deprecatedNode()) || (caretPos.deprecatedNode()->isTextNode() && caretPos.deprecatedNode()->renderer()->style()->preserveNewline()));
 
-    if (caretPos.deprecatedNode()->hasTagName(brTag))
+    if (isHTMLBRElement(*caretPos.deprecatedNode()))
         removeNodeAndPruneAncestors(caretPos.deprecatedNode());
     else if (caretPos.deprecatedNode()->isTextNode()) {
         ASSERT(caretPos.deprecatedEditingOffset() == 0);
@@ -1404,7 +1410,7 @@
             if (lineBreakExistsAtVisiblePosition(visiblePos) && downstream.deprecatedNode()->isDescendantOf(enclosingAnchor))
                 return original;
 
-            result = positionInParentAfterNode(enclosingAnchor);
+            result = positionInParentAfterNode(*enclosingAnchor);
         }
         // If visually just before an anchor, insert *outside* the anchor unless it's the first
         // VisiblePosition in a paragraph, to match NSTextView.
@@ -1418,7 +1424,7 @@
             if (!enclosingAnchor)
                 return original;
 
-            result = positionInParentBeforeNode(enclosingAnchor);
+            result = positionInParentBeforeNode(*enclosingAnchor);
         }
     }
 
@@ -1445,8 +1451,8 @@
         if (!node->parentNode()->isElementNode())
             break;
         // Do not split a node when doing so introduces an empty node.
-        VisiblePosition positionInParent = firstPositionInNode(node->parentNode());
-        VisiblePosition positionInNode = firstPositionInOrBeforeNode(node.get());
+        VisiblePosition positionInParent(firstPositionInNode(node->parentNode()));
+        VisiblePosition positionInNode(firstPositionInOrBeforeNode(node.get()));
         if (positionInParent != positionInNode)
             splitElement(toElement(node->parentNode()), node);
     }
diff --git a/Source/core/editing/CompositeEditCommand.h b/Source/core/editing/CompositeEditCommand.h
index 007c306..b0e019e 100644
--- a/Source/core/editing/CompositeEditCommand.h
+++ b/Source/core/editing/CompositeEditCommand.h
@@ -42,7 +42,7 @@
 public:
     static PassRefPtr<EditCommandComposition> create(Document*, const VisibleSelection&, const VisibleSelection&, EditAction);
 
-    virtual bool belongsTo(const Frame&) const OVERRIDE;
+    virtual bool belongsTo(const LocalFrame&) const OVERRIDE;
     virtual void unapply() OVERRIDE;
     virtual void reapply() OVERRIDE;
     virtual EditAction editingAction() const OVERRIDE { return m_editAction; }
@@ -121,7 +121,7 @@
     void removeNodePreservingChildren(PassRefPtr<Node>, ShouldAssumeContentIsAlwaysEditable = DoNotAssumeContentIsAlwaysEditable);
     void removeNodeAndPruneAncestors(PassRefPtr<Node>, Node* excludeNode = 0);
     void moveRemainingSiblingsToNewParent(Node*, Node* pastLastNodeToMove, PassRefPtr<Element> prpNewParent);
-    void updatePositionForNodeRemovalPreservingChildren(Position&, Node*);
+    void updatePositionForNodeRemovalPreservingChildren(Position&, Node&);
     void prune(PassRefPtr<Node>, Node* excludeNode = 0);
     void replaceTextInNode(PassRefPtr<Text>, unsigned offset, unsigned count, const String& replacementText);
     Position replaceSelectedTextInNode(const String&);
@@ -152,7 +152,7 @@
     void moveParagraph(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, bool preserveSelection = false, bool preserveStyle = true, Node* constrainingAncestor = 0);
     void moveParagraphs(const VisiblePosition&, const VisiblePosition&, const VisiblePosition&, bool preserveSelection = false, bool preserveStyle = true, Node* constrainingAncestor = 0);
     void moveParagraphWithClones(const VisiblePosition& startOfParagraphToMove, const VisiblePosition& endOfParagraphToMove, Element* blockElement, Node* outerNode);
-    void cloneParagraphUnderNewElement(Position& start, Position& end, Node* outerNode, Element* blockElement);
+    void cloneParagraphUnderNewElement(const Position& start, const Position& end, Node* outerNode, Element* blockElement);
     void cleanupAfterDeletion(VisiblePosition destination = VisiblePosition());
 
     bool breakOutOfEmptyListItem();
diff --git a/Source/core/editing/CreateLinkCommand.cpp b/Source/core/editing/CreateLinkCommand.cpp
index 7f8adff..dcc5deb 100644
--- a/Source/core/editing/CreateLinkCommand.cpp
+++ b/Source/core/editing/CreateLinkCommand.cpp
@@ -51,7 +51,7 @@
         insertNodeAt(anchorElement.get(), endingSelection().start());
         RefPtr<Text> textNode = Text::create(document(), m_url);
         appendNode(textNode.get(), anchorElement.get());
-        setEndingSelection(VisibleSelection(positionInParentBeforeNode(anchorElement.get()), positionInParentAfterNode(anchorElement.get()), DOWNSTREAM, endingSelection().isDirectional()));
+        setEndingSelection(VisibleSelection(positionInParentBeforeNode(*anchorElement), positionInParentAfterNode(*anchorElement), DOWNSTREAM, endingSelection().isDirectional()));
     }
 }
 
diff --git a/Source/core/editing/DeleteSelectionCommand.cpp b/Source/core/editing/DeleteSelectionCommand.cpp
index 0303cbb..7059c7d 100644
--- a/Source/core/editing/DeleteSelectionCommand.cpp
+++ b/Source/core/editing/DeleteSelectionCommand.cpp
@@ -35,19 +35,14 @@
 #include "core/editing/Editor.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLInputElement.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderTableCell.h"
 
 namespace WebCore {
 
 using namespace HTMLNames;
 
-static bool isTableRow(const Node* node)
-{
-    return node && node->hasTagName(trTag);
-}
-
 static bool isTableCellEmpty(Node* cell)
 {
     ASSERT(isTableCell(cell));
@@ -56,7 +51,7 @@
 
 static bool isTableRowEmpty(Node* row)
 {
-    if (!isTableRow(row))
+    if (!isHTMLTableRowElement(row))
         return false;
 
     for (Node* child = row->firstChild(); child; child = child->nextSibling())
@@ -76,10 +71,10 @@
     , m_pruneStartBlockIfNecessary(false)
     , m_startsAtEmptyLine(false)
     , m_sanitizeMarkup(sanitizeMarkup)
-    , m_startBlock(0)
-    , m_endBlock(0)
-    , m_typingStyle(0)
-    , m_deleteIntoBlockquoteStyle(0)
+    , m_startBlock(nullptr)
+    , m_endBlock(nullptr)
+    , m_typingStyle(nullptr)
+    , m_deleteIntoBlockquoteStyle(nullptr)
 {
 }
 
@@ -94,10 +89,10 @@
     , m_startsAtEmptyLine(false)
     , m_sanitizeMarkup(sanitizeMarkup)
     , m_selectionToDelete(selection)
-    , m_startBlock(0)
-    , m_endBlock(0)
-    , m_typingStyle(0)
-    , m_deleteIntoBlockquoteStyle(0)
+    , m_startBlock(nullptr)
+    , m_endBlock(nullptr)
+    , m_typingStyle(nullptr)
+    , m_deleteIntoBlockquoteStyle(nullptr)
 {
 }
 
@@ -111,9 +106,9 @@
 
     // For HRs, we'll get a position at (HR,1) when hitting delete from the beginning of the previous line, or (HR,0) when forward deleting,
     // but in these cases, we want to delete it, so manually expand the selection
-    if (start.deprecatedNode()->hasTagName(hrTag))
+    if (isHTMLHRElement(*start.deprecatedNode()))
         start = positionBeforeNode(start.deprecatedNode());
-    else if (end.deprecatedNode()->hasTagName(hrTag))
+    else if (isHTMLHRElement(*end.deprecatedNode()))
         end = positionAfterNode(end.deprecatedNode());
 
     // FIXME: This is only used so that moveParagraphs can avoid the bugs in special element expansion.
@@ -134,11 +129,11 @@
             break;
 
         // If we're going to expand to include the startSpecialContainer, it must be fully selected.
-        if (startSpecialContainer && !endSpecialContainer && comparePositions(positionInParentAfterNode(startSpecialContainer), end) > -1)
+        if (startSpecialContainer && !endSpecialContainer && comparePositions(positionInParentAfterNode(*startSpecialContainer), end) > -1)
             break;
 
         // If we're going to expand to include the endSpecialContainer, it must be fully selected.
-        if (endSpecialContainer && !startSpecialContainer && comparePositions(start, positionInParentBeforeNode(endSpecialContainer)) > -1)
+        if (endSpecialContainer && !startSpecialContainer && comparePositions(start, positionInParentBeforeNode(*endSpecialContainer)) > -1)
             break;
 
         if (startSpecialContainer && startSpecialContainer->isDescendantOf(endSpecialContainer))
@@ -158,15 +153,9 @@
 
 void DeleteSelectionCommand::setStartingSelectionOnSmartDelete(const Position& start, const Position& end)
 {
-    VisiblePosition newBase;
-    VisiblePosition newExtent;
-    if (startingSelection().isBaseFirst()) {
-        newBase = start;
-        newExtent = end;
-    } else {
-        newBase = end;
-        newExtent = start;
-    }
+    bool isBaseFirst = startingSelection().isBaseFirst();
+    VisiblePosition newBase(isBaseFirst ? start : end);
+    VisiblePosition newExtent(isBaseFirst ? end : start);
     setStartingSelection(VisibleSelection(newBase, newExtent, startingSelection().isDirectional()));
 }
 
@@ -183,8 +172,8 @@
     m_startRoot = editableRootForPosition(start);
     m_endRoot = editableRootForPosition(end);
 
-    m_startTableRow = enclosingNodeOfType(start, &isTableRow);
-    m_endTableRow = enclosingNodeOfType(end, &isTableRow);
+    m_startTableRow = enclosingNodeOfType(start, &isHTMLTableRowElement);
+    m_endTableRow = enclosingNodeOfType(end, &isHTMLTableRowElement);
 
     // Don't move content out of a table cell.
     // If the cell is non-editable, enclosingNodeOfType won't return it by default, so
@@ -297,7 +286,7 @@
     if (enclosingNodeOfType(m_selectionToDelete.start(), isMailBlockquote))
         m_deleteIntoBlockquoteStyle = EditingStyle::create(m_selectionToDelete.end());
     else
-        m_deleteIntoBlockquoteStyle = 0;
+        m_deleteIntoBlockquoteStyle = nullptr;
 }
 
 bool DeleteSelectionCommand::handleSpecialCaseBRDelete()
@@ -311,8 +300,8 @@
         return false;
 
     // Check for special-case where the selection contains only a BR on a line by itself after another BR.
-    bool upstreamStartIsBR = nodeAfterUpstreamStart->hasTagName(brTag);
-    bool downstreamStartIsBR = nodeAfterDownstreamStart->hasTagName(brTag);
+    bool upstreamStartIsBR = isHTMLBRElement(*nodeAfterUpstreamStart);
+    bool downstreamStartIsBR = isHTMLBRElement(*nodeAfterDownstreamStart);
     bool isBROnLineByItself = upstreamStartIsBR && downstreamStartIsBR && nodeAfterDownstreamStart == nodeAfterUpstreamEnd;
     if (isBROnLineByItself) {
         removeNode(nodeAfterDownstreamStart);
@@ -321,7 +310,7 @@
 
     // FIXME: This code doesn't belong in here.
     // We detect the case where the start is an empty line consisting of BR not wrapped in a block element.
-    if (upstreamStartIsBR && downstreamStartIsBR && !(isStartOfBlock(positionBeforeNode(nodeAfterUpstreamStart)) && isEndOfBlock(positionAfterNode(nodeAfterUpstreamStart)))) {
+    if (upstreamStartIsBR && downstreamStartIsBR && !(isStartOfBlock(VisiblePosition(positionBeforeNode(nodeAfterUpstreamStart))) && isEndOfBlock(VisiblePosition(positionAfterNode(nodeAfterUpstreamStart))))) {
         m_startsAtEmptyLine = true;
         m_endingPosition = m_downstreamEnd;
     }
@@ -392,9 +381,9 @@
         m_needPlaceholder = true;
 
     // FIXME: Update the endpoints of the range being deleted.
-    updatePositionForNodeRemoval(m_endingPosition, node.get());
-    updatePositionForNodeRemoval(m_leadingWhitespace, node.get());
-    updatePositionForNodeRemoval(m_trailingWhitespace, node.get());
+    updatePositionForNodeRemoval(m_endingPosition, *node);
+    updatePositionForNodeRemoval(m_leadingWhitespace, *node);
+    updatePositionForNodeRemoval(m_trailingWhitespace, *node);
 
     CompositeEditCommand::removeNode(node, shouldAssumeContentIsAlwaysEditable);
 }
@@ -427,7 +416,7 @@
     RefPtr<Node> node = range->firstNode();
     while (node && node != range->pastLastNode()) {
         RefPtr<Node> nextNode = NodeTraversal::next(*node);
-        if ((node->hasTagName(styleTag) && !(toElement(node)->hasAttribute(scopedAttr))) || node->hasTagName(linkTag)) {
+        if ((isHTMLStyleElement(*node) && !(toElement(node)->hasAttribute(scopedAttr))) || isHTMLLinkElement(*node)) {
             nextNode = NodeTraversal::nextSkippingChildren(*node);
             RefPtr<ContainerNode> rootEditableElement = node->rootEditableElement();
             if (rootEditableElement.get()) {
@@ -451,7 +440,7 @@
     makeStylingElementsDirectChildrenOfEditableRootToPreventStyleLoss();
 
     // Never remove the start block unless it's a table, in which case we won't merge content in.
-    if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChildrenForEditing(startNode) && !startNode->hasTagName(tableTag)) {
+    if (startNode->isSameNode(m_startBlock.get()) && !startOffset && canHaveChildrenForEditing(startNode) && !isHTMLTableElement(*startNode)) {
         startOffset = 0;
         startNode = NodeTraversal::next(*startNode);
         if (!startNode)
@@ -501,7 +490,7 @@
                 deleteTextFromNode(text, startOffset, text->length() - startOffset);
                 node = NodeTraversal::next(*node);
             } else {
-                node = startNode->childNode(startOffset);
+                node = startNode->traverseToChildAt(startOffset);
             }
         } else if (startNode == m_upstreamEnd.deprecatedNode() && startNode->isTextNode()) {
             Text* text = toText(m_upstreamEnd.deprecatedNode());
@@ -512,19 +501,19 @@
         while (node && node != m_downstreamEnd.deprecatedNode()) {
             if (comparePositions(firstPositionInOrBeforeNode(node.get()), m_downstreamEnd) >= 0) {
                 // NodeTraversal::nextSkippingChildren just blew past the end position, so stop deleting
-                node = 0;
+                node = nullptr;
             } else if (!m_downstreamEnd.deprecatedNode()->isDescendantOf(node.get())) {
                 RefPtr<Node> nextNode = NodeTraversal::nextSkippingChildren(*node);
                 // if we just removed a node from the end container, update end position so the
                 // check above will work
-                updatePositionForNodeRemoval(m_downstreamEnd, node.get());
+                updatePositionForNodeRemoval(m_downstreamEnd, *node);
                 removeNode(node.get());
                 node = nextNode.get();
             } else {
                 Node& n = node->lastDescendant();
                 if (m_downstreamEnd.deprecatedNode() == n && m_downstreamEnd.deprecatedEditingOffset() >= caretMaxOffset(&n)) {
                     removeNode(node.get());
-                    node = 0;
+                    node = nullptr;
                 } else {
                     node = NodeTraversal::next(*node);
                 }
@@ -649,7 +638,7 @@
     // The rule for merging into an empty block is: only do so if its farther to the right.
     // FIXME: Consider RTL.
     if (!m_startsAtEmptyLine && isStartOfParagraph(mergeDestination) && startOfParagraphToMove.absoluteCaretBounds().x() > mergeDestination.absoluteCaretBounds().x()) {
-        if (mergeDestination.deepEquivalent().downstream().deprecatedNode()->hasTagName(brTag)) {
+        if (isHTMLBRElement(*mergeDestination.deepEquivalent().downstream().deprecatedNode())) {
             removeNodeAndPruneAncestors(mergeDestination.deepEquivalent().downstream().deprecatedNode());
             m_endingPosition = startOfParagraphToMove.deepEquivalent();
             return;
@@ -722,17 +711,17 @@
     // Compute the difference between the style before the delete and the style now
     // after the delete has been done. Set this style on the frame, so other editing
     // commands being composed with this one will work, and also cache it on the command,
-    // so the Frame::appliedEditing can set it after the whole composite command
+    // so the LocalFrame::appliedEditing can set it after the whole composite command
     // has completed.
 
     // If we deleted into a blockquote, but are now no longer in a blockquote, use the alternate typing style
     if (m_deleteIntoBlockquoteStyle && !enclosingNodeOfType(m_endingPosition, isMailBlockquote, CanCrossEditingBoundary))
         m_typingStyle = m_deleteIntoBlockquoteStyle;
-    m_deleteIntoBlockquoteStyle = 0;
+    m_deleteIntoBlockquoteStyle = nullptr;
 
     m_typingStyle->prepareToApplyAt(m_endingPosition);
     if (m_typingStyle->isEmpty())
-        m_typingStyle = 0;
+        m_typingStyle = nullptr;
     // This is where we've deleted all traces of a style but not a whole paragraph (that's handled above).
     // In this case if we start typing, the new characters should have the same style as the just deleted ones,
     // but, if we change the selection, come back and start typing that style should be lost.  Also see
@@ -761,7 +750,7 @@
     while (node != rootNode) {
         if (isRemovableBlock(node)) {
             if (node == m_endingPosition.anchorNode())
-                updatePositionForNodeRemovalPreservingChildren(m_endingPosition, node);
+                updatePositionForNodeRemovalPreservingChildren(m_endingPosition, *node);
 
             CompositeEditCommand::removeNodePreservingChildren(node);
             node = m_endingPosition.anchorNode();
diff --git a/Source/core/editing/EditCommand.cpp b/Source/core/editing/EditCommand.cpp
index 4b318f7..d8c240c 100644
--- a/Source/core/editing/EditCommand.cpp
+++ b/Source/core/editing/EditCommand.cpp
@@ -30,7 +30,7 @@
 #include "core/dom/NodeTraversal.h"
 #include "core/editing/CompositeEditCommand.h"
 #include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
@@ -70,30 +70,40 @@
     return toCompositeEditCommand(command)->composition();
 }
 
-void EditCommand::setStartingSelection(const VisibleSelection& s)
+void EditCommand::setStartingSelection(const VisibleSelection& selection)
 {
-    for (EditCommand* cmd = this; ; cmd = cmd->m_parent) {
-        if (EditCommandComposition* composition = compositionIfPossible(cmd)) {
-            ASSERT(cmd->isTopLevelCommand());
-            composition->setStartingSelection(s);
+    for (EditCommand* command = this; ; command = command->m_parent) {
+        if (EditCommandComposition* composition = compositionIfPossible(command)) {
+            ASSERT(command->isTopLevelCommand());
+            composition->setStartingSelection(selection);
         }
-        cmd->m_startingSelection = s;
-        if (!cmd->m_parent || cmd->m_parent->isFirstCommand(cmd))
+        command->m_startingSelection = selection;
+        if (!command->m_parent || command->m_parent->isFirstCommand(command))
             break;
     }
 }
 
-void EditCommand::setEndingSelection(const VisibleSelection &s)
+void EditCommand::setStartingSelection(const VisiblePosition& position)
 {
-    for (EditCommand* cmd = this; cmd; cmd = cmd->m_parent) {
-        if (EditCommandComposition* composition = compositionIfPossible(cmd)) {
-            ASSERT(cmd->isTopLevelCommand());
-            composition->setEndingSelection(s);
+    setStartingSelection(VisibleSelection(position));
+}
+
+void EditCommand::setEndingSelection(const VisibleSelection& selection)
+{
+    for (EditCommand* command = this; command; command = command->m_parent) {
+        if (EditCommandComposition* composition = compositionIfPossible(command)) {
+            ASSERT(command->isTopLevelCommand());
+            composition->setEndingSelection(selection);
         }
-        cmd->m_endingSelection = s;
+        command->m_endingSelection = selection;
     }
 }
 
+void EditCommand::setEndingSelection(const VisiblePosition& position)
+{
+    setEndingSelection(VisibleSelection(position));
+}
+
 void EditCommand::setParent(CompositeEditCommand* parent)
 {
     ASSERT((parent && !m_parent) || (!parent && m_parent));
diff --git a/Source/core/editing/EditCommand.h b/Source/core/editing/EditCommand.h
index 7d54068..7db7351 100644
--- a/Source/core/editing/EditCommand.h
+++ b/Source/core/editing/EditCommand.h
@@ -63,7 +63,9 @@
     Document& document() const { return *m_document.get(); }
     CompositeEditCommand* parent() const { return m_parent; }
     void setStartingSelection(const VisibleSelection&);
+    void setStartingSelection(const VisiblePosition&);
     void setEndingSelection(const VisibleSelection&);
+    void setEndingSelection(const VisiblePosition&);
 
 private:
     RefPtr<Document> m_document;
diff --git a/Source/core/editing/EditingStyle.cpp b/Source/core/editing/EditingStyle.cpp
index 29a8fbe..5ab6d5b 100644
--- a/Source/core/editing/EditingStyle.cpp
+++ b/Source/core/editing/EditingStyle.cpp
@@ -49,7 +49,7 @@
 #include "core/editing/FrameSelection.h"
 #include "core/editing/HTMLInterchange.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFontElement.h"
 #include "core/rendering/style/RenderStyle.h"
 
@@ -147,7 +147,7 @@
 static bool isTransparentColorValue(CSSValue*);
 static bool hasTransparentBackgroundColor(CSSStyleDeclaration*);
 static bool hasTransparentBackgroundColor(StylePropertySet*);
-static PassRefPtr<CSSValue> backgroundColorInEffect(Node*);
+static PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node*);
 
 class HTMLElementEquivalent {
     WTF_MAKE_FAST_ALLOCATED;
@@ -195,7 +195,7 @@
 
 bool HTMLElementEquivalent::valueIsPresentInStyle(Element* element, StylePropertySet* style) const
 {
-    RefPtr<CSSValue> value = style->getPropertyCSSValue(m_propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(m_propertyID);
     return matches(element) && value && value->isPrimitiveValue() && toCSSPrimitiveValue(value.get())->getValueID() == m_primitiveValue->getValueID();
 }
 
@@ -231,7 +231,7 @@
 
 bool HTMLTextDecorationEquivalent::valueIsPresentInStyle(Element* element, StylePropertySet* style) const
 {
-    RefPtr<CSSValue> styleValue = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
+    RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
     if (!styleValue)
         styleValue = style->getPropertyCSSValue(textDecorationPropertyForEditing());
     return matches(element) && styleValue && styleValue->isValueList() && toCSSValueList(styleValue.get())->hasValue(m_primitiveValue.get());
@@ -252,7 +252,7 @@
     virtual bool hasAttribute() const OVERRIDE { return true; }
     virtual bool valueIsPresentInStyle(Element*, StylePropertySet*) const OVERRIDE;
     virtual void addToStyle(Element*, EditingStyle*) const OVERRIDE;
-    virtual PassRefPtr<CSSValue> attributeValueAsCSSValue(Element*) const;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const;
     inline const QualifiedName& attributeName() const { return m_attrName; }
 
 protected:
@@ -275,27 +275,28 @@
 
 bool HTMLAttributeEquivalent::valueIsPresentInStyle(Element* element, StylePropertySet* style) const
 {
-    RefPtr<CSSValue> value = attributeValueAsCSSValue(element);
-    RefPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element);
+    RefPtrWillBeRawPtr<CSSValue> styleValue = style->getPropertyCSSValue(m_propertyID);
 
     return compareCSSValuePtr(value, styleValue);
 }
 
 void HTMLAttributeEquivalent::addToStyle(Element* element, EditingStyle* style) const
 {
-    if (RefPtr<CSSValue> value = attributeValueAsCSSValue(element))
+    if (RefPtrWillBeRawPtr<CSSValue> value = attributeValueAsCSSValue(element))
         style->setProperty(m_propertyID, value->cssText());
 }
 
-PassRefPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSValue(Element* element) const
+PassRefPtrWillBeRawPtr<CSSValue> HTMLAttributeEquivalent::attributeValueAsCSSValue(Element* element) const
 {
     ASSERT(element);
-    if (!element->hasAttribute(m_attrName))
-        return 0;
+    const AtomicString& value = element->getAttribute(m_attrName);
+    if (value.isNull())
+        return nullptr;
 
     RefPtr<MutableStylePropertySet> dummyStyle;
     dummyStyle = MutableStylePropertySet::create();
-    dummyStyle->setProperty(m_propertyID, element->getAttribute(m_attrName));
+    dummyStyle->setProperty(m_propertyID, value);
     return dummyStyle->getPropertyCSSValue(m_propertyID);
 }
 
@@ -305,7 +306,7 @@
     {
         return adoptPtr(new HTMLFontSizeEquivalent());
     }
-    virtual PassRefPtr<CSSValue> attributeValueAsCSSValue(Element*) const OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> attributeValueAsCSSValue(Element*) const OVERRIDE;
 
 private:
     HTMLFontSizeEquivalent();
@@ -316,14 +317,15 @@
 {
 }
 
-PassRefPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValue(Element* element) const
+PassRefPtrWillBeRawPtr<CSSValue> HTMLFontSizeEquivalent::attributeValueAsCSSValue(Element* element) const
 {
     ASSERT(element);
-    if (!element->hasAttribute(m_attrName))
-        return 0;
+    const AtomicString& value = element->getAttribute(m_attrName);
+    if (value.isNull())
+        return nullptr;
     CSSValueID size;
-    if (!HTMLFontElement::cssValueFromFontSizeNumber(element->getAttribute(m_attrName), size))
-        return 0;
+    if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
+        return nullptr;
     return CSSPrimitiveValue::createIdentifier(size);
 }
 
@@ -350,7 +352,7 @@
 }
 
 EditingStyle::EditingStyle(const StylePropertySet* style)
-    : m_mutableStyle(style ? style->mutableCopy() : 0)
+    : m_mutableStyle(style ? style->mutableCopy() : nullptr)
     , m_shouldUseFixedDefaultFontSize(false)
     , m_fontSizeDelta(NoFontDelta)
 {
@@ -358,7 +360,7 @@
 }
 
 EditingStyle::EditingStyle(CSSPropertyID propertyID, const String& value)
-    : m_mutableStyle(0)
+    : m_mutableStyle(nullptr)
     , m_shouldUseFixedDefaultFontSize(false)
     , m_fontSizeDelta(NoFontDelta)
 {
@@ -447,9 +449,9 @@
     m_mutableStyle = propertiesToInclude == AllProperties && computedStyleAtPosition ? computedStyleAtPosition->copyProperties() : editingStyleFromComputedStyle(computedStyleAtPosition);
 
     if (propertiesToInclude == EditingPropertiesInEffect) {
-        if (RefPtr<CSSValue> value = backgroundColorInEffect(node))
+        if (RefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(node))
             m_mutableStyle->setProperty(CSSPropertyBackgroundColor, value->cssText());
-        if (RefPtr<CSSValue> value = computedStyleAtPosition->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect))
+        if (RefPtrWillBeRawPtr<CSSValue> value = computedStyleAtPosition->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect))
             m_mutableStyle->setProperty(CSSPropertyTextDecoration, value->cssText());
     }
 
@@ -501,7 +503,7 @@
     }
 
     // Get the adjustment amount out of the style.
-    RefPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitFontSizeDelta);
+    RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitFontSizeDelta);
     if (!value || !value->isPrimitiveValue())
         return;
 
@@ -526,13 +528,13 @@
     if (!m_mutableStyle)
         return false;
 
-    RefPtr<CSSValue> unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+    RefPtrWillBeRawPtr<CSSValue> unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
     if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
         return false;
 
     CSSValueID unicodeBidiValue = toCSSPrimitiveValue(unicodeBidi.get())->getValueID();
     if (unicodeBidiValue == CSSValueEmbed) {
-        RefPtr<CSSValue> direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
+        RefPtrWillBeRawPtr<CSSValue> direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
         if (!direction || !direction->isPrimitiveValue())
             return false;
 
@@ -639,7 +641,7 @@
     if (!m_mutableStyle)
         return;
 
-    RefPtr<CSSValue> textDecorationsInEffect = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
+    RefPtrWillBeRawPtr<CSSValue> textDecorationsInEffect = m_mutableStyle->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
     if (!textDecorationsInEffect)
         return;
 
@@ -879,8 +881,9 @@
 
 bool EditingStyle::elementIsStyledSpanOrHTMLEquivalent(const HTMLElement* element)
 {
+    ASSERT(element);
     bool elementIsSpanOrElementEquivalent = false;
-    if (element->hasTagName(HTMLNames::spanTag))
+    if (isHTMLSpanElement(*element))
         elementIsSpanOrElementEquivalent = true;
     else {
         const Vector<OwnPtr<HTMLElementEquivalent> >& HTMLElementEquivalents = htmlElementEquivalents();
@@ -936,8 +939,8 @@
     RefPtr<EditingStyle> editingStyleAtPosition = EditingStyle::create(position, EditingPropertiesInEffect);
     StylePropertySet* styleAtPosition = editingStyleAtPosition->m_mutableStyle.get();
 
-    RefPtr<CSSValue> unicodeBidi;
-    RefPtr<CSSValue> direction;
+    RefPtrWillBeRawPtr<CSSValue> unicodeBidi;
+    RefPtrWillBeRawPtr<CSSValue> direction;
     if (shouldPreserveWritingDirection == PreserveWritingDirection) {
         unicodeBidi = m_mutableStyle->getPropertyCSSValue(CSSPropertyUnicodeBidi);
         direction = m_mutableStyle->getPropertyCSSValue(CSSPropertyDirection);
@@ -1002,7 +1005,7 @@
 static PassRefPtr<MutableStylePropertySet> extractEditingProperties(const StylePropertySet* style, EditingStyle::PropertiesToInclude propertiesToInclude)
 {
     if (!style)
-        return 0;
+        return nullptr;
 
     switch (propertiesToInclude) {
     case EditingStyle::AllProperties:
@@ -1013,7 +1016,7 @@
     }
 
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 void EditingStyle::mergeInlineAndImplicitStyleOfElement(Element* element, CSSPropertyOverrideMode mode, PropertiesToInclude propertiesToInclude)
@@ -1096,7 +1099,7 @@
     unsigned propertyCount = style->propertyCount();
     for (unsigned i = 0; i < propertyCount; ++i) {
         StylePropertySet::PropertyReference property = style->propertyAt(i);
-        RefPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(property.id());
+        RefPtrWillBeRawPtr<CSSValue> value = m_mutableStyle->getPropertyCSSValue(property.id());
 
         // text decorations never override values
         if ((property.id() == textDecorationPropertyForEditing() || property.id() == CSSPropertyWebkitTextDecorationsInEffect) && property.value()->isValueList() && value) {
@@ -1104,7 +1107,7 @@
                 mergeTextDecorationValues(toCSSValueList(value.get()), toCSSValueList(property.value()));
                 continue;
             }
-            value = 0; // text-decoration: none is equivalent to not having the property
+            value = nullptr; // text-decoration: none is equivalent to not having the property
         }
 
         if (mode == OverrideValues || (mode == DoNotOverrideValues && !value))
@@ -1118,7 +1121,7 @@
     RefPtr<StyleRuleList> matchedRules = element->document().ensureStyleResolver().styleRulesForElement(element, rulesToInclude);
     if (matchedRules) {
         for (unsigned i = 0; i < matchedRules->m_list.size(); ++i)
-            style->mergeAndOverrideOnConflict(matchedRules->m_list[i]->properties());
+            style->mergeAndOverrideOnConflict(&matchedRules->m_list[i]->properties());
     }
     return style.release();
 }
@@ -1153,7 +1156,7 @@
             if (!value->isPrimitiveValue())
                 continue;
             if (toCSSPrimitiveValue(value)->isPercentage()) {
-                if (RefPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
+                if (RefPtrWillBeRawPtr<CSSValue> computedPropertyValue = computedStyleForElement->getPropertyCSSValue(property.id()))
                     fromComputedStyle->addParsedProperty(CSSProperty(property.id(), computedPropertyValue));
             }
         }
@@ -1222,7 +1225,7 @@
 
 int EditingStyle::legacyFontSize(Document* document) const
 {
-    RefPtr<CSSValue> cssValue = m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize);
+    RefPtrWillBeRawPtr<CSSValue> cssValue = m_mutableStyle->getPropertyCSSValue(CSSPropertyFontSize);
     if (!cssValue || !cssValue->isPrimitiveValue())
         return 0;
     return legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(cssValue.get()),
@@ -1232,7 +1235,7 @@
 PassRefPtr<EditingStyle> EditingStyle::styleAtSelectionStart(const VisibleSelection& selection, bool shouldUseBackgroundColorInEffect)
 {
     if (selection.isNone())
-        return 0;
+        return nullptr;
 
     Position position = adjustedSelectionStartForStyleComputation(selection);
 
@@ -1246,7 +1249,7 @@
 
     Element* element = position.element();
     if (!element)
-        return 0;
+        return nullptr;
 
     RefPtr<EditingStyle> style = EditingStyle::create(element, EditingStyle::AllProperties);
     style->mergeTypingStyle(&element->document());
@@ -1256,7 +1259,7 @@
     // and find the background color of the common ancestor.
     if (shouldUseBackgroundColorInEffect && (selection.isRange() || hasTransparentBackgroundColor(style->m_mutableStyle.get()))) {
         RefPtr<Range> range(selection.toNormalizedRange());
-        if (PassRefPtr<CSSValue> value = backgroundColorInEffect(range->commonAncestorContainer(IGNORE_EXCEPTION)))
+        if (PassRefPtrWillBeRawPtr<CSSValue> value = backgroundColorInEffect(range->commonAncestorContainer(IGNORE_EXCEPTION)))
             style->setProperty(CSSPropertyBackgroundColor, value->cssText());
     }
 
@@ -1287,7 +1290,7 @@
                 continue;
 
             RefPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(n);
-            RefPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+            RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
             if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
                 continue;
 
@@ -1316,7 +1319,7 @@
             continue;
 
         RefPtr<CSSComputedStyleDeclaration> style = CSSComputedStyleDeclaration::create(node);
-        RefPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
+        RefPtrWillBeRawPtr<CSSValue> unicodeBidi = style->getPropertyCSSValue(CSSPropertyUnicodeBidi);
         if (!unicodeBidi || !unicodeBidi->isPrimitiveValue())
             continue;
 
@@ -1328,7 +1331,7 @@
             return NaturalWritingDirection;
 
         ASSERT(unicodeBidiValue == CSSValueEmbed);
-        RefPtr<CSSValue> direction = style->getPropertyCSSValue(CSSPropertyDirection);
+        RefPtrWillBeRawPtr<CSSValue> direction = style->getPropertyCSSValue(CSSPropertyDirection);
         if (!direction || !direction->isPrimitiveValue())
             continue;
 
@@ -1351,8 +1354,8 @@
 
 static void reconcileTextDecorationProperties(MutableStylePropertySet* style)
 {
-    RefPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
-    RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
+    RefPtrWillBeRawPtr<CSSValue> textDecorationsInEffect = style->getPropertyCSSValue(CSSPropertyWebkitTextDecorationsInEffect);
+    RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
     // We shouldn't have both text-decoration and -webkit-text-decorations-in-effect because that wouldn't make sense.
     ASSERT(!textDecorationsInEffect || !textDecoration);
     if (textDecorationsInEffect) {
@@ -1405,7 +1408,6 @@
         style->setProperty(propertyID, newTextDecoration->cssText(), style->propertyIsImportant(propertyID));
     else {
         // text-decoration: none is redundant since it does not remove any text decorations.
-        ASSERT(!style->propertyIsImportant(propertyID));
         style->removeProperty(propertyID);
     }
 }
@@ -1427,7 +1429,7 @@
 
     // Assuming reconcileTextDecorationProperties has been called, there should not be -webkit-text-decorations-in-effect
     // Furthermore, text-decoration: none has been trimmed so that text-decoration property is always a CSSValueList.
-    RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
+    RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(textDecorationPropertyForEditing());
     if (textDecoration && textDecoration->isValueList()) {
         DEFINE_STATIC_REF(CSSPrimitiveValue, underline, (CSSPrimitiveValue::createIdentifier(CSSValueUnderline)));
         DEFINE_STATIC_REF(CSSPrimitiveValue, lineThrough, (CSSPrimitiveValue::createIdentifier(CSSValueLineThrough)));
@@ -1464,7 +1466,7 @@
     m_applyFontFace.replaceWithLiteral('\'', "");
     style->removeProperty(CSSPropertyFontFamily);
 
-    if (RefPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) {
+    if (RefPtrWillBeRawPtr<CSSValue> fontSize = style->getPropertyCSSValue(CSSPropertyFontSize)) {
         if (!fontSize->isPrimitiveValue())
             style->removeProperty(CSSPropertyFontSize); // Can't make sense of the number. Put no font size.
         else if (int legacyFontSize = legacyFontSizeFromCSSValue(document, toCSSPrimitiveValue(fontSize.get()),
@@ -1477,7 +1479,7 @@
 
 static void diffTextDecorations(MutableStylePropertySet* style, CSSPropertyID propertID, CSSValue* refTextDecoration)
 {
-    RefPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID);
+    RefPtrWillBeRawPtr<CSSValue> textDecoration = style->getPropertyCSSValue(propertID);
     if (!textDecoration || !textDecoration->isValueList() || !refTextDecoration || !refTextDecoration->isValueList())
         return;
 
@@ -1536,12 +1538,12 @@
 
     result->removeEquivalentProperties(baseStyle);
 
-    RefPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValueInternal(CSSPropertyWebkitTextDecorationsInEffect);
+    RefPtrWillBeRawPtr<CSSValue> baseTextDecorationsInEffect = baseStyle->getPropertyCSSValueInternal(CSSPropertyWebkitTextDecorationsInEffect);
     diffTextDecorations(result.get(), textDecorationPropertyForEditing(), baseTextDecorationsInEffect.get());
     diffTextDecorations(result.get(), CSSPropertyWebkitTextDecorationsInEffect, baseTextDecorationsInEffect.get());
 
-    if (RefPtr<CSSValue> baseFontWeight = baseStyle->getPropertyCSSValueInternal(CSSPropertyFontWeight)) {
-        if (RefPtr<CSSValue> fontWeight = result->getPropertyCSSValue(CSSPropertyFontWeight)) {
+    if (RefPtrWillBeRawPtr<CSSValue> baseFontWeight = baseStyle->getPropertyCSSValueInternal(CSSPropertyFontWeight)) {
+        if (RefPtrWillBeRawPtr<CSSValue> fontWeight = result->getPropertyCSSValue(CSSPropertyFontWeight)) {
             if (!fontWeightNeedsResolving(fontWeight.get()) && (fontWeightIsBold(fontWeight.get()) == fontWeightIsBold(baseFontWeight.get())))
                 result->removeProperty(CSSPropertyFontWeight);
         }
@@ -1564,7 +1566,7 @@
 {
     if (!style)
         return CSSValueInvalid;
-    RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
     if (!value || !value->isPrimitiveValue())
         return CSSValueInvalid;
     return toCSSPrimitiveValue(value.get())->getValueID();
@@ -1574,7 +1576,7 @@
 {
     if (!style)
         return CSSValueInvalid;
-    RefPtr<CSSValue> value = style->getPropertyCSSValueInternal(propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValueInternal(propertyID);
     if (!value || !value->isPrimitiveValue())
         return CSSValueInvalid;
     return toCSSPrimitiveValue(value.get())->getValueID();
@@ -1618,24 +1620,24 @@
 
 bool hasTransparentBackgroundColor(CSSStyleDeclaration* style)
 {
-    RefPtr<CSSValue> cssValue = style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor);
+    RefPtrWillBeRawPtr<CSSValue> cssValue = style->getPropertyCSSValueInternal(CSSPropertyBackgroundColor);
     return isTransparentColorValue(cssValue.get());
 }
 
 bool hasTransparentBackgroundColor(StylePropertySet* style)
 {
-    RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(CSSPropertyBackgroundColor);
+    RefPtrWillBeRawPtr<CSSValue> cssValue = style->getPropertyCSSValue(CSSPropertyBackgroundColor);
     return isTransparentColorValue(cssValue.get());
 }
 
-PassRefPtr<CSSValue> backgroundColorInEffect(Node* node)
+PassRefPtrWillBeRawPtr<CSSValue> backgroundColorInEffect(Node* node)
 {
     for (Node* ancestor = node; ancestor; ancestor = ancestor->parentNode()) {
         RefPtr<CSSComputedStyleDeclaration> ancestorStyle = CSSComputedStyleDeclaration::create(ancestor);
         if (!hasTransparentBackgroundColor(ancestorStyle.get()))
             return ancestorStyle->getPropertyCSSValue(CSSPropertyBackgroundColor);
     }
-    return 0;
+    return nullptr;
 }
 
 }
diff --git a/Source/core/editing/Editor.cpp b/Source/core/editing/Editor.cpp
index a8cee67..7227783 100644
--- a/Source/core/editing/Editor.cpp
+++ b/Source/core/editing/Editor.cpp
@@ -66,8 +66,8 @@
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/fetch/ImageResource.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLInputElement.h"
@@ -80,6 +80,7 @@
 #include "core/page/Page.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/RenderImage.h"
+#include "core/svg/SVGImageElement.h"
 #include "platform/KillRing.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/unicode/CharacterNames.h"
@@ -224,9 +225,7 @@
         return 0;
 
     Node* node = body->firstChild();
-    if (!node)
-        return 0;
-    if (!node->hasTagName(imgTag))
+    if (!isHTMLImageElement(node))
         return 0;
     return toHTMLImageElement(node);
 }
@@ -440,11 +439,11 @@
 
     // FIXME: This should probably be reconciled with HitTestResult::absoluteImageURL.
     AtomicString urlString;
-    if (node->hasTagName(imgTag) || node->hasTagName(inputTag))
+    if (isHTMLImageElement(*node) || isHTMLInputElement(*node))
         urlString = toElement(node)->getAttribute(srcAttr);
-    else if (node->hasTagName(SVGNames::imageTag))
+    else if (isSVGImageElement(*node))
         urlString = toElement(node)->getAttribute(XLinkNames::hrefAttr);
-    else if (node->hasTagName(embedTag) || node->hasTagName(objectTag))
+    else if (isHTMLEmbedElement(*node) || isHTMLObjectElement(*node))
         urlString = toElement(node)->imageSourceURL();
     KURL url = urlString.isEmpty() ? KURL() : node->document().completeURL(stripLeadingAndTrailingHTMLSpaces(urlString));
 
@@ -459,7 +458,7 @@
     if (!target)
         return true;
 
-    RefPtr<Clipboard> clipboard = Clipboard::create(
+    RefPtrWillBeRawPtr<Clipboard> clipboard = Clipboard::create(
         Clipboard::CopyAndPaste,
         policy,
         policy == ClipboardWritable
@@ -470,7 +469,7 @@
     target->dispatchEvent(evt, IGNORE_EXCEPTION);
     bool noDefaultProcessing = evt->defaultPrevented();
     if (noDefaultProcessing && policy == ClipboardWritable) {
-        RefPtr<DataObject> dataObject = clipboard->dataObject();
+        RefPtrWillBeRawPtr<DataObject> dataObject = clipboard->dataObject();
         Pasteboard::generalPasteboard()->writeDataObject(dataObject.release());
     }
 
@@ -722,7 +721,7 @@
     VisibleSelection newSelection(cmd->startingSelection());
     changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle);
 
-    m_lastEditCommand = 0;
+    m_lastEditCommand = nullptr;
     if (UndoStack* undoStack = this->undoStack())
         undoStack->registerRedoStep(cmd);
     respondToChangedContents(newSelection);
@@ -738,18 +737,18 @@
     VisibleSelection newSelection(cmd->endingSelection());
     changeSelectionAfterCommand(newSelection, FrameSelection::CloseTyping | FrameSelection::ClearTypingStyle);
 
-    m_lastEditCommand = 0;
+    m_lastEditCommand = nullptr;
     if (UndoStack* undoStack = this->undoStack())
         undoStack->registerUndoStep(cmd);
     respondToChangedContents(newSelection);
 }
 
-PassOwnPtr<Editor> Editor::create(Frame& frame)
+PassOwnPtr<Editor> Editor::create(LocalFrame& frame)
 {
     return adoptPtr(new Editor(frame));
 }
 
-Editor::Editor(Frame& frame)
+Editor::Editor(LocalFrame& frame)
     : m_frame(frame)
     , m_preventRevealSelection(0)
     , m_shouldStartNewKillRingSequence(false)
@@ -805,7 +804,7 @@
             TypingCommand::insertText(*document.get(), text, selection, options, triggeringEvent && triggeringEvent->isComposition() ? TypingCommand::TextCompositionConfirm : TypingCommand::TextCompositionNone);
 
             // Reveal the current selection
-            if (Frame* editedFrame = document->frame()) {
+            if (LocalFrame* editedFrame = document->frame()) {
                 if (Page* page = editedFrame->page())
                     page->focusController().focusedOrMainFrame()->selection().revealSelection(ScrollAlignment::alignCenterIfNeeded);
             }
@@ -1131,7 +1130,7 @@
 {
     RefPtr<Range> nextMatch = rangeOfString(target, previousMatch, options);
     if (!nextMatch)
-        return 0;
+        return nullptr;
 
     nextMatch->firstNode()->renderer()->scrollRectToVisible(nextMatch->boundingBox(),
         ScrollAlignment::alignCenterIfNeeded, ScrollAlignment::alignCenterIfNeeded);
@@ -1142,7 +1141,7 @@
 PassRefPtr<Range> Editor::rangeOfString(const String& target, Range* referenceRange, FindOptions options)
 {
     if (target.isEmpty())
-        return 0;
+        return nullptr;
 
     // Start from an edge of the reference range, if there's a reference range that's not in shadow content. Which edge
     // is used depends on whether we're searching forward or backward, and whether startInSelection is set.
@@ -1160,7 +1159,7 @@
     RefPtr<Node> shadowTreeRoot = referenceRange && referenceRange->startContainer() ? referenceRange->startContainer()->nonBoundaryShadowTreeRootNode() : 0;
     if (shadowTreeRoot) {
         if (forward)
-            searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
+            searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->countChildren());
         else
             searchRange->setStart(shadowTreeRoot.get(), 0);
     }
@@ -1178,7 +1177,7 @@
 
         if (shadowTreeRoot) {
             if (forward)
-                searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->childNodeCount());
+                searchRange->setEnd(shadowTreeRoot.get(), shadowTreeRoot->countChildren());
             else
                 searchRange->setStart(shadowTreeRoot.get(), 0);
         }
@@ -1207,7 +1206,7 @@
         // this should be a success case instead, so we'll just fall through in that case.
     }
 
-    return resultRange->collapsed(ASSERT_NO_EXCEPTION) ? 0 : resultRange.release();
+    return resultRange->collapsed(ASSERT_NO_EXCEPTION) ? nullptr : resultRange.release();
 }
 
 void Editor::setMarkedTextMatchesAreHighlighted(bool flag)
@@ -1216,7 +1215,7 @@
         return;
 
     m_areMarkedTextMatchesHighlighted = flag;
-    m_frame.document()->markers()->repaintMarkers(DocumentMarker::TextMatch);
+    m_frame.document()->markers().repaintMarkers(DocumentMarker::TextMatch);
 }
 
 void Editor::respondToChangedSelection(const VisibleSelection& oldSelection, FrameSelection::SetSelectionOptions options)
diff --git a/Source/core/editing/Editor.h b/Source/core/editing/Editor.h
index 1ff3e22..28d45d5 100644
--- a/Source/core/editing/Editor.h
+++ b/Source/core/editing/Editor.h
@@ -46,7 +46,7 @@
 class EditCommandComposition;
 class EditorClient;
 class EditorInternalCommand;
-class Frame;
+class LocalFrame;
 class HTMLElement;
 class HitTestResult;
 class KillRing;
@@ -65,12 +65,12 @@
 class Editor {
     WTF_MAKE_NONCOPYABLE(Editor);
 public:
-    static PassOwnPtr<Editor> create(Frame&);
+    static PassOwnPtr<Editor> create(LocalFrame&);
     ~Editor();
 
     EditorClient& client() const;
 
-    Frame& frame() const { return m_frame; }
+    LocalFrame& frame() const { return m_frame; }
 
     CompositeEditCommand* lastEditCommand() { return m_lastEditCommand.get(); }
 
@@ -135,7 +135,7 @@
     class Command {
     public:
         Command();
-        Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<Frame>);
+        Command(const EditorInternalCommand*, EditorCommandSource, PassRefPtr<LocalFrame>);
 
         bool execute(const String& parameter = String(), Event* triggeringEvent = 0) const;
         bool execute(Event* triggeringEvent) const;
@@ -151,7 +151,7 @@
     private:
         const EditorInternalCommand* m_command;
         EditorCommandSource m_source;
-        RefPtr<Frame> m_frame;
+        RefPtr<LocalFrame> m_frame;
     };
     Command command(const String& commandName); // Command source is CommandFromMenuOrKeyBinding.
     Command command(const String& commandName, EditorCommandSource);
@@ -232,7 +232,7 @@
     friend class RevealSelectionScope;
 
 private:
-    Frame& m_frame;
+    LocalFrame& m_frame;
     RefPtr<CompositeEditCommand> m_lastEditCommand;
     int m_preventRevealSelection;
     bool m_shouldStartNewKillRingSequence;
@@ -243,7 +243,7 @@
     EditorParagraphSeparator m_defaultParagraphSeparator;
     bool m_overwriteModeEnabled;
 
-    explicit Editor(Frame&);
+    explicit Editor(LocalFrame&);
 
     bool canDeleteRange(Range*) const;
 
diff --git a/Source/core/editing/EditorCommand.cpp b/Source/core/editing/EditorCommand.cpp
index e1b207b..ba4a113 100644
--- a/Source/core/editing/EditorCommand.cpp
+++ b/Source/core/editing/EditorCommand.cpp
@@ -47,9 +47,9 @@
 #include "core/editing/UnlinkCommand.h"
 #include "core/editing/markup.h"
 #include "core/events/Event.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFontElement.h"
 #include "core/html/HTMLHRElement.h"
@@ -70,11 +70,11 @@
 class EditorInternalCommand {
 public:
     int idForUserMetrics;
-    bool (*execute)(Frame&, Event*, EditorCommandSource, const String&);
-    bool (*isSupportedFromDOM)(Frame*);
-    bool (*isEnabled)(Frame&, Event*, EditorCommandSource);
-    TriState (*state)(Frame&, Event*);
-    String (*value)(Frame&, Event*);
+    bool (*execute)(LocalFrame&, Event*, EditorCommandSource, const String&);
+    bool (*isSupportedFromDOM)(LocalFrame*);
+    bool (*isEnabled)(LocalFrame&, Event*, EditorCommandSource);
+    TriState (*state)(LocalFrame&, Event*);
+    String (*value)(LocalFrame&, Event*);
     bool isTextInsertion;
     bool allowExecutionWhenDisabled;
 };
@@ -90,7 +90,7 @@
 // Related to Editor::selectionForCommand.
 // Certain operations continue to use the target control's selection even if the event handler
 // already moved the selection outside of the text control.
-static Frame* targetFrame(Frame& frame, Event* event)
+static LocalFrame* targetFrame(LocalFrame& frame, Event* event)
 {
     if (!event)
         return &frame;
@@ -100,7 +100,7 @@
     return node->document().frame();
 }
 
-static bool applyCommandToFrame(Frame& frame, EditorCommandSource source, EditAction action, StylePropertySet* style)
+static bool applyCommandToFrame(LocalFrame& frame, EditorCommandSource source, EditAction action, StylePropertySet* style)
 {
     // FIXME: We don't call shouldApplyStyle when the source is DOM; is there a good reason for that?
     switch (source) {
@@ -116,14 +116,14 @@
     return false;
 }
 
-static bool executeApplyStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
+static bool executeApplyStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
 {
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
     style->setProperty(propertyID, propertyValue);
     return applyCommandToFrame(frame, source, action, style.get());
 }
 
-static bool executeApplyStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValueID propertyValue)
+static bool executeApplyStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValueID propertyValue)
 {
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
     style->setProperty(propertyID, propertyValue);
@@ -133,13 +133,13 @@
 // FIXME: executeToggleStyleInList does not handle complicated cases such as <b><u>hello</u>world</b> properly.
 //        This function must use Editor::selectionHasStyle to determine the current style but we cannot fix this
 //        until https://bugs.webkit.org/show_bug.cgi?id=27818 is resolved.
-static bool executeToggleStyleInList(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValue* value)
+static bool executeToggleStyleInList(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, CSSValue* value)
 {
     RefPtr<EditingStyle> selectionStyle = EditingStyle::styleAtSelectionStart(frame.selection().selection());
     if (!selectionStyle || !selectionStyle->style())
         return false;
 
-    RefPtr<CSSValue> selectedCSSValue = selectionStyle->style()->getPropertyCSSValue(propertyID);
+    RefPtrWillBeRawPtr<CSSValue> selectedCSSValue = selectionStyle->style()->getPropertyCSSValue(propertyID);
     String newStyle("none");
     if (selectedCSSValue->isValueList()) {
         RefPtrWillBeRawPtr<CSSValueList> selectedCSSValueList = toCSSValueList(selectedCSSValue.get());
@@ -157,7 +157,7 @@
     return applyCommandToFrame(frame, source, action, newMutableStyle.get());
 }
 
-static bool executeToggleStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const char* offValue, const char* onValue)
+static bool executeToggleStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const char* offValue, const char* onValue)
 {
     // Style is considered present when
     // Mac: present at the beginning of selection
@@ -173,7 +173,7 @@
     return applyCommandToFrame(frame, source, action, style->style());
 }
 
-static bool executeApplyParagraphStyle(Frame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
+static bool executeApplyParagraphStyle(LocalFrame& frame, EditorCommandSource source, EditAction action, CSSPropertyID propertyID, const String& propertyValue)
 {
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
     style->setProperty(propertyID, propertyValue);
@@ -191,14 +191,14 @@
     return false;
 }
 
-static bool executeInsertFragment(Frame& frame, PassRefPtr<DocumentFragment> fragment)
+static bool executeInsertFragment(LocalFrame& frame, PassRefPtr<DocumentFragment> fragment)
 {
     ASSERT(frame.document());
     ReplaceSelectionCommand::create(*frame.document(), fragment, ReplaceSelectionCommand::PreventNesting, EditActionUnspecified)->apply();
     return true;
 }
 
-static bool executeInsertNode(Frame& frame, PassRefPtr<Node> content)
+static bool executeInsertNode(LocalFrame& frame, PassRefPtr<Node> content)
 {
     ASSERT(frame.document());
     RefPtr<DocumentFragment> fragment = DocumentFragment::create(*frame.document());
@@ -209,7 +209,7 @@
     return executeInsertFragment(frame, fragment.release());
 }
 
-static bool expandSelectionToGranularity(Frame& frame, TextGranularity granularity)
+static bool expandSelectionToGranularity(LocalFrame& frame, TextGranularity granularity)
 {
     VisibleSelection selection = frame.selection().selection();
     selection.expandUsingGranularity(granularity);
@@ -220,25 +220,25 @@
         return false;
     RefPtr<Range> oldRange = frame.selection().selection().toNormalizedRange();
     EAffinity affinity = frame.selection().affinity();
-    frame.selection().setSelectedRange(newRange.get(), affinity, true);
+    frame.selection().setSelectedRange(newRange.get(), affinity, FrameSelection::CloseTyping);
     return true;
 }
 
-static TriState stateStyle(Frame& frame, CSSPropertyID propertyID, const char* desiredValue)
+static TriState stateStyle(LocalFrame& frame, CSSPropertyID propertyID, const char* desiredValue)
 {
     if (frame.editor().behavior().shouldToggleStyleBasedOnStartOfSelection())
         return frame.editor().selectionStartHasStyle(propertyID, desiredValue) ? TrueTriState : FalseTriState;
     return frame.editor().selectionHasStyle(propertyID, desiredValue);
 }
 
-static String valueStyle(Frame& frame, CSSPropertyID propertyID)
+static String valueStyle(LocalFrame& frame, CSSPropertyID propertyID)
 {
     // FIXME: Rather than retrieving the style at the start of the current selection,
     // we should retrieve the style present throughout the selection for non-Mac platforms.
     return frame.editor().selectionStartCSSPropertyValue(propertyID);
 }
 
-static TriState stateTextWritingDirection(Frame& frame, WritingDirection direction)
+static TriState stateTextWritingDirection(LocalFrame& frame, WritingDirection direction)
 {
     bool hasNestedOrMultipleEmbeddings;
     WritingDirection selectionDirection = EditingStyle::textDirectionForSelection(frame.selection().selection(),
@@ -247,7 +247,7 @@
     return (selectionDirection == direction && !hasNestedOrMultipleEmbeddings) ? TrueTriState : FalseTriState;
 }
 
-static unsigned verticalScrollDistance(Frame& frame)
+static unsigned verticalScrollDistance(LocalFrame& frame)
 {
     Element* focusedElement = frame.document()->focusedElement();
     if (!focusedElement)
@@ -274,18 +274,18 @@
 
 // Execute command functions
 
-static bool executeBackColor(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeBackColor(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
 {
     return executeApplyStyle(frame, source, EditActionSetBackgroundColor, CSSPropertyBackgroundColor, value);
 }
 
-static bool executeCopy(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeCopy(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().copy();
     return true;
 }
 
-static bool executeCreateLink(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeCreateLink(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     // FIXME: If userInterface is true, we should display a dialog box to let the user enter a URL.
     if (value.isEmpty())
@@ -295,13 +295,13 @@
     return true;
 }
 
-static bool executeCut(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeCut(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().cut();
     return true;
 }
 
-static bool executeDefaultParagraphSeparator(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeDefaultParagraphSeparator(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     if (equalIgnoringCase(value, "div"))
         frame.editor().setDefaultParagraphSeparator(EditorParagraphSeparatorIsDiv);
@@ -311,7 +311,7 @@
     return true;
 }
 
-static bool executeDelete(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeDelete(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     switch (source) {
     case CommandFromMenuOrKeyBinding: {
@@ -331,38 +331,38 @@
     return false;
 }
 
-static bool executeDeleteBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
     return true;
 }
 
-static bool executeDeleteBackwardByDecomposingPreviousCharacter(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteBackwardByDecomposingPreviousCharacter(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     WTF_LOG_ERROR("DeleteBackwardByDecomposingPreviousCharacter is not implemented, doing DeleteBackward instead");
     frame.editor().deleteWithDirection(DirectionBackward, CharacterGranularity, false, true);
     return true;
 }
 
-static bool executeDeleteForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().deleteWithDirection(DirectionForward, CharacterGranularity, false, true);
     return true;
 }
 
-static bool executeDeleteToBeginningOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToBeginningOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().deleteWithDirection(DirectionBackward, LineBoundary, true, false);
     return true;
 }
 
-static bool executeDeleteToBeginningOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToBeginningOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().deleteWithDirection(DirectionBackward, ParagraphBoundary, true, false);
     return true;
 }
 
-static bool executeDeleteToEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     // Despite its name, this command should delete the newline at the end of
     // a paragraph if you are at the end of a paragraph (like DeleteToEndOfParagraph).
@@ -370,7 +370,7 @@
     return true;
 }
 
-static bool executeDeleteToEndOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToEndOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     // Despite its name, this command should delete the newline at the end of
     // a paragraph if you are at the end of a paragraph.
@@ -378,11 +378,11 @@
     return true;
 }
 
-static bool executeDeleteToMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteToMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     RefPtr<Range> mark = frame.editor().mark().toNormalizedRange();
     if (mark) {
-        bool selected = frame.selection().setSelectedRange(unionDOMRanges(mark.get(), frame.editor().selectedRange().get()).get(), DOWNSTREAM, true);
+        bool selected = frame.selection().setSelectedRange(unionDOMRanges(mark.get(), frame.editor().selectedRange().get()).get(), DOWNSTREAM, FrameSelection::CloseTyping);
         ASSERT(selected);
         if (!selected)
             return false;
@@ -392,29 +392,29 @@
     return true;
 }
 
-static bool executeDeleteWordBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteWordBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().deleteWithDirection(DirectionBackward, WordGranularity, true, false);
     return true;
 }
 
-static bool executeDeleteWordForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeDeleteWordForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().deleteWithDirection(DirectionForward, WordGranularity, true, false);
     return true;
 }
 
-static bool executeFindString(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeFindString(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     return frame.editor().findString(value, true, false, true, false);
 }
 
-static bool executeFontName(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeFontName(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
 {
     return executeApplyStyle(frame, source, EditActionSetFont, CSSPropertyFontFamily, value);
 }
 
-static bool executeFontSize(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeFontSize(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
 {
     CSSValueID size;
     if (!HTMLFontElement::cssValueFromFontSizeNumber(value, size))
@@ -422,17 +422,17 @@
     return executeApplyStyle(frame, source, EditActionChangeAttributes, CSSPropertyFontSize, size);
 }
 
-static bool executeFontSizeDelta(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeFontSizeDelta(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
 {
     return executeApplyStyle(frame, source, EditActionChangeAttributes, CSSPropertyWebkitFontSizeDelta, value);
 }
 
-static bool executeForeColor(Frame& frame, Event*, EditorCommandSource source, const String& value)
+static bool executeForeColor(LocalFrame& frame, Event*, EditorCommandSource source, const String& value)
 {
     return executeApplyStyle(frame, source, EditActionSetColor, CSSPropertyColor, value);
 }
 
-static bool executeFormatBlock(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeFormatBlock(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     String tagName = value.lower();
     if (tagName[0] == '<' && tagName[tagName.length() - 1] == '>')
@@ -449,7 +449,7 @@
     return command->didApply();
 }
 
-static bool executeForwardDelete(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeForwardDelete(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     switch (source) {
     case CommandFromMenuOrKeyBinding:
@@ -468,25 +468,25 @@
     return false;
 }
 
-static bool executeIgnoreSpelling(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeIgnoreSpelling(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.spellChecker().ignoreSpelling();
     return true;
 }
 
-static bool executeIndent(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeIndent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
     IndentOutdentCommand::create(*frame.document(), IndentOutdentCommand::Indent)->apply();
     return true;
 }
 
-static bool executeInsertBacktab(Frame& frame, Event* event, EditorCommandSource, const String&)
+static bool executeInsertBacktab(LocalFrame& frame, Event* event, EditorCommandSource, const String&)
 {
     return targetFrame(frame, event)->eventHandler().handleTextInputEvent("\t", event, TextEventInputBackTab);
 }
 
-static bool executeInsertHorizontalRule(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertHorizontalRule(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     ASSERT(frame.document());
     RefPtr<HTMLHRElement> rule = HTMLHRElement::create(*frame.document());
@@ -495,13 +495,13 @@
     return executeInsertNode(frame, rule.release());
 }
 
-static bool executeInsertHTML(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertHTML(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     ASSERT(frame.document());
     return executeInsertFragment(frame, createFragmentFromMarkup(*frame.document(), value, ""));
 }
 
-static bool executeInsertImage(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertImage(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     // FIXME: If userInterface is true, we should display a dialog box and let the user choose a local image.
     ASSERT(frame.document());
@@ -510,7 +510,7 @@
     return executeInsertNode(frame, image.release());
 }
 
-static bool executeInsertLineBreak(Frame& frame, Event* event, EditorCommandSource source, const String&)
+static bool executeInsertLineBreak(LocalFrame& frame, Event* event, EditorCommandSource source, const String&)
 {
     switch (source) {
     case CommandFromMenuOrKeyBinding:
@@ -528,73 +528,73 @@
     return false;
 }
 
-static bool executeInsertNewline(Frame& frame, Event* event, EditorCommandSource, const String&)
+static bool executeInsertNewline(LocalFrame& frame, Event* event, EditorCommandSource, const String&)
 {
-    Frame* targetFrame = WebCore::targetFrame(frame, event);
+    LocalFrame* targetFrame = WebCore::targetFrame(frame, event);
     return targetFrame->eventHandler().handleTextInputEvent("\n", event, targetFrame->editor().canEditRichly() ? TextEventInputKeyboard : TextEventInputLineBreak);
 }
 
-static bool executeInsertNewlineInQuotedContent(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertNewlineInQuotedContent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
     TypingCommand::insertParagraphSeparatorInQuotedContent(*frame.document());
     return true;
 }
 
-static bool executeInsertOrderedList(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertOrderedList(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
     InsertListCommand::create(*frame.document(), InsertListCommand::OrderedList)->apply();
     return true;
 }
 
-static bool executeInsertParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
     TypingCommand::insertParagraphSeparator(*frame.document(), 0);
     return true;
 }
 
-static bool executeInsertTab(Frame& frame, Event* event, EditorCommandSource, const String&)
+static bool executeInsertTab(LocalFrame& frame, Event* event, EditorCommandSource, const String&)
 {
     return targetFrame(frame, event)->eventHandler().handleTextInputEvent("\t", event);
 }
 
-static bool executeInsertText(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeInsertText(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     ASSERT(frame.document());
     TypingCommand::insertText(*frame.document(), value, 0);
     return true;
 }
 
-static bool executeInsertUnorderedList(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeInsertUnorderedList(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
     InsertListCommand::create(*frame.document(), InsertListCommand::UnorderedList)->apply();
     return true;
 }
 
-static bool executeJustifyCenter(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyCenter(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeApplyParagraphStyle(frame, source, EditActionCenter, CSSPropertyTextAlign, "center");
 }
 
-static bool executeJustifyFull(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyFull(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeApplyParagraphStyle(frame, source, EditActionJustify, CSSPropertyTextAlign, "justify");
 }
 
-static bool executeJustifyLeft(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyLeft(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeApplyParagraphStyle(frame, source, EditActionAlignLeft, CSSPropertyTextAlign, "left");
 }
 
-static bool executeJustifyRight(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeJustifyRight(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeApplyParagraphStyle(frame, source, EditActionAlignRight, CSSPropertyTextAlign, "right");
 }
 
-static bool executeMakeTextWritingDirectionLeftToRight(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMakeTextWritingDirectionLeftToRight(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
     style->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
@@ -603,7 +603,7 @@
     return true;
 }
 
-static bool executeMakeTextWritingDirectionNatural(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMakeTextWritingDirectionNatural(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
     style->setProperty(CSSPropertyUnicodeBidi, CSSValueNormal);
@@ -611,7 +611,7 @@
     return true;
 }
 
-static bool executeMakeTextWritingDirectionRightToLeft(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMakeTextWritingDirectionRightToLeft(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create();
     style->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
@@ -620,53 +620,53 @@
     return true;
 }
 
-static bool executeMoveBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, CharacterGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveBackwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveBackwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, CharacterGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveDown(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveDown(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, LineGranularity, UserTriggered);
 }
 
-static bool executeMoveDownAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveDownAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, LineGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveForwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveForwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, CharacterGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveLeft(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveLeft(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, CharacterGranularity, UserTriggered);
 }
 
-static bool executeMoveLeftAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveLeftAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, CharacterGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMovePageDown(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageDown(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     unsigned distance = verticalScrollDistance(frame);
     if (!distance)
@@ -675,7 +675,7 @@
         UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
 }
 
-static bool executeMovePageDownAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageDownAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     unsigned distance = verticalScrollDistance(frame);
     if (!distance)
@@ -684,7 +684,7 @@
         UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
 }
 
-static bool executeMovePageUp(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     unsigned distance = verticalScrollDistance(frame);
     if (!distance)
@@ -693,7 +693,7 @@
         UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
 }
 
-static bool executeMovePageUpAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMovePageUpAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     unsigned distance = verticalScrollDistance(frame);
     if (!distance)
@@ -702,240 +702,240 @@
         UserTriggered, FrameSelection::AlignCursorOnScrollAlways);
 }
 
-static bool executeMoveRight(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveRight(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, CharacterGranularity, UserTriggered);
 }
 
-static bool executeMoveRightAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveRightAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, CharacterGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, DocumentBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfDocumentAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfDocumentAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, DocumentBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, ParagraphBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfParagraphAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfParagraphAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, ParagraphBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfSentence(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfSentence(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, SentenceBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToBeginningOfSentenceAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToBeginningOfSentenceAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, SentenceBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, DocumentBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfDocumentAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfDocumentAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, DocumentBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfSentence(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfSentence(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, SentenceBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfSentenceAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfSentenceAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, SentenceBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, ParagraphBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToEndOfParagraphAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToEndOfParagraphAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, ParagraphBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveParagraphBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, ParagraphGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveParagraphBackwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphBackwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, ParagraphGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveParagraphForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, ParagraphGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveParagraphForwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveParagraphForwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, ParagraphGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveUp(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, LineGranularity, UserTriggered);
 }
 
-static bool executeMoveUpAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveUpAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, LineGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionBackward, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordBackwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordBackwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionBackward, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordForwardAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordForwardAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionForward, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordLeft(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordLeft(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordLeftAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordLeftAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordRight(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordRight(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveWordRightAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveWordRightAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, WordGranularity, UserTriggered);
     return true;
 }
 
-static bool executeMoveToLeftEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToLeftEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionLeft, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToLeftEndOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToLeftEndOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionLeft, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToRightEndOfLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToRightEndOfLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationMove, DirectionRight, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeMoveToRightEndOfLineAndModifySelection(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeMoveToRightEndOfLineAndModifySelection(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().modify(FrameSelection::AlterationExtend, DirectionRight, LineBoundary, UserTriggered);
     return true;
 }
 
-static bool executeOutdent(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeOutdent(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
     IndentOutdentCommand::create(*frame.document(), IndentOutdentCommand::Outdent)->apply();
     return true;
 }
 
-static bool executeToggleOverwrite(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeToggleOverwrite(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().toggleOverwriteModeEnabled();
     return true;
 }
 
-static bool executePaste(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executePaste(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().paste();
     return true;
 }
 
-static bool executePasteGlobalSelection(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executePasteGlobalSelection(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     if (!frame.editor().behavior().supportsGlobalSelection())
         return false;
@@ -948,13 +948,13 @@
     return true;
 }
 
-static bool executePasteAndMatchStyle(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executePasteAndMatchStyle(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().pasteAsPlainText();
     return true;
 }
 
-static bool executePrint(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executePrint(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     FrameHost* host = frame.host();
     if (!host)
@@ -963,119 +963,119 @@
     return true;
 }
 
-static bool executeRedo(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeRedo(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().redo();
     return true;
 }
 
-static bool executeRemoveFormat(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeRemoveFormat(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().removeFormattingAndStyle();
     return true;
 }
 
-static bool executeScrollPageBackward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollPageBackward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.eventHandler().bubblingScroll(ScrollBlockDirectionBackward, ScrollByPage);
 }
 
-static bool executeScrollPageForward(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollPageForward(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.eventHandler().bubblingScroll(ScrollBlockDirectionForward, ScrollByPage);
 }
 
-static bool executeScrollLineUp(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollLineUp(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.eventHandler().bubblingScroll(ScrollUp, ScrollByLine);
 }
 
-static bool executeScrollLineDown(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollLineDown(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.eventHandler().bubblingScroll(ScrollDown, ScrollByLine);
 }
 
-static bool executeScrollToBeginningOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollToBeginningOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.eventHandler().bubblingScroll(ScrollBlockDirectionBackward, ScrollByDocument);
 }
 
-static bool executeScrollToEndOfDocument(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeScrollToEndOfDocument(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return frame.eventHandler().bubblingScroll(ScrollBlockDirectionForward, ScrollByDocument);
 }
 
-static bool executeSelectAll(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectAll(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().selectAll();
     return true;
 }
 
-static bool executeSelectLine(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectLine(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return expandSelectionToGranularity(frame, LineGranularity);
 }
 
-static bool executeSelectParagraph(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectParagraph(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return expandSelectionToGranularity(frame, ParagraphGranularity);
 }
 
-static bool executeSelectSentence(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectSentence(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return expandSelectionToGranularity(frame, SentenceGranularity);
 }
 
-static bool executeSelectToMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectToMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     RefPtr<Range> mark = frame.editor().mark().toNormalizedRange();
     RefPtr<Range> selection = frame.editor().selectedRange();
     if (!mark || !selection)
         return false;
-    frame.selection().setSelectedRange(unionDOMRanges(mark.get(), selection.get()).get(), DOWNSTREAM, true);
+    frame.selection().setSelectedRange(unionDOMRanges(mark.get(), selection.get()).get(), DOWNSTREAM, FrameSelection::CloseTyping);
     return true;
 }
 
-static bool executeSelectWord(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSelectWord(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     return expandSelectionToGranularity(frame, WordGranularity);
 }
 
-static bool executeSetMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSetMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().setMark(frame.selection().selection());
     return true;
 }
 
-static bool executeStrikethrough(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeStrikethrough(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     RefPtrWillBeRawPtr<CSSPrimitiveValue> lineThrough = CSSPrimitiveValue::createIdentifier(CSSValueLineThrough);
     return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPropertyWebkitTextDecorationsInEffect, lineThrough.get());
 }
 
-static bool executeStyleWithCSS(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeStyleWithCSS(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     frame.editor().setShouldStyleWithCSS(!equalIgnoringCase(value, "false"));
     return true;
 }
 
-static bool executeUseCSS(Frame& frame, Event*, EditorCommandSource, const String& value)
+static bool executeUseCSS(LocalFrame& frame, Event*, EditorCommandSource, const String& value)
 {
     frame.editor().setShouldStyleWithCSS(equalIgnoringCase(value, "false"));
     return true;
 }
 
-static bool executeSubscript(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeSubscript(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeToggleStyle(frame, source, EditActionSubscript, CSSPropertyVerticalAlign, "baseline", "sub");
 }
 
-static bool executeSuperscript(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeSuperscript(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeToggleStyle(frame, source, EditActionSuperscript, CSSPropertyVerticalAlign, "baseline", "super");
 }
 
-static bool executeSwapWithMark(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeSwapWithMark(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     const VisibleSelection& mark = frame.editor().mark();
     const VisibleSelection& selection = frame.selection().selection();
@@ -1086,60 +1086,60 @@
     return true;
 }
 
-static bool executeToggleBold(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeToggleBold(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeToggleStyle(frame, source, EditActionBold, CSSPropertyFontWeight, "normal", "bold");
 }
 
-static bool executeToggleItalic(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeToggleItalic(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeToggleStyle(frame, source, EditActionItalics, CSSPropertyFontStyle, "normal", "italic");
 }
 
-static bool executeTranspose(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeTranspose(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().transpose();
     return true;
 }
 
-static bool executeUnderline(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeUnderline(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     RefPtrWillBeRawPtr<CSSPrimitiveValue> underline = CSSPrimitiveValue::createIdentifier(CSSValueUnderline);
     return executeToggleStyleInList(frame, source, EditActionUnderline, CSSPropertyWebkitTextDecorationsInEffect, underline.get());
 }
 
-static bool executeUndo(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeUndo(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().undo();
     return true;
 }
 
-static bool executeUnlink(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeUnlink(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     ASSERT(frame.document());
     UnlinkCommand::create(*frame.document())->apply();
     return true;
 }
 
-static bool executeUnscript(Frame& frame, Event*, EditorCommandSource source, const String&)
+static bool executeUnscript(LocalFrame& frame, Event*, EditorCommandSource source, const String&)
 {
     return executeApplyStyle(frame, source, EditActionUnscript, CSSPropertyVerticalAlign, "baseline");
 }
 
-static bool executeUnselect(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeUnselect(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.selection().clear();
     return true;
 }
 
-static bool executeYank(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeYank(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().insertTextWithoutSendingTextEvent(frame.editor().killRing().yank(), false, 0);
     frame.editor().killRing().setToYankedState();
     return true;
 }
 
-static bool executeYankAndSelect(Frame& frame, Event*, EditorCommandSource, const String&)
+static bool executeYankAndSelect(LocalFrame& frame, Event*, EditorCommandSource, const String&)
 {
     frame.editor().insertTextWithoutSendingTextEvent(frame.editor().killRing().yank(), true, 0);
     frame.editor().killRing().setToYankedState();
@@ -1148,17 +1148,17 @@
 
 // Supported functions
 
-static bool supported(Frame*)
+static bool supported(LocalFrame*)
 {
     return true;
 }
 
-static bool supportedFromMenuOrKeyBinding(Frame*)
+static bool supportedFromMenuOrKeyBinding(LocalFrame*)
 {
     return false;
 }
 
-static bool supportedCopyCut(Frame* frame)
+static bool supportedCopyCut(LocalFrame* frame)
 {
     if (!frame)
         return false;
@@ -1168,7 +1168,7 @@
     return frame->editor().client().canCopyCut(frame, defaultValue);
 }
 
-static bool supportedPaste(Frame* frame)
+static bool supportedPaste(LocalFrame* frame)
 {
     if (!frame)
         return false;
@@ -1180,60 +1180,60 @@
 
 // Enabled functions
 
-static bool enabled(Frame&, Event*, EditorCommandSource)
+static bool enabled(LocalFrame&, Event*, EditorCommandSource)
 {
     return true;
 }
 
-static bool enabledVisibleSelection(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledVisibleSelection(LocalFrame& frame, Event* event, EditorCommandSource)
 {
     // The term "visible" here includes a caret in editable text or a range in any text.
     const VisibleSelection& selection = frame.editor().selectionForCommand(event);
     return (selection.isCaret() && selection.isContentEditable()) || selection.isRange();
 }
 
-static bool caretBrowsingEnabled(Frame& frame)
+static bool caretBrowsingEnabled(LocalFrame& frame)
 {
     return frame.settings() && frame.settings()->caretBrowsingEnabled();
 }
 
 static EditorCommandSource dummyEditorCommandSource = static_cast<EditorCommandSource>(0);
 
-static bool enabledVisibleSelectionOrCaretBrowsing(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledVisibleSelectionOrCaretBrowsing(LocalFrame& frame, Event* event, EditorCommandSource)
 {
     // The EditorCommandSource parameter is unused in enabledVisibleSelection, so just pass a dummy variable
     return caretBrowsingEnabled(frame) || enabledVisibleSelection(frame, event, dummyEditorCommandSource);
 }
 
-static bool enabledVisibleSelectionAndMark(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledVisibleSelectionAndMark(LocalFrame& frame, Event* event, EditorCommandSource)
 {
     const VisibleSelection& selection = frame.editor().selectionForCommand(event);
     return ((selection.isCaret() && selection.isContentEditable()) || selection.isRange())
         && frame.editor().mark().isCaretOrRange();
 }
 
-static bool enableCaretInEditableText(Frame& frame, Event* event, EditorCommandSource)
+static bool enableCaretInEditableText(LocalFrame& frame, Event* event, EditorCommandSource)
 {
     const VisibleSelection& selection = frame.editor().selectionForCommand(event);
     return selection.isCaret() && selection.isContentEditable();
 }
 
-static bool enabledCopy(Frame& frame, Event*, EditorCommandSource)
+static bool enabledCopy(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.editor().canDHTMLCopy() || frame.editor().canCopy();
 }
 
-static bool enabledCut(Frame& frame, Event*, EditorCommandSource)
+static bool enabledCut(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.editor().canDHTMLCut() || frame.editor().canCut();
 }
 
-static bool enabledInEditableText(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledInEditableText(LocalFrame& frame, Event* event, EditorCommandSource)
 {
     return frame.editor().selectionForCommand(event).rootEditableElement();
 }
 
-static bool enabledDelete(Frame& frame, Event* event, EditorCommandSource source)
+static bool enabledDelete(LocalFrame& frame, Event* event, EditorCommandSource source)
 {
     switch (source) {
     case CommandFromMenuOrKeyBinding:
@@ -1248,142 +1248,142 @@
     return false;
 }
 
-static bool enabledInEditableTextOrCaretBrowsing(Frame& frame, Event* event, EditorCommandSource)
+static bool enabledInEditableTextOrCaretBrowsing(LocalFrame& frame, Event* event, EditorCommandSource)
 {
     // The EditorCommandSource parameter is unused in enabledInEditableText, so just pass a dummy variable
     return caretBrowsingEnabled(frame) || enabledInEditableText(frame, event, dummyEditorCommandSource);
 }
 
-static bool enabledInRichlyEditableText(Frame& frame, Event*, EditorCommandSource)
+static bool enabledInRichlyEditableText(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.selection().isCaretOrRange() && frame.selection().isContentRichlyEditable() && frame.selection().rootEditableElement();
 }
 
-static bool enabledPaste(Frame& frame, Event*, EditorCommandSource)
+static bool enabledPaste(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.editor().canPaste();
 }
 
-static bool enabledRangeInEditableText(Frame& frame, Event*, EditorCommandSource)
+static bool enabledRangeInEditableText(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.selection().isRange() && frame.selection().isContentEditable();
 }
 
-static bool enabledRangeInRichlyEditableText(Frame& frame, Event*, EditorCommandSource)
+static bool enabledRangeInRichlyEditableText(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.selection().isRange() && frame.selection().isContentRichlyEditable();
 }
 
-static bool enabledRedo(Frame& frame, Event*, EditorCommandSource)
+static bool enabledRedo(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.editor().canRedo();
 }
 
-static bool enabledUndo(Frame& frame, Event*, EditorCommandSource)
+static bool enabledUndo(LocalFrame& frame, Event*, EditorCommandSource)
 {
     return frame.editor().canUndo();
 }
 
 // State functions
 
-static TriState stateNone(Frame&, Event*)
+static TriState stateNone(LocalFrame&, Event*)
 {
     return FalseTriState;
 }
 
-static TriState stateBold(Frame& frame, Event*)
+static TriState stateBold(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyFontWeight, "bold");
 }
 
-static TriState stateItalic(Frame& frame, Event*)
+static TriState stateItalic(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyFontStyle, "italic");
 }
 
-static TriState stateOrderedList(Frame& frame, Event*)
+static TriState stateOrderedList(LocalFrame& frame, Event*)
 {
     return frame.editor().selectionOrderedListState();
 }
 
-static TriState stateStrikethrough(Frame& frame, Event*)
+static TriState stateStrikethrough(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyWebkitTextDecorationsInEffect, "line-through");
 }
 
-static TriState stateStyleWithCSS(Frame& frame, Event*)
+static TriState stateStyleWithCSS(LocalFrame& frame, Event*)
 {
     return frame.editor().shouldStyleWithCSS() ? TrueTriState : FalseTriState;
 }
 
-static TriState stateSubscript(Frame& frame, Event*)
+static TriState stateSubscript(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyVerticalAlign, "sub");
 }
 
-static TriState stateSuperscript(Frame& frame, Event*)
+static TriState stateSuperscript(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyVerticalAlign, "super");
 }
 
-static TriState stateTextWritingDirectionLeftToRight(Frame& frame, Event*)
+static TriState stateTextWritingDirectionLeftToRight(LocalFrame& frame, Event*)
 {
     return stateTextWritingDirection(frame, LeftToRightWritingDirection);
 }
 
-static TriState stateTextWritingDirectionNatural(Frame& frame, Event*)
+static TriState stateTextWritingDirectionNatural(LocalFrame& frame, Event*)
 {
     return stateTextWritingDirection(frame, NaturalWritingDirection);
 }
 
-static TriState stateTextWritingDirectionRightToLeft(Frame& frame, Event*)
+static TriState stateTextWritingDirectionRightToLeft(LocalFrame& frame, Event*)
 {
     return stateTextWritingDirection(frame, RightToLeftWritingDirection);
 }
 
-static TriState stateUnderline(Frame& frame, Event*)
+static TriState stateUnderline(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyWebkitTextDecorationsInEffect, "underline");
 }
 
-static TriState stateUnorderedList(Frame& frame, Event*)
+static TriState stateUnorderedList(LocalFrame& frame, Event*)
 {
     return frame.editor().selectionUnorderedListState();
 }
 
-static TriState stateJustifyCenter(Frame& frame, Event*)
+static TriState stateJustifyCenter(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyTextAlign, "center");
 }
 
-static TriState stateJustifyFull(Frame& frame, Event*)
+static TriState stateJustifyFull(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyTextAlign, "justify");
 }
 
-static TriState stateJustifyLeft(Frame& frame, Event*)
+static TriState stateJustifyLeft(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyTextAlign, "left");
 }
 
-static TriState stateJustifyRight(Frame& frame, Event*)
+static TriState stateJustifyRight(LocalFrame& frame, Event*)
 {
     return stateStyle(frame, CSSPropertyTextAlign, "right");
 }
 
 // Value functions
 
-static String valueNull(Frame&, Event*)
+static String valueNull(LocalFrame&, Event*)
 {
     return String();
 }
 
-static String valueBackColor(Frame& frame, Event*)
+static String valueBackColor(LocalFrame& frame, Event*)
 {
     return valueStyle(frame, CSSPropertyBackgroundColor);
 }
 
-static String valueDefaultParagraphSeparator(Frame& frame, Event*)
+static String valueDefaultParagraphSeparator(LocalFrame& frame, Event*)
 {
     switch (frame.editor().defaultParagraphSeparator()) {
     case EditorParagraphSeparatorIsDiv:
@@ -1396,27 +1396,27 @@
     return String();
 }
 
-static String valueFontName(Frame& frame, Event*)
+static String valueFontName(LocalFrame& frame, Event*)
 {
     return valueStyle(frame, CSSPropertyFontFamily);
 }
 
-static String valueFontSize(Frame& frame, Event*)
+static String valueFontSize(LocalFrame& frame, Event*)
 {
     return valueStyle(frame, CSSPropertyFontSize);
 }
 
-static String valueFontSizeDelta(Frame& frame, Event*)
+static String valueFontSizeDelta(LocalFrame& frame, Event*)
 {
     return valueStyle(frame, CSSPropertyWebkitFontSizeDelta);
 }
 
-static String valueForeColor(Frame& frame, Event*)
+static String valueForeColor(LocalFrame& frame, Event*)
 {
     return valueStyle(frame, CSSPropertyColor);
 }
 
-static String valueFormatBlock(Frame& frame, Event*)
+static String valueFormatBlock(LocalFrame& frame, Event*)
 {
     const VisibleSelection& selection = frame.selection().selection();
     if (!selection.isNonOrphanedCaretOrRange() || !selection.isContentEditable())
@@ -1664,10 +1664,10 @@
 {
 }
 
-Editor::Command::Command(const EditorInternalCommand* command, EditorCommandSource source, PassRefPtr<Frame> frame)
+Editor::Command::Command(const EditorInternalCommand* command, EditorCommandSource source, PassRefPtr<LocalFrame> frame)
     : m_command(command)
     , m_source(source)
-    , m_frame(command ? frame : 0)
+    , m_frame(command ? frame : nullptr)
 {
     // Use separate assertions so we can tell which bad thing happened.
     if (!command)
diff --git a/Source/core/editing/EditorKeyBindings.cpp b/Source/core/editing/EditorKeyBindings.cpp
index f39c047..4e59d26 100644
--- a/Source/core/editing/EditorKeyBindings.cpp
+++ b/Source/core/editing/EditorKeyBindings.cpp
@@ -28,7 +28,7 @@
 #include "core/editing/Editor.h"
 
 #include "core/events/KeyboardEvent.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/EditorClient.h"
 #include "platform/PlatformKeyboardEvent.h"
 
diff --git a/Source/core/editing/FormatBlockCommand.cpp b/Source/core/editing/FormatBlockCommand.cpp
index 57b9634..2c2d26a 100644
--- a/Source/core/editing/FormatBlockCommand.cpp
+++ b/Source/core/editing/FormatBlockCommand.cpp
@@ -61,7 +61,7 @@
 
 void FormatBlockCommand::formatRange(const Position& start, const Position& end, const Position& endOfSelection, RefPtr<Element>& blockNode)
 {
-    Element* refNode = enclosingBlockFlowElement(end);
+    Element* refNode = enclosingBlockFlowElement(VisiblePosition(end));
     Element* root = editableRootForPosition(start);
     // Root is null for elements with contenteditable=false.
     if (!root || !refNode)
@@ -72,8 +72,8 @@
     RefPtr<Node> nodeAfterInsertionPosition = outerBlock;
     RefPtr<Range> range = Range::create(document(), start, endOfSelection);
 
-    if (isElementForFormatBlock(refNode->tagQName()) && start == startOfBlock(start)
-        && (end == endOfBlock(end) || isNodeVisiblyContainedWithin(refNode, range.get()))
+    if (isElementForFormatBlock(refNode->tagQName()) && VisiblePosition(start) == startOfBlock(VisiblePosition(start))
+        && (VisiblePosition(end) == endOfBlock(VisiblePosition(end)) || isNodeVisiblyContainedWithin(*refNode, *range))
         && refNode != root && !root->isDescendantOf(refNode)) {
         // Already in a block element that only contains the current paragraph
         if (refNode->hasTagName(tagName()))
@@ -89,15 +89,15 @@
     }
 
     Position lastParagraphInBlockNode = blockNode->lastChild() ? positionAfterNode(blockNode->lastChild()) : Position();
-    bool wasEndOfParagraph = isEndOfParagraph(lastParagraphInBlockNode);
+    bool wasEndOfParagraph = isEndOfParagraph(VisiblePosition(lastParagraphInBlockNode));
 
-    moveParagraphWithClones(start, end, blockNode.get(), outerBlock.get());
+    moveParagraphWithClones(VisiblePosition(start), VisiblePosition(end), blockNode.get(), outerBlock.get());
 
     // Copy the inline style of the original block element to the newly created block-style element.
     if (outerBlock.get() != nodeAfterInsertionPosition.get() && toHTMLElement(nodeAfterInsertionPosition.get())->hasAttribute(styleAttr))
         blockNode->setAttribute(styleAttr, toHTMLElement(nodeAfterInsertionPosition.get())->getAttribute(styleAttr));
 
-    if (wasEndOfParagraph && !isEndOfParagraph(lastParagraphInBlockNode) && !isStartOfParagraph(lastParagraphInBlockNode))
+    if (wasEndOfParagraph && !isEndOfParagraph(VisiblePosition(lastParagraphInBlockNode)) && !isStartOfParagraph(VisiblePosition(lastParagraphInBlockNode)))
         insertBlockPlaceholder(lastParagraphInBlockNode);
 }
 
@@ -156,7 +156,7 @@
     for (Node* n = startNode; n; n = n->parentNode()) {
         if (!n->rendererIsEditable())
             return lastBlock;
-        if (isTableCell(n) || n->hasTagName(bodyTag) || !n->parentNode() || !n->parentNode()->rendererIsEditable() || isElementForFormatBlock(n))
+        if (isTableCell(n) || isHTMLBodyElement(*n) || !n->parentNode() || !n->parentNode()->rendererIsEditable() || isElementForFormatBlock(n))
             return n;
         if (isBlock(n))
             lastBlock = n;
diff --git a/Source/core/editing/FrameSelection.cpp b/Source/core/editing/FrameSelection.cpp
index 7f546b8..0c6083d 100644
--- a/Source/core/editing/FrameSelection.cpp
+++ b/Source/core/editing/FrameSelection.cpp
@@ -46,6 +46,8 @@
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
 #include "core/frame/DOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLBodyElement.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLInputElement.h"
@@ -53,7 +55,6 @@
 #include "core/page/EditorClient.h"
 #include "core/page/EventHandler.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
 #include "core/page/FrameTree.h"
 #include "core/frame/FrameView.h"
 #include "core/page/Page.h"
@@ -62,6 +63,7 @@
 #include "core/rendering/HitTestRequest.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/InlineTextBox.h"
+#include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderText.h"
 #include "core/rendering/RenderTheme.h"
 #include "core/rendering/RenderView.h"
@@ -82,14 +84,15 @@
     return LayoutUnit::min();
 }
 
-static inline bool shouldAlwaysUseDirectionalSelection(Frame* frame)
+static inline bool shouldAlwaysUseDirectionalSelection(LocalFrame* frame)
 {
     return !frame || frame->editor().behavior().shouldConsiderSelectionAsDirectional();
 }
 
-FrameSelection::FrameSelection(Frame* frame)
+FrameSelection::FrameSelection(LocalFrame* frame)
     : m_frame(frame)
     , m_xPosForVerticalArrowNavigation(NoXPosForVerticalArrowNavigation())
+    , m_observingVisibleSelection(false)
     , m_granularity(CharacterGranularity)
     , m_caretBlinkTimer(this, &FrameSelection::caretBlinkTimerFired)
     , m_absCaretBoundsDirty(true)
@@ -102,6 +105,11 @@
         m_selection.setIsDirectional(true);
 }
 
+FrameSelection::~FrameSelection()
+{
+    stopObservingVisibleSelectionChangeIfNecessary();
+}
+
 Element* FrameSelection::rootEditableElementOrDocumentElement() const
 {
     Element* selectionRoot = m_selection.rootEditableElement();
@@ -148,7 +156,7 @@
     if (base.atLeftBoundaryOfBidiRun()) {
         if (!extent.atRightBoundaryOfBidiRun(base.bidiLevelOnRight())
             && base.isEquivalent(extent.leftBoundaryOfBidiRun(base.bidiLevelOnRight()))) {
-            visibleBase = base.positionAtLeftBoundaryOfBiDiRun();
+            visibleBase = VisiblePosition(base.positionAtLeftBoundaryOfBiDiRun());
             return;
         }
         return;
@@ -157,19 +165,19 @@
     if (base.atRightBoundaryOfBidiRun()) {
         if (!extent.atLeftBoundaryOfBidiRun(base.bidiLevelOnLeft())
             && base.isEquivalent(extent.rightBoundaryOfBidiRun(base.bidiLevelOnLeft()))) {
-            visibleBase = base.positionAtRightBoundaryOfBiDiRun();
+            visibleBase = VisiblePosition(base.positionAtRightBoundaryOfBiDiRun());
             return;
         }
         return;
     }
 
     if (extent.atLeftBoundaryOfBidiRun() && extent.isEquivalent(base.leftBoundaryOfBidiRun(extent.bidiLevelOnRight()))) {
-        visibleExtent = extent.positionAtLeftBoundaryOfBiDiRun();
+        visibleExtent = VisiblePosition(extent.positionAtLeftBoundaryOfBiDiRun());
         return;
     }
 
     if (extent.atRightBoundaryOfBidiRun() && extent.isEquivalent(base.rightBoundaryOfBidiRun(extent.bidiLevelOnLeft()))) {
-        visibleExtent = extent.positionAtRightBoundaryOfBiDiRun();
+        visibleExtent = VisiblePosition(extent.positionAtRightBoundaryOfBiDiRun());
         return;
     }
 }
@@ -224,7 +232,7 @@
     if (s.base().anchorNode()) {
         Document& document = *s.base().document();
         if (document.frame() && document.frame() != m_frame && document != m_frame->document()) {
-            RefPtr<Frame> guard = document.frame();
+            RefPtr<LocalFrame> guard = document.frame();
             document.frame()->selection().setSelection(s, options, align, granularity);
             // It's possible that during the above set selection, this FrameSelection has been modified by
             // selectFrameElementInParentIfFullySelected, but that the selection is no longer valid since
@@ -260,6 +268,9 @@
 
     if (!(options & DoNotUpdateAppearance)) {
         m_frame->document()->updateLayoutIgnorePendingStylesheets();
+
+        // Hits in compositing/overflow/do-not-paint-outline-into-composited-scrolling-contents.html
+        DisableCompositingQueryAsserts disabler;
         updateAppearance();
     }
 
@@ -321,9 +332,9 @@
         Position start = m_selection.start();
         Position end = m_selection.end();
         if (startRemoved)
-            updatePositionForNodeRemoval(start, &node);
+            updatePositionForNodeRemoval(start, node);
         if (endRemoved)
-            updatePositionForNodeRemoval(end, &node);
+            updatePositionForNodeRemoval(end, node);
 
         if (start.isNotNull() && end.isNotNull()) {
             if (m_selection.isBaseFirst())
@@ -486,6 +497,8 @@
 
 void FrameSelection::didChangeFocus()
 {
+    // Hits in virtual/gpu/compositedscrolling/scrollbars/scrollbar-miss-mousemove-disabled.html
+    DisableCompositingQueryAsserts disabler;
     updateAppearance();
 }
 
@@ -584,7 +597,7 @@
 static void adjustPositionForUserSelectAll(VisiblePosition& pos, bool isForward)
 {
     if (Node* rootUserSelectAll = Position::rootUserSelectAllForNode(pos.deepEquivalent().anchorNode()))
-        pos = isForward ? positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary) : positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary);
+        pos = VisiblePosition(isForward ? positionAfterNode(rootUserSelectAll).downstream(CanCrossEditingBoundary) : positionBeforeNode(rootUserSelectAll).upstream(CanCrossEditingBoundary));
 }
 
 VisiblePosition FrameSelection::modifyExtendingRight(TextGranularity granularity)
@@ -932,7 +945,7 @@
     willBeModified(alter, direction);
 
     bool wasRange = m_selection.isRange();
-    Position originalStartPosition = m_selection.start();
+    VisiblePosition originalStartPosition = m_selection.visibleStart();
     VisiblePosition position;
     switch (direction) {
     case DirectionRight:
@@ -991,7 +1004,7 @@
             VisibleSelection newSelection = m_selection;
             newSelection.setExtent(position);
             if (m_selection.isBaseFirst() != newSelection.isBaseFirst())
-                position = m_selection.base();
+                position = m_selection.visibleBase();
         }
 
         // Standard Mac behavior when extending to a boundary is grow the selection rather than leaving the
@@ -1130,7 +1143,7 @@
         break;
     }
 
-    Frame* frame = pos.document()->frame();
+    LocalFrame* frame = pos.document()->frame();
     if (!frame)
         return x;
 
@@ -1307,7 +1320,7 @@
 void FrameSelection::selectFrameElementInParentIfFullySelected()
 {
     // Find the parent frame; if there is none, then we have nothing to do.
-    Frame* parent = m_frame->tree().parent();
+    LocalFrame* parent = m_frame->tree().parent();
     if (!parent)
         return;
     Page* page = m_frame->page();
@@ -1349,7 +1362,7 @@
 {
     Document* document = m_frame->document();
 
-    if (document->focusedElement() && document->focusedElement()->hasTagName(selectTag)) {
+    if (isHTMLSelectElement(document->focusedElement())) {
         HTMLSelectElement* selectElement = toHTMLSelectElement(document->focusedElement());
         if (selectElement->canSelectAll()) {
             selectElement->selectAll();
@@ -1357,7 +1370,7 @@
         }
     }
 
-    RefPtr<Node> root = 0;
+    RefPtr<Node> root = nullptr;
     Node* selectStartTarget = 0;
     if (isContentEditable()) {
         root = highestEditableRoot(m_selection.start());
@@ -1386,7 +1399,7 @@
     notifyRendererOfSelectionChange(UserTriggered);
 }
 
-bool FrameSelection::setSelectedRange(Range* range, EAffinity affinity, bool closeTyping)
+bool FrameSelection::setSelectedRange(Range* range, EAffinity affinity, SetSelectionOptions options)
 {
     if (!range || !range->startContainer() || !range->endContainer())
         return false;
@@ -1401,17 +1414,31 @@
     if (exceptionState.hadException())
         return false;
 
+    m_logicalRange = nullptr;
+    stopObservingVisibleSelectionChangeIfNecessary();
+
     // FIXME: Can we provide extentAffinity?
     VisiblePosition visibleStart(range->startPosition(), collapsed ? affinity : DOWNSTREAM);
     VisiblePosition visibleEnd(range->endPosition(), SEL_DEFAULT_AFFINITY);
-    setSelection(VisibleSelection(visibleStart, visibleEnd), ClearTypingStyle | (closeTyping ? CloseTyping : 0));
+    setSelection(VisibleSelection(visibleStart, visibleEnd), options);
+
+    m_logicalRange = range->cloneRange(ASSERT_NO_EXCEPTION);
+    startObservingVisibleSelectionChange();
+
     return true;
 }
 
+PassRefPtr<Range> FrameSelection::firstRange() const
+{
+    if (m_logicalRange)
+        return m_logicalRange->cloneRange(ASSERT_NO_EXCEPTION);
+    return m_selection.firstRange();
+}
+
 bool FrameSelection::isInPasswordField() const
 {
     HTMLTextFormControlElement* textControl = enclosingTextFormControl(start());
-    return textControl && textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isPasswordField();
+    return isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->isPasswordField();
 }
 
 void FrameSelection::notifyAccessibilityForSelectionChange()
@@ -1488,7 +1515,7 @@
     return m_focused && m_frame->page() && m_frame->page()->focusController().isActive();
 }
 
-inline static bool shouldStopBlinkingDueToTypingCommand(Frame* frame)
+inline static bool shouldStopBlinkingDueToTypingCommand(LocalFrame* frame)
 {
     return frame->editor().lastEditCommand() && frame->editor().lastEditCommand()->shouldStopCaretBlinking();
 }
@@ -1520,7 +1547,7 @@
     // already blinking in the right location.
     if (shouldBlink && !m_caretBlinkTimer.isActive()) {
         if (double blinkInterval = RenderTheme::theme().caretBlinkInterval())
-            m_caretBlinkTimer.startRepeating(blinkInterval);
+            m_caretBlinkTimer.startRepeating(blinkInterval, FROM_HERE);
 
         if (!m_caretPaint) {
             m_caretPaint = true;
@@ -1617,7 +1644,7 @@
 }
 
 // Helper function that tells whether a particular node is an element that has an entire
-// Frame and FrameView, a <frame>, <iframe>, or <object>.
+// LocalFrame and FrameView, a <frame>, <iframe>, or <object>.
 static bool isFrameElement(const Node* n)
 {
     if (!n)
@@ -1654,7 +1681,7 @@
             }
             target = target->parentOrShadowHostElement();
         }
-        m_frame->document()->setFocusedElement(0);
+        m_frame->document()->setFocusedElement(nullptr);
     }
 
     if (caretBrowsing)
@@ -1698,17 +1725,16 @@
 {
     if (!start)
         return 0;
-    Element* element = start->isElementNode() ? toElement(start) : ElementTraversal::next(*start);
-    for (; element; element = ElementTraversal::next(*element)) {
-        if (element->hasTagName(formTag))
+    HTMLElement* element = start->isHTMLElement() ? toHTMLElement(start) : Traversal<HTMLElement>::next(*start);
+    for (; element; element = Traversal<HTMLElement>::next(*element)) {
+        if (isHTMLFormElement(*element))
             return toHTMLFormElement(element);
-        if (element->isHTMLElement()) {
-            HTMLFormElement* owner = toHTMLElement(element)->formOwner();
-            if (owner)
+
+        if (HTMLFormElement* owner = element->formOwner())
                 return owner;
-        }
-        if (element->hasTagName(frameTag) || element->hasTagName(iframeTag)) {
-            Node* childDocument = toHTMLFrameElementBase(element)->contentDocument();
+
+        if (isHTMLFrameElement(*element) || isHTMLIFrameElement(*element)) {
+            Node* childDocument = toHTMLFrameElementBase(*element).contentDocument();
             if (HTMLFormElement* frameResult = scanForForm(childDocument))
                 return frameResult;
         }
@@ -1727,7 +1753,7 @@
     // Try walking up the node tree to find a form element.
     Node* node;
     for (node = start; node; node = node->parentNode()) {
-        if (node->hasTagName(formTag))
+        if (isHTMLFormElement(*node))
             return toHTMLFormElement(node);
         if (node->isHTMLElement()) {
             HTMLFormElement* owner = toHTMLElement(node)->formOwner();
@@ -1777,10 +1803,11 @@
         return;
 
     Node* node = document->documentElement();
-    while (node && !node->hasTagName(bodyTag))
-        node = NodeTraversal::next(*node);
-    if (node)
-        setSelection(VisibleSelection(firstPositionInOrBeforeNode(node), DOWNSTREAM));
+    if (!node)
+        return;
+    Node* body = isHTMLBodyElement(*node) ? node : Traversal<HTMLBodyElement>::next(*node);
+    if (body)
+        setSelection(VisibleSelection(firstPositionInOrBeforeNode(body), DOWNSTREAM));
 }
 
 bool FrameSelection::dispatchSelectStart()
@@ -1801,6 +1828,30 @@
     updateAppearance();
 }
 
+void FrameSelection::didChangeVisibleSelection()
+{
+    ASSERT(m_observingVisibleSelection);
+    // Invalidate the logical range when the underlying VisibleSelection has changed.
+    m_logicalRange = nullptr;
+    m_selection.clearChangeObserver();
+    m_observingVisibleSelection = false;
+}
+
+void FrameSelection::startObservingVisibleSelectionChange()
+{
+    ASSERT(!m_observingVisibleSelection);
+    m_selection.setChangeObserver(*this);
+    m_observingVisibleSelection = true;
+}
+
+void FrameSelection::stopObservingVisibleSelectionChangeIfNecessary()
+{
+    if (m_observingVisibleSelection) {
+        m_selection.clearChangeObserver();
+        m_observingVisibleSelection = false;
+    }
+}
+
 #ifndef NDEBUG
 
 void FrameSelection::formatForDebugger(char* buffer, unsigned length) const
diff --git a/Source/core/editing/FrameSelection.h b/Source/core/editing/FrameSelection.h
index 7e88d9f..cd32a53 100644
--- a/Source/core/editing/FrameSelection.h
+++ b/Source/core/editing/FrameSelection.h
@@ -39,7 +39,7 @@
 namespace WebCore {
 
 class CharacterData;
-class Frame;
+class LocalFrame;
 class GraphicsContext;
 class HTMLFormElement;
 class MutableStylePropertySet;
@@ -56,7 +56,7 @@
     DoNotRevealExtent
 };
 
-class FrameSelection : private CaretBase {
+class FrameSelection FINAL : public VisibleSelection::ChangeObserver, private CaretBase {
     WTF_MAKE_NONCOPYABLE(FrameSelection);
     WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -77,7 +77,8 @@
         return static_cast<EUserTriggered>(options & UserTriggered);
     }
 
-    explicit FrameSelection(Frame* = 0);
+    explicit FrameSelection(LocalFrame* = 0);
+    virtual ~FrameSelection();
 
     Element* rootEditableElement() const { return m_selection.rootEditableElement(); }
     Element* rootEditableElementOrDocumentElement() const;
@@ -94,7 +95,7 @@
     const VisibleSelection& selection() const { return m_selection; }
     void setSelection(const VisibleSelection&, SetSelectionOptions = CloseTyping | ClearTypingStyle, CursorAlignOnScroll = AlignCursorOnScrollIfNeeded, TextGranularity = CharacterGranularity);
     void setSelection(const VisibleSelection& selection, TextGranularity granularity) { setSelection(selection, CloseTyping | ClearTypingStyle, AlignCursorOnScrollIfNeeded, granularity); }
-    bool setSelectedRange(Range*, EAffinity, bool closeTyping);
+    bool setSelectedRange(Range*, EAffinity, SetSelectionOptions = CloseTyping | ClearTypingStyle);
     void selectAll();
     void clear();
     void prepareForDestruction();
@@ -144,6 +145,10 @@
     bool isCaretOrRange() const { return m_selection.isCaretOrRange(); }
     bool isInPasswordField() const;
 
+    // If this FrameSelection has a logical range which is still valid, this function return its clone. Otherwise,
+    // the return value from underlying VisibleSelection's firstRange() is returned.
+    PassRefPtr<Range> firstRange() const;
+
     PassRefPtr<Range> toNormalizedRange() const { return m_selection.toNormalizedRange(); }
 
     void nodeWillBeRemoved(Node&);
@@ -197,6 +202,9 @@
 
     void setShouldShowBlockCursor(bool);
 
+    // VisibleSelection::ChangeObserver interface.
+    virtual void didChangeVisibleSelection() OVERRIDE;
+
 private:
     enum EPositionType { START, END, BASE, EXTENT };
 
@@ -235,14 +243,23 @@
 
     void updateSelectionIfNeeded(const Position& base, const Position& extent, const Position& start, const Position& end);
 
-    Frame* m_frame;
+    void startObservingVisibleSelectionChange();
+    void stopObservingVisibleSelectionChangeIfNecessary();
+
+    LocalFrame* m_frame;
 
     LayoutUnit m_xPosForVerticalArrowNavigation;
 
     VisibleSelection m_selection;
+    bool m_observingVisibleSelection;
     VisiblePosition m_originalBase; // Used to store base before the adjustment at bidi boundary
     TextGranularity m_granularity;
 
+    // The range specified by the user, which may not be visually canonicalized (hence "logical").
+    // This will be invalidated if the underlying VisibleSelection changes. If that happens, this variable will
+    // become null, in which case logical positions == visible positions.
+    RefPtr<Range> m_logicalRange;
+
     RefPtr<Node> m_previousCaretNode; // The last node which painted the caret. Retained for clearing the old caret when it moves.
 
     RefPtr<EditingStyle> m_typingStyle;
diff --git a/Source/core/editing/IndentOutdentCommand.cpp b/Source/core/editing/IndentOutdentCommand.cpp
index ba5cf29..b38760d 100644
--- a/Source/core/editing/IndentOutdentCommand.cpp
+++ b/Source/core/editing/IndentOutdentCommand.cpp
@@ -41,7 +41,7 @@
 
 static bool isListOrIndentBlockquote(const Node* node)
 {
-    return node && (node->hasTagName(ulTag) || node->hasTagName(olTag) || node->hasTagName(blockquoteTag));
+    return node && (isHTMLUListElement(*node) || isHTMLOListElement(*node) || node->hasTagName(blockquoteTag));
 }
 
 IndentOutdentCommand::IndentOutdentCommand(Document& document, EIndentType typeOfAction)
@@ -62,7 +62,7 @@
     RefPtr<Element> selectedListItem = enclosingBlock(lastNodeInSelectedParagraph.get());
 
     // FIXME: we need to deal with the case where there is no li (malformed HTML)
-    if (!selectedListItem->hasTagName(liTag))
+    if (!isHTMLLIElement(*selectedListItem))
         return false;
 
     // FIXME: previousElementSibling does not ignore non-rendered content like <span></span>.  Should we?
@@ -79,9 +79,9 @@
     // selection does not encompass all its children, we need to explicitally handle the same. The original
     // list item too would require proper deletion in that case.
     if (end.anchorNode() == selectedListItem.get() || end.anchorNode()->isDescendantOf(selectedListItem->lastChild())) {
-        moveParagraphWithClones(start, end, newList.get(), selectedListItem.get());
+        moveParagraphWithClones(VisiblePosition(start), VisiblePosition(end), newList.get(), selectedListItem.get());
     } else {
-        moveParagraphWithClones(start, positionAfterNode(selectedListItem->lastChild()), newList.get(), selectedListItem.get());
+        moveParagraphWithClones(VisiblePosition(start), VisiblePosition(positionAfterNode(selectedListItem->lastChild())), newList.get(), selectedListItem.get());
         removeNode(selectedListItem.get());
     }
 
@@ -109,7 +109,7 @@
 
     RefPtr<Node> outerBlock = (start.containerNode() == nodeToSplitTo) ? start.containerNode() : splitTreeToNode(start.containerNode(), nodeToSplitTo);
 
-    VisiblePosition startOfContents = start;
+    VisiblePosition startOfContents(start);
     if (!targetBlockquote) {
         // Create a new blockquote and insert it as a child of the root editable element. We accomplish
         // this by splitting all parents of the current paragraph up to that point.
@@ -118,10 +118,10 @@
             insertNodeAt(targetBlockquote, start);
         else
             insertNodeBefore(targetBlockquote, outerBlock);
-        startOfContents = positionInParentAfterNode(targetBlockquote.get());
+        startOfContents = VisiblePosition(positionInParentAfterNode(*targetBlockquote));
     }
 
-    moveParagraphWithClones(startOfContents, end, targetBlockquote.get(), outerBlock.get());
+    moveParagraphWithClones(startOfContents, VisiblePosition(end), targetBlockquote.get(), outerBlock.get());
 }
 
 void IndentOutdentCommand::outdentParagraph()
@@ -134,11 +134,11 @@
         return;
 
     // Use InsertListCommand to remove the selection from the list
-    if (enclosingNode->hasTagName(olTag)) {
+    if (isHTMLOListElement(*enclosingNode)) {
         applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::OrderedList));
         return;
     }
-    if (enclosingNode->hasTagName(ulTag)) {
+    if (isHTMLUListElement(*enclosingNode)) {
         applyCommandToComposite(InsertListCommand::create(document(), InsertListCommand::UnorderedList));
         return;
     }
@@ -187,7 +187,7 @@
     }
     RefPtr<Node> placeholder = createBreakElement(document());
     insertNodeBefore(placeholder, splitBlockquoteNode);
-    moveParagraph(startOfParagraph(visibleStartOfParagraph), endOfParagraph(visibleEndOfParagraph), positionBeforeNode(placeholder.get()), true);
+    moveParagraph(startOfParagraph(visibleStartOfParagraph), endOfParagraph(visibleEndOfParagraph), VisiblePosition(positionBeforeNode(placeholder.get())), true);
 }
 
 // FIXME: We should merge this function with ApplyBlockElementCommand::formatSelection
@@ -220,7 +220,7 @@
             break;
 
         if (endOfNextParagraph.isNotNull() && !endOfNextParagraph.deepEquivalent().inDocument()) {
-            endOfCurrentParagraph = endingSelection().end();
+            endOfCurrentParagraph = VisiblePosition(endingSelection().end());
             endOfNextParagraph = endOfParagraph(endOfCurrentParagraph.next());
         }
         endOfCurrentParagraph = endOfNextParagraph;
@@ -238,7 +238,7 @@
 void IndentOutdentCommand::formatRange(const Position& start, const Position& end, const Position&, RefPtr<Element>& blockquoteForNextIndent)
 {
     if (tryIndentingAsListItem(start, end))
-        blockquoteForNextIndent = 0;
+        blockquoteForNextIndent = nullptr;
     else
         indentIntoBlockquote(start, end, blockquoteForNextIndent);
 }
diff --git a/Source/core/editing/InputMethodController.cpp b/Source/core/editing/InputMethodController.cpp
index 8e32f93..b0ce7d2 100644
--- a/Source/core/editing/InputMethodController.cpp
+++ b/Source/core/editing/InputMethodController.cpp
@@ -34,11 +34,11 @@
 #include "core/dom/Text.h"
 #include "core/editing/Editor.h"
 #include "core/editing/TypingCommand.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLTextAreaElement.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderObject.h"
 
 namespace WebCore {
@@ -56,12 +56,12 @@
 
 // ----------------------------
 
-PassOwnPtr<InputMethodController> InputMethodController::create(Frame& frame)
+PassOwnPtr<InputMethodController> InputMethodController::create(LocalFrame& frame)
 {
     return adoptPtr(new InputMethodController(frame));
 }
 
-InputMethodController::InputMethodController(Frame& frame)
+InputMethodController::InputMethodController(LocalFrame& frame)
     : m_frame(frame)
     , m_compositionStart(0)
     , m_compositionEnd(0)
@@ -84,7 +84,7 @@
 
 void InputMethodController::clear()
 {
-    m_compositionNode = 0;
+    m_compositionNode = nullptr;
     m_customCompositionUnderlines.clear();
 }
 
@@ -211,7 +211,7 @@
         TypingCommand::deleteSelection(*m_frame.document(), 0);
     }
 
-    m_compositionNode = 0;
+    m_compositionNode = nullptr;
     m_customCompositionUnderlines.clear();
 
     insertTextForConfirmedComposition(text);
@@ -279,7 +279,7 @@
         TypingCommand::deleteSelection(*m_frame.document(), TypingCommand::PreventSpellChecking);
     }
 
-    m_compositionNode = 0;
+    m_compositionNode = nullptr;
     m_customCompositionUnderlines.clear();
 
     if (!text.isEmpty()) {
@@ -310,7 +310,7 @@
             unsigned start = std::min(baseOffset + selectionStart, extentOffset);
             unsigned end = std::min(std::max(start, baseOffset + selectionEnd), extentOffset);
             RefPtr<Range> selectedRange = Range::create(baseNode->document(), baseNode, start, baseNode, end);
-            m_frame.selection().setSelectedRange(selectedRange.get(), DOWNSTREAM, false);
+            m_frame.selection().setSelectedRange(selectedRange.get(), DOWNSTREAM, static_cast<FrameSelection::SetSelectionOption>(0));
         }
     }
 }
@@ -321,7 +321,7 @@
     Position base = m_frame.selection().base().downstream();
     Node* baseNode = base.anchorNode();
     if (editable->firstChild() == baseNode && editable->lastChild() == baseNode && baseNode->isTextNode()) {
-        m_compositionNode = 0;
+        m_compositionNode = nullptr;
         m_customCompositionUnderlines.clear();
 
         if (base.anchorType() != Position::PositionIsOffsetInAnchor)
@@ -352,12 +352,12 @@
 PassRefPtr<Range> InputMethodController::compositionRange() const
 {
     if (!hasComposition())
-        return 0;
+        return nullptr;
     unsigned length = m_compositionNode->length();
     unsigned start = std::min(m_compositionStart, length);
     unsigned end = std::min(std::max(start, m_compositionEnd), length);
     if (start >= end)
-        return 0;
+        return nullptr;
     return Range::create(m_compositionNode->document(), m_compositionNode.get(), start, m_compositionNode.get(), end);
 }
 
@@ -383,7 +383,7 @@
     if (!range)
         return false;
 
-    return m_frame.selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, true);
+    return m_frame.selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY, FrameSelection::CloseTyping);
 }
 
 bool InputMethodController::setEditableSelectionOffsets(const PlainTextRange& selectionOffsets)
diff --git a/Source/core/editing/InputMethodController.h b/Source/core/editing/InputMethodController.h
index 843cd8a..2461ad7 100644
--- a/Source/core/editing/InputMethodController.h
+++ b/Source/core/editing/InputMethodController.h
@@ -34,7 +34,7 @@
 
 class Editor;
 class EditorClient;
-class Frame;
+class LocalFrame;
 class Range;
 class Text;
 
@@ -46,7 +46,7 @@
         KeepSelection,
     };
 
-    static PassOwnPtr<InputMethodController> create(Frame&);
+    static PassOwnPtr<InputMethodController> create(LocalFrame&);
     ~InputMethodController();
 
     // international text input composition
@@ -94,7 +94,7 @@
     };
     friend class SelectionOffsetsScope;
 
-    Frame& m_frame;
+    LocalFrame& m_frame;
     RefPtr<Text> m_compositionNode;
     // We don't use PlainTextRange which is immutable, for composition range.
     unsigned m_compositionStart;
@@ -103,7 +103,7 @@
     // m_compositionNode.
     Vector<CompositionUnderline> m_customCompositionUnderlines;
 
-    explicit InputMethodController(Frame&);
+    explicit InputMethodController(LocalFrame&);
     Editor& editor() const;
     bool insertTextForConfirmedComposition(const String& text);
     void selectComposition() const;
diff --git a/Source/core/editing/InsertLineBreakCommand.cpp b/Source/core/editing/InsertLineBreakCommand.cpp
index 6d8cf00..4c2699d 100644
--- a/Source/core/editing/InsertLineBreakCommand.cpp
+++ b/Source/core/editing/InsertLineBreakCommand.cpp
@@ -34,8 +34,8 @@
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderObject.h"
 
 namespace WebCore {
@@ -90,7 +90,7 @@
     // FIXME: Need to merge text nodes when inserting just after or before text.
 
     if (isEndOfParagraph(caret) && !lineBreakExistsAtVisiblePosition(caret)) {
-        bool needExtraLineBreak = !pos.deprecatedNode()->hasTagName(hrTag) && !pos.deprecatedNode()->hasTagName(tableTag);
+        bool needExtraLineBreak = !isHTMLHRElement(*pos.deprecatedNode()) && !isHTMLTableElement(*pos.deprecatedNode());
 
         insertNodeAt(nodeToInsert.get(), pos);
 
@@ -103,15 +103,15 @@
         insertNodeAt(nodeToInsert.get(), pos);
 
         // Insert an extra br or '\n' if the just inserted one collapsed.
-        if (!isStartOfParagraph(positionBeforeNode(nodeToInsert.get())))
+        if (!isStartOfParagraph(VisiblePosition(positionBeforeNode(nodeToInsert.get()))))
             insertNodeBefore(nodeToInsert->cloneNode(false).get(), nodeToInsert.get());
 
-        setEndingSelection(VisibleSelection(positionInParentAfterNode(nodeToInsert.get()), DOWNSTREAM, endingSelection().isDirectional()));
+        setEndingSelection(VisibleSelection(positionInParentAfterNode(*nodeToInsert), DOWNSTREAM, endingSelection().isDirectional()));
     // If we're inserting after all of the rendered text in a text node, or into a non-text node,
     // a simple insertion is sufficient.
     } else if (pos.deprecatedEditingOffset() >= caretMaxOffset(pos.deprecatedNode()) || !pos.deprecatedNode()->isTextNode()) {
         insertNodeAt(nodeToInsert.get(), pos);
-        setEndingSelection(VisibleSelection(positionInParentAfterNode(nodeToInsert.get()), DOWNSTREAM, endingSelection().isDirectional()));
+        setEndingSelection(VisibleSelection(positionInParentAfterNode(*nodeToInsert), DOWNSTREAM, endingSelection().isDirectional()));
     } else if (pos.deprecatedNode()->isTextNode()) {
         // Split a text node
         Text* textNode = toText(pos.deprecatedNode());
@@ -122,7 +122,7 @@
         // Handle whitespace that occurs after the split
         document().updateLayoutIgnorePendingStylesheets();
         if (!endingPosition.isRenderedCharacter()) {
-            Position positionBeforeTextNode(positionInParentBeforeNode(textNode));
+            Position positionBeforeTextNode(positionInParentBeforeNode(*textNode));
             // Clear out all whitespace and insert one non-breaking space
             deleteInsignificantTextDownstream(endingPosition);
             ASSERT(!textNode->renderer() || textNode->renderer()->style()->collapseWhiteSpace());
diff --git a/Source/core/editing/InsertListCommand.cpp b/Source/core/editing/InsertListCommand.cpp
index e5bedb0..6de0c13 100644
--- a/Source/core/editing/InsertListCommand.cpp
+++ b/Source/core/editing/InsertListCommand.cpp
@@ -65,7 +65,7 @@
         mergeIdenticalElements(previousList, list);
 
     if (!list)
-        return 0;
+        return nullptr;
 
     Element* nextSibling = ElementTraversal::nextSibling(*list);
     if (!nextSibling || !nextSibling->isHTMLElement())
@@ -120,8 +120,11 @@
     // FIXME: We paint the gap before some paragraphs that are indented with left
     // margin/padding, but not others.  We should make the gap painting more consistent and
     // then use a left margin/padding rule here.
-    if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOverEditingBoundary))
+    if (visibleEnd != visibleStart && isStartOfParagraph(visibleEnd, CanSkipOverEditingBoundary)) {
         setEndingSelection(VisibleSelection(visibleStart, visibleEnd.previous(CannotCrossEditingBoundary), endingSelection().isDirectional()));
+        if (!endingSelection().rootEditableElement())
+            return;
+    }
 
     const QualifiedName& listTag = (m_type == OrderedList) ? olTag : ulTag;
     if (endingSelection().isRange()) {
@@ -153,7 +156,7 @@
                 // FIXME: This is an inefficient way to keep selection alive because indexForVisiblePosition walks from
                 // the beginning of the document to the endOfSelection everytime this code is executed.
                 // But not using index is hard because there are so many ways we can lose selection inside doApplyForSingleParagraph.
-                doApplyForSingleParagraph(forceCreateList, listTag, currentSelection.get());
+                doApplyForSingleParagraph(forceCreateList, listTag, *currentSelection);
                 if (endOfSelection.isNull() || endOfSelection.isOrphan() || startOfLastParagraph.isNull() || startOfLastParagraph.isOrphan()) {
                     endOfSelection = visiblePositionForIndex(indexForEndOfSelection, scope.get());
                     // If endOfSelection is null, then some contents have been deleted from the document.
@@ -174,7 +177,7 @@
                 startOfCurrentParagraph = startOfNextParagraph(endingSelection().visibleStart());
             }
             setEndingSelection(endOfSelection);
-            doApplyForSingleParagraph(forceCreateList, listTag, currentSelection.get());
+            doApplyForSingleParagraph(forceCreateList, listTag, *currentSelection);
             // Fetch the end of the selection, for the reason mentioned above.
             if (endOfSelection.isNull() || endOfSelection.isOrphan()) {
                 endOfSelection = visiblePositionForIndex(indexForEndOfSelection, scope.get());
@@ -186,10 +189,11 @@
         }
     }
 
-    doApplyForSingleParagraph(false, listTag, endingSelection().firstRange().get());
+    ASSERT(endingSelection().firstRange());
+    doApplyForSingleParagraph(false, listTag, *endingSelection().firstRange());
 }
 
-void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const QualifiedName& listTag, Range* currentSelection)
+void InsertListCommand::doApplyForSingleParagraph(bool forceCreateList, const QualifiedName& listTag, Range& currentSelection)
 {
     // FIXME: This will produce unexpected results for a selection that starts just before a
     // table and ends inside the first cell, selectionForParagraphIteration should probably
@@ -213,17 +217,17 @@
             return;
 
         // If the entire list is selected, then convert the whole list.
-        if (switchListType && isNodeVisiblyContainedWithin(listNode.get(), currentSelection)) {
-            bool rangeStartIsInList = visiblePositionBeforeNode(listNode.get()) == currentSelection->startPosition();
-            bool rangeEndIsInList = visiblePositionAfterNode(listNode.get()) == currentSelection->endPosition();
+        if (switchListType && isNodeVisiblyContainedWithin(*listNode, currentSelection)) {
+            bool rangeStartIsInList = visiblePositionBeforeNode(*listNode) == VisiblePosition(currentSelection.startPosition());
+            bool rangeEndIsInList = visiblePositionAfterNode(*listNode) == VisiblePosition(currentSelection.endPosition());
 
             RefPtr<HTMLElement> newList = createHTMLElement(document(), listTag);
             insertNodeBefore(newList, listNode);
 
             Node* firstChildInList = enclosingListChild(VisiblePosition(firstPositionInNode(listNode.get())).deepEquivalent().deprecatedNode(), listNode.get());
-            Node* outerBlock = firstChildInList->isBlockFlowElement() ? firstChildInList : listNode.get();
+            Node* outerBlock = firstChildInList && firstChildInList->isBlockFlowElement() ? firstChildInList : listNode.get();
 
-            moveParagraphWithClones(firstPositionInNode(listNode.get()), lastPositionInNode(listNode.get()), newList.get(), outerBlock);
+            moveParagraphWithClones(VisiblePosition(firstPositionInNode(listNode.get())), VisiblePosition(lastPositionInNode(listNode.get())), newList.get(), outerBlock);
 
             // Manually remove listNode because moveParagraphWithClones sometimes leaves it behind in the document.
             // See the bug 33668 and editing/execCommand/insert-list-orphaned-item-with-nested-lists.html.
@@ -236,9 +240,9 @@
             // Restore the start and the end of current selection if they started inside listNode
             // because moveParagraphWithClones could have removed them.
             if (rangeStartIsInList && newList)
-                currentSelection->setStart(newList, 0, IGNORE_EXCEPTION);
+                currentSelection.setStart(newList, 0, IGNORE_EXCEPTION);
             if (rangeEndIsInList && newList)
-                currentSelection->setEnd(newList, lastOffsetInNode(newList.get()), IGNORE_EXCEPTION);
+                currentSelection.setEnd(newList, lastOffsetInNode(newList.get()), IGNORE_EXCEPTION);
 
             setEndingSelection(VisiblePosition(firstPositionInNode(newList.get())));
 
@@ -258,9 +262,10 @@
     Node* previousListChild;
     VisiblePosition start;
     VisiblePosition end;
-    if (listChildNode->hasTagName(liTag)) {
-        start = firstPositionInNode(listChildNode);
-        end = lastPositionInNode(listChildNode);
+    ASSERT(listChildNode);
+    if (isHTMLLIElement(*listChildNode)) {
+        start = VisiblePosition(firstPositionInNode(listChildNode));
+        end = VisiblePosition(lastPositionInNode(listChildNode));
         nextListChild = listChildNode->nextSibling();
         previousListChild = listChildNode->previousSibling();
     } else {
@@ -333,7 +338,7 @@
     VisiblePosition end = endOfParagraph(start, CanSkipOverEditingBoundary);
 
     if (start.isNull() || end.isNull())
-        return 0;
+        return nullptr;
 
     // Check for adjoining lists.
     RefPtr<HTMLElement> listItemElement = createListItemElement(document());
@@ -341,8 +346,8 @@
     appendNode(placeholder, listItemElement);
 
     // Place list item into adjoining lists.
-    Element* previousList = adjacentEnclosingList(start.deepEquivalent(), start.previous(CannotCrossEditingBoundary), listTag);
-    Element* nextList = adjacentEnclosingList(start.deepEquivalent(), end.next(CannotCrossEditingBoundary), listTag);
+    Element* previousList = adjacentEnclosingList(start, start.previous(CannotCrossEditingBoundary), listTag);
+    Element* nextList = adjacentEnclosingList(start, end.next(CannotCrossEditingBoundary), listTag);
     RefPtr<HTMLElement> listElement;
     if (previousList)
         appendNode(listItemElement, previousList);
@@ -358,7 +363,7 @@
             // by a br or a '\n', will invalidate start and end.  Insert
             // a placeholder and then recompute start and end.
             RefPtr<Node> placeholder = insertBlockPlaceholder(start.deepEquivalent());
-            start = positionBeforeNode(placeholder.get());
+            start = VisiblePosition(positionBeforeNode(placeholder.get()));
             end = start;
         }
 
@@ -370,8 +375,8 @@
         Position insertionPos(start.deepEquivalent().upstream());
         // Also avoid the containing list item.
         Node* listChild = enclosingListChild(insertionPos.deprecatedNode());
-        if (listChild && listChild->hasTagName(liTag))
-            insertionPos = positionInParentBeforeNode(listChild);
+        if (isHTMLLIElement(listChild))
+            insertionPos = positionInParentBeforeNode(*listChild);
 
         insertNodeAt(listElement, insertionPos);
 
@@ -386,7 +391,7 @@
         }
     }
 
-    moveParagraph(start, end, positionBeforeNode(placeholder.get()), true);
+    moveParagraph(start, end, VisiblePosition(positionBeforeNode(placeholder.get())), true);
 
     if (listElement)
         return mergeWithNeighboringLists(listElement);
diff --git a/Source/core/editing/InsertListCommand.h b/Source/core/editing/InsertListCommand.h
index fe1a5d5..aaa336a 100644
--- a/Source/core/editing/InsertListCommand.h
+++ b/Source/core/editing/InsertListCommand.h
@@ -52,7 +52,7 @@
     HTMLElement* fixOrphanedListChild(Node*);
     bool selectionHasListOfType(const VisibleSelection& selection, const QualifiedName&);
     PassRefPtr<HTMLElement> mergeWithNeighboringLists(PassRefPtr<HTMLElement>);
-    void doApplyForSingleParagraph(bool forceCreateList, const QualifiedName&, Range* currentSelection);
+    void doApplyForSingleParagraph(bool forceCreateList, const QualifiedName&, Range& currentSelection);
     void unlistifyParagraph(const VisiblePosition& originalStart, HTMLElement* listNode, Node* listChildNode);
     PassRefPtr<HTMLElement> listifyParagraph(const VisiblePosition& originalStart, const QualifiedName& listTag);
     RefPtr<HTMLElement> m_listElement;
diff --git a/Source/core/editing/InsertParagraphSeparatorCommand.cpp b/Source/core/editing/InsertParagraphSeparatorCommand.cpp
index 9ad4234..417ab39 100644
--- a/Source/core/editing/InsertParagraphSeparatorCommand.cpp
+++ b/Source/core/editing/InsertParagraphSeparatorCommand.cpp
@@ -50,7 +50,7 @@
     Element* curBlock = startBlock;
     // We don't want to return a root node (if it happens to be a div, e.g., in a document fragment) because there are no
     // siblings for us to append to.
-    while (!curBlock->nextSibling() && curBlock->parentElement()->hasTagName(divTag) && curBlock->parentElement()->parentElement()) {
+    while (!curBlock->nextSibling() && isHTMLDivElement(*curBlock->parentElement()) && curBlock->parentElement()->parentElement()) {
         if (curBlock->parentElement()->hasAttributes())
             break;
         curBlock = curBlock->parentElement();
@@ -170,10 +170,10 @@
     if (!startBlock
         || !startBlock->nonShadowBoundaryParentNode()
         || isTableCell(startBlock.get())
-        || startBlock->hasTagName(formTag)
+        || isHTMLFormElement(*startBlock)
         // FIXME: If the node is hidden, we don't have a canonical position so we will do the wrong thing for tables and <hr>. https://bugs.webkit.org/show_bug.cgi?id=40342
         || (!canonicalPos.isNull() && isRenderedTable(canonicalPos.deprecatedNode()))
-        || (!canonicalPos.isNull() && canonicalPos.deprecatedNode()->hasTagName(hrTag))) {
+        || (!canonicalPos.isNull() && isHTMLHRElement(*canonicalPos.deprecatedNode()))) {
         applyCommandToComposite(InsertLineBreakCommand::create(document()));
         return;
     }
@@ -240,7 +240,7 @@
                 // Most of the time we want to stay at the nesting level of the startBlock (e.g., when nesting within lists). However,
                 // for div nodes, this can result in nested div tags that are hard to break out of.
                 Element* siblingNode = startBlock.get();
-                if (blockToInsert->hasTagName(divTag))
+                if (isHTMLDivElement(*blockToInsert))
                     siblingNode = highestVisuallyEquivalentDivBelowRoot(startBlock.get());
                 insertNodeAfter(blockToInsert, siblingNode);
             }
@@ -280,7 +280,7 @@
             refNode = startBlock->firstChild();
         }
         else if (insertionPosition.deprecatedNode() == startBlock && nestNewBlock) {
-            refNode = startBlock->childNode(insertionPosition.deprecatedEditingOffset());
+            refNode = startBlock->traverseToChildAt(insertionPosition.deprecatedEditingOffset());
             ASSERT(refNode); // must be true or we'd be in the end of block case
         } else
             refNode = insertionPosition.deprecatedNode();
@@ -313,7 +313,7 @@
     if (isStartOfParagraph(visiblePos)) {
         RefPtr<Element> br = createBreakElement(document());
         insertNodeAt(br.get(), insertionPosition);
-        insertionPosition = positionInParentAfterNode(br.get());
+        insertionPosition = positionInParentAfterNode(*br);
         // If the insertion point is a break element, there is nothing else
         // we need to do.
         if (visiblePos.deepEquivalent().anchorNode()->renderer()->isBR()) {
@@ -400,7 +400,7 @@
             splitTreeToNode(splitTo, startBlock.get());
 
             for (n = startBlock->firstChild(); n; n = n->nextSibling()) {
-                VisiblePosition beforeNodePosition = positionBeforeNode(n);
+                VisiblePosition beforeNodePosition(positionBeforeNode(n));
                 if (!beforeNodePosition.isNull() && comparePositions(VisiblePosition(insertionPosition), beforeNodePosition) <= 0)
                     break;
             }
diff --git a/Source/core/editing/InsertTextCommand.cpp b/Source/core/editing/InsertTextCommand.cpp
index 213fc8d..da200d7 100644
--- a/Source/core/editing/InsertTextCommand.cpp
+++ b/Source/core/editing/InsertTextCommand.cpp
@@ -32,7 +32,7 @@
 #include "core/editing/Editor.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
@@ -164,7 +164,8 @@
 
     // It is possible for the node that contains startPosition to contain only unrendered whitespace,
     // and so deleteInsignificantText could remove it.  Save the position before the node in case that happens.
-    Position positionBeforeStartNode(positionInParentBeforeNode(startPosition.containerNode()));
+    ASSERT(startPosition.containerNode());
+    Position positionBeforeStartNode(positionInParentBeforeNode(*startPosition.containerNode()));
     deleteInsignificantText(startPosition, startPosition.downstream());
     if (!startPosition.inDocument())
         startPosition = positionBeforeStartNode;
diff --git a/Source/core/editing/MarkupAccumulator.cpp b/Source/core/editing/MarkupAccumulator.cpp
index 044e9ee..0dd6adf 100644
--- a/Source/core/editing/MarkupAccumulator.cpp
+++ b/Source/core/editing/MarkupAccumulator.cpp
@@ -96,10 +96,11 @@
         appendCharactersReplacingEntitiesInternal(result, source.characters16() + offset, length, entityMaps, WTF_ARRAY_LENGTH(entityMaps), entityMask);
 }
 
-MarkupAccumulator::MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs resolveUrlsMethod, const Range* range)
+MarkupAccumulator::MarkupAccumulator(Vector<Node*>* nodes, EAbsoluteURLs resolveUrlsMethod, const Range* range, SerializationType serializationType)
     : m_nodes(nodes)
     , m_range(range)
     , m_resolveURLsMethod(resolveUrlsMethod)
+    , m_serializationType(serializationType)
 {
 }
 
@@ -109,7 +110,15 @@
 
 String MarkupAccumulator::serializeNodes(Node& targetNode, EChildrenOnly childrenOnly, Vector<QualifiedName>* tagNamesToSkip)
 {
-    serializeNodesWithNamespaces(targetNode, childrenOnly, 0, tagNamesToSkip);
+    Namespaces* namespaces = 0;
+    Namespaces namespaceHash;
+    if (!serializeAsHTMLDocument(targetNode)) {
+        // Add pre-bound namespaces for XML fragments.
+        namespaceHash.set(xmlAtom.impl(), XMLNames::xmlNamespaceURI.impl());
+        namespaces = &namespaceHash;
+    }
+
+    serializeNodesWithNamespaces(targetNode, childrenOnly, namespaces, tagNamesToSkip);
     return m_markup.toString();
 }
 
@@ -129,8 +138,8 @@
     if (!childrenOnly)
         appendStartTag(targetNode, &namespaceHash);
 
-    if (!(targetNode.document().isHTMLDocument() && elementCannotHaveEndTag(targetNode))) {
-        Node* current = targetNode.hasTagName(templateTag) ? toHTMLTemplateElement(targetNode).content()->firstChild() : targetNode.firstChild();
+    if (!(serializeAsHTMLDocument(targetNode) && elementCannotHaveEndTag(targetNode))) {
+        Node* current = isHTMLTemplateElement(targetNode) ? toHTMLTemplateElement(targetNode).content()->firstChild() : targetNode.firstChild();
         for ( ; current; current = current->nextSibling())
             serializeNodesWithNamespaces(*current, IncludeNode, &namespaceHash, tagNamesToSkip);
     }
@@ -222,12 +231,17 @@
     result.append(quoteChar);
 }
 
-bool MarkupAccumulator::shouldAddNamespaceElement(const Element& element)
+bool MarkupAccumulator::shouldAddNamespaceElement(const Element& element, Namespaces& namespaces)
 {
     // Don't add namespace attribute if it is already defined for this elem.
     const AtomicString& prefix = element.prefix();
-    if (prefix.isEmpty())
-        return !element.hasAttribute(xmlnsAtom);
+    if (prefix.isEmpty()) {
+        if (element.hasAttribute(xmlnsAtom)) {
+            namespaces.set(emptyAtom.impl(), element.namespaceURI().impl());
+            return false;
+        }
+        return true;
+    }
 
     DEFINE_STATIC_LOCAL(String, xmlnsWithColon, ("xmlns:"));
     return !element.hasAttribute(xmlnsWithColon + prefix);
@@ -275,7 +289,7 @@
 
 EntityMask MarkupAccumulator::entityMaskForText(const Text& text) const
 {
-    if (!text.document().isHTMLDocument())
+    if (!serializeAsHTMLDocument(text))
         return EntityMaskInPCDATA;
 
     const QualifiedName* parentName = 0;
@@ -381,7 +395,7 @@
     if (element.hasAttributes()) {
         unsigned length = element.attributeCount();
         for (unsigned int i = 0; i < length; i++)
-            appendAttribute(result, element, *element.attributeItem(i), namespaces);
+            appendAttribute(result, element, element.attributeItem(i), namespaces);
     }
 
     // Give an opportunity to subclasses to add their own attributes.
@@ -399,7 +413,7 @@
 {
     result.append('<');
     result.append(nodeNamePreservingCase(element));
-    if (!element.document().isHTMLDocument() && namespaces && shouldAddNamespaceElement(element))
+    if (!serializeAsHTMLDocument(element) && namespaces && shouldAddNamespaceElement(element, *namespaces))
         appendNamespace(result, element.prefix(), element.namespaceURI(), *namespaces);
 }
 
@@ -422,14 +436,14 @@
 
 void MarkupAccumulator::appendAttribute(StringBuilder& result, const Element& element, const Attribute& attribute, Namespaces* namespaces)
 {
-    bool documentIsHTML = element.document().isHTMLDocument();
+    bool documentIsHTML = serializeAsHTMLDocument(element);
 
     result.append(' ');
 
-    if (documentIsHTML && !attributeIsInSerializedNamespace(attribute))
+    QualifiedName prefixedName = attribute.name();
+    if (documentIsHTML && !attributeIsInSerializedNamespace(attribute)) {
         result.append(attribute.name().localName());
-    else {
-        QualifiedName prefixedName = attribute.name();
+    } else {
         if (attribute.namespaceURI() == XLinkNames::xlinkNamespaceURI) {
             if (!attribute.prefix())
                 prefixedName.setPrefix(xlinkAtom);
@@ -445,16 +459,16 @@
 
     result.append('=');
 
-    if (element.isURLAttribute(attribute))
+    if (element.isURLAttribute(attribute)) {
         appendQuotedURLAttributeValue(result, element, attribute);
-    else {
+    } else {
         result.append('"');
         appendAttributeValue(result, attribute.value(), documentIsHTML);
         result.append('"');
     }
 
     if (!documentIsHTML && namespaces && shouldAddNamespaceAttribute(attribute, *namespaces))
-        appendNamespace(result, attribute.prefix(), attribute.namespaceURI(), *namespaces);
+        appendNamespace(result, prefixedName.prefix(), prefixedName.namespaceURI(), *namespaces);
 }
 
 void MarkupAccumulator::appendCDATASection(StringBuilder& result, const String& section)
@@ -504,9 +518,9 @@
 // 4. Other elements self-close.
 bool MarkupAccumulator::shouldSelfClose(const Node& node)
 {
-    if (node.document().isHTMLDocument())
+    if (serializeAsHTMLDocument(node))
         return false;
-    if (node.hasChildNodes())
+    if (node.hasChildren())
         return false;
     if (node.isHTMLElement() && !elementCannotHaveEndTag(node))
         return false;
@@ -527,7 +541,7 @@
 
 void MarkupAccumulator::appendEndMarkup(StringBuilder& result, const Node& node)
 {
-    if (!node.isElementNode() || shouldSelfClose(node) || (!node.hasChildNodes() && elementCannotHaveEndTag(node)))
+    if (!node.isElementNode() || shouldSelfClose(node) || (!node.hasChildren() && elementCannotHaveEndTag(node)))
         return;
 
     result.appendLiteral("</");
@@ -535,4 +549,11 @@
     result.append('>');
 }
 
+bool MarkupAccumulator::serializeAsHTMLDocument(const Node& node) const
+{
+    if (m_serializationType == ForcedXML)
+        return false;
+    return node.document().isHTMLDocument();
+}
+
 }
diff --git a/Source/core/editing/MarkupAccumulator.h b/Source/core/editing/MarkupAccumulator.h
index f14d6ed..595bf49 100644
--- a/Source/core/editing/MarkupAccumulator.h
+++ b/Source/core/editing/MarkupAccumulator.h
@@ -57,11 +57,16 @@
     EntityMaskInHTMLAttributeValue = EntityAmp | EntityQuot | EntityNbsp,
 };
 
+enum SerializationType {
+    AsOwnerDocument,
+    ForcedXML
+};
+
 class MarkupAccumulator {
     WTF_MAKE_NONCOPYABLE(MarkupAccumulator);
 
 public:
-    MarkupAccumulator(Vector<Node*>*, EAbsoluteURLs, const Range* = 0);
+    MarkupAccumulator(Vector<Node*>*, EAbsoluteURLs, const Range* = 0, SerializationType = AsOwnerDocument);
     virtual ~MarkupAccumulator();
 
     String serializeNodes(Node& targetNode, EChildrenOnly, Vector<QualifiedName>* tagNamesToSkip = 0);
@@ -79,7 +84,7 @@
     void concatenateMarkup(StringBuilder&);
     void appendAttributeValue(StringBuilder&, const String&, bool);
     virtual void appendCustomAttributes(StringBuilder&, const Element&, Namespaces*);
-    bool shouldAddNamespaceElement(const Element&);
+    bool shouldAddNamespaceElement(const Element&, Namespaces&);
     bool shouldAddNamespaceAttribute(const Attribute&, Namespaces&);
     void appendNamespace(StringBuilder&, const AtomicString& prefix, const AtomicString& namespaceURI, Namespaces&);
     EntityMask entityMaskForText(const Text&) const;
@@ -104,9 +109,11 @@
     String resolveURLIfNeeded(const Element&, const String&) const;
     void appendQuotedURLAttributeValue(StringBuilder&, const Element&, const Attribute&);
     void serializeNodesWithNamespaces(Node& targetNode, EChildrenOnly, const Namespaces*, Vector<QualifiedName>* tagNamesToSkip);
+    bool serializeAsHTMLDocument(const Node&) const;
 
     StringBuilder m_markup;
     const EAbsoluteURLs m_resolveURLsMethod;
+    SerializationType m_serializationType;
 };
 
 }
diff --git a/Source/core/editing/MoveSelectionCommand.cpp b/Source/core/editing/MoveSelectionCommand.cpp
index 7d45d37..9ea9521 100644
--- a/Source/core/editing/MoveSelectionCommand.cpp
+++ b/Source/core/editing/MoveSelectionCommand.cpp
@@ -65,7 +65,7 @@
     if (!pos.inDocument())
         pos = endingSelection().start();
 
-    cleanupAfterDeletion(pos);
+    cleanupAfterDeletion(VisiblePosition(pos));
 
     setEndingSelection(VisibleSelection(pos, endingSelection().affinity(), endingSelection().isDirectional()));
     if (!pos.inDocument()) {
diff --git a/Source/core/editing/PlainTextRange.cpp b/Source/core/editing/PlainTextRange.cpp
index 82f3215..096fb6d 100644
--- a/Source/core/editing/PlainTextRange.cpp
+++ b/Source/core/editing/PlainTextRange.cpp
@@ -147,7 +147,7 @@
     }
 
     if (!startRangeFound)
-        return 0;
+        return nullptr;
 
     if (length() && end() > docTextPosition) { // end() is out of bounds
         resultRange->setEnd(textRunRange->endContainer(), textRunRange->endOffset(), IGNORE_EXCEPTION);
diff --git a/Source/core/editing/RemoveFormatCommand.cpp b/Source/core/editing/RemoveFormatCommand.cpp
index d36a527..23c660e 100644
--- a/Source/core/editing/RemoveFormatCommand.cpp
+++ b/Source/core/editing/RemoveFormatCommand.cpp
@@ -34,7 +34,7 @@
 #include "core/editing/ApplyStyleCommand.h"
 #include "core/editing/EditingStyle.h"
 #include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
@@ -79,7 +79,7 @@
 
 void RemoveFormatCommand::doApply()
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
 
     if (!frame->selection().selection().isNonOrphanedCaretOrRange())
         return;
diff --git a/Source/core/editing/RenderedPosition.cpp b/Source/core/editing/RenderedPosition.cpp
index a364653..beb15ae 100644
--- a/Source/core/editing/RenderedPosition.cpp
+++ b/Source/core/editing/RenderedPosition.cpp
@@ -74,7 +74,7 @@
         return;
     position.getInlineBoxAndOffset(m_inlineBox, m_offset);
     if (m_inlineBox)
-        m_renderer = m_inlineBox->renderer();
+        m_renderer = &m_inlineBox->renderer();
     else
         m_renderer = rendererFromPosition(position.deepEquivalent());
 }
@@ -90,7 +90,7 @@
         return;
     position.getInlineBoxAndOffset(affinity, m_inlineBox, m_offset);
     if (m_inlineBox)
-        m_renderer = m_inlineBox->renderer();
+        m_renderer = &m_inlineBox->renderer();
     else
         m_renderer = rendererFromPosition(position);
 }
@@ -137,7 +137,7 @@
     do {
         InlineBox* prev = box->prevLeafChildIgnoringLineBreak();
         if (!prev || prev->bidiLevel() < bidiLevelOfRun)
-            return RenderedPosition(box->renderer(), box, box->caretLeftmostOffset());
+            return RenderedPosition(&box->renderer(), box, box->caretLeftmostOffset());
         box = prev;
     } while (box);
 
@@ -154,7 +154,7 @@
     do {
         InlineBox* next = box->nextLeafChildIgnoringLineBreak();
         if (!next || next->bidiLevel() < bidiLevelOfRun)
-            return RenderedPosition(box->renderer(), box, box->caretRightmostOffset());
+            return RenderedPosition(&box->renderer(), box, box->caretRightmostOffset());
         box = next;
     } while (box);
 
@@ -209,7 +209,7 @@
     if (atLeftmostOffsetInBox())
         return createLegacyEditingPosition(m_renderer->node(), m_offset);
 
-    return createLegacyEditingPosition(nextLeafChild()->renderer()->node(), nextLeafChild()->caretLeftmostOffset());
+    return createLegacyEditingPosition(nextLeafChild()->renderer().node(), nextLeafChild()->caretLeftmostOffset());
 }
 
 Position RenderedPosition::positionAtRightBoundaryOfBiDiRun() const
@@ -219,7 +219,7 @@
     if (atRightmostOffsetInBox())
         return createLegacyEditingPosition(m_renderer->node(), m_offset);
 
-    return createLegacyEditingPosition(prevLeafChild()->renderer()->node(), prevLeafChild()->caretRightmostOffset());
+    return createLegacyEditingPosition(prevLeafChild()->renderer().node(), prevLeafChild()->caretRightmostOffset());
 }
 
 IntRect RenderedPosition::absoluteRect(LayoutUnit* extraWidthToEndOfLine) const
diff --git a/Source/core/editing/RenderedPosition.h b/Source/core/editing/RenderedPosition.h
index 7cf2195..fff2d2b 100644
--- a/Source/core/editing/RenderedPosition.h
+++ b/Source/core/editing/RenderedPosition.h
@@ -49,7 +49,7 @@
     bool isEquivalent(const RenderedPosition&) const;
 
     bool isNull() const { return !m_renderer; }
-    RootInlineBox* rootBox() { return m_inlineBox ? m_inlineBox->root() : 0; }
+    RootInlineBox* rootBox() { return m_inlineBox ? &m_inlineBox->root() : 0; }
 
     unsigned char bidiLevelOnLeft() const;
     unsigned char bidiLevelOnRight() const;
diff --git a/Source/core/editing/ReplaceSelectionCommand.cpp b/Source/core/editing/ReplaceSelectionCommand.cpp
index 984c9e0..7428ed7 100644
--- a/Source/core/editing/ReplaceSelectionCommand.cpp
+++ b/Source/core/editing/ReplaceSelectionCommand.cpp
@@ -48,9 +48,9 @@
 #include "core/editing/markup.h"
 #include "core/events/BeforeTextInsertedEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLInputElement.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/RenderText.h"
 #include "wtf/StdLibExtras.h"
@@ -97,7 +97,7 @@
 static bool isInterchangeNewlineNode(const Node *node)
 {
     DEFINE_STATIC_LOCAL(String, interchangeNewlineClassString, (AppleInterchangeNewline));
-    return node && node->hasTagName(brTag) && toElement(node)->getAttribute(classAttr) == interchangeNewlineClassString;
+    return isHTMLBRElement(node) && toElement(node)->getAttribute(classAttr) == interchangeNewlineClassString;
 }
 
 static bool isInterchangeConvertedSpaceSpan(const Node *node)
@@ -122,7 +122,7 @@
             break;
 
         if (pos.containerNode()->nonShadowBoundaryParentNode())
-            nextPosition = positionInParentAfterNode(pos.containerNode());
+            nextPosition = positionInParentAfterNode(*pos.containerNode());
 
         if (nextPosition == pos
             || enclosingBlock(nextPosition.containerNode()) != enclosingBlockNode
@@ -295,7 +295,7 @@
         }
         node = node->firstChild();
     }
-    if (!container->hasChildNodes())
+    if (!container->hasChildren())
         return;
     // Interchange newlines at the "end" of the incoming fragment must be
     // either the last node in the fragment or the last leaf in the fragment.
@@ -339,8 +339,8 @@
 inline void ReplaceSelectionCommand::InsertedNodes::willRemoveNode(Node& node)
 {
     if (m_firstNodeInserted == node && m_lastNodeInserted == node) {
-        m_firstNodeInserted = 0;
-        m_lastNodeInserted = 0;
+        m_firstNodeInserted = nullptr;
+        m_lastNodeInserted = nullptr;
     } else if (m_firstNodeInserted == node) {
         m_firstNodeInserted = NodeTraversal::nextSkippingChildren(*m_firstNodeInserted);
     } else if (m_lastNodeInserted == node) {
@@ -399,7 +399,7 @@
     return !selectionStartWasStartOfParagraph
         && !fragmentHasInterchangeNewlineAtStart
         && isStartOfParagraph(startOfInsertedContent)
-        && !startOfInsertedContent.deepEquivalent().deprecatedNode()->hasTagName(brTag)
+        && !isHTMLBRElement(*startOfInsertedContent.deepEquivalent().deprecatedNode())
         && shouldMerge(startOfInsertedContent, prev);
 }
 
@@ -412,13 +412,13 @@
 
     return !selectionEndWasEndOfParagraph
         && isEndOfParagraph(endOfInsertedContent)
-        && !endOfInsertedContent.deepEquivalent().deprecatedNode()->hasTagName(brTag)
+        && !isHTMLBRElement(*endOfInsertedContent.deepEquivalent().deprecatedNode())
         && shouldMerge(endOfInsertedContent, next);
 }
 
 static bool isMailPasteAsQuotationNode(const Node* node)
 {
-    return node && node->hasTagName(blockquoteTag) && node->isElementNode() && toElement(node)->getAttribute(classAttr) == ApplePasteAsQuotation;
+    return node && node->hasTagName(blockquoteTag) && toElement(node)->getAttribute(classAttr) == ApplePasteAsQuotation;
 }
 
 static bool isHeaderElement(const Node* a)
@@ -620,12 +620,12 @@
             continue;
 
         if (isProhibitedParagraphChild(toHTMLElement(node)->localName())) {
-            if (HTMLElement* paragraphElement = toHTMLElement(enclosingNodeWithTag(positionInParentBeforeNode(node.get()), pTag)))
+            if (HTMLElement* paragraphElement = toHTMLElement(enclosingNodeWithTag(positionInParentBeforeNode(*node), pTag)))
                 moveNodeOutOfAncestor(node, paragraphElement);
         }
 
         if (isHeaderElement(node.get())) {
-            if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(node.get()), isHeaderElement)))
+            if (HTMLElement* headerElement = toHTMLElement(highestEnclosingNodeOfType(positionInParentBeforeNode(*node), isHeaderElement)))
                 moveNodeOutOfAncestor(node, headerElement);
         }
     }
@@ -639,8 +639,8 @@
     if (!ancestor->parentNode()->rendererIsEditable())
         return;
 
-    VisiblePosition positionAtEndOfNode = lastPositionInOrAfterNode(node.get());
-    VisiblePosition lastPositionInParagraph = lastPositionInNode(ancestor.get());
+    VisiblePosition positionAtEndOfNode(lastPositionInOrAfterNode(node.get()));
+    VisiblePosition lastPositionInParagraph(lastPositionInNode(ancestor.get()));
     if (positionAtEndOfNode == lastPositionInParagraph) {
         removeNode(node);
         if (ancestor->nextSibling())
@@ -686,23 +686,23 @@
 {
     // FIXME: Why is this hack here?  What's special about <select> tags?
     Node* enclosingSelect = enclosingNodeWithTag(m_endOfInsertedContent, selectTag);
-    return enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endOfInsertedContent;
+    return VisiblePosition(enclosingSelect ? lastPositionInOrAfterNode(enclosingSelect) : m_endOfInsertedContent);
 }
 
 VisiblePosition ReplaceSelectionCommand::positionAtStartOfInsertedContent() const
 {
-    return m_startOfInsertedContent;
+    return VisiblePosition(m_startOfInsertedContent);
 }
 
 static void removeHeadContents(ReplacementFragment& fragment)
 {
     Node* next = 0;
     for (Node* node = fragment.firstChild(); node; node = next) {
-        if (node->hasTagName(baseTag)
-            || node->hasTagName(linkTag)
-            || node->hasTagName(metaTag)
-            || node->hasTagName(styleTag)
-            || node->hasTagName(titleTag)) {
+        if (isHTMLBaseElement(*node)
+            || isHTMLLinkElement(*node)
+            || isHTMLMetaElement(*node)
+            || isHTMLStyleElement(*node)
+            || isHTMLTitleElement(*node)) {
             next = NodeTraversal::nextSkippingChildren(*node);
             fragment.removeNode(node);
         } else {
@@ -840,7 +840,7 @@
 static Node* enclosingInline(Node* node)
 {
     while (ContainerNode* parent = node->parentNode()) {
-        if (parent->isBlockFlowElement() || parent->hasTagName(bodyTag))
+        if (parent->isBlockFlowElement() || isHTMLBodyElement(*parent))
             return node;
         // Stop if any previous sibling is a block.
         for (Node* sibling = node->previousSibling(); sibling; sibling = sibling->previousSibling()) {
@@ -971,9 +971,9 @@
         applyCommandToComposite(BreakBlockquoteCommand::create(document()));
         // This will leave a br between the split.
         Node* br = endingSelection().start().deprecatedNode();
-        ASSERT(br->hasTagName(brTag));
+        ASSERT(isHTMLBRElement(br));
         // Insert content between the two blockquotes, but remove the br (since it was just a placeholder).
-        insertionPos = positionInParentBeforeNode(br);
+        insertionPos = positionInParentBeforeNode(*br);
         removeNode(br);
     }
 
@@ -987,7 +987,7 @@
     // NOTE: This would be an incorrect usage of downstream() if downstream() were changed to mean the last position after
     // p that maps to the same visible position as p (since in the case where a br is at the end of a block and collapsed
     // away, there are positions after the br which map to the same visible position as [br, 0]).
-    Node* endBR = insertionPos.downstream().deprecatedNode()->hasTagName(brTag) ? insertionPos.downstream().deprecatedNode() : 0;
+    Node* endBR = isHTMLBRElement(*insertionPos.downstream().deprecatedNode()) ? insertionPos.downstream().deprecatedNode() : 0;
     VisiblePosition originalVisPosBeforeEndBR;
     if (endBR)
         originalVisPosBeforeEndBR = VisiblePosition(positionBeforeNode(endBR), DOWNSTREAM).previous();
@@ -1000,9 +1000,9 @@
         ASSERT(insertionBlock != currentRoot);
         VisiblePosition visibleInsertionPos(insertionPos);
         if (isEndOfBlock(visibleInsertionPos) && !(isStartOfBlock(visibleInsertionPos) && fragment.hasInterchangeNewlineAtEnd()))
-            insertionPos = positionInParentAfterNode(insertionBlock.get());
+            insertionPos = positionInParentAfterNode(*insertionBlock);
         else if (isStartOfBlock(visibleInsertionPos))
-            insertionPos = positionInParentBeforeNode(insertionBlock.get());
+            insertionPos = positionInParentBeforeNode(*insertionBlock);
     }
 
     // Paste at start or end of link goes outside of link.
@@ -1010,7 +1010,7 @@
 
     // FIXME: Can this wait until after the operation has been performed?  There doesn't seem to be
     // any work performed after this that queries or uses the typing style.
-    if (Frame* frame = document().frame())
+    if (LocalFrame* frame = document().frame())
         frame->selection().clearTypingStyle();
 
     removeHeadContents(fragment);
@@ -1047,7 +1047,7 @@
                 if (!splitStart)
                     splitStart = insertionPos.containerNode();
                 nodeToSplitTo = splitTreeToNode(splitStart, nodeToSplitTo->parentNode()).get();
-                insertionPos = positionInParentBeforeNode(nodeToSplitTo.get());
+                insertionPos = positionInParentBeforeNode(*nodeToSplitTo);
             }
         }
     }
@@ -1115,13 +1115,13 @@
     // Scripts specified in javascript protocol may remove |insertionBlock|
     // during insertion, e.g. <iframe src="javascript:...">
     if (insertionBlock && !insertionBlock->inDocument())
-        insertionBlock = 0;
+        insertionBlock = nullptr;
 
-    VisiblePosition startOfInsertedContent = firstPositionInOrBeforeNode(insertedNodes.firstNodeInserted());
+    VisiblePosition startOfInsertedContent(firstPositionInOrBeforeNode(insertedNodes.firstNodeInserted()));
 
     // We inserted before the insertionBlock to prevent nesting, and the content before the insertionBlock wasn't in its own block and
     // didn't have a br after it, so the inserted content ended up in the same paragraph.
-    if (insertionBlock && insertionPos.deprecatedNode() == insertionBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < insertionBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
+    if (!startOfInsertedContent.isNull() && insertionBlock && insertionPos.deprecatedNode() == insertionBlock->parentNode() && (unsigned)insertionPos.deprecatedEditingOffset() < insertionBlock->nodeIndex() && !isStartOfParagraph(startOfInsertedContent))
         insertNodeAt(createBreakElement(document()).get(), startOfInsertedContent.deepEquivalent());
 
     if (endBR && (plainTextFragment || (shouldRemoveEndBR(endBR, originalVisPosBeforeEndBR) && !(fragment.hasInterchangeNewlineAtEnd() && selectionIsPlainText)))) {
@@ -1254,7 +1254,7 @@
         return false;
 
     Element* textControl = enclosingTextFormControl(positionAtStartOfInsertedContent().deepEquivalent());
-    if (textControl && textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isPasswordField())
+    if (isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->isPasswordField())
         return false; // Disable smart replace for password fields.
 
     return true;
@@ -1354,7 +1354,7 @@
 {
     bool positionIsOffsetInAnchor = position.anchorType() == Position::PositionIsOffsetInAnchor;
     bool positionOnlyToBeUpdatedIsOffsetInAnchor = positionOnlyToBeUpdated.anchorType() == Position::PositionIsOffsetInAnchor;
-    RefPtr<Text> text = 0;
+    RefPtr<Text> text = nullptr;
     if (positionIsOffsetInAnchor && position.containerNode() && position.containerNode()->isTextNode())
         text = toText(position.containerNode());
     else {
@@ -1377,15 +1377,16 @@
         if (positionIsOffsetInAnchor)
             position.moveToOffset(previous->length() + position.offsetInContainerNode());
         else
-            updatePositionForNodeRemoval(position, previous.get());
+            updatePositionForNodeRemoval(position, *previous);
 
         if (positionOnlyToBeUpdatedIsOffsetInAnchor) {
             if (positionOnlyToBeUpdated.containerNode() == text)
                 positionOnlyToBeUpdated.moveToOffset(previous->length() + positionOnlyToBeUpdated.offsetInContainerNode());
             else if (positionOnlyToBeUpdated.containerNode() == previous)
                 positionOnlyToBeUpdated.moveToPosition(text, positionOnlyToBeUpdated.offsetInContainerNode());
-        } else
-            updatePositionForNodeRemoval(positionOnlyToBeUpdated, previous.get());
+        } else {
+            updatePositionForNodeRemoval(positionOnlyToBeUpdated, *previous);
+        }
 
         removeNode(previous);
     }
@@ -1395,12 +1396,12 @@
         insertTextIntoNode(text, originalLength, next->data());
 
         if (!positionIsOffsetInAnchor)
-            updatePositionForNodeRemoval(position, next.get());
+            updatePositionForNodeRemoval(position, *next);
 
         if (positionOnlyToBeUpdatedIsOffsetInAnchor && positionOnlyToBeUpdated.containerNode() == next)
             positionOnlyToBeUpdated.moveToPosition(text, originalLength + positionOnlyToBeUpdated.offsetInContainerNode());
         else
-            updatePositionForNodeRemoval(positionOnlyToBeUpdated, next.get());
+            updatePositionForNodeRemoval(positionOnlyToBeUpdated, *next);
 
         removeNode(next);
     }
@@ -1417,11 +1418,11 @@
 {
     RefPtr<HTMLElement> listElement = prpListElement;
 
-    while (listElement->hasChildNodes() && isListElement(listElement->firstChild()) && listElement->childNodeCount() == 1)
+    while (listElement->hasChildren() && isListElement(listElement->firstChild()) && listElement->hasOneChild())
         listElement = toHTMLElement(listElement->firstChild());
 
-    bool isStart = isStartOfParagraph(insertPos);
-    bool isEnd = isEndOfParagraph(insertPos);
+    bool isStart = isStartOfParagraph(VisiblePosition(insertPos));
+    bool isEnd = isEndOfParagraph(VisiblePosition(insertPos));
     bool isMiddle = !isStart && !isEnd;
     Node* lastNode = insertionBlock;
 
@@ -1488,8 +1489,8 @@
     if (end.isNull())
         return false;
 
-    if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && nodeAfterInsertionPos->hasTagName(brTag)
-        && shouldRemoveEndBR(nodeAfterInsertionPos.get(), positionBeforeNode(nodeAfterInsertionPos.get())))
+    if (nodeAfterInsertionPos && nodeAfterInsertionPos->parentNode() && isHTMLBRElement(*nodeAfterInsertionPos)
+        && shouldRemoveEndBR(nodeAfterInsertionPos.get(), VisiblePosition(positionBeforeNode(nodeAfterInsertionPos.get()))))
         removeNodeAndPruneAncestors(nodeAfterInsertionPos.get());
 
     VisibleSelection selectionAfterReplace(m_selectReplacement ? start : end, end);
diff --git a/Source/core/editing/ReplaceSelectionCommand.h b/Source/core/editing/ReplaceSelectionCommand.h
index 4173df5..e4411cc 100644
--- a/Source/core/editing/ReplaceSelectionCommand.h
+++ b/Source/core/editing/ReplaceSelectionCommand.h
@@ -67,7 +67,7 @@
 
         Node* firstNodeInserted() const { return m_firstNodeInserted.get(); }
         Node* lastLeafInserted() const { return m_lastNodeInserted ? &m_lastNodeInserted->lastDescendant() : 0; }
-        Node* pastLastLeaf() const { return m_lastNodeInserted ? NodeTraversal::next(*lastLeafInserted()) : 0; }
+        Node* pastLastLeaf() const { return m_lastNodeInserted ? NodeTraversal::next(m_lastNodeInserted->lastDescendant()) : 0; }
 
     private:
         RefPtr<Node> m_firstNodeInserted;
diff --git a/Source/core/editing/SpellCheckRequester.cpp b/Source/core/editing/SpellCheckRequester.cpp
index 104f446..ebe860f 100644
--- a/Source/core/editing/SpellCheckRequester.cpp
+++ b/Source/core/editing/SpellCheckRequester.cpp
@@ -30,7 +30,7 @@
 #include "core/dom/DocumentMarkerController.h"
 #include "core/dom/Node.h"
 #include "core/editing/SpellChecker.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "platform/text/TextCheckerClient.h"
 
@@ -68,7 +68,7 @@
     if (!text.length())
         return PassRefPtr<SpellCheckRequest>();
 
-    const Vector<DocumentMarker*>& markers = checkingRange->ownerDocument().markers()->markersInRange(checkingRange.get(), DocumentMarker::SpellCheckClientMarkers());
+    const Vector<DocumentMarker*>& markers = checkingRange->ownerDocument().markers().markersInRange(checkingRange.get(), DocumentMarker::SpellCheckClientMarkers());
     Vector<uint32_t> hashes(markers.size());
     Vector<unsigned> offsets(markers.size());
     for (size_t i = 0; i < markers.size(); i++) {
@@ -115,7 +115,7 @@
     m_requester = 0;
 }
 
-SpellCheckRequester::SpellCheckRequester(Frame& frame)
+SpellCheckRequester::SpellCheckRequester(LocalFrame& frame)
     : m_frame(frame)
     , m_lastRequestSequence(0)
     , m_lastProcessedSequence(0)
@@ -240,7 +240,7 @@
 
     m_processingRequest.clear();
     if (!m_requestQueue.isEmpty())
-        m_timerToProcessQueuedRequest.startOneShot(0);
+        m_timerToProcessQueuedRequest.startOneShot(0, FROM_HERE);
 }
 
 void SpellCheckRequester::didCheckSucceed(int sequence, const Vector<TextCheckingResult>& results)
@@ -252,7 +252,7 @@
             markers.remove(DocumentMarker::Spelling);
         if (!requestData.maskContains(TextCheckingTypeGrammar))
             markers.remove(DocumentMarker::Grammar);
-        m_frame.document()->markers()->removeMarkers(m_processingRequest->checkingRange().get(), markers);
+        m_frame.document()->markers().removeMarkers(m_processingRequest->checkingRange().get(), markers);
     }
     didCheck(sequence, results);
 }
diff --git a/Source/core/editing/SpellCheckRequester.h b/Source/core/editing/SpellCheckRequester.h
index f3fd57f..642329b 100644
--- a/Source/core/editing/SpellCheckRequester.h
+++ b/Source/core/editing/SpellCheckRequester.h
@@ -38,7 +38,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class Node;
 class SpellCheckRequester;
 class TextCheckerClient;
@@ -77,7 +77,7 @@
 public:
     friend class SpellCheckRequest;
 
-    explicit SpellCheckRequester(Frame&);
+    explicit SpellCheckRequester(LocalFrame&);
     ~SpellCheckRequester();
 
     bool isAsynchronousEnabled() const;
@@ -108,7 +108,7 @@
     void didCheckCancel(int sequence);
     void didCheck(int sequence, const Vector<TextCheckingResult>&);
 
-    Frame& m_frame;
+    LocalFrame& m_frame;
     int m_lastRequestSequence;
     int m_lastProcessedSequence;
 
diff --git a/Source/core/editing/SpellChecker.cpp b/Source/core/editing/SpellChecker.cpp
index f73f78a..770ce93 100644
--- a/Source/core/editing/SpellChecker.cpp
+++ b/Source/core/editing/SpellChecker.cpp
@@ -37,7 +37,7 @@
 #include "core/editing/TextCheckingHelper.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/loader/EmptyClients.h"
 #include "core/page/Page.h"
@@ -55,12 +55,12 @@
 bool isSelectionInTextField(const VisibleSelection& selection)
 {
     HTMLTextFormControlElement* textControl = enclosingTextFormControl(selection.start());
-    return textControl && textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isTextField();
+    return isHTMLInputElement(textControl) && toHTMLInputElement(textControl)->isTextField();
 }
 
 } // namespace
 
-PassOwnPtr<SpellChecker> SpellChecker::create(Frame& frame)
+PassOwnPtr<SpellChecker> SpellChecker::create(LocalFrame& frame)
 {
     return adoptPtr(new SpellChecker(frame));
 }
@@ -83,7 +83,7 @@
     return spellCheckerClient().textChecker();
 }
 
-SpellChecker::SpellChecker(Frame& frame)
+SpellChecker::SpellChecker(LocalFrame& frame)
     : m_frame(frame)
     , m_spellCheckRequester(adoptPtr(new SpellCheckRequester(frame)))
 {
@@ -103,7 +103,7 @@
     spellCheckerClient().toggleContinuousSpellChecking();
     if (isContinuousSpellCheckingEnabled())
         return;
-    for (Frame* frame = m_frame.page()->mainFrame(); frame && frame->document(); frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = m_frame.page()->mainFrame(); frame && frame->document(); frame = frame->tree().traverseNext()) {
         for (Node* node = &frame->document()->rootNode(); node; node = NodeTraversal::next(*node)) {
             node->setAlreadySpellChecked(false);
         }
@@ -128,7 +128,7 @@
             HTMLTextFormControlElement* textControl = toHTMLTextFormControlElement(element);
             parent = textControl;
             element = textControl->innerTextElement();
-            isTextField = textControl->hasTagName(inputTag) && toHTMLInputElement(textControl)->isTextField();
+            isTextField = isHTMLInputElement(*textControl) && toHTMLInputElement(*textControl).isTextField();
         }
 
         if (isTextField || !parent->isAlreadySpellChecked()) {
@@ -144,7 +144,7 @@
 void SpellChecker::ignoreSpelling()
 {
     if (RefPtr<Range> selectedRange = m_frame.selection().toNormalizedRange())
-        m_frame.document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
+        m_frame.document()->markers().removeMarkers(selectedRange.get(), DocumentMarker::Spelling);
 }
 
 void SpellChecker::advanceToNextMisspelling(bool startBeforeSelection)
@@ -290,7 +290,7 @@
         m_frame.selection().setSelection(VisibleSelection(badGrammarRange.get(), SEL_DEFAULT_AFFINITY));
         m_frame.selection().revealSelection();
 
-        m_frame.document()->markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
+        m_frame.document()->markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, grammarDetail.userDescription);
     } else if (!misspelledWord.isEmpty()) {
         // We found a misspelling, but not any earlier bad grammar. Select the misspelling, update the spelling panel, and store
         // a marker so we draw the red squiggle later.
@@ -300,7 +300,7 @@
         m_frame.selection().revealSelection();
 
         spellCheckerClient().updateSpellingUIWithMisspelledWord(misspelledWord);
-        m_frame.document()->markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+        m_frame.document()->markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling);
     }
 }
 
@@ -319,7 +319,7 @@
 {
     RefPtr<Range> selectedRange = movingSelection.toNormalizedRange();
     if (selectedRange)
-        m_frame.document()->markers()->removeMarkers(selectedRange.get(), DocumentMarker::MisspellingMarkers());
+        m_frame.document()->markers().removeMarkers(selectedRange.get(), DocumentMarker::MisspellingMarkers());
 }
 
 void SpellChecker::markMisspellingsAndBadGrammar(const VisibleSelection &movingSelection)
@@ -376,7 +376,7 @@
         m_frame.editor().replaceSelectionWithText(autocorrectedString, false, false);
 
         // Reset the charet one character further.
-        m_frame.selection().moveTo(m_frame.selection().end());
+        m_frame.selection().moveTo(m_frame.selection().selection().visibleEnd());
         m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
     }
 
@@ -498,8 +498,8 @@
 
     for (int iter = 0; iter < kNumChunksToCheck; ++iter) {
         checkRange = fullParagraphToCheck.subrange(currentChunkStart, kChunkSize);
-        setStart(checkRange.get(), startOfSentence(checkRange->startPosition()));
-        setEnd(checkRange.get(), endOfSentence(checkRange->endPosition()));
+        setStart(checkRange.get(), startOfSentence(VisiblePosition(checkRange->startPosition())));
+        setEnd(checkRange.get(), endOfSentence(VisiblePosition(checkRange->endPosition())));
 
         int checkingLength = 0;
         markAllMisspellingsAndBadGrammarInRanges(textCheckingOptions, checkRange.get(), checkRange.get(), asynchronous, iter, &checkingLength);
@@ -569,7 +569,7 @@
         if (shouldMarkSpelling && result->decoration == TextDecorationTypeSpelling && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset && !resultEndsAtAmbiguousBoundary) {
             ASSERT(resultLength > 0 && resultLocation >= 0);
             RefPtr<Range> misspellingRange = paragraph.subrange(resultLocation, resultLength);
-            misspellingRange->startContainer()->document().markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling, result->replacement, result->hash);
+            misspellingRange->startContainer()->document().markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling, result->replacement, result->hash);
         } else if (shouldMarkGrammar && result->decoration == TextDecorationTypeGrammar && paragraph.checkingRangeCovers(resultLocation, resultLength)) {
             ASSERT(resultLength > 0 && resultLocation >= 0);
             for (unsigned j = 0; j < result->details.size(); j++) {
@@ -577,13 +577,13 @@
                 ASSERT(detail->length > 0 && detail->location >= 0);
                 if (paragraph.checkingRangeCovers(resultLocation + detail->location, detail->length)) {
                     RefPtr<Range> badGrammarRange = paragraph.subrange(resultLocation + detail->location, detail->length);
-                    badGrammarRange->startContainer()->document().markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription, result->hash);
+                    badGrammarRange->startContainer()->document().markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription, result->hash);
                 }
             }
         } else if (result->decoration == TextDecorationTypeInvisibleSpellcheck && resultLocation >= paragraph.checkingStart() && resultLocation + resultLength <= spellingRangeEndOffset) {
             ASSERT(resultLength > 0 && resultLocation >= 0);
             RefPtr<Range> invisibleSpellcheckRange = paragraph.subrange(resultLocation, resultLength);
-            invisibleSpellcheckRange->startContainer()->document().markers()->addMarker(invisibleSpellcheckRange.get(), DocumentMarker::InvisibleSpellcheck, result->replacement, result->hash);
+            invisibleSpellcheckRange->startContainer()->document().markers().addMarker(invisibleSpellcheckRange.get(), DocumentMarker::InvisibleSpellcheck, result->replacement, result->hash);
         }
     }
 
@@ -598,7 +598,7 @@
                 m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
         } else {
             // If this fails for any reason, the fallback is to go one position beyond the last replacement
-            m_frame.selection().moveTo(m_frame.selection().end());
+            m_frame.selection().moveTo(m_frame.selection().selection().visibleEnd());
             m_frame.selection().modify(FrameSelection::AlterationMove, DirectionForward, CharacterGranularity);
         }
     }
@@ -639,8 +639,8 @@
     // Of course, if current selection is a range, we potentially will edit two words that fall on the boundaries of
     // selection, and remove words between the selection boundaries.
     //
-    VisiblePosition startOfSelection = m_frame.selection().selection().start();
-    VisiblePosition endOfSelection = m_frame.selection().selection().end();
+    VisiblePosition startOfSelection = m_frame.selection().selection().visibleStart();
+    VisiblePosition endOfSelection = m_frame.selection().selection().visibleEnd();
     if (startOfSelection.isNull())
         return;
     // First word is the word that ends after or on the start of selection.
@@ -691,7 +691,7 @@
     ASSERT(document);
     RefPtr<Range> wordRange = Range::create(*document, startOfFirstWord.deepEquivalent(), endOfLastWord.deepEquivalent());
 
-    document->markers()->removeMarkers(wordRange.get(), DocumentMarker::MisspellingMarkers(), DocumentMarkerController::RemovePartiallyOverlappingMarker);
+    document->markers().removeMarkers(wordRange.get(), DocumentMarker::MisspellingMarkers(), DocumentMarkerController::RemovePartiallyOverlappingMarker);
 }
 
 void SpellChecker::didEndEditingOnTextField(Element* e)
@@ -705,7 +705,7 @@
     if (isGrammarCheckingEnabled() || unifiedTextCheckerEnabled())
         markerTypes.add(DocumentMarker::Grammar);
     for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerText)) {
-        m_frame.document()->markers()->removeMarkers(node, markerTypes);
+        m_frame.document()->markers().removeMarkers(node, markerTypes);
     }
 }
 
@@ -741,19 +741,19 @@
 
         if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeSpelling)) {
             if (RefPtr<Range> wordRange = newAdjacentWords.toNormalizedRange())
-                m_frame.document()->markers()->removeMarkers(wordRange.get(), DocumentMarker::Spelling);
+                m_frame.document()->markers().removeMarkers(wordRange.get(), DocumentMarker::Spelling);
         }
         if (textChecker().shouldEraseMarkersAfterChangeSelection(TextCheckingTypeGrammar)) {
             if (RefPtr<Range> sentenceRange = newSelectedSentence.toNormalizedRange())
-                m_frame.document()->markers()->removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
+                m_frame.document()->markers().removeMarkers(sentenceRange.get(), DocumentMarker::Grammar);
         }
     }
 
     // When continuous spell checking is off, existing markers disappear after the selection changes.
     if (!isContinuousSpellCheckingEnabled)
-        m_frame.document()->markers()->removeMarkers(DocumentMarker::Spelling);
+        m_frame.document()->markers().removeMarkers(DocumentMarker::Spelling);
     if (!isContinuousGrammarCheckingEnabled)
-        m_frame.document()->markers()->removeMarkers(DocumentMarker::Grammar);
+        m_frame.document()->markers().removeMarkers(DocumentMarker::Grammar);
 }
 
 void SpellChecker::spellCheckAfterBlur()
@@ -810,7 +810,7 @@
 
     unsigned startOffset = static_cast<unsigned>(from);
     unsigned endOffset = static_cast<unsigned>(from + length);
-    Vector<DocumentMarker*> markers = m_frame.document()->markers()->markersFor(node);
+    Vector<DocumentMarker*> markers = m_frame.document()->markers().markersFor(node);
     for (size_t i = 0; i < markers.size(); ++i) {
         DocumentMarker* marker = markers[i];
         if (marker->startOffset() <= startOffset && endOffset <= marker->endOffset() && marker->type() == markerType)
diff --git a/Source/core/editing/SpellChecker.h b/Source/core/editing/SpellChecker.h
index 6a57063..c1b9788 100644
--- a/Source/core/editing/SpellChecker.h
+++ b/Source/core/editing/SpellChecker.h
@@ -34,7 +34,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class SpellCheckerClient;
 class SpellCheckRequest;
 class SpellCheckRequester;
@@ -45,7 +45,7 @@
 class SpellChecker {
     WTF_MAKE_NONCOPYABLE(SpellChecker);
 public:
-    static PassOwnPtr<SpellChecker> create(Frame&);
+    static PassOwnPtr<SpellChecker> create(LocalFrame&);
 
     ~SpellChecker();
 
@@ -84,10 +84,10 @@
     SpellCheckRequester& spellCheckRequester() const { return *m_spellCheckRequester; }
 
 private:
-    Frame& m_frame;
+    LocalFrame& m_frame;
     const OwnPtr<SpellCheckRequester> m_spellCheckRequester;
 
-    explicit SpellChecker(Frame&);
+    explicit SpellChecker(LocalFrame&);
 
     void markMisspellingsOrBadGrammar(const VisibleSelection&, bool checkSpelling, RefPtr<Range>& firstMisspellingRange);
     TextCheckingTypeMask resolveTextCheckingTypeMask(TextCheckingTypeMask);
diff --git a/Source/core/editing/SplitElementCommand.cpp b/Source/core/editing/SplitElementCommand.cpp
index 128c370..02a2761 100644
--- a/Source/core/editing/SplitElementCommand.cpp
+++ b/Source/core/editing/SplitElementCommand.cpp
@@ -93,8 +93,9 @@
         m_element2->insertBefore(children[i].get(), refChild.get(), IGNORE_EXCEPTION);
 
     // Recover the id attribute of the original element.
-    if (m_element1->hasAttribute(HTMLNames::idAttr))
-        m_element2->setAttribute(HTMLNames::idAttr, m_element1->getAttribute(HTMLNames::idAttr));
+    const AtomicString& id = m_element1->getAttribute(HTMLNames::idAttr);
+    if (!id.isNull())
+        m_element2->setAttribute(HTMLNames::idAttr, id);
 
     m_element1->remove(IGNORE_EXCEPTION);
 }
diff --git a/Source/core/editing/SplitTextNodeCommand.cpp b/Source/core/editing/SplitTextNodeCommand.cpp
index 3408659..3979a73 100644
--- a/Source/core/editing/SplitTextNodeCommand.cpp
+++ b/Source/core/editing/SplitTextNodeCommand.cpp
@@ -62,7 +62,7 @@
 
     m_text1 = Text::create(document(), prefixText);
     ASSERT(m_text1);
-    document().markers()->copyMarkers(m_text2.get(), 0, m_offset, m_text1.get(), 0);
+    document().markers().copyMarkers(m_text2.get(), 0, m_offset, m_text1.get(), 0);
 
     insertText1AndTrimText2();
 }
@@ -78,7 +78,7 @@
 
     m_text2->insertData(0, prefixText, ASSERT_NO_EXCEPTION, CharacterData::DeprecatedRecalcStyleImmediatlelyForEditing);
 
-    document().markers()->copyMarkers(m_text1.get(), 0, prefixText.length(), m_text2.get(), 0);
+    document().markers().copyMarkers(m_text1.get(), 0, prefixText.length(), m_text2.get(), 0);
     m_text1->remove(ASSERT_NO_EXCEPTION);
 }
 
diff --git a/Source/core/editing/SurroundingText.cpp b/Source/core/editing/SurroundingText.cpp
index e90e9e7..8bcd90f 100644
--- a/Source/core/editing/SurroundingText.cpp
+++ b/Source/core/editing/SurroundingText.cpp
@@ -77,7 +77,7 @@
 PassRefPtr<Range> SurroundingText::rangeFromContentOffsets(unsigned startOffsetInContent, unsigned endOffsetInContent)
 {
     if (startOffsetInContent >= endOffsetInContent || endOffsetInContent > content().length())
-        return 0;
+        return nullptr;
 
     CharacterIterator iterator(m_contentRange.get());
 
diff --git a/Source/core/editing/TextCheckingHelper.cpp b/Source/core/editing/TextCheckingHelper.cpp
index 091585a..e96620a 100644
--- a/Source/core/editing/TextCheckingHelper.cpp
+++ b/Source/core/editing/TextCheckingHelper.cpp
@@ -35,7 +35,7 @@
 #include "core/editing/TextIterator.h"
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/VisibleUnits.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/page/SpellCheckerClient.h"
 #include "platform/text/TextBreakIterator.h"
@@ -101,8 +101,8 @@
 static PassRefPtr<Range> expandToParagraphBoundary(PassRefPtr<Range> range)
 {
     RefPtr<Range> paragraphRange = range->cloneRange(IGNORE_EXCEPTION);
-    setStart(paragraphRange.get(), startOfParagraph(range->startPosition()));
-    setEnd(paragraphRange.get(), endOfParagraph(range->endPosition()));
+    setStart(paragraphRange.get(), startOfParagraph(VisiblePosition(range->startPosition())));
+    setEnd(paragraphRange.get(), endOfParagraph(VisiblePosition(range->endPosition())));
     return paragraphRange;
 }
 
@@ -130,14 +130,14 @@
 void TextCheckingParagraph::expandRangeToNextEnd()
 {
     ASSERT(m_checkingRange);
-    setEnd(paragraphRange().get(), endOfParagraph(startOfNextParagraph(paragraphRange()->startPosition())));
+    setEnd(paragraphRange().get(), endOfParagraph(startOfNextParagraph(VisiblePosition(paragraphRange()->startPosition()))));
     invalidateParagraphRangeValues();
 }
 
 void TextCheckingParagraph::invalidateParagraphRangeValues()
 {
     m_checkingStart = m_checkingEnd = -1;
-    m_offsetAsRange = 0;
+    m_offsetAsRange = nullptr;
     m_text = String();
 }
 
@@ -271,7 +271,7 @@
                 }
 
                 // Store marker for misspelled word.
-                misspellingRange->startContainer()->document().markers()->addMarker(misspellingRange.get(), DocumentMarker::Spelling);
+                misspellingRange->startContainer()->document().markers().addMarker(misspellingRange.get(), DocumentMarker::Spelling);
 
                 // Bail out if we're marking only the first misspelling, and not all instances.
                 if (!markAll)
@@ -307,9 +307,9 @@
     // Determine the character offset from the start of the paragraph to the start of the original search range,
     // since we will want to ignore results in this area.
     RefPtr<Range> paragraphRange = m_range->cloneRange(IGNORE_EXCEPTION);
-    setStart(paragraphRange.get(), startOfParagraph(m_range->startPosition()));
+    setStart(paragraphRange.get(), startOfParagraph(VisiblePosition(m_range->startPosition())));
     int totalRangeLength = TextIterator::rangeLength(paragraphRange.get());
-    setEnd(paragraphRange.get(), endOfParagraph(m_range->startPosition()));
+    setEnd(paragraphRange.get(), endOfParagraph(VisiblePosition(m_range->startPosition())));
 
     RefPtr<Range> offsetAsRange = Range::create(paragraphRange->startContainer()->document(), paragraphRange->startPosition(), m_range->startPosition());
     int rangeStartOffset = TextIterator::rangeLength(offsetAsRange.get());
@@ -322,7 +322,7 @@
         int currentLength = TextIterator::rangeLength(paragraphRange.get());
         int currentStartOffset = firstIteration ? rangeStartOffset : 0;
         int currentEndOffset = currentLength;
-        if (inSameParagraph(paragraphRange->startPosition(), m_range->endPosition())) {
+        if (inSameParagraph(VisiblePosition(paragraphRange->startPosition()), VisiblePosition(m_range->endPosition()))) {
             // Determine the character offset from the end of the original search range to the end of the paragraph,
             // since we will want to ignore results in this area.
             RefPtr<Range> endOffsetAsRange = Range::create(paragraphRange->startContainer()->document(), paragraphRange->startPosition(), m_range->endPosition());
@@ -401,7 +401,7 @@
         }
         if (lastIteration || totalLengthProcessed + currentLength >= totalRangeLength)
             break;
-        VisiblePosition newParagraphStart = startOfNextParagraph(paragraphRange->endPosition());
+        VisiblePosition newParagraphStart = startOfNextParagraph(VisiblePosition(paragraphRange->endPosition()));
         setStart(paragraphRange.get(), newParagraphStart);
         setEnd(paragraphRange.get(), endOfParagraph(newParagraphStart));
         firstIteration = false;
@@ -432,7 +432,7 @@
 
         if (markAll) {
             RefPtr<Range> badGrammarRange = TextIterator::subrange(m_range.get(), badGrammarPhraseLocation - startOffset + detail->location, detail->length);
-            badGrammarRange->startContainer()->document().markers()->addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
+            badGrammarRange->startContainer()->document().markers().addMarker(badGrammarRange.get(), DocumentMarker::Grammar, detail->userDescription);
         }
 
         // Remember this detail only if it's earlier than our current candidate (the details aren't in a guaranteed order)
@@ -559,11 +559,11 @@
         if (results.isEmpty())
             results.swap(spellingResult);
         else
-            results.append(spellingResult);
+            results.appendVector(spellingResult);
     }
 }
 
-bool unifiedTextCheckerEnabled(const Frame* frame)
+bool unifiedTextCheckerEnabled(const LocalFrame* frame)
 {
     if (!frame)
         return false;
diff --git a/Source/core/editing/TextCheckingHelper.h b/Source/core/editing/TextCheckingHelper.h
index a69116e..b572d03 100644
--- a/Source/core/editing/TextCheckingHelper.h
+++ b/Source/core/editing/TextCheckingHelper.h
@@ -27,7 +27,7 @@
 namespace WebCore {
 
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class Range;
 class Position;
 class SpellCheckerClient;
@@ -98,7 +98,7 @@
 
 void checkTextOfParagraph(TextCheckerClient&, const String&, TextCheckingTypeMask, Vector<TextCheckingResult>&);
 
-bool unifiedTextCheckerEnabled(const Frame*);
+bool unifiedTextCheckerEnabled(const LocalFrame*);
 
 } // namespace WebCore
 
diff --git a/Source/core/editing/TextGranularity.h b/Source/core/editing/TextGranularity.h
index 4aea8d8..d61f252 100644
--- a/Source/core/editing/TextGranularity.h
+++ b/Source/core/editing/TextGranularity.h
@@ -29,7 +29,7 @@
 namespace WebCore {
 
 // FIXME: This really should be broken up into more than one concept.
-// Frame doesn't need the 3 boundaries in this enum.
+// LocalFrame doesn't need the 3 boundaries in this enum.
 enum TextGranularity {
     CharacterGranularity,
     WordGranularity,
diff --git a/Source/core/editing/TextInsertionBaseCommand.cpp b/Source/core/editing/TextInsertionBaseCommand.cpp
index 918bf75..21e2b7d 100644
--- a/Source/core/editing/TextInsertionBaseCommand.cpp
+++ b/Source/core/editing/TextInsertionBaseCommand.cpp
@@ -31,7 +31,7 @@
 #include "core/dom/Element.h"
 #include "core/dom/Node.h"
 #include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
@@ -40,7 +40,7 @@
 {
 }
 
-void TextInsertionBaseCommand::applyTextInsertionCommand(Frame* frame, PassRefPtr<TextInsertionBaseCommand> command, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection)
+void TextInsertionBaseCommand::applyTextInsertionCommand(LocalFrame* frame, PassRefPtr<TextInsertionBaseCommand> command, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection)
 {
     bool changeSelection = selectionForInsertion != endingSelection;
     if (changeSelection) {
diff --git a/Source/core/editing/TextInsertionBaseCommand.h b/Source/core/editing/TextInsertionBaseCommand.h
index 6f2f355..25baac6 100644
--- a/Source/core/editing/TextInsertionBaseCommand.h
+++ b/Source/core/editing/TextInsertionBaseCommand.h
@@ -40,7 +40,7 @@
 
 protected:
     explicit TextInsertionBaseCommand(Document&);
-    static void applyTextInsertionCommand(Frame*, PassRefPtr<TextInsertionBaseCommand>, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection);
+    static void applyTextInsertionCommand(LocalFrame*, PassRefPtr<TextInsertionBaseCommand>, const VisibleSelection& selectionForInsertion, const VisibleSelection& endingSelection);
 };
 
 String dispatchBeforeTextInsertedEvent(const String& text, const VisibleSelection& selectionForInsertion, bool insertionIsForUpdatingComposition);
diff --git a/Source/core/editing/TextIterator.cpp b/Source/core/editing/TextIterator.cpp
index b85b148..3c452ce 100644
--- a/Source/core/editing/TextIterator.cpp
+++ b/Source/core/editing/TextIterator.cpp
@@ -175,7 +175,7 @@
     if (!rangeEndContainer)
         return 0;
     if (rangeEndOffset >= 0 && !rangeEndContainer->offsetInCharacters()) {
-        if (Node* next = rangeEndContainer->childNode(rangeEndOffset))
+        if (Node* next = rangeEndContainer->traverseToChildAt(rangeEndOffset))
             return next;
     }
     for (Node* node = rangeEndContainer; node; node = node->parentOrShadowHostNode()) {
@@ -406,9 +406,9 @@
                 } else if (renderer && (renderer->isImage() || renderer->isWidget()
                     || (m_node && m_node->isElementNode()
                     && (toElement(m_node)->isFormControlElement()
-                    || toElement(m_node)->hasTagName(legendTag)
-                    || toElement(m_node)->hasTagName(meterTag)
-                    || toElement(m_node)->hasTagName(progressTag))))) {
+                    || isHTMLLegendElement(toElement(*m_node))
+                    || isHTMLMeterElement(toElement(*m_node))
+                    || isHTMLProgressElement(toElement(*m_node)))))) {
                     handledNode = handleReplacedElement();
                 } else {
                     handledNode = handleNonTextNode();
@@ -808,9 +808,9 @@
 {
     RenderObject* renderer = node->renderer();
 
-    if (renderer ? !renderer->isBR() : !node->hasTagName(brTag))
+    if (renderer ? !renderer->isBR() : !isHTMLBRElement(node))
         return false;
-    return emitsOriginalText || !(node->isInShadowTree() && node->shadowHost()->hasTagName(inputTag));
+    return emitsOriginalText || !(node->isInShadowTree() && isHTMLInputElement(*node->shadowHost()));
 }
 
 static bool shouldEmitNewlinesBeforeAndAfterNode(Node& node)
@@ -975,7 +975,7 @@
     // Additionally, if the range we are iterating over contains huge sections of unrendered content,
     // we would create VisiblePositions on every call to this function without this check.
     if (!m_node->renderer() || m_node->renderer()->style()->visibility() != VISIBLE
-        || (m_node->renderer()->isRenderBlockFlow() && !toRenderBlock(m_node->renderer())->height() && !m_node->hasTagName(bodyTag)))
+        || (m_node->renderer()->isRenderBlockFlow() && !toRenderBlock(m_node->renderer())->height() && !isHTMLBodyElement(*m_node)))
         return false;
 
     // The startPos.isNotNull() check is needed because the start could be before the body,
@@ -1128,7 +1128,7 @@
     if (m_endContainer)
         return Range::create(m_endContainer->document(), m_endContainer, m_endOffset, m_endContainer, m_endOffset);
 
-    return 0;
+    return nullptr;
 }
 
 Node* TextIterator::node() const
@@ -1143,7 +1143,7 @@
     if (node->offsetInCharacters())
         return node;
 
-    return node->childNode(textRange->startOffset());
+    return node->traverseToChildAt(textRange->startOffset());
 }
 
 // --------
@@ -1183,15 +1183,19 @@
     int startOffset = r->startOffset();
     int endOffset = r->endOffset();
 
-    if (!startNode->offsetInCharacters()) {
-        if (startOffset >= 0 && startOffset < static_cast<int>(startNode->childNodeCount())) {
-            startNode = startNode->childNode(startOffset);
+    if (!startNode->offsetInCharacters() && startOffset >= 0) {
+        // traverseToChildAt() will return 0 if the offset is out of range. We rely on this behavior
+        // instead of calling countChildren() to avoid traversing the children twice.
+        if (Node* childAtOffset = startNode->traverseToChildAt(startOffset)) {
+            startNode = childAtOffset;
             startOffset = 0;
         }
     }
-    if (!endNode->offsetInCharacters()) {
-        if (endOffset > 0 && endOffset <= static_cast<int>(endNode->childNodeCount())) {
-            endNode = endNode->childNode(endOffset - 1);
+    if (!endNode->offsetInCharacters() && endOffset > 0) {
+        // traverseToChildAt() will return 0 if the offset is out of range. We rely on this behavior
+        // instead of calling countChildren() to avoid traversing the children twice.
+        if (Node* childAtOffset = endNode->traverseToChildAt(endOffset - 1)) {
+            endNode = childAtOffset;
             endOffset = lastOffsetInNode(endNode);
         }
     }
@@ -1253,7 +1257,7 @@
                 return;
         }
 
-        if (!m_handledChildren && m_node->hasChildNodes()) {
+        if (!m_handledChildren && m_node->hasChildren()) {
             m_node = m_node->lastChild();
             pushFullyClippedState(m_fullyClippedStack, m_node);
         } else {
diff --git a/Source/core/editing/TypingCommand.cpp b/Source/core/editing/TypingCommand.cpp
index 709bb88..fcca6ce 100644
--- a/Source/core/editing/TypingCommand.cpp
+++ b/Source/core/editing/TypingCommand.cpp
@@ -40,7 +40,8 @@
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLBRElement.h"
 #include "core/rendering/RenderObject.h"
 
 namespace WebCore {
@@ -93,7 +94,7 @@
 
 void TypingCommand::deleteSelection(Document& document, Options options)
 {
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     ASSERT(frame);
 
     if (!frame->selection().isRange())
@@ -111,7 +112,7 @@
 void TypingCommand::deleteKeyPressed(Document& document, Options options, TextGranularity granularity)
 {
     if (granularity == CharacterGranularity) {
-        Frame* frame = document.frame();
+        LocalFrame* frame = document.frame();
         if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
             // If the last typing command is not Delete, open a new typing command.
             // We need to group continuous delete commands alone in a single typing command.
@@ -131,7 +132,7 @@
 {
     // FIXME: Forward delete in TextEdit appears to open and close a new typing command.
     if (granularity == CharacterGranularity) {
-        Frame* frame = document.frame();
+        LocalFrame* frame = document.frame();
         if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame)) {
             updateSelectionIfDifferentFromCurrentSelection(lastTypingCommand.get(), frame);
             lastTypingCommand->setShouldPreventSpellChecking(options & PreventSpellChecking);
@@ -143,7 +144,7 @@
     TypingCommand::create(document, ForwardDeleteKey, "", options, granularity)->apply();
 }
 
-void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand* typingCommand, Frame* frame)
+void TypingCommand::updateSelectionIfDifferentFromCurrentSelection(TypingCommand* typingCommand, LocalFrame* frame)
 {
     ASSERT(frame);
     VisibleSelection currentSelection = frame->selection().selection();
@@ -156,7 +157,7 @@
 
 void TypingCommand::insertText(Document& document, const String& text, Options options, TextCompositionType composition)
 {
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     ASSERT(frame);
 
     if (!text.isEmpty())
@@ -168,7 +169,7 @@
 // FIXME: We shouldn't need to take selectionForInsertion. It should be identical to FrameSelection's current selection.
 void TypingCommand::insertText(Document& document, const String& text, const VisibleSelection& selectionForInsertion, Options options, TextCompositionType compositionType)
 {
-    RefPtr<Frame> frame = document.frame();
+    RefPtr<LocalFrame> frame = document.frame();
     ASSERT(frame);
 
     VisibleSelection currentSelection = frame->selection().selection();
@@ -227,18 +228,18 @@
     TypingCommand::create(document, InsertParagraphSeparator, "", options)->apply();
 }
 
-PassRefPtr<TypingCommand> TypingCommand::lastTypingCommandIfStillOpenForTyping(Frame* frame)
+PassRefPtr<TypingCommand> TypingCommand::lastTypingCommandIfStillOpenForTyping(LocalFrame* frame)
 {
     ASSERT(frame);
 
     RefPtr<CompositeEditCommand> lastEditCommand = frame->editor().lastEditCommand();
     if (!lastEditCommand || !lastEditCommand->isTypingCommand() || !static_cast<TypingCommand*>(lastEditCommand.get())->isOpenForMoreTyping())
-        return 0;
+        return nullptr;
 
     return static_cast<TypingCommand*>(lastEditCommand.get());
 }
 
-void TypingCommand::closeTyping(Frame* frame)
+void TypingCommand::closeTyping(LocalFrame* frame)
 {
     if (RefPtr<TypingCommand> lastTypingCommand = lastTypingCommandIfStillOpenForTyping(frame))
         lastTypingCommand->closeTyping();
@@ -287,7 +288,7 @@
 
 void TypingCommand::markMisspellingsAfterTyping(ETypingCommand commandType)
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
@@ -312,7 +313,7 @@
 
 void TypingCommand::typingAddedToOpenCommand(ETypingCommand commandTypeForAddedTyping)
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
@@ -384,7 +385,7 @@
 
     if (root->firstChild() == root->lastChild()) {
         Element* firstElementChild = ElementTraversal::firstWithin(*root);
-        if (firstElementChild && firstElementChild->hasTagName(brTag)) {
+        if (isHTMLBRElement(firstElementChild)) {
             // If there is a single child and it could be a placeholder, leave it alone.
             if (root->renderer() && root->renderer()->isRenderBlockFlow())
                 return false;
@@ -402,7 +403,7 @@
 
 void TypingCommand::deleteKeyPressed(TextGranularity granularity, bool killRing)
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
@@ -446,7 +447,7 @@
 
         // If we have a caret selection at the beginning of a cell, we have nothing to do.
         Node* enclosingTableCell = enclosingNodeOfType(visibleStart.deepEquivalent(), &isTableCell);
-        if (enclosingTableCell && visibleStart == firstPositionInNode(enclosingTableCell))
+        if (enclosingTableCell && visibleStart == VisiblePosition(firstPositionInNode(enclosingTableCell)))
             return;
 
         // If the caret is at the start of a paragraph after a table, move content into the last table cell.
@@ -506,7 +507,7 @@
 
 void TypingCommand::forwardDeleteKeyPressed(TextGranularity granularity, bool killRing)
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
@@ -535,7 +536,7 @@
         Position downstreamEnd = endingSelection().end().downstream();
         VisiblePosition visibleEnd = endingSelection().visibleEnd();
         Node* enclosingTableCell = enclosingNodeOfType(visibleEnd.deepEquivalent(), &isTableCell);
-        if (enclosingTableCell && visibleEnd == lastPositionInNode(enclosingTableCell))
+        if (enclosingTableCell && visibleEnd == VisiblePosition(lastPositionInNode(enclosingTableCell)))
             return;
         if (visibleEnd == endOfParagraph(visibleEnd))
             downstreamEnd = visibleEnd.next(CannotCrossEditingBoundary).deepEquivalent().downstream();
diff --git a/Source/core/editing/TypingCommand.h b/Source/core/editing/TypingCommand.h
index ea4612e..80117c4 100644
--- a/Source/core/editing/TypingCommand.h
+++ b/Source/core/editing/TypingCommand.h
@@ -65,7 +65,7 @@
     static void insertLineBreak(Document&, Options);
     static void insertParagraphSeparator(Document&, Options);
     static void insertParagraphSeparatorInQuotedContent(Document&);
-    static void closeTyping(Frame*);
+    static void closeTyping(LocalFrame*);
 
     void insertText(const String &text, bool selectInsertedText);
     void insertTextRunWithoutNewlines(const String &text, bool selectInsertedText);
@@ -94,7 +94,7 @@
     bool isOpenForMoreTyping() const { return m_openForMoreTyping; }
     void closeTyping() { m_openForMoreTyping = false; }
 
-    static PassRefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(Frame*);
+    static PassRefPtr<TypingCommand> lastTypingCommandIfStillOpenForTyping(LocalFrame*);
 
     virtual void doApply() OVERRIDE;
     virtual EditAction editingAction() const OVERRIDE;
@@ -104,7 +104,7 @@
     virtual bool shouldStopCaretBlinking() const OVERRIDE { return true; }
     void setShouldPreventSpellChecking(bool prevent) { m_shouldPreventSpellChecking = prevent; }
 
-    static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, Frame*);
+    static void updateSelectionIfDifferentFromCurrentSelection(TypingCommand*, LocalFrame*);
 
     void updatePreservesTypingStyle(ETypingCommand);
     void markMisspellingsAfterTyping(ETypingCommand);
diff --git a/Source/core/editing/UndoStack.cpp b/Source/core/editing/UndoStack.cpp
index cdcd9ae..1ffd427 100644
--- a/Source/core/editing/UndoStack.cpp
+++ b/Source/core/editing/UndoStack.cpp
@@ -67,14 +67,14 @@
     m_redoStack.append(step);
 }
 
-void UndoStack::didUnloadFrame(const Frame& frame)
+void UndoStack::didUnloadFrame(const LocalFrame& frame)
 {
     NoEventDispatchAssertion assertNoEventDispatch;
     filterOutUndoSteps(m_undoStack, frame);
     filterOutUndoSteps(m_redoStack, frame);
 }
 
-void UndoStack::filterOutUndoSteps(UndoStepStack& stack, const Frame& frame)
+void UndoStack::filterOutUndoSteps(UndoStepStack& stack, const LocalFrame& frame)
 {
     UndoStepStack newStack;
     while (!stack.isEmpty()) {
diff --git a/Source/core/editing/UndoStack.h b/Source/core/editing/UndoStack.h
index 507e899..6b996cc 100644
--- a/Source/core/editing/UndoStack.h
+++ b/Source/core/editing/UndoStack.h
@@ -36,7 +36,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class UndoStep;
 
 class UndoStack {
@@ -47,7 +47,7 @@
 
     void registerUndoStep(PassRefPtr<UndoStep>);
     void registerRedoStep(PassRefPtr<UndoStep>);
-    void didUnloadFrame(const Frame&);
+    void didUnloadFrame(const LocalFrame&);
     bool canUndo() const;
     bool canRedo() const;
     void undo();
@@ -59,7 +59,7 @@
     bool m_inRedo;
 
     typedef Deque<RefPtr<UndoStep> > UndoStepStack;
-    void filterOutUndoSteps(UndoStepStack&, const Frame&);
+    void filterOutUndoSteps(UndoStepStack&, const LocalFrame&);
     UndoStepStack m_undoStack;
     UndoStepStack m_redoStack;
 };
diff --git a/Source/core/editing/UndoStep.h b/Source/core/editing/UndoStep.h
index 3084946..93804d1 100644
--- a/Source/core/editing/UndoStep.h
+++ b/Source/core/editing/UndoStep.h
@@ -36,13 +36,13 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 
 class UndoStep : public RefCounted<UndoStep> {
 public:
     virtual ~UndoStep() { }
 
-    virtual bool belongsTo(const Frame&) const = 0;
+    virtual bool belongsTo(const LocalFrame&) const = 0;
     virtual void unapply() = 0;
     virtual void reapply() = 0;
     virtual EditAction editingAction() const = 0;
diff --git a/Source/core/editing/VisiblePosition.cpp b/Source/core/editing/VisiblePosition.cpp
index 71205fd..92e4490 100644
--- a/Source/core/editing/VisiblePosition.cpp
+++ b/Source/core/editing/VisiblePosition.cpp
@@ -135,7 +135,7 @@
         if (!box)
             return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
 
-        RenderObject* renderer = box->renderer();
+        RenderObject* renderer = &box->renderer();
 
         while (true) {
             if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretRightmostOffset())
@@ -145,7 +145,7 @@
                 box = box->prevLeafChild();
                 if (!box)
                     return primaryDirection == LTR ? previousVisuallyDistinctCandidate(m_deepPosition) : nextVisuallyDistinctCandidate(m_deepPosition);
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = box->caretRightmostOffset();
                 continue;
             }
@@ -176,7 +176,7 @@
 
                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                 box = prevBox;
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = prevBox->caretRightmostOffset();
                 continue;
             }
@@ -189,9 +189,9 @@
             if (box->direction() == primaryDirection) {
                 if (!prevBox) {
                     InlineBox* logicalStart = 0;
-                    if (primaryDirection == LTR ? box->root()->getLogicalStartBoxWithNode(logicalStart) : box->root()->getLogicalEndBoxWithNode(logicalStart)) {
+                    if (primaryDirection == LTR ? box->root().getLogicalStartBoxWithNode(logicalStart) : box->root().getLogicalEndBoxWithNode(logicalStart)) {
                         box = logicalStart;
-                        renderer = box->renderer();
+                        renderer = &box->renderer();
                         offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
                     }
                     break;
@@ -210,19 +210,19 @@
                     break;
 
                 box = prevBox;
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = box->caretRightmostOffset();
                 if (box->direction() == primaryDirection)
                     break;
                 continue;
             }
 
-            while (prevBox && !prevBox->renderer()->node())
+            while (prevBox && !prevBox->renderer().node())
                 prevBox = prevBox->prevLeafChild();
 
             if (prevBox) {
                 box = prevBox;
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = box->caretRightmostOffset();
                 if (box->bidiLevel() > level) {
                     do {
@@ -252,7 +252,7 @@
                         break;
                     level = box->bidiLevel();
                 }
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = primaryDirection == LTR ? box->caretMinOffset() : box->caretMaxOffset();
             }
             break;
@@ -300,7 +300,7 @@
         if (!box)
             return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
 
-        RenderObject* renderer = box->renderer();
+        RenderObject* renderer = &box->renderer();
 
         while (true) {
             if ((renderer->isReplaced() || renderer->isBR()) && offset == box->caretLeftmostOffset())
@@ -310,7 +310,7 @@
                 box = box->nextLeafChild();
                 if (!box)
                     return primaryDirection == LTR ? nextVisuallyDistinctCandidate(m_deepPosition) : previousVisuallyDistinctCandidate(m_deepPosition);
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = box->caretLeftmostOffset();
                 continue;
             }
@@ -341,7 +341,7 @@
 
                 // Reposition at the other logical position corresponding to our edge's visual position and go for another round.
                 box = nextBox;
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = nextBox->caretLeftmostOffset();
                 continue;
             }
@@ -354,9 +354,9 @@
             if (box->direction() == primaryDirection) {
                 if (!nextBox) {
                     InlineBox* logicalEnd = 0;
-                    if (primaryDirection == LTR ? box->root()->getLogicalEndBoxWithNode(logicalEnd) : box->root()->getLogicalStartBoxWithNode(logicalEnd)) {
+                    if (primaryDirection == LTR ? box->root().getLogicalEndBoxWithNode(logicalEnd) : box->root().getLogicalStartBoxWithNode(logicalEnd)) {
                         box = logicalEnd;
-                        renderer = box->renderer();
+                        renderer = &box->renderer();
                         offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
                     }
                     break;
@@ -377,19 +377,19 @@
 
                 // For example, abc 123 ^ CBA or 123 ^ CBA abc
                 box = nextBox;
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = box->caretLeftmostOffset();
                 if (box->direction() == primaryDirection)
                     break;
                 continue;
             }
 
-            while (nextBox && !nextBox->renderer()->node())
+            while (nextBox && !nextBox->renderer().node())
                 nextBox = nextBox->nextLeafChild();
 
             if (nextBox) {
                 box = nextBox;
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = box->caretLeftmostOffset();
 
                 if (box->bidiLevel() > level) {
@@ -420,7 +420,7 @@
                         break;
                     level = box->bidiLevel();
                 }
-                renderer = box->renderer();
+                renderer = &box->renderer();
                 offset = primaryDirection == LTR ? box->caretMaxOffset() : box->caretMinOffset();
             }
             break;
@@ -518,7 +518,7 @@
 
     // If |pos| has an editable root, skip to the start
     if (highestRootOfPos)
-        return previousVisuallyDistinctCandidate(Position(highestRootOfPos, Position::PositionIsBeforeAnchor).parentAnchoredEquivalent());
+        return VisiblePosition(previousVisuallyDistinctCandidate(Position(highestRootOfPos, Position::PositionIsBeforeAnchor).parentAnchoredEquivalent()));
 
     // That must mean that |pos| is not editable. Return the last position before pos that is in the same editable region as this position
     return lastEditablePositionBeforePositionInRoot(pos.deepEquivalent(), highestRoot);
@@ -538,7 +538,7 @@
 
     // If |pos| has an editable root, skip to the end
     if (highestRootOfPos)
-        return Position(highestRootOfPos, Position::PositionIsAfterAnchor).parentAnchoredEquivalent();
+        return VisiblePosition(Position(highestRootOfPos, Position::PositionIsAfterAnchor).parentAnchoredEquivalent());
 
     // That must mean that |pos| is not editable. Return the next position after pos that is in the same editable region as this position
     return firstEditablePositionAfterPositionInRoot(pos.deepEquivalent(), highestRoot);
@@ -591,14 +591,14 @@
 
     // The new position must be in the same editable element. Enforce that first.
     // Unless the descent is from a non-editable html element to an editable body.
-    if (node && node->hasTagName(htmlTag) && !node->rendererIsEditable() && node->document().body() && node->document().body()->rendererIsEditable())
+    if (isHTMLHtmlElement(node) && !node->rendererIsEditable() && node->document().body() && node->document().body()->rendererIsEditable())
         return next.isNotNull() ? next : prev;
 
     Node* editingRoot = editableRootForPosition(position);
 
     // If the html element is editable, descending into its body will look like a descent
     // from non-editable to editable content since rootEditableElement() always stops at the body.
-    if ((editingRoot && editingRoot->hasTagName(htmlTag)) || position.deprecatedNode()->isDocumentNode())
+    if (isHTMLHtmlElement(editingRoot) || position.deprecatedNode()->isDocumentNode())
         return next.isNotNull() ? next : prev;
 
     bool prevIsInSameEditableElement = prevNode && editableRootForPosition(prev) == editingRoot;
@@ -664,7 +664,7 @@
     getInlineBoxAndOffset(inlineBox, caretOffset);
 
     if (inlineBox)
-        renderer = inlineBox->renderer();
+        renderer = &inlineBox->renderer();
 
     return renderer->localCaretRect(inlineBox, caretOffset);
 }
@@ -723,12 +723,12 @@
 PassRefPtr<Range> makeRange(const VisiblePosition &start, const VisiblePosition &end)
 {
     if (start.isNull() || end.isNull())
-        return 0;
+        return nullptr;
 
     Position s = start.deepEquivalent().parentAnchoredEquivalent();
     Position e = end.deepEquivalent().parentAnchoredEquivalent();
     if (s.isNull() || e.isNull())
-        return 0;
+        return nullptr;
 
     return Range::create(s.containerNode()->document(), s.containerNode(), s.offsetInContainerNode(), e.containerNode(), e.offsetInContainerNode());
 }
diff --git a/Source/core/editing/VisiblePosition.h b/Source/core/editing/VisiblePosition.h
index bb684c3..53d10a3 100644
--- a/Source/core/editing/VisiblePosition.h
+++ b/Source/core/editing/VisiblePosition.h
@@ -53,7 +53,7 @@
     // NOTE: UPSTREAM affinity will be used only if pos is at end of a wrapped line,
     // otherwise it will be converted to DOWNSTREAM
     VisiblePosition() : m_affinity(VP_DEFAULT_AFFINITY) { }
-    VisiblePosition(const Position&, EAffinity = VP_DEFAULT_AFFINITY);
+    explicit VisiblePosition(const Position&, EAffinity = VP_DEFAULT_AFFINITY);
     explicit VisiblePosition(const PositionWithAffinity&);
 
     void clear() { m_deepPosition.clear(); }
diff --git a/Source/core/editing/VisibleSelection.cpp b/Source/core/editing/VisibleSelection.cpp
index 2330625..c08edf4 100644
--- a/Source/core/editing/VisibleSelection.cpp
+++ b/Source/core/editing/VisibleSelection.cpp
@@ -48,6 +48,7 @@
 
 VisibleSelection::VisibleSelection()
     : m_affinity(DOWNSTREAM)
+    , m_changeObserver(0)
     , m_selectionType(NoSelection)
     , m_baseIsFirst(true)
     , m_isDirectional(false)
@@ -58,6 +59,7 @@
     : m_base(pos)
     , m_extent(pos)
     , m_affinity(affinity)
+    , m_changeObserver(0)
     , m_isDirectional(isDirectional)
 {
     validate();
@@ -67,6 +69,7 @@
     : m_base(base)
     , m_extent(extent)
     , m_affinity(affinity)
+    , m_changeObserver(0)
     , m_isDirectional(isDirectional)
 {
     validate();
@@ -76,6 +79,7 @@
     : m_base(pos.deepEquivalent())
     , m_extent(pos.deepEquivalent())
     , m_affinity(pos.affinity())
+    , m_changeObserver(0)
     , m_isDirectional(isDirectional)
 {
     validate();
@@ -85,6 +89,7 @@
     : m_base(base.deepEquivalent())
     , m_extent(extent.deepEquivalent())
     , m_affinity(base.affinity())
+    , m_changeObserver(0)
     , m_isDirectional(isDirectional)
 {
     validate();
@@ -94,11 +99,46 @@
     : m_base(range->startPosition())
     , m_extent(range->endPosition())
     , m_affinity(affinity)
+    , m_changeObserver(0)
     , m_isDirectional(isDirectional)
 {
     validate();
 }
 
+VisibleSelection::VisibleSelection(const VisibleSelection& other)
+    : m_base(other.m_base)
+    , m_extent(other.m_extent)
+    , m_start(other.m_start)
+    , m_end(other.m_end)
+    , m_affinity(other.m_affinity)
+    , m_changeObserver(0) // Observer is associated with only one VisibleSelection, so this should not be copied.
+    , m_selectionType(other.m_selectionType)
+    , m_baseIsFirst(other.m_baseIsFirst)
+    , m_isDirectional(other.m_isDirectional)
+{
+}
+
+VisibleSelection& VisibleSelection::operator=(const VisibleSelection& other)
+{
+    didChange();
+
+    m_base = other.m_base;
+    m_extent = other.m_extent;
+    m_start = other.m_start;
+    m_end = other.m_end;
+    m_affinity = other.m_affinity;
+    m_changeObserver = 0;
+    m_selectionType = other.m_selectionType;
+    m_baseIsFirst = other.m_baseIsFirst;
+    m_isDirectional = other.m_isDirectional;
+    return *this;
+}
+
+VisibleSelection::~VisibleSelection()
+{
+    didChange();
+}
+
 VisibleSelection VisibleSelection::selectionFromContentsOfNode(Node* node)
 {
     ASSERT(!editingIgnoresContent(node));
@@ -107,32 +147,44 @@
 
 void VisibleSelection::setBase(const Position& position)
 {
+    Position oldBase = m_base;
     m_base = position;
     validate();
+    if (m_base != oldBase)
+        didChange();
 }
 
 void VisibleSelection::setBase(const VisiblePosition& visiblePosition)
 {
+    Position oldBase = m_base;
     m_base = visiblePosition.deepEquivalent();
     validate();
+    if (m_base != oldBase)
+        didChange();
 }
 
 void VisibleSelection::setExtent(const Position& position)
 {
+    Position oldExtent = m_extent;
     m_extent = position;
     validate();
+    if (m_extent != oldExtent)
+        didChange();
 }
 
 void VisibleSelection::setExtent(const VisiblePosition& visiblePosition)
 {
+    Position oldExtent = m_extent;
     m_extent = visiblePosition.deepEquivalent();
     validate();
+    if (m_extent != oldExtent)
+        didChange();
 }
 
 PassRefPtr<Range> VisibleSelection::firstRange() const
 {
     if (isNone())
-        return 0;
+        return nullptr;
     Position start = m_start.parentAnchoredEquivalent();
     Position end = m_end.parentAnchoredEquivalent();
     return Range::create(*start.document(), start, end);
@@ -141,7 +193,7 @@
 PassRefPtr<Range> VisibleSelection::toNormalizedRange() const
 {
     if (isNone())
-        return 0;
+        return nullptr;
 
     // Make sure we have an updated layout since this function is called
     // in the course of running edit commands which modify the DOM.
@@ -151,7 +203,7 @@
 
     // Check again, because updating layout can clear the selection.
     if (isNone())
-        return 0;
+        return nullptr;
 
     Position s, e;
     if (isCaret()) {
@@ -187,7 +239,7 @@
     }
 
     if (!s.containerNode() || !e.containerNode())
-        return 0;
+        return nullptr;
 
     // VisibleSelections are supposed to always be valid.  This constructor will ASSERT
     // if a valid range could not be created, which is fine for this callsite.
@@ -199,7 +251,14 @@
     if (isNone())
         return false;
 
+    // FIXME: Do we need to check all of them?
+    Position oldBase = m_base;
+    Position oldExtent = m_extent;
+    Position oldStart = m_start;
+    Position oldEnd = m_end;
     validate(granularity);
+    if (m_base != oldBase || m_extent != oldExtent || m_start != oldStart || m_end != oldEnd)
+        didChange();
     return true;
 }
 
@@ -207,14 +266,14 @@
 {
     Node* n = pos.deprecatedNode();
     if (!n)
-        return 0;
+        return nullptr;
     Document& d = n->document();
     Node* de = d.documentElement();
     if (!de)
-        return 0;
+        return nullptr;
     Node* boundary = n->enclosingBlockFlowElement();
     if (!boundary)
-        return 0;
+        return nullptr;
 
     RefPtr<Range> searchRange(Range::create(d));
     TrackExceptionState exceptionState;
@@ -225,7 +284,7 @@
 
     ASSERT(!exceptionState.hadException());
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     return searchRange.release();
 }
@@ -237,13 +296,17 @@
         return;
 
     CharacterIterator charIt(searchRange.get(), TextIteratorEmitsCharactersBetweenAllVisiblePositions);
+    bool changed = false;
 
     for (; charIt.length(); charIt.advance(1)) {
         UChar c = charIt.characterAt(0);
         if ((!isSpaceOrNewline(c) && c != noBreakSpace) || c == '\n')
             break;
         m_end = charIt.range()->endPosition();
+        changed = true;
     }
+    if (changed)
+        didChange();
 }
 
 void VisibleSelection::setBaseAndExtentToDeepEquivalents()
@@ -460,6 +523,7 @@
         m_end = base;
     }
     m_selectionType = base == extent ? CaretSelection : RangeSelection;
+    didChange();
 }
 
 static Position adjustPositionForEnd(const Position& currentPosition, Node* startContainerNode)
@@ -571,7 +635,7 @@
             while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
                 Node* root = editableRootForPosition(p);
                 shadowAncestor = root ? root->shadowHost() : 0;
-                p = isAtomicNode(p.containerNode()) ? positionInParentBeforeNode(p.containerNode()) : previousVisuallyDistinctCandidate(p);
+                p = isAtomicNode(p.containerNode()) ? positionInParentBeforeNode(*p.containerNode()) : previousVisuallyDistinctCandidate(p);
                 if (p.isNull() && shadowAncestor)
                     p = positionAfterNode(shadowAncestor);
             }
@@ -600,7 +664,7 @@
             while (p.isNotNull() && !(lowestEditableAncestor(p.containerNode()) == baseEditableAncestor && !isEditablePosition(p))) {
                 Node* root = editableRootForPosition(p);
                 shadowAncestor = root ? root->shadowHost() : 0;
-                p = isAtomicNode(p.containerNode()) ? positionInParentAfterNode(p.containerNode()) : nextVisuallyDistinctCandidate(p);
+                p = isAtomicNode(p.containerNode()) ? positionInParentAfterNode(*p.containerNode()) : nextVisuallyDistinctCandidate(p);
                 if (p.isNull() && shadowAncestor)
                     p = positionBeforeNode(shadowAncestor);
             }
@@ -670,6 +734,32 @@
     return start().deprecatedNode() ? start().deprecatedNode()->nonBoundaryShadowTreeRootNode() : 0;
 }
 
+VisibleSelection::ChangeObserver::ChangeObserver()
+{
+}
+
+VisibleSelection::ChangeObserver::~ChangeObserver()
+{
+}
+
+void VisibleSelection::setChangeObserver(ChangeObserver& observer)
+{
+    ASSERT(!m_changeObserver);
+    m_changeObserver = &observer;
+}
+
+void VisibleSelection::clearChangeObserver()
+{
+    ASSERT(m_changeObserver);
+    m_changeObserver = 0;
+}
+
+void VisibleSelection::didChange()
+{
+    if (m_changeObserver)
+        m_changeObserver->didChangeVisibleSelection();
+}
+
 #ifndef NDEBUG
 
 void VisibleSelection::debugPosition() const
diff --git a/Source/core/editing/VisibleSelection.h b/Source/core/editing/VisibleSelection.h
index dd97eb7..2b7bd2a 100644
--- a/Source/core/editing/VisibleSelection.h
+++ b/Source/core/editing/VisibleSelection.h
@@ -45,11 +45,16 @@
     VisibleSelection(const Position&, EAffinity, bool isDirectional = false);
     VisibleSelection(const Position&, const Position&, EAffinity = SEL_DEFAULT_AFFINITY, bool isDirectional = false);
 
-    VisibleSelection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY, bool isDirectional = false);
+    explicit VisibleSelection(const Range*, EAffinity = SEL_DEFAULT_AFFINITY, bool isDirectional = false);
 
-    VisibleSelection(const VisiblePosition&, bool isDirectional = false);
+    explicit VisibleSelection(const VisiblePosition&, bool isDirectional = false);
     VisibleSelection(const VisiblePosition&, const VisiblePosition&, bool isDirectional = false);
 
+    VisibleSelection(const VisibleSelection&);
+    VisibleSelection& operator=(const VisibleSelection&);
+
+    ~VisibleSelection();
+
     static VisibleSelection selectionFromContentsOfNode(Node*);
 
     SelectionType selectionType() const { return m_selectionType; }
@@ -105,6 +110,23 @@
 
     VisiblePosition visiblePositionRespectingEditingBoundary(const LayoutPoint& localPoint, Node* targetNode) const;
 
+    void setWithoutValidation(const Position&, const Position&);
+
+    // Listener of VisibleSelection modification. didChangeVisibleSelection() will be invoked when base, extent, start
+    // or end is moved to a different position.
+    //
+    // Objects implementing |ChangeObserver| interface must outlive the VisibleSelection object.
+    class ChangeObserver {
+        WTF_MAKE_NONCOPYABLE(ChangeObserver);
+    public:
+        ChangeObserver();
+        virtual ~ChangeObserver();
+        virtual void didChangeVisibleSelection() = 0;
+    };
+
+    void setChangeObserver(ChangeObserver&);
+    void clearChangeObserver();
+    void didChange(); // Fire the change observer, if any.
 
 #ifndef NDEBUG
     void debugPosition() const;
@@ -112,8 +134,6 @@
     void showTreeForThis() const;
 #endif
 
-    void setWithoutValidation(const Position&, const Position&);
-
 private:
     void validate(TextGranularity = CharacterGranularity);
 
@@ -136,6 +156,8 @@
 
     EAffinity m_affinity;           // the upstream/downstream affinity of the caret
 
+    ChangeObserver* m_changeObserver;
+
     // these are cached, can be recalculated by validate()
     SelectionType m_selectionType; // None, Caret, Range
     bool m_baseIsFirst : 1; // True if base is before the extent
diff --git a/Source/core/editing/VisibleUnits.cpp b/Source/core/editing/VisibleUnits.cpp
index 49923bf..ed06b27 100644
--- a/Source/core/editing/VisibleUnits.cpp
+++ b/Source/core/editing/VisibleUnits.cpp
@@ -39,6 +39,7 @@
 #include "core/editing/TextIterator.h"
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/htmlediting.h"
+#include "core/html/HTMLBRElement.h"
 #include "core/rendering/InlineTextBox.h"
 #include "core/rendering/RenderBlockFlow.h"
 #include "core/rendering/RenderObject.h"
@@ -82,14 +83,14 @@
     Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), editableType);
     Node* previousNode = previousLeafWithSameEditability(node, editableType);
 
-    while (previousNode && (!previousNode->renderer() || inSameLine(firstPositionInOrBeforeNode(previousNode), visiblePosition)))
+    while (previousNode && (!previousNode->renderer() || inSameLine(VisiblePosition(firstPositionInOrBeforeNode(previousNode)), visiblePosition)))
         previousNode = previousLeafWithSameEditability(previousNode, editableType);
 
     while (previousNode && !previousNode->isShadowRoot()) {
         if (highestEditableRoot(firstPositionInOrBeforeNode(previousNode), editableType) != highestRoot)
             break;
 
-        Position pos = previousNode->hasTagName(brTag) ? positionBeforeNode(previousNode) :
+        Position pos = isHTMLBRElement(*previousNode) ? positionBeforeNode(previousNode) :
             createLegacyEditingPosition(previousNode, caretMaxOffset(previousNode));
 
         if (pos.isCandidate())
@@ -104,7 +105,7 @@
 {
     Node* highestRoot = highestEditableRoot(visiblePosition.deepEquivalent(), editableType);
     Node* nextNode = nextLeafWithSameEditability(node, editableType);
-    while (nextNode && (!nextNode->renderer() || inSameLine(firstPositionInOrBeforeNode(nextNode), visiblePosition)))
+    while (nextNode && (!nextNode->renderer() || inSameLine(VisiblePosition(firstPositionInOrBeforeNode(nextNode)), visiblePosition)))
         nextNode = nextLeafWithSameEditability(nextNode, ContentIsEditable);
 
     while (nextNode && !nextNode->isShadowRoot()) {
@@ -207,16 +208,16 @@
 {
     const InlineBox* startBox = textBox;
 
-    const InlineTextBox* previousBox = leafBoxes.previousTextBox(startBox->root(), textBox);
+    const InlineTextBox* previousBox = leafBoxes.previousTextBox(&startBox->root(), textBox);
     if (previousBox)
         return previousBox;
 
-    previousBox = leafBoxes.previousTextBox(startBox->root()->prevRootBox(), 0);
+    previousBox = leafBoxes.previousTextBox(startBox->root().prevRootBox(), 0);
     if (previousBox)
         return previousBox;
 
     while (1) {
-        Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudoNode() : 0;
+        Node* startNode = startBox->renderer().nonPseudoNode();
         if (!startNode)
             break;
 
@@ -248,16 +249,16 @@
 {
     const InlineBox* startBox = textBox;
 
-    const InlineTextBox* nextBox = leafBoxes.nextTextBox(startBox->root(), textBox);
+    const InlineTextBox* nextBox = leafBoxes.nextTextBox(&startBox->root(), textBox);
     if (nextBox)
         return nextBox;
 
-    nextBox = leafBoxes.nextTextBox(startBox->root()->nextRootBox(), 0);
+    nextBox = leafBoxes.nextTextBox(startBox->root().nextRootBox(), 0);
     if (nextBox)
         return nextBox;
 
     while (1) {
-        Node* startNode = startBox->renderer() ? startBox->renderer()->nonPseudoNode() : 0;
+        Node* startNode =startBox->renderer().nonPseudoNode();
         if (!startNode)
             break;
 
@@ -295,10 +296,10 @@
     string.clear();
     if (previousBox) {
         previousBoxLength = previousBox->len();
-        previousBox->textRenderer()->text().appendTo(string, previousBox->start(), previousBoxLength);
+        previousBox->textRenderer().text().appendTo(string, previousBox->start(), previousBoxLength);
         len += previousBoxLength;
     }
-    textBox->textRenderer()->text().appendTo(string, textBox->start(), textBox->len());
+    textBox->textRenderer().text().appendTo(string, textBox->start(), textBox->len());
     len += textBox->len();
 
     return wordBreakIterator(string.data(), len);
@@ -314,10 +315,10 @@
 
     int len = 0;
     string.clear();
-    textBox->textRenderer()->text().appendTo(string, textBox->start(), textBox->len());
+    textBox->textRenderer().text().appendTo(string, textBox->start(), textBox->len());
     len += textBox->len();
     if (nextBox) {
-        nextBox->textRenderer()->text().appendTo(string, nextBox->start(), nextBox->len());
+        nextBox->textRenderer().text().appendTo(string, nextBox->start(), nextBox->len());
         len += nextBox->len();
     }
 
@@ -384,7 +385,7 @@
         else if (offsetInBox == box->caretMaxOffset())
             iter = wordBreakIteratorForMaxOffsetBoundary(visiblePosition, textBox, nextBoxInDifferentBlock, string, leafBoxes);
         else if (movingIntoNewBox) {
-            iter = wordBreakIterator(textBox->textRenderer()->text(), textBox->start(), textBox->len());
+            iter = wordBreakIterator(textBox->textRenderer().text(), textBox->start(), textBox->len());
             previouslyVisitedBox = box;
         }
 
@@ -737,11 +738,7 @@
             if (!startBox)
                 return VisiblePosition();
 
-            RenderObject* startRenderer = startBox->renderer();
-            if (!startRenderer)
-                return VisiblePosition();
-
-            startNode = startRenderer->nonPseudoNode();
+            startNode = startBox->renderer().nonPseudoNode();
             if (startNode)
                 break;
 
@@ -749,8 +746,7 @@
         }
     }
 
-    return startNode->isTextNode() ? Position(toText(startNode), toInlineTextBox(startBox)->start())
-        : positionBeforeNode(startNode);
+    return VisiblePosition(startNode->isTextNode() ? Position(toText(startNode), toInlineTextBox(startBox)->start()) : positionBeforeNode(startNode));
 }
 
 static VisiblePosition startOfLine(const VisiblePosition& c, LineEndpointComputationMode mode)
@@ -762,7 +758,7 @@
     if (mode == UseLogicalOrdering) {
         if (Node* editableRoot = highestEditableRoot(c.deepEquivalent())) {
             if (!editableRoot->contains(visPos.deepEquivalent().containerNode()))
-                return firstPositionInNode(editableRoot);
+                return VisiblePosition(firstPositionInNode(editableRoot));
         }
     }
 
@@ -809,11 +805,7 @@
             if (!endBox)
                 return VisiblePosition();
 
-            RenderObject* endRenderer = endBox->renderer();
-            if (!endRenderer)
-                return VisiblePosition();
-
-            endNode = endRenderer->nonPseudoNode();
+            endNode = endBox->renderer().nonPseudoNode();
             if (endNode)
                 break;
 
@@ -822,7 +814,7 @@
     }
 
     Position pos;
-    if (endNode->hasTagName(brTag))
+    if (isHTMLBRElement(*endNode))
         pos = positionBeforeNode(endNode);
     else if (endBox->isInlineTextBox() && endNode->isTextNode()) {
         InlineTextBox* endTextBox = toInlineTextBox(endBox);
@@ -858,7 +850,7 @@
 
         if (Node* editableRoot = highestEditableRoot(c.deepEquivalent())) {
             if (!editableRoot->contains(visPos.deepEquivalent().containerNode()))
-                return lastPositionInNode(editableRoot);
+                return VisiblePosition(lastPositionInNode(editableRoot));
         }
 
         return c.honorEditingBoundaryAtOrAfter(visPos);
@@ -908,12 +900,12 @@
 static inline IntPoint absoluteLineDirectionPointToLocalPointInBlock(RootInlineBox* root, int lineDirectionPoint)
 {
     ASSERT(root);
-    RenderBlockFlow* containingBlock = root->block();
-    FloatPoint absoluteBlockPoint = containingBlock->localToAbsolute(FloatPoint());
-    if (containingBlock->hasOverflowClip())
-        absoluteBlockPoint -= containingBlock->scrolledContentOffset();
+    RenderBlockFlow& containingBlock = root->block();
+    FloatPoint absoluteBlockPoint = containingBlock.localToAbsolute(FloatPoint());
+    if (containingBlock.hasOverflowClip())
+        absoluteBlockPoint -= containingBlock.scrolledContentOffset();
 
-    if (root->block()->isHorizontalWritingMode())
+    if (root->block().isHorizontalWritingMode())
         return IntPoint(lineDirectionPoint - absoluteBlockPoint.x(), root->blockDirectionPointInLine());
 
     return IntPoint(root->blockDirectionPointInLine(), lineDirectionPoint - absoluteBlockPoint.y());
@@ -938,7 +930,7 @@
     int ignoredCaretOffset;
     visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset);
     if (box) {
-        root = box->root()->prevRootBox();
+        root = box->root().prevRootBox();
         // We want to skip zero height boxes.
         // This could happen in case it is a TrailingFloatsRootInlineBox.
         if (!root || !root->logicalHeight() || !root->firstLeafChild())
@@ -948,21 +940,21 @@
     if (!root) {
         Position position = previousRootInlineBoxCandidatePosition(node, visiblePosition, editableType);
         if (position.isNotNull()) {
-            RenderedPosition renderedPosition(position);
+            RenderedPosition renderedPosition((VisiblePosition(position)));
             root = renderedPosition.rootBox();
             if (!root)
-                return position;
+                return VisiblePosition(position);
         }
     }
 
     if (root) {
         // FIXME: Can be wrong for multi-column layout and with transforms.
         IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint);
-        RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
-        Node* node = renderer->node();
+        RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
+        Node* node = renderer.node();
         if (node && editingIgnoresContent(node))
-            return positionInParentBeforeNode(node);
-        return VisiblePosition(renderer->positionForPoint(pointInLine));
+            return VisiblePosition(positionInParentBeforeNode(*node));
+        return VisiblePosition(renderer.positionForPoint(pointInLine));
     }
 
     // Could not find a previous line. This means we must already be on the first line.
@@ -993,7 +985,7 @@
     int ignoredCaretOffset;
     visiblePosition.getInlineBoxAndOffset(box, ignoredCaretOffset);
     if (box) {
-        root = box->root()->nextRootBox();
+        root = box->root().nextRootBox();
         // We want to skip zero height boxes.
         // This could happen in case it is a TrailingFloatsRootInlineBox.
         if (!root || !root->logicalHeight() || !root->firstLeafChild())
@@ -1002,25 +994,25 @@
 
     if (!root) {
         // FIXME: We need do the same in previousLinePosition.
-        Node* child = node->childNode(p.deprecatedEditingOffset());
+        Node* child = node->traverseToChildAt(p.deprecatedEditingOffset());
         node = child ? child : &node->lastDescendant();
         Position position = nextRootInlineBoxCandidatePosition(node, visiblePosition, editableType);
         if (position.isNotNull()) {
-            RenderedPosition renderedPosition(position);
+            RenderedPosition renderedPosition((VisiblePosition(position)));
             root = renderedPosition.rootBox();
             if (!root)
-                return position;
+                return VisiblePosition(position);
         }
     }
 
     if (root) {
         // FIXME: Can be wrong for multi-column layout and with transforms.
         IntPoint pointInLine = absoluteLineDirectionPointToLocalPointInBlock(root, lineDirectionPoint);
-        RenderObject* renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
-        Node* node = renderer->node();
+        RenderObject& renderer = root->closestLeafChildForPoint(pointInLine, isEditablePosition(p))->renderer();
+        Node* node = renderer.node();
         if (node && editingIgnoresContent(node))
-            return positionInParentBeforeNode(node);
-        return VisiblePosition(renderer->positionForPoint(pointInLine));
+            return VisiblePosition(positionInParentBeforeNode(*node));
+        return VisiblePosition(renderer.positionForPoint(pointInLine));
     }
 
     // Could not find a next line. This means we must already be on the last line.
@@ -1095,7 +1087,7 @@
         return VisiblePosition();
 
     if (isRenderedAsNonInlineTableImageOrHR(startNode))
-        return positionBeforeNode(startNode);
+        return VisiblePosition(positionBeforeNode(startNode));
 
     Node* startBlock = enclosingBlock(startNode);
 
@@ -1172,7 +1164,7 @@
     Node* startNode = p.deprecatedNode();
 
     if (isRenderedAsNonInlineTableImageOrHR(startNode))
-        return positionAfterNode(startNode);
+        return VisiblePosition(positionAfterNode(startNode));
 
     Node* startBlock = enclosingBlock(startNode);
     Node* stayInsideBlock = startBlock;
@@ -1298,7 +1290,7 @@
     Node* startBlock;
     if (!position.containerNode() || !(startBlock = enclosingBlock(position.containerNode(), rule)))
         return VisiblePosition();
-    return firstPositionInNode(startBlock);
+    return VisiblePosition(firstPositionInNode(startBlock));
 }
 
 VisiblePosition endOfBlock(const VisiblePosition& visiblePosition, EditingBoundaryCrossingRule rule)
@@ -1307,7 +1299,7 @@
     Node* endBlock;
     if (!position.containerNode() || !(endBlock = enclosingBlock(position.containerNode(), rule)))
         return VisiblePosition();
-    return lastPositionInNode(endBlock);
+    return VisiblePosition(lastPositionInNode(endBlock));
 }
 
 bool inSameBlock(const VisiblePosition &a, const VisiblePosition &b)
@@ -1372,7 +1364,7 @@
     if (!highestRoot)
         return VisiblePosition();
 
-    return firstPositionInNode(highestRoot);
+    return VisiblePosition(firstPositionInNode(highestRoot));
 }
 
 VisiblePosition endOfEditableContent(const VisiblePosition& visiblePosition)
@@ -1381,7 +1373,7 @@
     if (!highestRoot)
         return VisiblePosition();
 
-    return lastPositionInNode(highestRoot);
+    return VisiblePosition(lastPositionInNode(highestRoot));
 }
 
 bool isEndOfEditableOrNonEditableContent(const VisiblePosition &p)
diff --git a/Source/core/editing/htmlediting.cpp b/Source/core/editing/htmlediting.cpp
index 7d8591f..616a5ad 100644
--- a/Source/core/editing/htmlediting.cpp
+++ b/Source/core/editing/htmlediting.cpp
@@ -43,13 +43,14 @@
 #include "core/editing/VisiblePosition.h"
 #include "core/editing/VisibleSelection.h"
 #include "core/editing/VisibleUnits.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLBRElement.h"
 #include "core/html/HTMLDivElement.h"
 #include "core/html/HTMLLIElement.h"
 #include "core/html/HTMLOListElement.h"
 #include "core/html/HTMLParagraphElement.h"
+#include "core/html/HTMLTableCellElement.h"
 #include "core/html/HTMLUListElement.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderObject.h"
 #include "wtf/Assertions.h"
 #include "wtf/StdLibExtras.h"
@@ -65,13 +66,15 @@
 // purposes of editing.
 bool isAtomicNode(const Node *node)
 {
-    return node && (!node->hasChildNodes() || editingIgnoresContent(node));
+    return node && (!node->hasChildren() || editingIgnoresContent(node));
 }
 
 // Compare two positions, taking into account the possibility that one or both
 // could be inside a shadow tree. Only works for non-null values.
 int comparePositions(const Position& a, const Position& b)
 {
+    ASSERT(a.isNotNull());
+    ASSERT(b.isNotNull());
     TreeScope* commonScope = commonTreeScope(a.containerNode(), b.containerNode());
 
     ASSERT(commonScope);
@@ -120,14 +123,14 @@
     if (!highestRoot)
         return 0;
 
-    if (highestRoot->hasTagName(bodyTag))
+    if (isHTMLBodyElement(*highestRoot))
         return highestRoot;
 
     node = highestRoot->parentNode();
     while (node) {
         if (node->rendererIsEditable(editableType))
             highestRoot = node;
-        if (node->hasTagName(bodyTag))
+        if (isHTMLBodyElement(*node))
             break;
         node = node->parentNode();
     }
@@ -140,7 +143,7 @@
     while (node) {
         if (node->rendererIsEditable())
             return node->rootEditableElement();
-        if (node->hasTagName(bodyTag))
+        if (isHTMLBodyElement(*node))
             break;
         node = node->parentNode();
     }
@@ -259,7 +262,7 @@
 {
     // position falls before highestRoot.
     if (comparePositions(position, firstPositionInNode(highestRoot)) == -1 && highestRoot->rendererIsEditable())
-        return firstPositionInNode(highestRoot);
+        return VisiblePosition(firstPositionInNode(highestRoot));
 
     Position p = position;
 
@@ -272,7 +275,7 @@
     }
 
     while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
-        p = isAtomicNode(p.deprecatedNode()) ? positionInParentAfterNode(p.deprecatedNode()) : nextVisuallyDistinctCandidate(p);
+        p = isAtomicNode(p.deprecatedNode()) ? positionInParentAfterNode(*p.deprecatedNode()) : nextVisuallyDistinctCandidate(p);
 
     if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
         return VisiblePosition();
@@ -284,7 +287,7 @@
 {
     // When position falls after highestRoot, the result is easy to compute.
     if (comparePositions(position, lastPositionInNode(highestRoot)) == 1)
-        return lastPositionInNode(highestRoot);
+        return VisiblePosition(lastPositionInNode(highestRoot));
 
     Position p = position;
 
@@ -297,7 +300,7 @@
     }
 
     while (p.deprecatedNode() && !isEditablePosition(p) && p.deprecatedNode()->isDescendantOf(highestRoot))
-        p = isAtomicNode(p.deprecatedNode()) ? positionInParentBeforeNode(p.deprecatedNode()) : previousVisuallyDistinctCandidate(p);
+        p = isAtomicNode(p.deprecatedNode()) ? positionInParentBeforeNode(*p.deprecatedNode()) : previousVisuallyDistinctCandidate(p);
 
     if (p.deprecatedNode() && p.deprecatedNode() != highestRoot && !p.deprecatedNode()->isDescendantOf(highestRoot))
         return VisiblePosition();
@@ -309,12 +312,12 @@
 // Whether or not content before and after this node will collapse onto the same line as it.
 bool isBlock(const Node* node)
 {
-    return node && node->isElementNode() && node->renderer() && !node->renderer()->isInline() && !node->renderer()->isRubyText();
+    return node && node->renderer() && !node->renderer()->isInline() && !node->renderer()->isRubyText();
 }
 
 bool isInline(const Node* node)
 {
-    return node && node->isElementNode() && node->renderer() && node->renderer()->isInline();
+    return node && node->renderer() && node->renderer()->isInline();
 }
 
 // FIXME: Deploy this in all of the places where enclosingBlockFlow/enclosingBlockFlowOrTableElement are used.
@@ -324,7 +327,7 @@
 Element* enclosingBlock(Node* node, EditingBoundaryCrossingRule rule)
 {
     Node* enclosingNode = enclosingNodeOfType(firstPositionInOrBeforeNode(node), isBlock, rule);
-    return toElement(enclosingNode);
+    return enclosingNode && enclosingNode->isElementNode() ? toElement(enclosingNode) : 0;
 }
 
 TextDirection directionOfEnclosingBlock(const Position& position)
@@ -348,8 +351,8 @@
     if (node->offsetInCharacters())
         return node->maxCharacterOffset();
 
-    if (node->hasChildNodes())
-        return node->childNodeCount();
+    if (node->hasChildren())
+        return node->countChildren();
 
     // NOTE: This should preempt the childNodeCount for, e.g., select nodes
     if (editingIgnoresContent(node))
@@ -460,7 +463,7 @@
     Node* n = firstInSpecialElement(pos);
     if (!n)
         return pos;
-    Position result = positionInParentBeforeNode(n);
+    Position result = positionInParentBeforeNode(*n);
     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
         return pos;
     if (containingSpecialElement)
@@ -473,7 +476,7 @@
     Node* n = lastInSpecialElement(pos);
     if (!n)
         return pos;
-    Position result = positionInParentAfterNode(n);
+    Position result = positionInParentAfterNode(*n);
     if (result.isNull() || result.deprecatedNode()->rootEditableElement() != pos.deprecatedNode()->rootEditableElement())
         return pos;
     if (containingSpecialElement)
@@ -500,25 +503,23 @@
 }
 
 // Returns the visible position at the beginning of a node
-VisiblePosition visiblePositionBeforeNode(Node* node)
+VisiblePosition visiblePositionBeforeNode(Node& node)
 {
-    ASSERT(node);
-    if (node->childNodeCount())
-        return VisiblePosition(firstPositionInOrBeforeNode(node), DOWNSTREAM);
-    ASSERT(node->parentNode());
-    ASSERT(!node->parentNode()->isShadowRoot());
-    return positionInParentBeforeNode(node);
+    if (node.hasChildren())
+        return VisiblePosition(firstPositionInOrBeforeNode(&node), DOWNSTREAM);
+    ASSERT(node.parentNode());
+    ASSERT(!node.parentNode()->isShadowRoot());
+    return VisiblePosition(positionInParentBeforeNode(node));
 }
 
 // Returns the visible position at the ending of a node
-VisiblePosition visiblePositionAfterNode(Node* node)
+VisiblePosition visiblePositionAfterNode(Node& node)
 {
-    ASSERT(node);
-    if (node->childNodeCount())
-        return VisiblePosition(lastPositionInOrAfterNode(node), DOWNSTREAM);
-    ASSERT(node->parentNode());
-    ASSERT(!node->parentNode()->isShadowRoot());
-    return positionInParentAfterNode(node);
+    if (node.hasChildren())
+        return VisiblePosition(lastPositionInOrAfterNode(&node), DOWNSTREAM);
+    ASSERT(node.parentNode());
+    ASSERT(!node.parentNode()->isShadowRoot());
+    return VisiblePosition(positionInParentAfterNode(node));
 }
 
 // Create a range object with two visible positions, start and end.
@@ -533,12 +534,12 @@
     return selectedRange.release();
 }
 
-bool isListElement(Node *n)
+bool isListElement(Node* n)
 {
-    return (n && (n->hasTagName(ulTag) || n->hasTagName(olTag) || n->hasTagName(dlTag)));
+    return (n && (isHTMLUListElement(*n) || isHTMLOListElement(*n) || isHTMLDListElement(*n)));
 }
 
-bool isListItem(const Node *n)
+bool isListItem(const Node* n)
 {
     return n && n->renderer() && n->renderer()->isListItem();
 }
@@ -651,7 +652,7 @@
     Node* root = highestEditableRoot(firstPositionInOrBeforeNode(node));
 
     for (ContainerNode* n = node->parentNode(); n; n = n->parentNode()) {
-        if (n->hasTagName(ulTag) || n->hasTagName(olTag))
+        if (isHTMLUListElement(*n) || isHTMLOListElement(*n))
             return toHTMLElement(n);
         if (n == root)
             return 0;
@@ -670,7 +671,7 @@
 
     // FIXME: This function is inappropriately named if it starts with node instead of node->parentNode()
     for (Node* n = node; n && n->parentNode(); n = n->parentNode()) {
-        if (n->hasTagName(liTag) || (isListElement(n->parentNode()) && n != root))
+        if (isHTMLLIElement(*n) || (isListElement(n->parentNode()) && n != root))
             return n;
         if (n == root || isTableCell(n))
             return 0;
@@ -719,16 +720,13 @@
     return firstList->hasTagName(secondList->tagQName()) // make sure the list types match (ol vs. ul)
     && firstList->rendererIsEditable() && secondList->rendererIsEditable() // both lists are editable
     && firstList->rootEditableElement() == secondList->rootEditableElement() // don't cross editing boundaries
-    && isVisiblyAdjacent(positionInParentAfterNode(firstList), positionInParentBeforeNode(secondList));
+    && isVisiblyAdjacent(positionInParentAfterNode(*firstList), positionInParentBeforeNode(*secondList));
     // Make sure there is no visible content between this li and the previous list
 }
 
 bool isRenderedTableElement(const Node* node)
 {
-    if (!node || !node->isElementNode())
-        return false;
-
-    return node->renderer() && node->hasTagName(tableTag);
+    return isHTMLTableElement(*node) && node->renderer();
 }
 
 bool isRenderedTable(const Node* node)
@@ -742,11 +740,9 @@
 
 bool isTableCell(const Node* node)
 {
+    ASSERT(node);
     RenderObject* r = node->renderer();
-    if (!r)
-        return node->hasTagName(tdTag) || node->hasTagName(thTag);
-
-    return r->isTableCell();
+    return r ? r->isTableCell() : isHTMLTableCellElement(*node);
 }
 
 bool isEmptyTableCell(const Node* node)
@@ -792,7 +788,7 @@
     }
 
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<HTMLElement> createBreakElement(Document& document)
@@ -825,17 +821,17 @@
     return HTMLElementFactory::createHTMLElement(tagName, document, 0, false);
 }
 
-bool isTabSpanNode(const Node *node)
+bool isTabSpanNode(const Node* node)
 {
-    return node && node->hasTagName(spanTag) && node->isElementNode() && toElement(node)->getAttribute(classAttr) == AppleTabSpanClass;
+    return isHTMLSpanElement(node) && toElement(node)->getAttribute(classAttr) == AppleTabSpanClass;
 }
 
-bool isTabSpanTextNode(const Node *node)
+bool isTabSpanTextNode(const Node* node)
 {
     return node && node->isTextNode() && node->parentNode() && isTabSpanNode(node->parentNode());
 }
 
-Node* tabSpanNode(const Node *node)
+Node* tabSpanNode(const Node* node)
 {
     return isTabSpanTextNode(node) ? node->parentNode() : 0;
 }
@@ -890,7 +886,7 @@
     return num;
 }
 
-void updatePositionForNodeRemoval(Position& position, Node* node)
+void updatePositionForNodeRemoval(Position& position, Node& node)
 {
     if (position.isNull())
         return;
@@ -904,17 +900,17 @@
             position = positionInParentAfterNode(node);
         break;
     case Position::PositionIsOffsetInAnchor:
-        if (position.containerNode() == node->parentNode() && static_cast<unsigned>(position.offsetInContainerNode()) > node->nodeIndex())
+        if (position.containerNode() == node.parentNode() && static_cast<unsigned>(position.offsetInContainerNode()) > node.nodeIndex())
             position.moveToOffset(position.offsetInContainerNode() - 1);
-        else if (node->containsIncludingShadowDOM(position.containerNode()))
+        else if (node.containsIncludingShadowDOM(position.containerNode()))
             position = positionInParentBeforeNode(node);
         break;
     case Position::PositionIsAfterAnchor:
-        if (node->containsIncludingShadowDOM(position.anchorNode()))
+        if (node.containsIncludingShadowDOM(position.anchorNode()))
             position = positionInParentAfterNode(node);
         break;
     case Position::PositionIsBeforeAnchor:
-        if (node->containsIncludingShadowDOM(position.anchorNode()))
+        if (node.containsIncludingShadowDOM(position.anchorNode()))
             position = positionInParentBeforeNode(node);
         break;
     }
@@ -956,7 +952,7 @@
     if (position.isNull())
         return false;
 
-    if (position.anchorNode()->hasTagName(brTag) && position.atFirstEditingPositionForNode())
+    if (isHTMLBRElement(*position.anchorNode()) && position.atFirstEditingPositionForNode())
         return true;
 
     if (!position.anchorNode()->renderer())
@@ -1044,20 +1040,18 @@
 
 // Determines whether a node is inside a range or visibly starts and ends at the boundaries of the range.
 // Call this function to determine whether a node is visibly fit inside selectedRange
-bool isNodeVisiblyContainedWithin(Node* node, const Range* selectedRange)
+bool isNodeVisiblyContainedWithin(Node& node, const Range& selectedRange)
 {
-    ASSERT(node);
-    ASSERT(selectedRange);
     // If the node is inside the range, then it surely is contained within
-    if (selectedRange->compareNode(node, IGNORE_EXCEPTION) == Range::NODE_INSIDE)
+    if (selectedRange.compareNode(&node, IGNORE_EXCEPTION) == Range::NODE_INSIDE)
         return true;
 
-    bool startIsVisuallySame = visiblePositionBeforeNode(node) == selectedRange->startPosition();
-    if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node), selectedRange->endPosition()) < 0)
+    bool startIsVisuallySame = visiblePositionBeforeNode(node) == VisiblePosition(selectedRange.startPosition());
+    if (startIsVisuallySame && comparePositions(positionInParentAfterNode(node), selectedRange.endPosition()) < 0)
         return true;
 
-    bool endIsVisuallySame = visiblePositionAfterNode(node) == selectedRange->endPosition();
-    if (endIsVisuallySame && comparePositions(selectedRange->startPosition(), positionInParentBeforeNode(node)) < 0)
+    bool endIsVisuallySame = visiblePositionAfterNode(node) == VisiblePosition(selectedRange.endPosition());
+    if (endIsVisuallySame && comparePositions(selectedRange.startPosition(), positionInParentBeforeNode(node)) < 0)
         return true;
 
     return startIsVisuallySame && endIsVisuallySame;
@@ -1106,7 +1100,7 @@
     // It is important to skip certain irrelevant content at the start of the selection, so we do not wind up
     // with a spurious "mixed" style.
 
-    VisiblePosition visiblePosition = selection.start();
+    VisiblePosition visiblePosition(selection.start());
     if (visiblePosition.isNull())
         return Position();
 
diff --git a/Source/core/editing/htmlediting.h b/Source/core/editing/htmlediting.h
index 5439bc0..115ad0d 100644
--- a/Source/core/editing/htmlediting.h
+++ b/Source/core/editing/htmlediting.h
@@ -109,7 +109,7 @@
 bool isListElement(Node*);
 bool isListItem(const Node*);
 bool isNodeRendered(const Node*);
-bool isNodeVisiblyContainedWithin(Node*, const Range*);
+bool isNodeVisiblyContainedWithin(Node&, const Range&);
 bool isRenderedAsNonInlineTableImageOrHR(const Node*);
 bool areIdenticalElements(const Node*, const Node*);
 bool isNonTableCellHTMLBlockElement(const Node*);
@@ -165,7 +165,7 @@
 // miscellaneous functions on Position
 
 unsigned numEnclosingMailBlockquotes(const Position&);
-void updatePositionForNodeRemoval(Position&, Node*);
+void updatePositionForNodeRemoval(Position&, Node&);
 
 // -------------------------------------------------------------------------
 // VisiblePosition
@@ -175,8 +175,8 @@
 
 VisiblePosition firstEditablePositionAfterPositionInRoot(const Position&, Node*);
 VisiblePosition lastEditablePositionBeforePositionInRoot(const Position&, Node*);
-VisiblePosition visiblePositionBeforeNode(Node*);
-VisiblePosition visiblePositionAfterNode(Node*);
+VisiblePosition visiblePositionBeforeNode(Node&);
+VisiblePosition visiblePositionAfterNode(Node&);
 
 bool lineBreakExistsAtVisiblePosition(const VisiblePosition&);
 
diff --git a/Source/core/editing/markup.cpp b/Source/core/editing/markup.cpp
index ce74846..f7240eb 100644
--- a/Source/core/editing/markup.cpp
+++ b/Source/core/editing/markup.cpp
@@ -50,10 +50,11 @@
 #include "core/editing/VisibleSelection.h"
 #include "core/editing/VisibleUnits.h"
 #include "core/editing/htmlediting.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLBodyElement.h"
 #include "core/html/HTMLElement.h"
+#include "core/html/HTMLTableCellElement.h"
 #include "core/html/HTMLTextFormControlElement.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderObject.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/StdLibExtras.h"
@@ -101,9 +102,9 @@
             continue;
         unsigned length = element->attributeCount();
         for (unsigned i = 0; i < length; i++) {
-            const Attribute* attribute = element->attributeItem(i);
-            if (element->isURLAttribute(*attribute) && !attribute->value().isEmpty())
-                changes.append(AttributeChange(element, attribute->name(), KURL(parsedBaseURL, attribute->value()).string()));
+            const Attribute& attribute = element->attributeItem(i);
+            if (element->isURLAttribute(attribute) && !attribute.value().isEmpty())
+                changes.append(AttributeChange(element, attribute.name(), KURL(parsedBaseURL, attribute.value()).string()));
         }
     }
 
@@ -280,11 +281,11 @@
     const bool shouldAnnotateOrForceInline = element.isHTMLElement() && (shouldAnnotate() || addDisplayInline);
     const bool shouldOverrideStyleAttr = shouldAnnotateOrForceInline || shouldApplyWrappingStyle(element);
     for (unsigned i = 0; i < length; ++i) {
-        const Attribute* attribute = element.attributeItem(i);
+        const Attribute& attribute = element.attributeItem(i);
         // We'll handle the style attribute separately, below.
-        if (attribute->name() == styleAttr && shouldOverrideStyleAttr)
+        if (attribute.name() == styleAttr && shouldOverrideStyleAttr)
             continue;
-        appendAttribute(out, element, *attribute, 0);
+        appendAttribute(out, element, attribute, 0);
     }
 
     if (shouldOverrideStyleAttr) {
@@ -369,7 +370,7 @@
                 appendStartTag(*n);
 
             // If node has no children, close the tag now.
-            if (!n->childNodeCount()) {
+            if (!n->hasChildren()) {
                 if (shouldEmit)
                     appendEndTag(*n);
                 lastClosed = n;
@@ -418,8 +419,8 @@
 
 static bool isHTMLBlockElement(const Node* node)
 {
-    return node->hasTagName(tdTag)
-        || node->hasTagName(thTag)
+    ASSERT(node);
+    return isHTMLTableCellElement(*node)
         || isNonTableCellHTMLBlockElement(node);
 }
 
@@ -428,9 +429,9 @@
     if (!commonAncestorBlock)
         return 0;
 
-    if (commonAncestorBlock->hasTagName(tbodyTag) || commonAncestorBlock->hasTagName(trTag)) {
+    if (commonAncestorBlock->hasTagName(tbodyTag) || isHTMLTableRowElement(*commonAncestorBlock)) {
         ContainerNode* table = commonAncestorBlock->parentNode();
-        while (table && !table->hasTagName(tableTag))
+        while (table && !isHTMLTableElement(*table))
             table = table->parentNode();
 
         return table;
@@ -457,7 +458,7 @@
 {
     if (!style)
         return false;
-    RefPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
+    RefPtrWillBeRawPtr<CSSValue> value = style->getPropertyCSSValue(propertyID);
     if (!value)
         return true;
     if (!value->isPrimitiveValue())
@@ -471,13 +472,13 @@
     Node* upstreamNode = next.deepEquivalent().upstream().deprecatedNode();
     Node* downstreamNode = v.deepEquivalent().downstream().deprecatedNode();
     // Add an interchange newline if a paragraph break is selected and a br won't already be added to the markup to represent it.
-    return isEndOfParagraph(v) && isStartOfParagraph(next) && !(upstreamNode->hasTagName(brTag) && upstreamNode == downstreamNode);
+    return isEndOfParagraph(v) && isStartOfParagraph(next) && !(isHTMLBRElement(*upstreamNode) && upstreamNode == downstreamNode);
 }
 
 static PassRefPtr<EditingStyle> styleFromMatchedRulesAndInlineDecl(const Node* node)
 {
     if (!node->isHTMLElement())
-        return 0;
+        return nullptr;
 
     // FIXME: Having to const_cast here is ugly, but it is quite a bit of work to untangle
     // the non-const-ness of styleFromMatchedRulesForElement.
@@ -710,7 +711,7 @@
     RefPtr<Node> nodeBeforeContext;
     RefPtr<Node> nodeAfterContext;
     if (!findNodesSurroundingContext(taggedDocument.get(), nodeBeforeContext, nodeAfterContext))
-        return 0;
+        return nullptr;
 
     RefPtr<Range> range = Range::create(*taggedDocument.get(),
         positionAfterNode(nodeBeforeContext.get()).parentAnchoredEquivalent(),
@@ -782,15 +783,20 @@
     }
 }
 
-bool isPlainTextMarkup(Node *node)
+bool isPlainTextMarkup(Node* node)
 {
-    if (!node->isElementNode() || !node->hasTagName(divTag) || toElement(node)->hasAttributes())
+    ASSERT(node);
+    if (!node->isElementNode())
         return false;
 
-    if (node->childNodeCount() == 1 && (node->firstChild()->isTextNode() || (node->firstChild()->firstChild())))
+    Element* element = toElement(node);
+    if (!isHTMLDivElement(*element) || !element->hasAttributes())
+        return false;
+
+    if (element->hasOneChild() && (element->firstChild()->isTextNode() || (element->firstChild()->firstChild())))
         return true;
 
-    return (node->childNodeCount() == 2 && isTabSpanTextNode(node->firstChild()->firstChild()) && node->firstChild()->nextSibling()->isTextNode());
+    return element->hasChildCount(2) && isTabSpanTextNode(element->firstChild()->firstChild()) && element->lastChild()->isTextNode();
 }
 
 static bool shouldPreserveNewline(const Range& range)
@@ -811,7 +817,7 @@
 PassRefPtr<DocumentFragment> createFragmentFromText(Range* context, const String& text)
 {
     if (!context)
-        return 0;
+        return nullptr;
 
     Document& document = context->ownerDocument();
     RefPtr<DocumentFragment> fragment = document.createDocumentFragment();
@@ -844,8 +850,8 @@
     Element* block = toElement(blockNode);
     bool useClonesOfEnclosingBlock = blockNode
         && blockNode->isElementNode()
-        && !block->hasTagName(bodyTag)
-        && !block->hasTagName(htmlTag)
+        && !isHTMLBodyElement(*block)
+        && !isHTMLHtmlElement(*block)
         && block != editableRootForPosition(context->startPosition());
     bool useLineBreak = enclosingTextFormControl(context->startPosition());
 
@@ -880,7 +886,7 @@
     if (!node)
         return String();
 
-    Frame* frame = node->document().frame();
+    LocalFrame* frame = node->document().frame();
     if (!frame)
         return String();
 
@@ -906,7 +912,8 @@
 
 PassRefPtr<DocumentFragment> createFragmentForInnerOuterHTML(const String& markup, Element* contextElement, ParserContentPolicy parserContentPolicy, const char* method, ExceptionState& exceptionState)
 {
-    Document& document = contextElement->hasTagName(templateTag) ? contextElement->document().ensureTemplateDocument() : contextElement->document();
+    ASSERT(contextElement);
+    Document& document = isHTMLTemplateElement(*contextElement) ? contextElement->document().ensureTemplateDocument() : contextElement->document();
     RefPtr<DocumentFragment> fragment = DocumentFragment::create(document);
 
     if (document.isHTMLDocument()) {
@@ -917,7 +924,7 @@
     bool wasValid = fragment->parseXML(markup, contextElement, parserContentPolicy);
     if (!wasValid) {
         exceptionState.throwDOMException(SyntaxError, "The provided markup is invalid XML, and therefore cannot be inserted into an XML document.");
-        return 0;
+        return nullptr;
     }
     return fragment.release();
 }
@@ -938,7 +945,7 @@
     } else {
         bool successfulParse = fragment->parseXML(sourceString, 0);
         if (!successfulParse)
-            return 0;
+            return nullptr;
     }
 
     // FIXME: Do we need to mess with URLs here?
@@ -963,12 +970,12 @@
     if (element->ieForbidsInsertHTML() || element->hasLocalName(colTag) || element->hasLocalName(colgroupTag) || element->hasLocalName(framesetTag)
         || element->hasLocalName(headTag) || element->hasLocalName(styleTag) || element->hasLocalName(titleTag)) {
         exceptionState.throwDOMException(NotSupportedError, "The range's container is '" + element->localName() + "', which is not supported.");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<DocumentFragment> fragment = createFragmentForInnerOuterHTML(markup, element, parserContentPolicy, "createContextualFragment", exceptionState);
     if (!fragment)
-        return 0;
+        return nullptr;
 
     // We need to pop <html> and <body> elements and remove <head> to
     // accommodate folks passing complete HTML documents to make the
@@ -977,7 +984,7 @@
     RefPtr<Node> nextNode;
     for (RefPtr<Node> node = fragment->firstChild(); node; node = nextNode) {
         nextNode = node->nextSibling();
-        if (node->hasTagName(htmlTag) || node->hasTagName(headTag) || node->hasTagName(bodyTag)) {
+        if (isHTMLHtmlElement(*node) || isHTMLHeadElement(*node) || isHTMLBodyElement(*node)) {
             HTMLElement* element = toHTMLElement(node);
             if (Node* firstChild = element->firstChild())
                 nextNode = firstChild;
diff --git a/Source/core/events/AutocompleteErrorEvent.h b/Source/core/events/AutocompleteErrorEvent.h
index 847f257..c845802 100644
--- a/Source/core/events/AutocompleteErrorEvent.h
+++ b/Source/core/events/AutocompleteErrorEvent.h
@@ -55,6 +55,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::AutocompleteErrorEvent; }
 
+    virtual void trace(Visitor* visitor) OVERRIDE { Event::trace(visitor); }
+
 private:
     AutocompleteErrorEvent()
     {
diff --git a/Source/core/events/BeforeLoadEvent.h b/Source/core/events/BeforeLoadEvent.h
index b7fc894..f605a7b 100644
--- a/Source/core/events/BeforeLoadEvent.h
+++ b/Source/core/events/BeforeLoadEvent.h
@@ -62,6 +62,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::BeforeLoadEvent; }
 
+    virtual void trace(Visitor* visitor) OVERRIDE { Event::trace(visitor); }
+
 private:
     BeforeLoadEvent()
     {
diff --git a/Source/core/events/BeforeTextInsertedEvent.cpp b/Source/core/events/BeforeTextInsertedEvent.cpp
index fc0ed37..3afb5bc 100644
--- a/Source/core/events/BeforeTextInsertedEvent.cpp
+++ b/Source/core/events/BeforeTextInsertedEvent.cpp
@@ -45,4 +45,9 @@
     return EventNames::Event;
 }
 
+void BeforeTextInsertedEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 }
diff --git a/Source/core/events/BeforeTextInsertedEvent.h b/Source/core/events/BeforeTextInsertedEvent.h
index 44f0434..fe0f3f7 100644
--- a/Source/core/events/BeforeTextInsertedEvent.h
+++ b/Source/core/events/BeforeTextInsertedEvent.h
@@ -45,6 +45,8 @@
     const String& text() const { return m_text; }
     void setText(const String& s) { m_text = s; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     explicit BeforeTextInsertedEvent(const String&);
 
diff --git a/Source/core/events/BeforeUnloadEvent.cpp b/Source/core/events/BeforeUnloadEvent.cpp
index 15dd1ad..06993cd 100644
--- a/Source/core/events/BeforeUnloadEvent.cpp
+++ b/Source/core/events/BeforeUnloadEvent.cpp
@@ -42,4 +42,9 @@
     return true;
 }
 
+void BeforeUnloadEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/BeforeUnloadEvent.h b/Source/core/events/BeforeUnloadEvent.h
index 7f7e881..460ea13 100644
--- a/Source/core/events/BeforeUnloadEvent.h
+++ b/Source/core/events/BeforeUnloadEvent.h
@@ -46,6 +46,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::BeforeUnloadEvent; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     BeforeUnloadEvent();
 
diff --git a/Source/core/events/ClipboardEvent.cpp b/Source/core/events/ClipboardEvent.cpp
index 849a64b..32d8c11 100644
--- a/Source/core/events/ClipboardEvent.cpp
+++ b/Source/core/events/ClipboardEvent.cpp
@@ -32,7 +32,7 @@
 {
 }
 
-ClipboardEvent::ClipboardEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<Clipboard> clipboard)
+ClipboardEvent::ClipboardEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtrWillBeRawPtr<Clipboard> clipboard)
     : Event(eventType, canBubble, cancelable), m_clipboard(clipboard)
 {
 }
@@ -52,4 +52,10 @@
     return true;
 }
 
+void ClipboardEvent::trace(Visitor* visitor)
+{
+    visitor->trace(m_clipboard);
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/ClipboardEvent.h b/Source/core/events/ClipboardEvent.h
index d0d93c4..66ae9c8 100644
--- a/Source/core/events/ClipboardEvent.h
+++ b/Source/core/events/ClipboardEvent.h
@@ -34,21 +34,23 @@
     public:
         virtual ~ClipboardEvent();
 
-        static PassRefPtr<ClipboardEvent> create(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtr<Clipboard> clipboardArg)
+        static PassRefPtr<ClipboardEvent> create(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtrWillBeRawPtr<Clipboard> clipboardArg)
         {
             return adoptRef(new ClipboardEvent(type, canBubbleArg, cancelableArg, clipboardArg));
         }
 
         Clipboard* clipboard() const { return m_clipboard.get(); }
 
+        virtual void trace(Visitor*) OVERRIDE;
+
     private:
         ClipboardEvent();
-        ClipboardEvent(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtr<Clipboard>);
+        ClipboardEvent(const AtomicString& type, bool canBubbleArg, bool cancelableArg, PassRefPtrWillBeRawPtr<Clipboard>);
 
         virtual const AtomicString& interfaceName() const OVERRIDE;
         virtual bool isClipboardEvent() const OVERRIDE;
 
-        RefPtr<Clipboard> m_clipboard;
+        RefPtrWillBeMember<Clipboard> m_clipboard;
     };
 
 } // namespace WebCore
diff --git a/Source/core/events/CompositionEvent.cpp b/Source/core/events/CompositionEvent.cpp
index 6281bdc..9d543ce 100644
--- a/Source/core/events/CompositionEvent.cpp
+++ b/Source/core/events/CompositionEvent.cpp
@@ -105,4 +105,9 @@
     return EventNames::CompositionEvent;
 }
 
+void CompositionEvent::trace(Visitor* visitor)
+{
+    UIEvent::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/CompositionEvent.h b/Source/core/events/CompositionEvent.h
index b3c1a74..96e5ac3 100644
--- a/Source/core/events/CompositionEvent.h
+++ b/Source/core/events/CompositionEvent.h
@@ -66,6 +66,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CompositionEvent();
     CompositionEvent(const AtomicString& type, PassRefPtr<AbstractView>, const String&, const Vector<CompositionUnderline>& underlines);
diff --git a/Source/core/events/CustomEvent.cpp b/Source/core/events/CustomEvent.cpp
index ea3ac91..a51cea9 100644
--- a/Source/core/events/CustomEvent.cpp
+++ b/Source/core/events/CustomEvent.cpp
@@ -61,4 +61,9 @@
     return EventNames::CustomEvent;
 }
 
+void CustomEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/CustomEvent.h b/Source/core/events/CustomEvent.h
index 8b855d7..a2ae195 100644
--- a/Source/core/events/CustomEvent.h
+++ b/Source/core/events/CustomEvent.h
@@ -60,6 +60,8 @@
         m_serializedDetail = detail;
     }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     CustomEvent();
     CustomEvent(const AtomicString& type, const CustomEventInit& initializer);
diff --git a/Source/core/events/DOMWindowEventQueue.cpp b/Source/core/events/DOMWindowEventQueue.cpp
index e18530c..6ede339 100644
--- a/Source/core/events/DOMWindowEventQueue.cpp
+++ b/Source/core/events/DOMWindowEventQueue.cpp
@@ -73,7 +73,7 @@
     ASSERT_UNUSED(wasAdded, wasAdded); // It should not have already been in the list.
 
     if (!m_pendingEventTimer->isActive())
-        m_pendingEventTimer->startOneShot(0);
+        m_pendingEventTimer->startOneShot(0, FROM_HERE);
 
     return true;
 }
@@ -102,8 +102,8 @@
     ASSERT(!m_queuedEvents.isEmpty());
 
     // Insert a marker for where we should stop.
-    ASSERT(!m_queuedEvents.contains(0));
-    bool wasAdded = m_queuedEvents.add(0).isNewEntry;
+    ASSERT(!m_queuedEvents.contains(nullptr));
+    bool wasAdded = m_queuedEvents.add(nullptr).isNewEntry;
     ASSERT_UNUSED(wasAdded, wasAdded); // It should not have already been in the list.
 
     RefPtr<DOMWindowEventQueue> protector(this);
@@ -122,7 +122,7 @@
 {
     EventTarget* eventTarget = event->target();
     if (eventTarget->toDOMWindow())
-        eventTarget->toDOMWindow()->dispatchEvent(event, 0);
+        eventTarget->toDOMWindow()->dispatchEvent(event, nullptr);
     else
         eventTarget->dispatchEvent(event);
 }
diff --git a/Source/core/events/ErrorEvent.cpp b/Source/core/events/ErrorEvent.cpp
index 5485e81..4b13db1 100644
--- a/Source/core/events/ErrorEvent.cpp
+++ b/Source/core/events/ErrorEvent.cpp
@@ -60,7 +60,7 @@
     ScriptWrappable::init(this);
 }
 
-ErrorEvent::ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld> world)
+ErrorEvent::ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, DOMWrapperWorld* world)
     : Event(EventTypeNames::error, false, true)
     , m_sanitizedMessage(message)
     , m_fileName(fileName)
@@ -86,4 +86,9 @@
     return EventNames::ErrorEvent;
 }
 
+void ErrorEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/ErrorEvent.h b/Source/core/events/ErrorEvent.h
index 09912ec..f29df31 100644
--- a/Source/core/events/ErrorEvent.h
+++ b/Source/core/events/ErrorEvent.h
@@ -53,7 +53,7 @@
     {
         return adoptRef(new ErrorEvent);
     }
-    static PassRefPtr<ErrorEvent> create(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld> world)
+    static PassRefPtr<ErrorEvent> create(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, DOMWrapperWorld* world)
     {
         return adoptRef(new ErrorEvent(message, fileName, lineNumber, columnNumber, world));
     }
@@ -61,7 +61,7 @@
     {
         return adoptRef(new ErrorEvent(type, initializer));
     }
-    static PassRefPtr<ErrorEvent> createSanitizedError(PassRefPtr<DOMWrapperWorld> world)
+    static PassRefPtr<ErrorEvent> createSanitizedError(DOMWrapperWorld* world)
     {
         return adoptRef(new ErrorEvent("Script error.", String(), 0, 0, world));
     }
@@ -78,13 +78,15 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
-    PassRefPtr<DOMWrapperWorld> world() const { return m_world; }
+    DOMWrapperWorld* world() const { return m_world.get(); }
 
     void setUnsanitizedMessage(const String&);
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     ErrorEvent();
-    ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, PassRefPtr<DOMWrapperWorld>);
+    ErrorEvent(const String& message, const String& fileName, unsigned lineNumber, unsigned columnNumber, DOMWrapperWorld*);
     ErrorEvent(const AtomicString&, const ErrorEventInit&);
 
     String m_unsanitizedMessage;
diff --git a/Source/core/events/Event.cpp b/Source/core/events/Event.cpp
index ee384a5..043b305 100644
--- a/Source/core/events/Event.cpp
+++ b/Source/core/events/Event.cpp
@@ -202,14 +202,20 @@
     if (!m_currentTarget || !m_currentTarget->toNode())
         return StaticNodeList::createEmpty();
     Node* node = m_currentTarget->toNode();
+    // FIXME: Support SVG Elements.
+    if (node->isSVGElement())
+        return StaticNodeList::createEmpty();
     size_t eventPathSize = m_eventPath->size();
     for (size_t i = 0; i < eventPathSize; ++i) {
         if (node == (*m_eventPath)[i].node()) {
-            ASSERT((*m_eventPath)[i].eventPath());
-            return (*m_eventPath)[i].eventPath();
+            return (*m_eventPath)[i].treeScopeEventContext()->ensureEventPath(*m_eventPath);
         }
     }
     return StaticNodeList::createEmpty();
 }
 
+void Event::trace(Visitor*)
+{
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/Event.h b/Source/core/events/Event.h
index fab6c95..c66daeb 100644
--- a/Source/core/events/Event.h
+++ b/Source/core/events/Event.h
@@ -27,6 +27,7 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/DOMTimeStamp.h"
 #include "core/events/EventPath.h"
+#include "heap/Handle.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/AtomicString.h"
 
@@ -43,7 +44,7 @@
     bool cancelable;
 };
 
-class Event : public ScriptWrappable, public RefCounted<Event> {
+class Event : public RefCounted<Event>,  public ScriptWrappable {
 public:
     enum PhaseType {
         NONE                = 0,
@@ -178,6 +179,8 @@
 
     bool isBeingDispatched() const { return eventPhase(); }
 
+    virtual void trace(Visitor*);
+
 protected:
     Event();
     Event(const AtomicString& type, bool canBubble, bool cancelable);
diff --git a/Source/core/events/Event.idl b/Source/core/events/Event.idl
index 3f8e80b..dc030b0 100644
--- a/Source/core/events/Event.idl
+++ b/Source/core/events/Event.idl
@@ -68,10 +68,10 @@
 
     // IE Extensions
     readonly attribute EventTarget      srcElement;
-    [ImplementedAs=legacyReturnValue, DeprecateAs=EventReturnValue] attribute boolean returnValue;
+    [ImplementedAs=legacyReturnValue, MeasureAs=EventReturnValue] attribute boolean returnValue;
              attribute boolean          cancelBubble;
 
     [RuntimeEnabled=ShadowDOM] readonly attribute NodeList path;
 
-    [Custom=Getter] readonly attribute Clipboard clipboardData;
+    [Custom=Getter] readonly attribute DataTransfer clipboardData;
 };
diff --git a/Source/core/events/EventPath.cpp b/Source/core/events/EventPath.cpp
index c35c575..7d80754 100644
--- a/Source/core/events/EventPath.cpp
+++ b/Source/core/events/EventPath.cpp
@@ -39,6 +39,7 @@
 #include "core/events/MouseEvent.h"
 #include "core/events/TouchEvent.h"
 #include "core/events/TouchEventContext.h"
+#include "core/html/HTMLMediaElement.h"
 #include "core/svg/SVGElementInstance.h"
 #include "core/svg/SVGUseElement.h"
 
@@ -65,10 +66,10 @@
     Node& rootNode = referenceNode->treeScope().rootNode();
     Element* shadowHostElement = rootNode.isShadowRoot() ? toShadowRoot(rootNode).host() : 0;
     // At this time, SVG nodes are not supported in non-<use> shadow trees.
-    if (!shadowHostElement || !shadowHostElement->hasTagName(SVGNames::useTag))
+    if (!isSVGUseElement(shadowHostElement))
         return referenceNode;
-    SVGUseElement* useElement = toSVGUseElement(shadowHostElement);
-    if (SVGElementInstance* instance = useElement->instanceForShadowTreeElement(referenceNode))
+    SVGUseElement& useElement = toSVGUseElement(*shadowHostElement);
+    if (SVGElementInstance* instance = useElement.instanceForShadowTreeElement(referenceNode))
         return instance;
 
     return referenceNode;
@@ -83,10 +84,10 @@
 {
     // Video-only full screen is a mode where we use the shadow DOM as an implementation
     // detail that should not be detectable by the web content.
-    if (Element* element = FullscreenElementStack::currentFullScreenElementFrom(&target->toNode()->document())) {
+    if (Element* element = FullscreenElementStack::currentFullScreenElementFrom(target->toNode()->document())) {
         // FIXME: We assume that if the full screen element is a media element that it's
         // the video-only full screen. Both here and elsewhere. But that is probably wrong.
-        if (element->isMediaElement() && shadowRoot && shadowRoot->host() == element)
+        if (isHTMLMediaElement(*element) && shadowRoot && shadowRoot->host() == element)
             return StayInsideShadowDOM;
     }
 
@@ -130,7 +131,8 @@
     m_treeScopeEventContexts.clear();
     calculatePath();
     calculateAdjustedTargets();
-    calculateAdjustedEventPath();
+    if (RuntimeEnabledFeatures::shadowDOMEnabled() && !node->isSVGElement())
+        calculateTreeScopePrePostOrderNumbers();
 }
 
 void EventPath::addNodeEventContext(Node* node)
@@ -178,25 +180,30 @@
     }
 }
 
-void EventPath::calculateAdjustedEventPath()
+void EventPath::calculateTreeScopePrePostOrderNumbers()
 {
-    if (!RuntimeEnabledFeatures::shadowDOMEnabled())
-        return;
+    // Precondition:
+    //   - TreeScopes in m_treeScopeEventContexts must be *connected* in the same tree of trees.
+    //   - The root tree must be included.
+    HashMap<const TreeScope*, TreeScopeEventContext*> treeScopeEventContextMap;
+    for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i)
+        treeScopeEventContextMap.add(&m_treeScopeEventContexts[i]->treeScope(), m_treeScopeEventContexts[i].get());
+    TreeScopeEventContext* rootTree = 0;
     for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
         TreeScopeEventContext* treeScopeEventContext = m_treeScopeEventContexts[i].get();
-        Vector<RefPtr<Node> > nodes;
-        nodes.reserveInitialCapacity(size());
-        for (size_t i = 0; i < size(); ++i) {
-            if (at(i).node()->treeScope().isInclusiveOlderSiblingShadowRootOrAncestorTreeScopeOf(treeScopeEventContext->treeScope())) {
-                ASSERT(!at(i).node()->containingShadowRoot()
-                    || at(i).node()->treeScope() == treeScopeEventContext->treeScope()
-                    || toShadowRoot(treeScopeEventContext->treeScope().rootNode()).type() == ShadowRoot::UserAgentShadowRoot
-                    || at(i).node()->containingShadowRoot()->type() != ShadowRoot::UserAgentShadowRoot);
-                nodes.append(at(i).node());
-            }
+        // Use olderShadowRootOrParentTreeScope here for parent-child relationships.
+        // See the definition of trees of trees in the Shado DOM spec: http://w3c.github.io/webcomponents/spec/shadow/
+        TreeScope* parent = treeScopeEventContext->treeScope().olderShadowRootOrParentTreeScope();
+        if (!parent) {
+            ASSERT(!rootTree);
+            rootTree = treeScopeEventContext;
+            continue;
         }
-        treeScopeEventContext->adoptEventPath(nodes);
+        ASSERT(treeScopeEventContextMap.find(parent) != treeScopeEventContextMap.end());
+        treeScopeEventContextMap.find(parent)->value->addChild(*treeScopeEventContext);
     }
+    ASSERT(rootTree);
+    rootTree->calculatePrePostOrderNumber(0);
 }
 
 TreeScopeEventContext* EventPath::ensureTreeScopeEventContext(Node* currentTarget, TreeScope* treeScope, TreeScopeEventContextMap& treeScopeEventContextMap)
@@ -324,9 +331,9 @@
 
 void EventPath::adjustForTouchEvent(Node* node, TouchEvent& touchEvent)
 {
-    Vector<TouchList*> adjustedTouches;
-    Vector<TouchList*> adjustedTargetTouches;
-    Vector<TouchList*> adjustedChangedTouches;
+    WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouches;
+    WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTargetTouches;
+    WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedChangedTouches;
     Vector<TreeScope*> treeScopes;
 
     for (size_t i = 0; i < m_treeScopeEventContexts.size(); ++i) {
@@ -352,7 +359,7 @@
 #endif
 }
 
-void EventPath::adjustTouchList(const Node* node, const TouchList* touchList, Vector<TouchList*> adjustedTouchList, const Vector<TreeScope*>& treeScopes)
+void EventPath::adjustTouchList(const Node* node, const TouchList* touchList, WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouchList, const Vector<TreeScope*>& treeScopes)
 {
     if (!touchList)
         return;
diff --git a/Source/core/events/EventPath.h b/Source/core/events/EventPath.h
index b29f2b6..c3d51ad 100644
--- a/Source/core/events/EventPath.h
+++ b/Source/core/events/EventPath.h
@@ -75,12 +75,12 @@
 
     void calculatePath();
     void calculateAdjustedTargets();
-    void calculateAdjustedEventPath();
+    void calculateTreeScopePrePostOrderNumbers();
 
     void shrink(size_t newSize) { m_nodeEventContexts.shrink(newSize); }
     void shrinkIfNeeded(const Node* target, const EventTarget* relatedTarget);
 
-    void adjustTouchList(const Node*, const TouchList*, Vector<TouchList*> adjustedTouchList, const Vector<TreeScope*>& treeScopes);
+    void adjustTouchList(const Node*, const TouchList*, WillBeHeapVector<RawPtrWillBeMember<TouchList> > adjustedTouchList, const Vector<TreeScope*>& treeScopes);
 
     typedef HashMap<TreeScope*, RefPtr<TreeScopeEventContext> > TreeScopeEventContextMap;
     TreeScopeEventContext* ensureTreeScopeEventContext(Node* currentTarget, TreeScope*, TreeScopeEventContextMap&);
diff --git a/Source/core/events/EventSender.h b/Source/core/events/EventSender.h
index f07678f..8a8cfd4 100644
--- a/Source/core/events/EventSender.h
+++ b/Source/core/events/EventSender.h
@@ -68,7 +68,7 @@
 {
     m_dispatchSoonList.append(sender);
     if (!m_timer.isActive())
-        m_timer.startOneShot(0);
+        m_timer.startOneShot(0, FROM_HERE);
 }
 
 template<typename T> void EventSender<T>::cancelEvent(T* sender)
diff --git a/Source/core/events/EventTarget.h b/Source/core/events/EventTarget.h
index 28f7545..6323036 100644
--- a/Source/core/events/EventTarget.h
+++ b/Source/core/events/EventTarget.h
@@ -162,26 +162,26 @@
     void setOn##attribute(PassRefPtr<EventListener> listener) { setAttributeEventListener(EventTypeNames::attribute, listener); } \
 
 #define DEFINE_STATIC_ATTRIBUTE_EVENT_LISTENER(attribute) \
-    static EventListener* on##attribute(EventTarget* eventTarget) { return eventTarget->getAttributeEventListener(EventTypeNames::attribute); } \
-    static void setOn##attribute(EventTarget* eventTarget, PassRefPtr<EventListener> listener) { eventTarget->setAttributeEventListener(EventTypeNames::attribute, listener); } \
+    static EventListener* on##attribute(EventTarget& eventTarget) { return eventTarget.getAttributeEventListener(EventTypeNames::attribute); } \
+    static void setOn##attribute(EventTarget& eventTarget, PassRefPtr<EventListener> listener) { eventTarget.setAttributeEventListener(EventTypeNames::attribute, listener); } \
 
 #define DEFINE_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
     EventListener* on##attribute() { return document().getWindowAttributeEventListener(EventTypeNames::attribute); } \
     void setOn##attribute(PassRefPtr<EventListener> listener) { document().setWindowAttributeEventListener(EventTypeNames::attribute, listener); } \
 
 #define DEFINE_STATIC_WINDOW_ATTRIBUTE_EVENT_LISTENER(attribute) \
-    static EventListener* on##attribute(EventTarget* eventTarget) { \
-        if (Node* node = eventTarget->toNode()) \
+    static EventListener* on##attribute(EventTarget& eventTarget) { \
+        if (Node* node = eventTarget.toNode()) \
             return node->document().getWindowAttributeEventListener(EventTypeNames::attribute); \
-        ASSERT(eventTarget->toDOMWindow()); \
-        return eventTarget->getAttributeEventListener(EventTypeNames::attribute); \
+        ASSERT(eventTarget.toDOMWindow()); \
+        return eventTarget.getAttributeEventListener(EventTypeNames::attribute); \
     } \
-    static void setOn##attribute(EventTarget* eventTarget, PassRefPtr<EventListener> listener) { \
-        if (Node* node = eventTarget->toNode()) \
+    static void setOn##attribute(EventTarget& eventTarget, PassRefPtr<EventListener> listener) { \
+        if (Node* node = eventTarget.toNode()) \
             node->document().setWindowAttributeEventListener(EventTypeNames::attribute, listener); \
         else { \
-            ASSERT(eventTarget->toDOMWindow()); \
-            eventTarget->setAttributeEventListener(EventTypeNames::attribute, listener); \
+            ASSERT(eventTarget.toDOMWindow()); \
+            eventTarget.setAttributeEventListener(EventTypeNames::attribute, listener); \
         } \
     }
 
diff --git a/Source/core/events/EventTargetFactory.in b/Source/core/events/EventTargetFactory.in
index 69317cb..62c6b90 100644
--- a/Source/core/events/EventTargetFactory.in
+++ b/Source/core/events/EventTargetFactory.in
@@ -21,6 +21,7 @@
 core/workers/Worker
 core/xml/XMLHttpRequest
 core/xml/XMLHttpRequestUpload
+modules/battery/BatteryManager
 modules/encryptedmedia/MediaKeySession
 modules/filesystem/FileWriter
 modules/indexeddb/IDBDatabase
@@ -38,7 +39,6 @@
 modules/mediastream/RTCDataChannel
 modules/mediastream/RTCPeerConnection
 modules/notifications/Notification
-modules/notifications/WebKitNotification Conditional=LEGACY_NOTIFICATIONS
 modules/serviceworkers/ServiceWorkerGlobalScope
 modules/speech/SpeechRecognition
 modules/speech/SpeechSynthesisUtterance
diff --git a/Source/core/events/FocusEvent.cpp b/Source/core/events/FocusEvent.cpp
index b69c74a..8cae98e 100644
--- a/Source/core/events/FocusEvent.cpp
+++ b/Source/core/events/FocusEvent.cpp
@@ -33,7 +33,7 @@
 namespace WebCore {
 
 FocusEventInit::FocusEventInit()
-    : relatedTarget(0)
+    : relatedTarget(nullptr)
 {
 }
 
@@ -66,6 +66,11 @@
     ScriptWrappable::init(this);
 }
 
+void FocusEvent::trace(Visitor* visitor)
+{
+    UIEvent::trace(visitor);
+}
+
 PassRefPtr<FocusEventDispatchMediator> FocusEventDispatchMediator::create(PassRefPtr<FocusEvent> focusEvent)
 {
     return adoptRef(new FocusEventDispatchMediator(focusEvent));
diff --git a/Source/core/events/FocusEvent.h b/Source/core/events/FocusEvent.h
index 517f71f..fd66f18 100644
--- a/Source/core/events/FocusEvent.h
+++ b/Source/core/events/FocusEvent.h
@@ -63,6 +63,8 @@
     virtual const AtomicString& interfaceName() const OVERRIDE;
     virtual bool isFocusEvent() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     FocusEvent();
     FocusEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, int, EventTarget*);
diff --git a/Source/core/events/GenericEventQueue.cpp b/Source/core/events/GenericEventQueue.cpp
index 453eeba..ef3d81a 100644
--- a/Source/core/events/GenericEventQueue.cpp
+++ b/Source/core/events/GenericEventQueue.cpp
@@ -54,13 +54,13 @@
         return false;
 
     if (event->target() == m_owner)
-        event->setTarget(0);
+        event->setTarget(nullptr);
 
     TRACE_EVENT_ASYNC_BEGIN1("event", "GenericEventQueue:enqueueEvent", event.get(), "type", event->type().ascii());
     m_pendingEvents.append(event);
 
     if (!m_timer.isActive())
-        m_timer.startOneShot(0);
+        m_timer.startOneShot(0, FROM_HERE);
 
     return true;
 }
diff --git a/Source/core/events/GestureEvent.cpp b/Source/core/events/GestureEvent.cpp
index 5c7e937..645b72a 100644
--- a/Source/core/events/GestureEvent.cpp
+++ b/Source/core/events/GestureEvent.cpp
@@ -63,7 +63,7 @@
     case PlatformEvent::GesturePinchUpdate:
     case PlatformEvent::GestureTapDownCancel:
     default:
-        return 0;
+        return nullptr;
     }
     return adoptRef(new GestureEvent(eventType, view, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(), event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), deltaX, deltaY));
 }
@@ -94,6 +94,11 @@
 {
 }
 
+void GestureEvent::trace(Visitor* visitor)
+{
+    MouseRelatedEvent::trace(visitor);
+}
+
 GestureEventDispatchMediator::GestureEventDispatchMediator(PassRefPtr<GestureEvent> gestureEvent)
     : EventDispatchMediator(gestureEvent)
 {
diff --git a/Source/core/events/GestureEvent.h b/Source/core/events/GestureEvent.h
index a9696d2..b02ed44 100644
--- a/Source/core/events/GestureEvent.h
+++ b/Source/core/events/GestureEvent.h
@@ -45,6 +45,8 @@
     float deltaX() const { return m_deltaX; }
     float deltaY() const { return m_deltaY; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     GestureEvent();
     GestureEvent(const AtomicString& type, PassRefPtr<AbstractView>, int screenX, int screenY, int clientX, int clientY, bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, float deltaX, float deltaY);
diff --git a/Source/core/events/HashChangeEvent.h b/Source/core/events/HashChangeEvent.h
index 16d4f73..ee7d77d 100644
--- a/Source/core/events/HashChangeEvent.h
+++ b/Source/core/events/HashChangeEvent.h
@@ -68,6 +68,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::HashChangeEvent; }
 
+    virtual void trace(Visitor* visitor) OVERRIDE { Event::trace(visitor); }
+
 private:
     HashChangeEvent()
     {
diff --git a/Source/core/events/KeyboardEvent.cpp b/Source/core/events/KeyboardEvent.cpp
index 93034ad..cbc3cf4 100644
--- a/Source/core/events/KeyboardEvent.cpp
+++ b/Source/core/events/KeyboardEvent.cpp
@@ -217,6 +217,11 @@
     return keyCode();
 }
 
+void KeyboardEvent::trace(Visitor* visitor)
+{
+    UIEventWithKeyState::trace(visitor);
+}
+
 PassRefPtr<KeyboardEventDispatchMediator> KeyboardEventDispatchMediator::create(PassRefPtr<KeyboardEvent> event)
 {
     return adoptRef(new KeyboardEventDispatchMediator(event));
diff --git a/Source/core/events/KeyboardEvent.h b/Source/core/events/KeyboardEvent.h
index 671b1bf..d8b784f 100644
--- a/Source/core/events/KeyboardEvent.h
+++ b/Source/core/events/KeyboardEvent.h
@@ -100,6 +100,8 @@
     virtual bool isKeyboardEvent() const OVERRIDE;
     virtual int which() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     KeyboardEvent();
     KeyboardEvent(const PlatformKeyboardEvent&, AbstractView*);
diff --git a/Source/core/events/MessageEvent.cpp b/Source/core/events/MessageEvent.cpp
index 883b1f9..9bb7fa6 100644
--- a/Source/core/events/MessageEvent.cpp
+++ b/Source/core/events/MessageEvent.cpp
@@ -54,7 +54,7 @@
     , m_dataType(DataTypeScriptValue)
     , m_origin(initializer.origin)
     , m_lastEventId(initializer.lastEventId)
-    , m_source(isValidSource(initializer.source.get()) ? initializer.source : 0)
+    , m_source(isValidSource(initializer.source.get()) ? initializer.source : nullptr)
     , m_ports(adoptPtr(new MessagePortArray(initializer.ports)))
 {
     ScriptWrappable::init(this);
@@ -112,7 +112,7 @@
     ScriptWrappable::init(this);
 }
 
-MessageEvent::MessageEvent(PassRefPtr<Blob> data, const String& origin)
+MessageEvent::MessageEvent(PassRefPtrWillBeRawPtr<Blob> data, const String& origin)
     : Event(EventTypeNames::message, false, false)
     , m_dataType(DataTypeBlob)
     , m_dataAsBlob(data)
@@ -138,7 +138,7 @@
 {
     if (initializer.source.get() && !isValidSource(initializer.source.get())) {
         exceptionState.throwTypeError("The optional 'source' property is neither a Window nor MessagePort.");
-        return 0;
+        return nullptr;
     }
     return adoptRef(new MessageEvent(type, initializer));
 }
@@ -185,4 +185,9 @@
     m_ports = MessagePort::entanglePorts(*context, m_channels.release());
 }
 
+void MessageEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/MessageEvent.h b/Source/core/events/MessageEvent.h
index 1442bf4..548517f 100644
--- a/Source/core/events/MessageEvent.h
+++ b/Source/core/events/MessageEvent.h
@@ -53,15 +53,15 @@
     {
         return adoptRef(new MessageEvent);
     }
-    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
+    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = nullptr)
     {
         return adoptRef(new MessageEvent(origin, lastEventId, source, ports));
     }
-    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
+    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortArray> ports, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = nullptr)
     {
         return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
     }
-    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortChannelArray> channels, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = 0)
+    static PassRefPtr<MessageEvent> create(PassOwnPtr<MessagePortChannelArray> channels, PassRefPtr<SerializedScriptValue> data, const String& origin = String(), const String& lastEventId = String(), PassRefPtr<EventTarget> source = nullptr)
     {
         return adoptRef(new MessageEvent(data, origin, lastEventId, source, channels));
     }
@@ -69,7 +69,7 @@
     {
         return adoptRef(new MessageEvent(data, origin));
     }
-    static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data, const String& origin = String())
+    static PassRefPtr<MessageEvent> create(PassRefPtrWillBeRawPtr<Blob> data, const String& origin = String())
     {
         return adoptRef(new MessageEvent(data, origin));
     }
@@ -113,6 +113,8 @@
 
     void entangleMessagePorts(ExecutionContext*);
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     MessageEvent();
     MessageEvent(const AtomicString&, const MessageEventInit&);
@@ -121,13 +123,13 @@
     MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<EventTarget> source, PassOwnPtr<MessagePortChannelArray>);
 
     explicit MessageEvent(const String& data, const String& origin);
-    explicit MessageEvent(PassRefPtr<Blob> data, const String& origin);
+    explicit MessageEvent(PassRefPtrWillBeRawPtr<Blob> data, const String& origin);
     explicit MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin);
 
     DataType m_dataType;
     RefPtr<SerializedScriptValue> m_dataAsSerializedScriptValue;
     String m_dataAsString;
-    RefPtr<Blob> m_dataAsBlob;
+    RefPtrWillBePersistent<Blob> m_dataAsBlob;
     RefPtr<ArrayBuffer> m_dataAsArrayBuffer;
     String m_origin;
     String m_lastEventId;
diff --git a/Source/core/events/MouseEvent.cpp b/Source/core/events/MouseEvent.cpp
index 8c3d2fa..9788317 100644
--- a/Source/core/events/MouseEvent.cpp
+++ b/Source/core/events/MouseEvent.cpp
@@ -41,7 +41,7 @@
     , shiftKey(false)
     , metaKey(false)
     , button(0)
-    , relatedTarget(0)
+    , relatedTarget(nullptr)
 {
 }
 
@@ -62,14 +62,14 @@
         detail, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
         event.movementDelta().x(), event.movementDelta().y(),
         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(), event.button(),
-        relatedTarget, 0, false);
+        relatedTarget, nullptr, false);
 }
 
 PassRefPtr<MouseEvent> MouseEvent::create(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
     int detail, int screenX, int screenY, int pageX, int pageY,
     int movementX, int movementY,
     bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
-    PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard> clipboard, bool isSimulated)
+    PassRefPtr<EventTarget> relatedTarget, PassRefPtrWillBeRawPtr<Clipboard> clipboard, bool isSimulated)
 {
     return adoptRef(new MouseEvent(type, canBubble, cancelable, view,
         detail, screenX, screenY, pageX, pageY,
@@ -85,11 +85,11 @@
 }
 
 MouseEvent::MouseEvent(const AtomicString& eventType, bool canBubble, bool cancelable, PassRefPtr<AbstractView> view,
-                       int detail, int screenX, int screenY, int pageX, int pageY,
-                       int movementX, int movementY,
-                       bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
-                       unsigned short button, PassRefPtr<EventTarget> relatedTarget,
-                       PassRefPtr<Clipboard> clipboard, bool isSimulated)
+    int detail, int screenX, int screenY, int pageX, int pageY,
+    int movementX, int movementY,
+    bool ctrlKey, bool altKey, bool shiftKey, bool metaKey,
+    unsigned short button, PassRefPtr<EventTarget> relatedTarget,
+    PassRefPtrWillBeRawPtr<Clipboard> clipboard, bool isSimulated)
     : MouseRelatedEvent(eventType, canBubble, cancelable, view, detail, IntPoint(screenX, screenY),
                         IntPoint(pageX, pageY),
                         IntPoint(movementX, movementY),
@@ -110,7 +110,7 @@
     , m_button(initializer.button == (unsigned short)-1 ? 0 : initializer.button)
     , m_buttonDown(initializer.button != (unsigned short)-1)
     , m_relatedTarget(initializer.relatedTarget)
-    , m_clipboard(0 /* clipboard */)
+    , m_clipboard(nullptr /* clipboard */)
 {
     ScriptWrappable::init(this);
     initCoordinates(IntPoint(initializer.clientX, initializer.clientY));
@@ -190,6 +190,12 @@
     return target() ? target()->toNode() : 0;
 }
 
+void MouseEvent::trace(Visitor* visitor)
+{
+    visitor->trace(m_clipboard);
+    MouseRelatedEvent::trace(visitor);
+}
+
 PassRefPtr<SimulatedMouseEvent> SimulatedMouseEvent::create(const AtomicString& eventType, PassRefPtr<AbstractView> view, PassRefPtr<Event> underlyingEvent)
 {
     return adoptRef(new SimulatedMouseEvent(eventType, view, underlyingEvent));
@@ -202,7 +208,7 @@
 SimulatedMouseEvent::SimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<AbstractView> view, PassRefPtr<Event> underlyingEvent)
     : MouseEvent(eventType, true, true, view, 0, 0, 0, 0, 0,
                  0, 0,
-                 false, false, false, false, 0, 0, 0, true)
+                 false, false, false, false, 0, nullptr, nullptr, true)
 {
     if (UIEventWithKeyState* keyStateEvent = findEventWithKeyState(underlyingEvent.get())) {
         m_ctrlKey = keyStateEvent->ctrlKey();
@@ -219,6 +225,11 @@
     }
 }
 
+void SimulatedMouseEvent::trace(Visitor* visitor)
+{
+    MouseEvent::trace(visitor);
+}
+
 PassRefPtr<MouseEventDispatchMediator> MouseEventDispatchMediator::create(PassRefPtr<MouseEvent> mouseEvent, MouseEventType mouseEventType)
 {
     return adoptRef(new MouseEventDispatchMediator(mouseEvent, mouseEventType));
diff --git a/Source/core/events/MouseEvent.h b/Source/core/events/MouseEvent.h
index a61c73e..3783fa6 100644
--- a/Source/core/events/MouseEvent.h
+++ b/Source/core/events/MouseEvent.h
@@ -59,7 +59,7 @@
         int detail, int screenX, int screenY, int pageX, int pageY,
         int movementX, int movementY,
         bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
-        PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard>, bool isSimulated = false);
+        PassRefPtr<EventTarget> relatedTarget, PassRefPtrWillBeRawPtr<Clipboard>, bool isSimulated = false);
 
     static PassRefPtr<MouseEvent> create(const AtomicString& eventType, PassRefPtr<AbstractView>, const PlatformMouseEvent&, int detail, PassRefPtr<Node> relatedTarget);
 
@@ -91,12 +91,14 @@
     virtual bool isDragEvent() const OVERRIDE FINAL;
     virtual int which() const OVERRIDE FINAL;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 protected:
     MouseEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
         int detail, int screenX, int screenY, int pageX, int pageY,
         int movementX, int movementY,
         bool ctrlKey, bool altKey, bool shiftKey, bool metaKey, unsigned short button,
-        PassRefPtr<EventTarget> relatedTarget, PassRefPtr<Clipboard>, bool isSimulated);
+        PassRefPtr<EventTarget> relatedTarget, PassRefPtrWillBeRawPtr<Clipboard>, bool isSimulated);
 
     MouseEvent(const AtomicString& type, const MouseEventInit&);
 
@@ -106,7 +108,7 @@
     unsigned short m_button;
     bool m_buttonDown;
     RefPtr<EventTarget> m_relatedTarget;
-    RefPtr<Clipboard> m_clipboard;
+    RefPtrWillBeMember<Clipboard> m_clipboard;
 };
 
 class SimulatedMouseEvent FINAL : public MouseEvent {
@@ -114,6 +116,8 @@
     static PassRefPtr<SimulatedMouseEvent> create(const AtomicString& eventType, PassRefPtr<AbstractView>, PassRefPtr<Event> underlyingEvent);
     virtual ~SimulatedMouseEvent();
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     SimulatedMouseEvent(const AtomicString& eventType, PassRefPtr<AbstractView>, PassRefPtr<Event> underlyingEvent);
 };
diff --git a/Source/core/events/MouseEvent.idl b/Source/core/events/MouseEvent.idl
index 7dd8284..0b9211c 100644
--- a/Source/core/events/MouseEvent.idl
+++ b/Source/core/events/MouseEvent.idl
@@ -57,6 +57,6 @@
     readonly attribute Node             fromElement;
     readonly attribute Node             toElement;
 
-    readonly attribute Clipboard        dataTransfer;
+    readonly attribute DataTransfer     dataTransfer;
 };
 
diff --git a/Source/core/events/MouseRelatedEvent.cpp b/Source/core/events/MouseRelatedEvent.cpp
index f9df0d8..6918ae3 100644
--- a/Source/core/events/MouseRelatedEvent.cpp
+++ b/Source/core/events/MouseRelatedEvent.cpp
@@ -25,8 +25,8 @@
 
 #include "core/dom/Document.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderObject.h"
 
@@ -42,7 +42,7 @@
 {
     if (!abstractView)
         return LayoutSize();
-    Frame* frame = abstractView->frame();
+    LocalFrame* frame = abstractView->frame();
     if (!frame)
         return LayoutSize();
     FrameView* frameView = frame->view();
@@ -64,7 +64,7 @@
     LayoutPoint adjustedPageLocation;
     LayoutPoint scrollPosition;
 
-    Frame* frame = view() ? view()->frame() : 0;
+    LocalFrame* frame = view() ? view()->frame() : 0;
     if (frame && !isSimulated) {
         if (FrameView* frameView = frame->view()) {
             scrollPosition = frameView->scrollPosition();
@@ -113,7 +113,7 @@
     DOMWindow* window = event->view();
     if (!window)
         return 1;
-    Frame* frame = window->frame();
+    LocalFrame* frame = window->frame();
     if (!frame)
         return 1;
     return frame->pageZoomFactor();
@@ -222,4 +222,9 @@
     return m_clientLocation.y();
 }
 
+void MouseRelatedEvent::trace(Visitor* visitor)
+{
+    UIEventWithKeyState::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/MouseRelatedEvent.h b/Source/core/events/MouseRelatedEvent.h
index ee70b84..bc6863c 100644
--- a/Source/core/events/MouseRelatedEvent.h
+++ b/Source/core/events/MouseRelatedEvent.h
@@ -57,6 +57,8 @@
         const LayoutPoint& absoluteLocation() const { return m_absoluteLocation; }
         void setAbsoluteLocation(const LayoutPoint& p) { m_absoluteLocation = p; }
 
+        virtual void trace(Visitor*) OVERRIDE;
+
     protected:
         MouseRelatedEvent();
         MouseRelatedEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>,
diff --git a/Source/core/events/MutationEvent.cpp b/Source/core/events/MutationEvent.cpp
index 542b304..1a2c9cc 100644
--- a/Source/core/events/MutationEvent.cpp
+++ b/Source/core/events/MutationEvent.cpp
@@ -71,4 +71,9 @@
     return EventNames::MutationEvent;
 }
 
+void MutationEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/MutationEvent.h b/Source/core/events/MutationEvent.h
index e2e9f56..c86f2d1 100644
--- a/Source/core/events/MutationEvent.h
+++ b/Source/core/events/MutationEvent.h
@@ -44,7 +44,7 @@
             return adoptRef(new MutationEvent);
         }
 
-        static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode = 0,
+        static PassRefPtr<MutationEvent> create(const AtomicString& type, bool canBubble, PassRefPtr<Node> relatedNode = nullptr,
             const String& prevValue = String(), const String& newValue = String(), const String& attrName = String(), unsigned short attrChange = 0)
         {
             return adoptRef(new MutationEvent(type, canBubble, false, relatedNode, prevValue, newValue, attrName, attrChange));
@@ -62,6 +62,8 @@
 
         virtual const AtomicString& interfaceName() const OVERRIDE;
 
+        virtual void trace(Visitor*) OVERRIDE;
+
     private:
         MutationEvent();
         MutationEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<Node> relatedNode,
diff --git a/Source/core/events/NavigatorEvents.cpp b/Source/core/events/NavigatorEvents.cpp
index a4285c2..526cdc8 100644
--- a/Source/core/events/NavigatorEvents.cpp
+++ b/Source/core/events/NavigatorEvents.cpp
@@ -31,15 +31,15 @@
 #include "config.h"
 #include "core/events/NavigatorEvents.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Navigator.h"
 #include "core/frame/Settings.h"
 
 namespace WebCore {
 
-long NavigatorEvents::maxTouchPoints(Navigator* navigator)
+long NavigatorEvents::maxTouchPoints(Navigator& navigator)
 {
-    Frame* frame = navigator->frame();
+    LocalFrame* frame = navigator.frame();
     if (!frame)
         return 0;
     if (Settings* settings = frame->settings())
diff --git a/Source/core/events/NavigatorEvents.h b/Source/core/events/NavigatorEvents.h
index 44cead9..84f3ad7 100644
--- a/Source/core/events/NavigatorEvents.h
+++ b/Source/core/events/NavigatorEvents.h
@@ -37,7 +37,7 @@
 
 class NavigatorEvents {
 public:
-    static long maxTouchPoints(Navigator*);
+    static long maxTouchPoints(Navigator&);
 };
 
 } // namespace WebCore
diff --git a/Source/core/events/NavigatorEvents.idl b/Source/core/events/NavigatorEvents.idl
index 2b83961..ed3d206 100644
--- a/Source/core/events/NavigatorEvents.idl
+++ b/Source/core/events/NavigatorEvents.idl
@@ -29,5 +29,5 @@
  */
 
 partial interface Navigator {
-    [RuntimeEnabled=PointerEventsMaxTouchPoints] readonly attribute long maxTouchPoints;
+    readonly attribute long maxTouchPoints;
 };
diff --git a/Source/core/events/NodeEventContext.h b/Source/core/events/NodeEventContext.h
index 4a8cf0c..d01f849 100644
--- a/Source/core/events/NodeEventContext.h
+++ b/Source/core/events/NodeEventContext.h
@@ -47,11 +47,11 @@
     Node* node() const { return m_node.get(); }
 
     void setTreeScopeEventContext(PassRefPtr<TreeScopeEventContext> prpTreeScopeEventContext) { m_treeScopeEventContext = prpTreeScopeEventContext; }
+    TreeScopeEventContext* treeScopeEventContext() { return m_treeScopeEventContext.get(); }
 
     EventTarget* target() const { return m_treeScopeEventContext->target(); }
     EventTarget* relatedTarget() const { return m_treeScopeEventContext->relatedTarget(); }
     TouchEventContext* touchEventContext() const { return m_treeScopeEventContext->touchEventContext(); }
-    PassRefPtr<NodeList> eventPath() const { return m_treeScopeEventContext->eventPath(); }
 
     bool currentTargetSameAsTarget() const { return m_currentTarget.get() == target(); }
     void handleLocalEvents(Event*) const;
diff --git a/Source/core/events/OverflowEvent.cpp b/Source/core/events/OverflowEvent.cpp
index 376404d..a674e65 100644
--- a/Source/core/events/OverflowEvent.cpp
+++ b/Source/core/events/OverflowEvent.cpp
@@ -76,4 +76,9 @@
     return EventNames::OverflowEvent;
 }
 
+void OverflowEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 }
diff --git a/Source/core/events/OverflowEvent.h b/Source/core/events/OverflowEvent.h
index 1f8e1a1..2a20a8d 100644
--- a/Source/core/events/OverflowEvent.h
+++ b/Source/core/events/OverflowEvent.h
@@ -65,6 +65,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     OverflowEvent();
     OverflowEvent(bool horizontalOverflowChanged, bool horizontalOverflow, bool verticalOverflowChanged, bool verticalOverflow);
diff --git a/Source/core/events/PageTransitionEvent.cpp b/Source/core/events/PageTransitionEvent.cpp
index a1878c4..4462808 100644
--- a/Source/core/events/PageTransitionEvent.cpp
+++ b/Source/core/events/PageTransitionEvent.cpp
@@ -64,4 +64,9 @@
     return EventNames::PageTransitionEvent;
 }
 
+void PageTransitionEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/PageTransitionEvent.h b/Source/core/events/PageTransitionEvent.h
index cc79580..f249292 100644
--- a/Source/core/events/PageTransitionEvent.h
+++ b/Source/core/events/PageTransitionEvent.h
@@ -57,6 +57,8 @@
 
     bool persisted() const { return m_persisted; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     PageTransitionEvent();
     PageTransitionEvent(const AtomicString& type, bool persisted);
diff --git a/Source/core/events/PopStateEvent.cpp b/Source/core/events/PopStateEvent.cpp
index 2ab213a..c310932 100644
--- a/Source/core/events/PopStateEvent.cpp
+++ b/Source/core/events/PopStateEvent.cpp
@@ -35,15 +35,15 @@
 
 PopStateEvent::PopStateEvent()
     : Event(EventTypeNames::popstate, false, true)
-    , m_serializedState(0)
-    , m_history(0)
+    , m_serializedState(nullptr)
+    , m_history(nullptr)
 {
     ScriptWrappable::init(this);
 }
 
 PopStateEvent::PopStateEvent(const AtomicString& type, const PopStateEventInit& initializer)
     : Event(type, initializer)
-    , m_history(0)
+    , m_history(nullptr)
 {
     ScriptWrappable::init(this);
 }
@@ -80,4 +80,9 @@
     return EventNames::PopStateEvent;
 }
 
+void PopStateEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/PopStateEvent.h b/Source/core/events/PopStateEvent.h
index 889e5aaf..19f5f88 100644
--- a/Source/core/events/PopStateEvent.h
+++ b/Source/core/events/PopStateEvent.h
@@ -53,6 +53,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     PopStateEvent();
     PopStateEvent(const AtomicString&, const PopStateEventInit&);
diff --git a/Source/core/events/ProgressEvent.cpp b/Source/core/events/ProgressEvent.cpp
index d50bdad..0835160 100644
--- a/Source/core/events/ProgressEvent.cpp
+++ b/Source/core/events/ProgressEvent.cpp
@@ -68,4 +68,9 @@
     return EventNames::ProgressEvent;
 }
 
+void ProgressEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 }
diff --git a/Source/core/events/ProgressEvent.h b/Source/core/events/ProgressEvent.h
index 76bc750..337a9a8 100644
--- a/Source/core/events/ProgressEvent.h
+++ b/Source/core/events/ProgressEvent.h
@@ -59,6 +59,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 protected:
     ProgressEvent();
     ProgressEvent(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total);
diff --git a/Source/core/events/ResourceProgressEvent.cpp b/Source/core/events/ResourceProgressEvent.cpp
index 59d10d4..08fd75b 100644
--- a/Source/core/events/ResourceProgressEvent.cpp
+++ b/Source/core/events/ResourceProgressEvent.cpp
@@ -51,4 +51,9 @@
     return EventNames::ResourceProgressEvent;
 }
 
+void ResourceProgressEvent::trace(Visitor* visitor)
+{
+    ProgressEvent::trace(visitor);
+}
+
 }
diff --git a/Source/core/events/ResourceProgressEvent.h b/Source/core/events/ResourceProgressEvent.h
index bb8ae58..596baf1 100644
--- a/Source/core/events/ResourceProgressEvent.h
+++ b/Source/core/events/ResourceProgressEvent.h
@@ -57,6 +57,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 protected:
     ResourceProgressEvent();
     ResourceProgressEvent(const AtomicString& type, bool lengthComputable, unsigned long long loaded, unsigned long long total, const String& url);
diff --git a/Source/core/events/SecurityPolicyViolationEvent.h b/Source/core/events/SecurityPolicyViolationEvent.h
index 5c52cab..efe2481 100644
--- a/Source/core/events/SecurityPolicyViolationEvent.h
+++ b/Source/core/events/SecurityPolicyViolationEvent.h
@@ -72,6 +72,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::SecurityPolicyViolationEvent; }
 
+    virtual void trace(Visitor* visitor) OVERRIDE { Event::trace(visitor); }
+
 private:
     SecurityPolicyViolationEvent()
     {
diff --git a/Source/core/events/TextEvent.cpp b/Source/core/events/TextEvent.cpp
index 2ed8274..1347c64 100644
--- a/Source/core/events/TextEvent.cpp
+++ b/Source/core/events/TextEvent.cpp
@@ -43,7 +43,7 @@
 
 PassRefPtr<TextEvent> TextEvent::createForPlainTextPaste(PassRefPtr<AbstractView> view, const String& data, bool shouldSmartReplace)
 {
-    return adoptRef(new TextEvent(view, data, 0, shouldSmartReplace, false));
+    return adoptRef(new TextEvent(view, data, nullptr, shouldSmartReplace, false));
 }
 
 PassRefPtr<TextEvent> TextEvent::createForFragmentPaste(PassRefPtr<AbstractView> view, PassRefPtr<DocumentFragment> data, bool shouldSmartReplace, bool shouldMatchStyle)
@@ -68,7 +68,7 @@
     : UIEvent(EventTypeNames::textInput, true, true, view, 0)
     , m_inputType(inputType)
     , m_data(data)
-    , m_pastingFragment(0)
+    , m_pastingFragment(nullptr)
     , m_shouldSmartReplace(false)
     , m_shouldMatchStyle(false)
 {
@@ -106,4 +106,9 @@
     return EventNames::TextEvent;
 }
 
+void TextEvent::trace(Visitor* visitor)
+{
+    UIEvent::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/TextEvent.h b/Source/core/events/TextEvent.h
index 782ed0d..cbb0afb 100644
--- a/Source/core/events/TextEvent.h
+++ b/Source/core/events/TextEvent.h
@@ -61,6 +61,8 @@
         bool shouldMatchStyle() const { return m_shouldMatchStyle; }
         DocumentFragment* pastingFragment() const { return m_pastingFragment.get(); }
 
+        virtual void trace(Visitor*) OVERRIDE;
+
     private:
         TextEvent();
 
diff --git a/Source/core/events/TouchEvent.cpp b/Source/core/events/TouchEvent.cpp
index 68d8095..cd7f311 100644
--- a/Source/core/events/TouchEvent.cpp
+++ b/Source/core/events/TouchEvent.cpp
@@ -88,6 +88,11 @@
     return true;
 }
 
+void TouchEvent::trace(Visitor* visitor)
+{
+    MouseRelatedEvent::trace(visitor);
+}
+
 PassRefPtr<TouchEventDispatchMediator> TouchEventDispatchMediator::create(PassRefPtr<TouchEvent> touchEvent)
 {
     return adoptRef(new TouchEventDispatchMediator(touchEvent));
diff --git a/Source/core/events/TouchEvent.h b/Source/core/events/TouchEvent.h
index 0961817..d929d9e 100644
--- a/Source/core/events/TouchEvent.h
+++ b/Source/core/events/TouchEvent.h
@@ -42,34 +42,36 @@
         return adoptRef(new TouchEvent);
     }
     static PassRefPtr<TouchEvent> create(TouchList* touches,
-            TouchList* targetTouches, TouchList* changedTouches,
-            const AtomicString& type, PassRefPtr<AbstractView> view,
-            int screenX, int screenY, int pageX, int pageY,
-            bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
+        TouchList* targetTouches, TouchList* changedTouches,
+        const AtomicString& type, PassRefPtr<AbstractView> view,
+        int screenX, int screenY, int pageX, int pageY,
+        bool ctrlKey, bool altKey, bool shiftKey, bool metaKey)
     {
         return adoptRef(new TouchEvent(touches, targetTouches, changedTouches,
-                type, view, screenX, screenY, pageX, pageY,
-                ctrlKey, altKey, shiftKey, metaKey));
+            type, view, screenX, screenY, pageX, pageY,
+            ctrlKey, altKey, shiftKey, metaKey));
     }
 
     void initTouchEvent(TouchList* touches, TouchList* targetTouches,
-            TouchList* changedTouches, const AtomicString& type,
-            PassRefPtr<AbstractView> view, int screenX, int screenY,
-            int clientX, int clientY,
-            bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
+        TouchList* changedTouches, const AtomicString& type,
+        PassRefPtr<AbstractView>, int screenX, int screenY,
+        int clientX, int clientY,
+        bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
 
     TouchList* touches() const { return m_touches.get(); }
     TouchList* targetTouches() const { return m_targetTouches.get(); }
     TouchList* changedTouches() const { return m_changedTouches.get(); }
 
-    void setTouches(PassRefPtr<TouchList> touches) { m_touches = touches; }
-    void setTargetTouches(PassRefPtr<TouchList> targetTouches) { m_targetTouches = targetTouches; }
-    void setChangedTouches(PassRefPtr<TouchList> changedTouches) { m_changedTouches = changedTouches; }
+    void setTouches(PassRefPtrWillBeRawPtr<TouchList> touches) { m_touches = touches; }
+    void setTargetTouches(PassRefPtrWillBeRawPtr<TouchList> targetTouches) { m_targetTouches = targetTouches; }
+    void setChangedTouches(PassRefPtrWillBeRawPtr<TouchList> changedTouches) { m_changedTouches = changedTouches; }
 
     virtual bool isTouchEvent() const OVERRIDE;
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     TouchEvent();
     TouchEvent(TouchList* touches, TouchList* targetTouches,
@@ -78,9 +80,9 @@
             int pageY,
             bool ctrlKey, bool altKey, bool shiftKey, bool metaKey);
 
-    RefPtr<TouchList> m_touches;
-    RefPtr<TouchList> m_targetTouches;
-    RefPtr<TouchList> m_changedTouches;
+    RefPtrWillBePersistent<TouchList> m_touches;
+    RefPtrWillBePersistent<TouchList> m_targetTouches;
+    RefPtrWillBePersistent<TouchList> m_changedTouches;
 };
 
 class TouchEventDispatchMediator FINAL : public EventDispatchMediator {
diff --git a/Source/core/events/TouchEventContext.cpp b/Source/core/events/TouchEventContext.cpp
index 5bdd411..c95ba8b 100644
--- a/Source/core/events/TouchEventContext.cpp
+++ b/Source/core/events/TouchEventContext.cpp
@@ -33,9 +33,9 @@
 
 namespace WebCore {
 
-PassRefPtr<TouchEventContext> TouchEventContext::create()
+PassRefPtrWillBeRawPtr<TouchEventContext> TouchEventContext::create()
 {
-    return adoptRef(new TouchEventContext);
+    return adoptRefWillBeNoop(new TouchEventContext);
 }
 
 TouchEventContext::TouchEventContext()
@@ -45,9 +45,7 @@
 {
 }
 
-TouchEventContext::~TouchEventContext()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(TouchEventContext)
 
 void TouchEventContext::handleLocalEvents(Event* event) const
 {
@@ -58,4 +56,11 @@
     touchEvent->setChangedTouches(m_changedTouches);
 }
 
+void TouchEventContext::trace(Visitor* visitor)
+{
+    visitor->trace(m_touches);
+    visitor->trace(m_targetTouches);
+    visitor->trace(m_changedTouches);
+}
+
 }
diff --git a/Source/core/events/TouchEventContext.h b/Source/core/events/TouchEventContext.h
index b6c0f1a..7ae8dce 100644
--- a/Source/core/events/TouchEventContext.h
+++ b/Source/core/events/TouchEventContext.h
@@ -27,6 +27,7 @@
 #ifndef TouchEventContext_h
 #define TouchEventContext_h
 
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -36,21 +37,23 @@
 class Event;
 class TouchList;
 
-class TouchEventContext : public RefCounted<TouchEventContext> {
+class TouchEventContext : public RefCountedWillBeGarbageCollected<TouchEventContext> {
+    DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(TouchEventContext);
 public:
-    static PassRefPtr<TouchEventContext> create();
-    ~TouchEventContext();
+    static PassRefPtrWillBeRawPtr<TouchEventContext> create();
     void handleLocalEvents(Event*) const;
     TouchList& touches() { return *m_touches; }
     TouchList& targetTouches() { return *m_targetTouches; }
     TouchList& changedTouches() { return *m_changedTouches; }
 
+    void trace(Visitor*);
+
 private:
     TouchEventContext();
 
-    RefPtr<TouchList> m_touches;
-    RefPtr<TouchList> m_targetTouches;
-    RefPtr<TouchList> m_changedTouches;
+    RefPtrWillBeMember<TouchList> m_touches;
+    RefPtrWillBeMember<TouchList> m_targetTouches;
+    RefPtrWillBeMember<TouchList> m_changedTouches;
 };
 
 }
diff --git a/Source/core/events/TransitionEvent.cpp b/Source/core/events/TransitionEvent.cpp
index dfc32fd..d997485 100644
--- a/Source/core/events/TransitionEvent.cpp
+++ b/Source/core/events/TransitionEvent.cpp
@@ -84,4 +84,9 @@
     return EventNames::TransitionEvent;
 }
 
+void TransitionEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/TransitionEvent.h b/Source/core/events/TransitionEvent.h
index 91bab0e..27d774a 100644
--- a/Source/core/events/TransitionEvent.h
+++ b/Source/core/events/TransitionEvent.h
@@ -62,6 +62,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     TransitionEvent();
     TransitionEvent(const AtomicString& type, const String& propertyName, double elapsedTime, const String& pseudoElement);
diff --git a/Source/core/events/TreeScopeEventContext.cpp b/Source/core/events/TreeScopeEventContext.cpp
index 98df539..a86922b 100644
--- a/Source/core/events/TreeScopeEventContext.cpp
+++ b/Source/core/events/TreeScopeEventContext.cpp
@@ -28,13 +28,25 @@
 #include "core/events/TreeScopeEventContext.h"
 
 #include "core/dom/StaticNodeList.h"
+#include "core/dom/shadow/ShadowRoot.h"
+#include "core/events/EventPath.h"
 #include "core/events/TouchEventContext.h"
 
 namespace WebCore {
 
-void TreeScopeEventContext::adoptEventPath(Vector<RefPtr<Node> >& nodes)
+PassRefPtr<NodeList> TreeScopeEventContext::ensureEventPath(EventPath& path)
 {
+    if (m_eventPath)
+        return m_eventPath;
+
+    Vector<RefPtr<Node> > nodes;
+    nodes.reserveInitialCapacity(path.size());
+    for (size_t i = 0; i < path.size(); ++i) {
+        if (path[i].treeScopeEventContext()->isInclusiveAncestorOf(*this))
+            nodes.append(path[i].node());
+    }
     m_eventPath = StaticNodeList::adopt(nodes);
+    return m_eventPath;
 }
 
 TouchEventContext* TreeScopeEventContext::ensureTouchEventContext()
@@ -51,6 +63,8 @@
 
 TreeScopeEventContext::TreeScopeEventContext(TreeScope& treeScope)
     : m_treeScope(treeScope)
+    , m_preOrder(-1)
+    , m_postOrder(-1)
 {
 }
 
@@ -58,4 +72,13 @@
 {
 }
 
+int TreeScopeEventContext::calculatePrePostOrderNumber(int orderNumber)
+{
+    m_preOrder = orderNumber;
+    for (size_t i = 0; i < m_children.size(); ++i)
+        orderNumber = m_children[i]->calculatePrePostOrderNumber(orderNumber + 1);
+    m_postOrder = orderNumber + 1;
+    return orderNumber + 1;
+}
+
 }
diff --git a/Source/core/events/TreeScopeEventContext.h b/Source/core/events/TreeScopeEventContext.h
index c697566..11a7c8a 100644
--- a/Source/core/events/TreeScopeEventContext.h
+++ b/Source/core/events/TreeScopeEventContext.h
@@ -37,6 +37,7 @@
 
 namespace WebCore {
 
+class EventPath;
 class EventTarget;
 class Node;
 class TouchEventContext;
@@ -58,8 +59,14 @@
     TouchEventContext* touchEventContext() const { return m_touchEventContext.get(); }
     TouchEventContext* ensureTouchEventContext();
 
-    PassRefPtr<NodeList> eventPath() const { return m_eventPath; }
-    void adoptEventPath(Vector<RefPtr<Node> >&);
+    PassRefPtr<NodeList> ensureEventPath(EventPath&);
+
+    bool isInclusiveAncestorOf(const TreeScopeEventContext&);
+    void addChild(TreeScopeEventContext& child) { m_children.append(&child); }
+
+    // For ancestor-descendant relationship check in Q(1).
+    // Preprocessing takes O(N).
+    int calculatePrePostOrderNumber(int orderNumber);
 
 private:
     TreeScopeEventContext(TreeScope&);
@@ -72,7 +79,11 @@
     RefPtr<EventTarget> m_target;
     RefPtr<EventTarget> m_relatedTarget;
     RefPtr<NodeList> m_eventPath;
-    RefPtr<TouchEventContext> m_touchEventContext;
+    RefPtrWillBePersistent<TouchEventContext> m_touchEventContext;
+
+    Vector<TreeScopeEventContext*> m_children;
+    int m_preOrder;
+    int m_postOrder;
 };
 
 #ifndef NDEBUG
@@ -97,6 +108,12 @@
     m_relatedTarget = relatedTarget;
 }
 
+inline bool TreeScopeEventContext::isInclusiveAncestorOf(const TreeScopeEventContext& other)
+{
+    ASSERT(m_preOrder != -1 && m_postOrder != -1 && other.m_preOrder != -1 && other.m_postOrder != -1);
+    return m_preOrder <= other.m_preOrder && other.m_postOrder <= m_postOrder;
+}
+
 }
 
 #endif // TreeScopeEventContext_h
diff --git a/Source/core/events/UIEvent.cpp b/Source/core/events/UIEvent.cpp
index 6a0db63..c19a74f 100644
--- a/Source/core/events/UIEvent.cpp
+++ b/Source/core/events/UIEvent.cpp
@@ -27,7 +27,7 @@
 namespace WebCore {
 
 UIEventInit::UIEventInit()
-    : view(0)
+    : view(nullptr)
     , detail(0)
 {
 }
@@ -114,4 +114,9 @@
     return 0;
 }
 
+void UIEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/UIEvent.h b/Source/core/events/UIEvent.h
index b0d3844..bccb5d9 100644
--- a/Source/core/events/UIEvent.h
+++ b/Source/core/events/UIEvent.h
@@ -75,6 +75,8 @@
 
     virtual int which() const;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 protected:
     UIEvent();
     UIEvent(const AtomicString& type, bool canBubble, bool cancelable, PassRefPtr<AbstractView>, int detail);
diff --git a/Source/core/events/WebKitAnimationEvent.cpp b/Source/core/events/WebKitAnimationEvent.cpp
index cefe08f..09787b3 100644
--- a/Source/core/events/WebKitAnimationEvent.cpp
+++ b/Source/core/events/WebKitAnimationEvent.cpp
@@ -77,4 +77,9 @@
     return EventNames::WebKitAnimationEvent;
 }
 
+void WebKitAnimationEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/events/WebKitAnimationEvent.h b/Source/core/events/WebKitAnimationEvent.h
index 731f45d..0c4549a 100644
--- a/Source/core/events/WebKitAnimationEvent.h
+++ b/Source/core/events/WebKitAnimationEvent.h
@@ -62,6 +62,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     WebKitAnimationEvent();
     WebKitAnimationEvent(const AtomicString& type, const String& animationName, double elapsedTime);
diff --git a/Source/core/events/WheelEvent.cpp b/Source/core/events/WheelEvent.cpp
index 37bf05b..7495430 100644
--- a/Source/core/events/WheelEvent.cpp
+++ b/Source/core/events/WheelEvent.cpp
@@ -68,7 +68,7 @@
                  true, true, view, 0, screenLocation.x(), screenLocation.y(),
                  pageLocation.x(), pageLocation.y(),
                  0, 0,
-                 ctrlKey, altKey, shiftKey, metaKey, 0, 0, 0, false)
+                 ctrlKey, altKey, shiftKey, metaKey, 0, nullptr, nullptr, false)
     , m_wheelDelta(wheelTicks.x() * TickMultiplier, wheelTicks.y() * TickMultiplier)
     , m_deltaX(-rawDelta.x())
     , m_deltaY(-rawDelta.y())
@@ -126,6 +126,11 @@
     return true;
 }
 
+void WheelEvent::trace(Visitor* visitor)
+{
+    MouseEvent::trace(visitor);
+}
+
 inline static unsigned deltaMode(const PlatformWheelEvent& event)
 {
     return event.granularity() == ScrollByPageWheelEvent ? WheelEvent::DOM_DELTA_PAGE : WheelEvent::DOM_DELTA_PIXEL;
diff --git a/Source/core/events/WheelEvent.h b/Source/core/events/WheelEvent.h
index b527130..080c256 100644
--- a/Source/core/events/WheelEvent.h
+++ b/Source/core/events/WheelEvent.h
@@ -97,6 +97,8 @@
     virtual bool isMouseEvent() const OVERRIDE;
     virtual bool isWheelEvent() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     WheelEvent();
     WheelEvent(const AtomicString&, const WheelEventInit&);
diff --git a/Source/core/fetch/CSSStyleSheetResource.cpp b/Source/core/fetch/CSSStyleSheetResource.cpp
index 0d431c8..b92f8fb 100644
--- a/Source/core/fetch/CSSStyleSheetResource.cpp
+++ b/Source/core/fetch/CSSStyleSheetResource.cpp
@@ -110,12 +110,12 @@
 
 bool CSSStyleSheetResource::isSafeToUnlock() const
 {
-    return m_parsedStyleSheetCache;
+    return m_data->hasOneRef();
 }
 
 void CSSStyleSheetResource::destroyDecodedDataIfPossible()
 {
-    if (!isSafeToUnlock())
+    if (!m_parsedStyleSheetCache)
         return;
 
     m_parsedStyleSheetCache->removedFromMemoryCache();
@@ -148,14 +148,14 @@
     return typeOK;
 }
 
-PassRefPtr<StyleSheetContents> CSSStyleSheetResource::restoreParsedStyleSheet(const CSSParserContext& context)
+PassRefPtrWillBeRawPtr<StyleSheetContents> CSSStyleSheetResource::restoreParsedStyleSheet(const CSSParserContext& context)
 {
     if (!m_parsedStyleSheetCache)
-        return 0;
+        return nullptr;
     if (m_parsedStyleSheetCache->hasFailedOrCanceledSubresources()) {
         m_parsedStyleSheetCache->removedFromMemoryCache();
         m_parsedStyleSheetCache.clear();
-        return 0;
+        return nullptr;
     }
 
     ASSERT(m_parsedStyleSheetCache->isCacheable());
@@ -163,14 +163,14 @@
 
     // Contexts must be identical so we know we would get the same exact result if we parsed again.
     if (m_parsedStyleSheetCache->parserContext() != context)
-        return 0;
+        return nullptr;
 
     didAccessDecodedData(currentTime());
 
     return m_parsedStyleSheetCache;
 }
 
-void CSSStyleSheetResource::saveParsedStyleSheet(PassRefPtr<StyleSheetContents> sheet)
+void CSSStyleSheetResource::saveParsedStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents> sheet)
 {
     ASSERT(sheet && sheet->isCacheable());
 
diff --git a/Source/core/fetch/CSSStyleSheetResource.h b/Source/core/fetch/CSSStyleSheetResource.h
index f2fea75..35d0b0f 100644
--- a/Source/core/fetch/CSSStyleSheetResource.h
+++ b/Source/core/fetch/CSSStyleSheetResource.h
@@ -28,6 +28,7 @@
 
 #include "core/fetch/ResourcePtr.h"
 #include "core/fetch/StyleSheetResource.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -47,8 +48,8 @@
     virtual void setEncoding(const String&) OVERRIDE;
     virtual String encoding() const OVERRIDE;
 
-    PassRefPtr<StyleSheetContents> restoreParsedStyleSheet(const CSSParserContext&);
-    void saveParsedStyleSheet(PassRefPtr<StyleSheetContents>);
+    PassRefPtrWillBeRawPtr<StyleSheetContents> restoreParsedStyleSheet(const CSSParserContext&);
+    void saveParsedStyleSheet(PassRefPtrWillBeRawPtr<StyleSheetContents>);
 
 protected:
     virtual bool isSafeToUnlock() const OVERRIDE;
@@ -61,7 +62,7 @@
     OwnPtr<TextResourceDecoder> m_decoder;
     String m_decodedSheetText;
 
-    RefPtr<StyleSheetContents> m_parsedStyleSheetCache;
+    RefPtrWillBePersistent<StyleSheetContents> m_parsedStyleSheetCache;
 };
 
 DEFINE_RESOURCE_TYPE_CASTS(CSSStyleSheet);
diff --git a/Source/core/fetch/CachingCorrectnessTest.cpp b/Source/core/fetch/CachingCorrectnessTest.cpp
index 1056506..ab3c77d 100644
--- a/Source/core/fetch/CachingCorrectnessTest.cpp
+++ b/Source/core/fetch/CachingCorrectnessTest.cpp
@@ -121,7 +121,7 @@
         m_testingMemoryCache = adoptPtr(new MemoryCache());
         setMemoryCacheForTesting(m_testingMemoryCache.leakPtr());
 
-        // Create a ResourceFetcher that has a real DocumentLoader and Document, but is not attached to a Frame.
+        // Create a ResourceFetcher that has a real DocumentLoader and Document, but is not attached to a LocalFrame.
         const KURL kDocumentURL(ParsedURLString, "http://document.com/");
         m_documentLoader = DocumentLoader::create(0, ResourceRequest(kDocumentURL), SubstituteData());
         m_document = HTMLDocument::create();
diff --git a/Source/core/fetch/CrossOriginAccessControl.cpp b/Source/core/fetch/CrossOriginAccessControl.cpp
index 98d2b1a..0a841ac 100644
--- a/Source/core/fetch/CrossOriginAccessControl.cpp
+++ b/Source/core/fetch/CrossOriginAccessControl.cpp
@@ -103,7 +103,7 @@
 void updateRequestForAccessControl(ResourceRequest& request, SecurityOrigin* securityOrigin, StoredCredentials allowCredentials)
 {
     request.removeCredentials();
-    request.setAllowCookies(allowCredentials == AllowStoredCredentials);
+    request.setAllowStoredCredentials(allowCredentials == AllowStoredCredentials);
 
     if (securityOrigin)
         request.setHTTPOrigin(securityOrigin->toAtomicString());
@@ -152,16 +152,18 @@
         return false;
     }
 
-    // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
-    // even with Access-Control-Allow-Credentials set to true.
     const AtomicString& accessControlOriginString = response.httpHeaderField(accessControlAllowOrigin);
-    if (accessControlOriginString == starAtom && includeCredentials == DoNotAllowStoredCredentials)
-        return true;
-
-    if (accessControlOriginString != securityOrigin->toAtomicString()) {
-        if (accessControlOriginString == starAtom) {
+    if (accessControlOriginString == starAtom) {
+        // A wildcard Access-Control-Allow-Origin can not be used if credentials are to be sent,
+        // even with Access-Control-Allow-Credentials set to true.
+        if (includeCredentials == DoNotAllowStoredCredentials)
+            return true;
+        if (response.isHTTP()) {
             errorDescription = "A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is true. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
-        } else if (accessControlOriginString.isEmpty()) {
+            return false;
+        }
+    } else if (accessControlOriginString != securityOrigin->toAtomicString()) {
+        if (accessControlOriginString.isEmpty()) {
             errorDescription = "No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
         } else if (accessControlOriginString.string().find(isOriginSeparator, 0) != kNotFound) {
             errorDescription = "The 'Access-Control-Allow-Origin' header contains multiple values '" + accessControlOriginString + "', but only one is allowed. Origin '" + securityOrigin->toString() + "' is therefore not allowed access.";
@@ -240,7 +242,7 @@
         bool allowRedirect = isLegalRedirectLocation(requestURL, errorDescription);
         if (allowRedirect) {
             // Step 5: perform resource sharing access check.
-            StoredCredentials withCredentials = resource->resourceRequest().allowCookies() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
+            StoredCredentials withCredentials = resource->resourceRequest().allowStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials;
             allowRedirect = passesAccessControlCheck(redirectResponse, withCredentials, securityOrigin, errorDescription);
             if (allowRedirect) {
                 RefPtr<SecurityOrigin> originalOrigin = SecurityOrigin::create(originalURL);
diff --git a/Source/core/fetch/DocumentResource.cpp b/Source/core/fetch/DocumentResource.cpp
index 61521b0..4cb90aa 100644
--- a/Source/core/fetch/DocumentResource.cpp
+++ b/Source/core/fetch/DocumentResource.cpp
@@ -73,7 +73,7 @@
     default:
         // FIXME: We'll add more types to support HTMLImports.
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 }
 
diff --git a/Source/core/fetch/FetchContext.h b/Source/core/fetch/FetchContext.h
index 9e40ac1..6d79f2e 100644
--- a/Source/core/fetch/FetchContext.h
+++ b/Source/core/fetch/FetchContext.h
@@ -41,7 +41,7 @@
 
 class Document;
 class DocumentLoader;
-class Frame;
+class LocalFrame;
 class KURL;
 class Page;
 class ResourceError;
diff --git a/Source/core/fetch/FetchRequest.cpp b/Source/core/fetch/FetchRequest.cpp
index 4ec40cc..367069a 100644
--- a/Source/core/fetch/FetchRequest.cpp
+++ b/Source/core/fetch/FetchRequest.cpp
@@ -73,13 +73,12 @@
 {
     updateRequestForAccessControl(m_resourceRequest, origin, allowCredentials);
     m_options.corsEnabled = IsCORSEnabled;
+    m_options.securityOrigin = origin;
 }
 
 void FetchRequest::setCrossOriginAccessControl(SecurityOrigin* origin, const AtomicString& crossOriginMode)
 {
-    StoredCredentials allowCredentials = equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials;
-    updateRequestForAccessControl(m_resourceRequest, origin, allowCredentials);
-    m_options.corsEnabled = IsCORSEnabled;
+    setCrossOriginAccessControl(origin, equalIgnoringCase(crossOriginMode, "use-credentials") ? AllowStoredCredentials : DoNotAllowStoredCredentials);
 }
 
 } // namespace WebCore
diff --git a/Source/core/fetch/FontResource.cpp b/Source/core/fetch/FontResource.cpp
index a3c8824..0a0138d 100644
--- a/Source/core/fetch/FontResource.cpp
+++ b/Source/core/fetch/FontResource.cpp
@@ -44,9 +44,13 @@
 
 namespace WebCore {
 
+static const double fontLoadWaitLimitSec = 3.0;
+
 FontResource::FontResource(const ResourceRequest& resourceRequest)
     : Resource(resourceRequest, Font)
     , m_loadInitiated(false)
+    , m_exceedsFontLoadWaitLimit(false)
+    , m_fontLoadWaitLimitTimer(this, &FontResource::fontLoadWaitLimitCallback)
 {
 }
 
@@ -74,6 +78,7 @@
     if (!m_loadInitiated) {
         m_loadInitiated = true;
         Resource::load(dl, m_options);
+        m_fontLoadWaitLimitTimer.startOneShot(fontLoadWaitLimitSec, FROM_HERE);
 
         ResourceClientWalker<FontResourceClient> walker(m_clients);
         while (FontResourceClient* client = walker.next())
@@ -116,7 +121,7 @@
             m_externalSVGDocument->setContent(svgSource);
 
             if (decoder->sawError())
-                m_externalSVGDocument = 0;
+                m_externalSVGDocument = nullptr;
         }
         if (!m_externalSVGDocument)
             setStatus(DecodeError);
@@ -138,7 +143,7 @@
 #ifndef NDEBUG
     for (unsigned i = 0; i < collectionLength; ++i) {
         ASSERT(collection->item(i));
-        ASSERT(collection->item(i)->hasTagName(SVGNames::fontTag));
+        ASSERT(isSVGFontElement(collection->item(i)));
     }
 #endif
 
@@ -155,6 +160,21 @@
 }
 #endif
 
+bool FontResource::isSafeToUnlock() const
+{
+    return m_data->hasOneRef();
+}
+
+void FontResource::fontLoadWaitLimitCallback(Timer<FontResource>*)
+{
+    if (!isLoading())
+        return;
+    m_exceedsFontLoadWaitLimit = true;
+    ResourceClientWalker<FontResourceClient> walker(m_clients);
+    while (FontResourceClient* client = walker.next())
+        client->fontLoadWaitLimitExceeded(this);
+}
+
 void FontResource::allClientsRemoved()
 {
     m_fontData.clear();
@@ -163,6 +183,7 @@
 
 void FontResource::checkNotify()
 {
+    m_fontLoadWaitLimitTimer.stop();
     ResourceClientWalker<FontResourceClient> w(m_clients);
     while (FontResourceClient* c = w.next())
         c->fontLoaded(this);
diff --git a/Source/core/fetch/FontResource.h b/Source/core/fetch/FontResource.h
index 306d204..66df929 100644
--- a/Source/core/fetch/FontResource.h
+++ b/Source/core/fetch/FontResource.h
@@ -28,6 +28,7 @@
 
 #include "core/fetch/ResourceClient.h"
 #include "core/fetch/ResourcePtr.h"
+#include "platform/Timer.h"
 #include "platform/fonts/FontOrientation.h"
 #include "platform/fonts/FontWidthVariant.h"
 #include "wtf/OwnPtr.h"
@@ -54,6 +55,7 @@
     virtual void allClientsRemoved() OVERRIDE;
     void beginLoadIfNeeded(ResourceFetcher* dl);
     virtual bool stillNeedsLoad() const OVERRIDE { return !m_loadInitiated; }
+    bool exceedsFontLoadWaitLimit() const { return m_exceedsFontLoadWaitLimit; }
 
     bool ensureCustomFontData();
     FontPlatformData platformDataFromCustomData(float size, bool bold, bool italic, FontOrientation = Horizontal, FontWidthVariant = RegularWidth);
@@ -63,10 +65,17 @@
     SVGFontElement* getSVGFontById(const String&) const;
 #endif
 
+protected:
+    virtual bool isSafeToUnlock() const OVERRIDE;
+
 private:
     virtual void checkNotify() OVERRIDE;
+    void fontLoadWaitLimitCallback(Timer<FontResource>*);
+
     OwnPtr<FontCustomPlatformData> m_fontData;
     bool m_loadInitiated;
+    bool m_exceedsFontLoadWaitLimit;
+    Timer<FontResource> m_fontLoadWaitLimitTimer;
 
 #if ENABLE(SVG_FONTS)
     RefPtr<WebCore::SVGDocument> m_externalSVGDocument;
@@ -84,6 +93,7 @@
     virtual ResourceClientType resourceClientType() const OVERRIDE FINAL { return expectedType(); }
     virtual void fontLoaded(FontResource*) { }
     virtual void didStartFontLoad(FontResource*) { }
+    virtual void fontLoadWaitLimitExceeded(FontResource*) { }
 };
 
 }
diff --git a/Source/core/fetch/ImageResource.cpp b/Source/core/fetch/ImageResource.cpp
index 543f392..065587c 100644
--- a/Source/core/fetch/ImageResource.cpp
+++ b/Source/core/fetch/ImageResource.cpp
@@ -44,7 +44,7 @@
 ImageResource::ImageResource(const ResourceRequest& resourceRequest)
     : Resource(resourceRequest, Image)
     , m_devicePixelRatioHeaderValue(1.0)
-    , m_image(0)
+    , m_image(nullptr)
     , m_loadingMultipartContent(false)
     , m_hasDevicePixelRatioHeaderValue(false)
 {
@@ -131,13 +131,14 @@
 
 bool ImageResource::isSafeToUnlock() const
 {
-    return !m_image || (m_image->hasOneRef() && m_image->isBitmapImage());
+    // Note that |m_image| holds a reference to |m_data| in addition to the one held by the Resource parent class.
+    return !m_image || (m_image->hasOneRef() && m_data->refCount() == 2);
 }
 
 void ImageResource::destroyDecodedDataIfPossible()
 {
-    if (isSafeToUnlock() && !hasClients() && !isLoading()) {
-        m_image = 0;
+    if (!hasClients() && !isLoading() && (!m_image || (m_image->hasOneRef() && m_image->isBitmapImage()))) {
+        m_image = nullptr;
         setDecodedSize(0);
     } else if (m_image && !errorOccurred()) {
         m_image->destroyDecodedData(true);
@@ -426,7 +427,7 @@
         return;
 
     double timeStamp = FrameView::currentFrameTimeStamp();
-    if (!timeStamp) // If didDraw is called outside of a Frame paint.
+    if (!timeStamp) // If didDraw is called outside of a LocalFrame paint.
         timeStamp = currentTime();
 
     Resource::didAccessDecodedData(timeStamp);
diff --git a/Source/core/fetch/MemoryCache.cpp b/Source/core/fetch/MemoryCache.cpp
index 0092519..e6d24c9 100644
--- a/Source/core/fetch/MemoryCache.cpp
+++ b/Source/core/fetch/MemoryCache.cpp
@@ -81,7 +81,7 @@
 {
 #ifdef MEMORY_CACHE_STATS
     const double statsIntervalInSeconds = 15;
-    m_statsTimer.startRepeating(statsIntervalInSeconds);
+    m_statsTimer.startRepeating(statsIntervalInSeconds, FROM_HERE);
 #endif
     m_pruneTimeStamp = m_pruneFrameTimeStamp = FrameView::currentFrameTimeStamp();
 }
@@ -332,6 +332,7 @@
         return;
 
     MemoryCacheEntry* entry = m_resources.get(resource->url());
+    ASSERT(entry->m_resource == resource);
     LRUList* list = lruListFor(entry);
 
 #if !ASSERT_DISABLED
@@ -349,26 +350,24 @@
     MemoryCacheEntry* next = entry->m_nextInAllResourcesList;
     MemoryCacheEntry* previous = entry->m_previousInAllResourcesList;
 
-    if (!next && !previous && list->m_head != entry)
-        return;
-
     entry->m_nextInAllResourcesList = 0;
     entry->m_previousInAllResourcesList = 0;
 
     if (next)
         next->m_previousInAllResourcesList = previous;
-    else if (list->m_tail == entry)
+    else
         list->m_tail = previous;
 
     if (previous)
         previous->m_nextInAllResourcesList = next;
-    else if (list->m_head == entry)
+    else
         list->m_head = next;
 }
 
 void MemoryCache::insertInLRUList(Resource* resource)
 {
     MemoryCacheEntry* entry = m_resources.get(resource->url());
+    ASSERT(entry->m_resource == resource);
 
     // Make sure we aren't in some list already.
     ASSERT(!entry->m_nextInAllResourcesList && !entry->m_previousInAllResourcesList);
@@ -402,6 +401,7 @@
 void MemoryCache::removeFromLiveDecodedResourcesList(Resource* resource)
 {
     MemoryCacheEntry* entry = m_resources.get(resource->url());
+    ASSERT(entry->m_resource == resource);
 
     // If we've never been accessed, then we're brand new and not in any list.
     if (!entry->m_inLiveDecodedResourcesList)
@@ -425,26 +425,24 @@
     MemoryCacheEntry* next = entry->m_nextInLiveResourcesList;
     MemoryCacheEntry* previous = entry->m_previousInLiveResourcesList;
 
-    if (!next && !previous && list->m_head != entry)
-        return;
-
     entry->m_nextInLiveResourcesList = 0;
     entry->m_previousInLiveResourcesList = 0;
 
     if (next)
         next->m_previousInLiveResourcesList = previous;
-    else if (list->m_tail == entry)
+    else
         list->m_tail = previous;
 
     if (previous)
         previous->m_nextInLiveResourcesList = next;
-    else if (list->m_head == entry)
+    else
         list->m_head = next;
 }
 
 void MemoryCache::insertInLiveDecodedResourcesList(Resource* resource)
 {
     MemoryCacheEntry* entry = m_resources.get(resource->url());
+    ASSERT(entry->m_resource == resource);
 
     // Make sure we aren't in the list already.
     ASSERT(!entry->m_nextInLiveResourcesList && !entry->m_previousInLiveResourcesList && !entry->m_inLiveDecodedResourcesList);
@@ -475,6 +473,7 @@
 bool MemoryCache::isInLiveDecodedResourcesList(Resource* resource)
 {
     MemoryCacheEntry* entry = m_resources.get(resource->url());
+    ASSERT(entry->m_resource == resource);
     return entry ? entry->m_inLiveDecodedResourcesList : false;
 }
 
diff --git a/Source/core/fetch/RawResource.cpp b/Source/core/fetch/RawResource.cpp
index 1d4fe56..8bcabe3 100644
--- a/Source/core/fetch/RawResource.cpp
+++ b/Source/core/fetch/RawResource.cpp
@@ -154,7 +154,7 @@
     if (m_resourceRequest.httpBody() != newRequest.httpBody())
         return false;
 
-    if (m_resourceRequest.allowCookies() != newRequest.allowCookies())
+    if (m_resourceRequest.allowStoredCredentials() != newRequest.allowStoredCredentials())
         return false;
 
     // Ensure most headers match the existing headers before continuing.
diff --git a/Source/core/fetch/Resource.cpp b/Source/core/fetch/Resource.cpp
index c728f37..d097051 100644
--- a/Source/core/fetch/Resource.cpp
+++ b/Source/core/fetch/Resource.cpp
@@ -35,7 +35,6 @@
 #include "core/fetch/ResourcePtr.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "platform/Logging.h"
-#include "platform/PurgeableBuffer.h"
 #include "platform/SharedBuffer.h"
 #include "platform/weborigin/KURL.h"
 #include "public/platform/Platform.h"
@@ -141,7 +140,8 @@
 {
     ASSERT(!m_resourceToRevalidate); // Should be true because canDelete() checks this.
     ASSERT(canDelete());
-    ASSERT(!inCache());
+    RELEASE_ASSERT(!inCache());
+    RELEASE_ASSERT(!ResourceCallback::callbackHandler()->isScheduled(this));
     ASSERT(!m_deleted);
     ASSERT(url().isNull() || memoryCache()->resourceForURL(KURL(ParsedURLString, url())) != this);
 
@@ -209,7 +209,7 @@
     if (m_data)
         m_data->append(data, length);
     else
-        m_data = SharedBuffer::create(data, length);
+        m_data = SharedBuffer::createPurgeable(data, length);
     setEncodedSize(m_data->size());
 }
 
@@ -269,7 +269,7 @@
 
 bool Resource::passesAccessControlCheck(SecurityOrigin* securityOrigin, String& errorDescription)
 {
-    return WebCore::passesAccessControlCheck(m_response, resourceRequest().allowCookies() ? AllowStoredCredentials : DoNotAllowStoredCredentials, securityOrigin, errorDescription);
+    return WebCore::passesAccessControlCheck(m_response, resourceRequest().allowStoredCredentials() ? AllowStoredCredentials : DoNotAllowStoredCredentials, securityOrigin, errorDescription);
 }
 
 static double currentAge(const ResourceResponse& response, double responseTimestamp)
@@ -344,27 +344,16 @@
 
 bool Resource::unlock()
 {
-    if (hasClients() || m_proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock())
-        return false;
-
-    if (m_purgeableData) {
-        ASSERT(!m_data);
-        return true;
-    }
     if (!m_data)
         return false;
 
-    // Should not make buffer purgeable if it has refs other than this since we don't want two copies.
-    if (!m_data->hasOneRef())
+    if (!m_data->isLocked())
+        return true;
+
+    if (!inCache() || hasClients() || m_handleCount > 1 || m_proxyResource || m_resourceToRevalidate || !m_loadFinishTime || !isSafeToUnlock())
         return false;
 
-    m_data->createPurgeableBuffer();
-    if (!m_data->hasPurgeableBuffer())
-        return false;
-
-    m_purgeableData = m_data->releasePurgeableBuffer();
-    m_purgeableData->unlock();
-    m_data.clear();
+    m_data->unlock();
     return true;
 }
 
@@ -426,7 +415,7 @@
 
 void Resource::clearLoader()
 {
-    m_loader = 0;
+    m_loader = nullptr;
 }
 
 void Resource::addClient(ResourceClient* client)
@@ -507,13 +496,14 @@
         }
         if (!m_switchingClientsToRevalidatedResource)
             allClientsRemoved();
-        if (response().cacheControlContainsNoStore()) {
-            // RFC2616 14.9.2:
-            // "no-store: ... MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible"
-            // "... History buffers MAY store such responses as part of their normal operation."
-            // We allow non-secure content to be reused in history, but we do not allow secure content to be reused.
-            if (url().protocolIs("https"))
-                memoryCache()->remove(this);
+
+        // RFC2616 14.9.2:
+        // "no-store: ... MUST make a best-effort attempt to remove the information from volatile storage as promptly as possible"
+        // "... History buffers MAY store such responses as part of their normal operation."
+        // We allow non-secure content to be reused in history, but we do not allow secure content to be reused.
+        if (response().cacheControlContainsNoStore() && url().protocolIs("https")) {
+            memoryCache()->remove(this);
+            memoryCache()->prune();
         } else {
             memoryCache()->prune(this);
         }
@@ -528,7 +518,9 @@
     if (m_type == MainResource || m_type == Raw)
         cancelTimerFired(&m_cancelTimer);
     else if (!m_cancelTimer.isActive())
-        m_cancelTimer.startOneShot(0);
+        m_cancelTimer.startOneShot(0, FROM_HERE);
+
+    unlock();
 }
 
 void Resource::cancelTimerFired(Timer<Resource>* timer)
@@ -805,8 +797,13 @@
     if (m_resourceToRevalidate)
         m_handlesToRevalidate.remove(h);
 
-    if (!m_handleCount)
-        deleteIfPossible();
+    if (!m_handleCount) {
+        if (deleteIfPossible())
+            return;
+        unlock();
+    } else if (m_handleCount == 1 && inCache()) {
+        unlock();
+    }
 }
 
 bool Resource::canReuseRedirectChain() const
@@ -835,7 +832,7 @@
 
 bool Resource::isPurgeable() const
 {
-    return m_purgeableData && !m_purgeableData->isLocked();
+    return m_data && !m_data->isLocked();
 }
 
 bool Resource::wasPurged() const
@@ -845,18 +842,17 @@
 
 bool Resource::lock()
 {
-    if (!m_purgeableData)
+    if (!m_data)
+        return true;
+    if (m_data->isLocked())
         return true;
 
-    ASSERT(!m_data);
     ASSERT(!hasClients());
 
-    if (!m_purgeableData->lock()) {
+    if (!m_data->lock()) {
         m_wasPurged = true;
         return false;
     }
-
-    m_data = SharedBuffer::adoptPurgeableBuffer(m_purgeableData.release());
     return true;
 }
 
@@ -886,7 +882,7 @@
 void Resource::ResourceCallback::schedule(Resource* resource)
 {
     if (!m_callbackTimer.isActive())
-        m_callbackTimer.startOneShot(0);
+        m_callbackTimer.startOneShot(0, FROM_HERE);
     m_resourcesWithPendingClients.add(resource);
 }
 
@@ -897,6 +893,11 @@
         m_callbackTimer.stop();
 }
 
+bool Resource::ResourceCallback::isScheduled(Resource* resource) const
+{
+    return m_resourcesWithPendingClients.contains(resource);
+}
+
 void Resource::ResourceCallback::timerFired(Timer<ResourceCallback>*)
 {
     HashSet<Resource*>::iterator end = m_resourcesWithPendingClients.end();
diff --git a/Source/core/fetch/Resource.h b/Source/core/fetch/Resource.h
index ed2a99a..b6c970d 100644
--- a/Source/core/fetch/Resource.h
+++ b/Source/core/fetch/Resource.h
@@ -43,7 +43,6 @@
 class ResourcePtrBase;
 class ResourceFetcher;
 class InspectorResource;
-class PurgeableBuffer;
 class ResourceLoader;
 class SecurityOrigin;
 class SharedBuffer;
@@ -183,7 +182,7 @@
 
     void clearLoader();
 
-    SharedBuffer* resourceBuffer() const { ASSERT(!m_purgeableData); return m_data.get(); }
+    SharedBuffer* resourceBuffer() const { return m_data.get(); }
     void setResourceBuffer(PassRefPtr<SharedBuffer>);
 
     virtual void willSendRequest(ResourceRequest&, const ResourceResponse&);
@@ -244,6 +243,7 @@
 
     virtual bool canReuse(const ResourceRequest&) const { return true; }
 
+    // Used by the MemoryCache to reduce the memory consumption of the entry.
     void prune();
 
     static const char* resourceTypeToString(Type, const FetchInitiatorInfo&);
@@ -296,6 +296,7 @@
         static ResourceCallback* callbackHandler();
         void schedule(Resource*);
         void cancel(Resource*);
+        bool isScheduled(Resource*) const;
     private:
         ResourceCallback();
         void timerFired(Timer<ResourceCallback>*);
@@ -330,7 +331,6 @@
     double m_responseTimestamp;
 
     RefPtr<SharedBuffer> m_data;
-    OwnPtr<PurgeableBuffer> m_purgeableData;
     Timer<Resource> m_cancelTimer;
 
 private:
diff --git a/Source/core/fetch/ResourceFetcher.cpp b/Source/core/fetch/ResourceFetcher.cpp
index e41f648..ce1e184 100644
--- a/Source/core/fetch/ResourceFetcher.cpp
+++ b/Source/core/fetch/ResourceFetcher.cpp
@@ -45,7 +45,7 @@
 #include "core/fetch/XSLStyleSheetResource.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLImport.h"
+#include "core/html/imports/HTMLImport.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
@@ -54,9 +54,9 @@
 #include "core/loader/SubstituteData.h"
 #include "core/loader/UniqueIdentifier.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/timing/Performance.h"
 #include "core/timing/ResourceTimingInfo.h"
 #include "core/frame/Settings.h"
@@ -180,10 +180,8 @@
         initiatorDocument = initiatorDocument->parentDocument();
     if (!initiatorDocument || !initiatorDocument->loader())
         return;
-    if (DOMWindow* initiatorWindow = initiatorDocument->domWindow()) {
-        if (Performance* performance = initiatorWindow->performance())
-            performance->addResourceTiming(*info, initiatorDocument);
-    }
+    if (DOMWindow* initiatorWindow = initiatorDocument->domWindow())
+        initiatorWindow->performance().addResourceTiming(*info, initiatorDocument);
 }
 
 static ResourceRequest::TargetType requestTargetType(const ResourceFetcher* fetcher, const ResourceRequest& request, Resource::Type type)
@@ -249,7 +247,7 @@
     return m_documentResources.get(url).get();
 }
 
-Frame* ResourceFetcher::frame() const
+LocalFrame* ResourceFetcher::frame() const
 {
     if (m_documentLoader)
         return m_documentLoader->frame();
@@ -260,7 +258,7 @@
 
 FetchContext& ResourceFetcher::context() const
 {
-    if (Frame* frame = this->frame())
+    if (LocalFrame* frame = this->frame())
         return frame->fetchContext();
     return FetchContext::nullInstance();
 }
@@ -277,7 +275,7 @@
 
 ResourcePtr<ImageResource> ResourceFetcher::fetchImage(FetchRequest& request)
 {
-    if (Frame* f = frame()) {
+    if (LocalFrame* f = frame()) {
         if (f->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal) {
             KURL requestURL = request.resourceRequest().url();
             if (requestURL.isValid() && canRequest(Resource::Image, requestURL, request.options(), request.forPreload(), request.originRestriction()))
@@ -427,16 +425,16 @@
         }
     }
     if (treatment == TreatAsActiveContent) {
-        if (Frame* f = frame()) {
+        if (LocalFrame* f = frame()) {
             if (!f->loader().mixedContentChecker()->canRunInsecureContent(m_document->securityOrigin(), url))
                 return false;
-            Frame* top = f->tree().top();
+            LocalFrame* top = f->tree().top();
             if (top != f && !top->loader().mixedContentChecker()->canRunInsecureContent(top->document()->securityOrigin(), url))
                 return false;
         }
     } else if (treatment == TreatAsPassiveContent) {
-        if (Frame* f = frame()) {
-            Frame* top = f->tree().top();
+        if (LocalFrame* f = frame()) {
+            LocalFrame* top = f->tree().top();
             if (!top->loader().mixedContentChecker()->canDisplayInsecureContent(top->document()->securityOrigin(), url))
                 return false;
         }
@@ -613,7 +611,7 @@
     if (!canRequest(type, url, request.options(), request.forPreload(), request.originRestriction()))
         return 0;
 
-    if (Frame* f = frame())
+    if (LocalFrame* f = frame())
         f->loader().client()->dispatchWillRequestResource(&request);
 
     // See if we can use an existing resource from the cache.
@@ -698,7 +696,7 @@
             populateResourceTiming(info.get(), resource.get(), true);
             m_scheduledResourceTimingReports.add(info, resource->type() == Resource::MainResource);
             if (!m_resourceTimingReportTimer.isActive())
-                m_resourceTimingReportTimer.startOneShot(0);
+                m_resourceTimingReportTimer.startOneShot(0, FROM_HERE);
         }
 
         m_validatedURLs.add(request.resourceRequest().url());
@@ -739,7 +737,7 @@
             return ReturnCacheDataElseLoad;
         if (isReload || frameLoadType == FrameLoadTypeSame || request.isConditional() || request.httpMethod() == "POST")
             return ReloadIgnoringCacheData;
-        if (Frame* parent = frame()->tree().parent())
+        if (LocalFrame* parent = frame()->tree().parent())
             return parent->document()->fetcher()->resourceRequestCachePolicy(request, type);
         return UseProtocolCachePolicy;
     }
@@ -747,7 +745,7 @@
     if (request.isConditional())
         return ReloadIgnoringCacheData;
 
-    if (m_documentLoader && m_documentLoader->isLoadingInAPISense()) {
+    if (m_documentLoader && m_document && !m_document->loadEventFinished()) {
         // For POST requests, we mutate the main resource's cache policy to avoid form resubmission.
         // This policy should not be inherited by subresources.
         ResourceRequestCachePolicy mainResourceCachePolicy = m_documentLoader->request().cachePolicy();
@@ -782,6 +780,7 @@
     ASSERT(!resource->resourceToRevalidate());
 
     ResourceRequest revalidatingRequest(resource->resourceRequest());
+    revalidatingRequest.clearHTTPReferrer();
     addAdditionalRequestHeaders(revalidatingRequest, resource->type());
 
     const AtomicString& lastModified = resource->response().httpHeaderField("Last-Modified");
@@ -913,7 +912,7 @@
     // This helps with the case where the server sends back
     // "Access-Control-Allow-Origin: *" all the time, but some of the
     // client's requests are made without CORS and some with.
-    if (existingResource->resourceRequest().allowCookies() != request.allowCookies()) {
+    if (existingResource->resourceRequest().allowStoredCredentials() != request.allowStoredCredentials()) {
         WTF_LOG(ResourceLoading, "ResourceFetcher::determineRevalidationPolicy reloading due to difference in credentials settings.");
         return Reload;
     }
@@ -1052,7 +1051,7 @@
 void ResourceFetcher::scheduleDocumentResourcesGC()
 {
     if (!m_garbageCollectDocumentResourcesTimer.isActive())
-        m_garbageCollectDocumentResourcesTimer.startOneShot(0);
+        m_garbageCollectDocumentResourcesTimer.startOneShot(0, FROM_HERE);
 }
 
 // Garbage collecting m_documentResources is a workaround for the
@@ -1225,7 +1224,7 @@
         m_multipartLoaders->add(loader);
     if (m_loaders)
         m_loaders->remove(loader);
-    if (Frame* frame = this->frame())
+    if (LocalFrame* frame = this->frame())
         return frame->loader().checkLoadComplete(m_documentLoader);
 }
 
@@ -1244,7 +1243,7 @@
     if (!m_loaders || !m_loaders->contains(loader))
         return;
     m_loaders->remove(loader);
-    if (Frame* frame = this->frame())
+    if (LocalFrame* frame = this->frame())
         frame->loader().checkLoadComplete(m_documentLoader);
 }
 
@@ -1275,7 +1274,7 @@
 
 bool ResourceFetcher::defersLoading() const
 {
-    if (Frame* frame = this->frame())
+    if (LocalFrame* frame = this->frame())
         return frame->page()->defersLoading();
     return false;
 }
diff --git a/Source/core/fetch/ResourceFetcher.h b/Source/core/fetch/ResourceFetcher.h
index 0a65fe8..4bdfeeb 100644
--- a/Source/core/fetch/ResourceFetcher.h
+++ b/Source/core/fetch/ResourceFetcher.h
@@ -54,7 +54,7 @@
 class XSLStyleSheetResource;
 class Document;
 class DocumentLoader;
-class Frame;
+class LocalFrame;
 class FrameLoader;
 class ImageLoader;
 class KURL;
@@ -67,7 +67,7 @@
 // in the DocumentLoader constructor and loses its ability to generate network
 // requests when the DocumentLoader is destroyed. Documents also hold a
 // RefPtr<ResourceFetcher> for their lifetime (and will create one if they
-// are initialized without a Frame), so a Document can keep a ResourceFetcher
+// are initialized without a LocalFrame), so a Document can keep a ResourceFetcher
 // alive past detach if scripts still reference the Document.
 class ResourceFetcher FINAL : public RefCounted<ResourceFetcher>, public ResourceLoaderHost {
     WTF_MAKE_NONCOPYABLE(ResourceFetcher); WTF_MAKE_FAST_ALLOCATED;
@@ -110,7 +110,7 @@
 
     bool shouldDeferImageLoad(const KURL&) const;
 
-    Frame* frame() const; // Can be null
+    LocalFrame* frame() const; // Can be null
     FetchContext& context() const;
     Document* document() const { return m_document; } // Can be null
     void setDocument(Document* document) { m_document = document; }
diff --git a/Source/core/fetch/ResourceFetcherTest.cpp b/Source/core/fetch/ResourceFetcherTest.cpp
index e2a99ed..7f8639c 100644
--- a/Source/core/fetch/ResourceFetcherTest.cpp
+++ b/Source/core/fetch/ResourceFetcherTest.cpp
@@ -48,14 +48,14 @@
 {
     KURL testURL(ParsedURLString, "http://www.test.com/cancelTest.jpg");
 
-    // Create a ResourceFetcher that has a real DocumentLoader and Document, but is not attached to a Frame.
-    // Technically, we're concerned about what happens after a Frame is detached (rather than before
+    // Create a ResourceFetcher that has a real DocumentLoader and Document, but is not attached to a LocalFrame.
+    // Technically, we're concerned about what happens after a LocalFrame is detached (rather than before
     // any attach occurs), but ResourceFetcher can't tell the difference.
     RefPtr<DocumentLoader> documentLoader = DocumentLoader::create(0, ResourceRequest(testURL), SubstituteData());
     RefPtr<HTMLDocument> document = HTMLDocument::create();
     RefPtr<ResourceFetcher> fetcher(documentLoader->fetcher());
     fetcher->setDocument(document.get());
-    EXPECT_EQ(fetcher->frame(), static_cast<Frame*>(0));
+    EXPECT_EQ(fetcher->frame(), static_cast<LocalFrame*>(0));
 
     // Try to request a url. The request should fail, no resource should be returned,
     // and no resource should be present in the cache.
diff --git a/Source/core/fetch/ResourceLoader.cpp b/Source/core/fetch/ResourceLoader.cpp
index f371aba..9f786aa 100644
--- a/Source/core/fetch/ResourceLoader.cpp
+++ b/Source/core/fetch/ResourceLoader.cpp
@@ -327,6 +327,7 @@
         else
             m_resource->setResponse(resourceResponse);
         if (!m_host->canAccessResource(resource, m_options.securityOrigin.get(), response.url())) {
+            m_host->didReceiveResponse(m_resource, resourceResponse);
             cancel();
             return;
         }
diff --git a/Source/core/fetch/ResourceLoaderHost.h b/Source/core/fetch/ResourceLoaderHost.h
index 270b379..edf49a3 100644
--- a/Source/core/fetch/ResourceLoaderHost.h
+++ b/Source/core/fetch/ResourceLoaderHost.h
@@ -38,7 +38,7 @@
 
 class Resource;
 class ResourceFetcher;
-class Frame;
+class LocalFrame;
 class ResourceLoader;
 class ResourceRequest;
 class ResourceResponse;
diff --git a/Source/core/fileapi/Blob.cpp b/Source/core/fileapi/Blob.cpp
index 4fa8e1f..ec9b1f4 100644
--- a/Source/core/fileapi/Blob.cpp
+++ b/Source/core/fileapi/Blob.cpp
@@ -31,6 +31,11 @@
 #include "config.h"
 #include "core/fileapi/Blob.h"
 
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/DOMURL.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/dom/ExecutionContext.h"
+#include "core/fileapi/File.h"
 #include "platform/blob/BlobRegistry.h"
 #include "platform/blob/BlobURL.h"
 
@@ -46,10 +51,11 @@
     static URLRegistry& registry();
 };
 
-void BlobURLRegistry::registerURL(SecurityOrigin* origin, const KURL& publicURL, URLRegistrable* blob)
+void BlobURLRegistry::registerURL(SecurityOrigin* origin, const KURL& publicURL, URLRegistrable* registrableObject)
 {
-    ASSERT(&blob->registry() == this);
-    BlobRegistry::registerPublicBlobURL(origin, publicURL, static_cast<Blob*>(blob)->blobDataHandle());
+    ASSERT(&registrableObject->registry() == this);
+    Blob* blob = static_cast<Blob*>(registrableObject);
+    BlobRegistry::registerPublicBlobURL(origin, publicURL, blob->blobDataHandle());
 }
 
 void BlobURLRegistry::unregisterURL(const KURL& publicURL)
@@ -67,6 +73,7 @@
 
 Blob::Blob(PassRefPtr<BlobDataHandle> dataHandle)
     : m_blobDataHandle(dataHandle)
+    , m_hasBeenClosed(false)
 {
     ScriptWrappable::init(this);
 }
@@ -99,8 +106,13 @@
         end = size;
 }
 
-PassRefPtr<Blob> Blob::slice(long long start, long long end, const String& contentType) const
+PassRefPtrWillBeRawPtr<Blob> Blob::slice(long long start, long long end, const String& contentType, ExceptionState& exceptionState) const
 {
+    if (hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, "Blob has been closed.");
+        return nullptr;
+    }
+
     long long size = this->size();
     clampSliceOffsets(size, start, end);
 
@@ -111,6 +123,28 @@
     return Blob::create(BlobDataHandle::create(blobData.release(), length));
 }
 
+void Blob::close(ExecutionContext* executionContext, ExceptionState& exceptionState)
+{
+    if (hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, "Blob has been closed.");
+        return;
+    }
+
+    // Dereferencing a Blob that has been closed should result in
+    // a network error. Revoke URLs registered against it through
+    // its UUID.
+    DOMURL::revokeObjectUUID(executionContext, uuid());
+
+    // A Blob enters a 'readability state' of closed, where it will report its
+    // size as zero. Blob and FileReader operations now throws on
+    // being passed a Blob in that state. Downstream uses of closed Blobs
+    // (e.g., XHR.send()) consider them as empty.
+    OwnPtr<BlobData> blobData = BlobData::create();
+    blobData->setContentType(type());
+    m_blobDataHandle = BlobDataHandle::create(blobData.release(), 0);
+    m_hasBeenClosed = true;
+}
+
 void Blob::appendTo(BlobData& blobData) const
 {
     blobData.appendBlob(m_blobDataHandle, 0, m_blobDataHandle->size());
@@ -121,5 +155,4 @@
     return BlobURLRegistry::registry();
 }
 
-
 } // namespace WebCore
diff --git a/Source/core/fileapi/Blob.h b/Source/core/fileapi/Blob.h
index e564a65..529117d 100644
--- a/Source/core/fileapi/Blob.h
+++ b/Source/core/fileapi/Blob.h
@@ -33,6 +33,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/html/URLRegistry.h"
+#include "heap/Handle.h"
 #include "platform/blob/BlobData.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/PassRefPtr.h"
@@ -41,32 +42,50 @@
 
 namespace WebCore {
 
+class ExceptionState;
 class ExecutionContext;
 
-class Blob : public ScriptWrappable, public URLRegistrable, public RefCounted<Blob> {
+class Blob : public RefCountedWillBeGarbageCollectedFinalized<Blob>, public ScriptWrappable, public URLRegistrable {
 public:
-    static PassRefPtr<Blob> create()
+    static PassRefPtrWillBeRawPtr<Blob> create()
     {
-        return adoptRef(new Blob(BlobDataHandle::create()));
+        return adoptRefWillBeNoop(new Blob(BlobDataHandle::create()));
     }
 
-    static PassRefPtr<Blob> create(PassRefPtr<BlobDataHandle> blobDataHandle)
+    static PassRefPtrWillBeRawPtr<Blob> create(PassRefPtr<BlobDataHandle> blobDataHandle)
     {
-        return adoptRef(new Blob(blobDataHandle));
+        return adoptRefWillBeNoop(new Blob(blobDataHandle));
     }
 
     virtual ~Blob();
 
     virtual unsigned long long size() const { return m_blobDataHandle->size(); }
-    virtual PassRefPtr<Blob> slice(long long start = 0, long long end = std::numeric_limits<long long>::max(), const String& contentType = String()) const;
+    virtual PassRefPtrWillBeRawPtr<Blob> slice(long long start, long long end, const String& contentType, ExceptionState&) const;
 
-    String type() const {  return m_blobDataHandle->type(); }
+    // To allow ExceptionState to be passed in last, manually enumerate the optional argument overloads.
+    PassRefPtrWillBeRawPtr<Blob> slice(ExceptionState& exceptionState) const
+    {
+        return slice(0, std::numeric_limits<long long>::max(), String(), exceptionState);
+    }
+    PassRefPtrWillBeRawPtr<Blob> slice(long long start, ExceptionState& exceptionState) const
+    {
+        return slice(start, std::numeric_limits<long long>::max(), String(), exceptionState);
+    }
+    PassRefPtrWillBeRawPtr<Blob> slice(long long start, long long end, ExceptionState& exceptionState) const
+    {
+        return slice(start, end, String(), exceptionState);
+    }
+
+    virtual void close(ExecutionContext*, ExceptionState&);
+
+    String type() const { return m_blobDataHandle->type(); }
     String uuid() const { return m_blobDataHandle->uuid(); }
     PassRefPtr<BlobDataHandle> blobDataHandle() const { return m_blobDataHandle; }
     // True for all File instances, including the user-built ones.
     virtual bool isFile() const { return false; }
     // Only true for File instances that are backed by platform files.
     virtual bool hasBackingFile() const { return false; }
+    bool hasBeenClosed() const { return m_hasBeenClosed; }
 
     // Used by the JavaScript Blob and File constructors.
     virtual void appendTo(BlobData&) const;
@@ -74,13 +93,17 @@
     // URLRegistrable to support PublicURLs.
     virtual URLRegistry& registry() const OVERRIDE FINAL;
 
-    static void clampSliceOffsets(long long size, long long& start, long long& end);
+    void trace(Visitor*) { }
+
 protected:
     explicit Blob(PassRefPtr<BlobDataHandle>);
 
+    static void clampSliceOffsets(long long size, long long& start, long long& end);
 private:
     Blob();
+
     RefPtr<BlobDataHandle> m_blobDataHandle;
+    bool m_hasBeenClosed;
 };
 
 } // namespace WebCore
diff --git a/Source/core/fileapi/Blob.idl b/Source/core/fileapi/Blob.idl
index 28fd1aa..32adc30 100644
--- a/Source/core/fileapi/Blob.idl
+++ b/Source/core/fileapi/Blob.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     CustomConstructor,
     CustomConstructor(sequence<any> blobParts, optional BlobPropertyBag options),
     GlobalContext=Window&WorkerGlobalScope,
@@ -37,6 +38,7 @@
     readonly attribute unsigned long long size;
     readonly attribute DOMString type;
 
-    Blob slice(optional long long start, optional long long end, [TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString contentType);
+    [RaisesException] Blob slice(optional long long start, optional long long end, [TreatNullAs=NullString, TreatUndefinedAs=NullString] optional DOMString contentType);
+    [RaisesException, CallWith=ExecutionContext, RuntimeEnabled=FileAPIBlobClose] void close();
 };
 
diff --git a/Source/core/fileapi/File.cpp b/Source/core/fileapi/File.cpp
index de776d5..127eaca 100644
--- a/Source/core/fileapi/File.cpp
+++ b/Source/core/fileapi/File.cpp
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "core/fileapi/File.h"
 
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
 #include "platform/FileMetadata.h"
 #include "platform/MIMETypeRegistry.h"
 #include "public/platform/Platform.h"
@@ -84,9 +86,9 @@
     return blobData.release();
 }
 
-PassRefPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
+PassRefPtrWillBeRawPtr<File> File::createWithRelativePath(const String& path, const String& relativePath)
 {
-    RefPtr<File> file = adoptRef(new File(path, AllContentTypes));
+    RefPtrWillBeRawPtr<File> file = adoptRefWillBeNoop(new File(path, AllContentTypes));
     file->m_relativePath = relativePath;
     return file.release();
 }
@@ -162,7 +164,7 @@
         return m_snapshotModificationTime * msPerSecond;
 
     time_t modificationTime;
-    if (getFileModificationTime(m_path, modificationTime) && isValidFileTime(modificationTime))
+    if (hasBackingFile() && getFileModificationTime(m_path, modificationTime) && isValidFileTime(modificationTime))
         return modificationTime * msPerSecond;
 
     return currentTime() * msPerSecond;
@@ -176,15 +178,20 @@
     // FIXME: JavaScript cannot represent sizes as large as unsigned long long, we need to
     // come up with an exception to throw if file size is not representable.
     long long size;
-    if (!getFileSize(m_path, size))
+    if (!hasBackingFile() || !getFileSize(m_path, size))
         return 0;
     return static_cast<unsigned long long>(size);
 }
 
-PassRefPtr<Blob> File::slice(long long start, long long end, const String& contentType) const
+PassRefPtrWillBeRawPtr<Blob> File::slice(long long start, long long end, const String& contentType, ExceptionState& exceptionState) const
 {
+    if (hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, "File has been closed.");
+        return nullptr;
+    }
+
     if (!m_hasBackingFile)
-        return Blob::slice(start, end, contentType);
+        return Blob::slice(start, end, contentType, exceptionState);
 
     // FIXME: This involves synchronous file operation. We need to figure out how to make it asynchronous.
     long long size;
@@ -215,7 +222,7 @@
     // Obtains a snapshot of the file by capturing its current size and modification time. This is used when we slice a file for the first time.
     // If we fail to retrieve the size or modification time, probably due to that the file has been deleted, 0 size is returned.
     FileMetadata metadata;
-    if (!getFileMetadata(m_path, metadata)) {
+    if (!hasBackingFile() || !getFileMetadata(m_path, metadata)) {
         snapshotSize = 0;
         snapshotModificationTime = invalidFileTime();
         return;
@@ -225,6 +232,24 @@
     snapshotModificationTime = metadata.modificationTime;
 }
 
+void File::close(ExecutionContext* executionContext, ExceptionState& exceptionState)
+{
+    if (hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, "Blob has been closed.");
+        return;
+    }
+
+    // Reset the File to its closed representation, an empty
+    // Blob. The name isn't cleared, as it should still be
+    // available.
+    m_hasBackingFile = false;
+    m_path = String();
+    m_fileSystemURL = KURL();
+    invalidateSnapshotMetadata();
+    m_relativePath = String();
+    Blob::close(executionContext, exceptionState);
+}
+
 void File::appendTo(BlobData& blobData) const
 {
     if (!m_hasBackingFile) {
diff --git a/Source/core/fileapi/File.h b/Source/core/fileapi/File.h
index 6c5dd1a..1c3bc1b 100644
--- a/Source/core/fileapi/File.h
+++ b/Source/core/fileapi/File.h
@@ -27,11 +27,14 @@
 #define File_h
 
 #include "core/fileapi/Blob.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
+class ExceptionState;
+class ExecutionContext;
 struct FileMetadata;
 class KURL;
 
@@ -44,59 +47,60 @@
         AllContentTypes,
     };
 
-    static PassRefPtr<File> create(const String& path, ContentTypeLookupPolicy policy = WellKnownContentTypes)
+    static PassRefPtrWillBeRawPtr<File> create(const String& path, ContentTypeLookupPolicy policy = WellKnownContentTypes)
     {
-        return adoptRef(new File(path, policy));
+        return adoptRefWillBeNoop(new File(path, policy));
     }
 
-    static PassRefPtr<File> create(const String& name, double modificationTime, PassRefPtr<BlobDataHandle> blobDataHandle)
+    static PassRefPtrWillBeRawPtr<File> create(const String& name, double modificationTime, PassRefPtr<BlobDataHandle> blobDataHandle)
     {
-        return adoptRef(new File(name, modificationTime, blobDataHandle));
+        return adoptRefWillBeNoop(new File(name, modificationTime, blobDataHandle));
     }
 
     // For deserialization.
-    static PassRefPtr<File> create(const String& path, const String& name, const String& relativePath, bool hasSnaphotData, uint64_t size, double lastModified, PassRefPtr<BlobDataHandle> blobDataHandle)
+    static PassRefPtrWillBeRawPtr<File> create(const String& path, const String& name, const String& relativePath, bool hasSnaphotData, uint64_t size, double lastModified, PassRefPtr<BlobDataHandle> blobDataHandle)
     {
-        return adoptRef(new File(path, name, relativePath, hasSnaphotData, size, lastModified, blobDataHandle));
+        return adoptRefWillBeNoop(new File(path, name, relativePath, hasSnaphotData, size, lastModified, blobDataHandle));
     }
 
-    static PassRefPtr<File> createWithRelativePath(const String& path, const String& relativePath);
+    static PassRefPtrWillBeRawPtr<File> createWithRelativePath(const String& path, const String& relativePath);
 
     // If filesystem files live in the remote filesystem, the port might pass the valid metadata (whose length field is non-negative) and cache in the File object.
     //
     // Otherwise calling size(), lastModifiedTime() and slice() will synchronously query the file metadata.
-    static PassRefPtr<File> createForFileSystemFile(const String& name, const FileMetadata& metadata)
+    static PassRefPtrWillBeRawPtr<File> createForFileSystemFile(const String& name, const FileMetadata& metadata)
     {
-        return adoptRef(new File(name, metadata));
+        return adoptRefWillBeNoop(new File(name, metadata));
     }
 
-    static PassRefPtr<File> createForFileSystemFile(const KURL& url, const FileMetadata& metadata)
+    static PassRefPtrWillBeRawPtr<File> createForFileSystemFile(const KURL& url, const FileMetadata& metadata)
     {
-        return adoptRef(new File(url, metadata));
+        return adoptRefWillBeNoop(new File(url, metadata));
     }
 
-    KURL fileSystemURL() const { ASSERT(m_hasBackingFile); return m_fileSystemURL; }
+    KURL fileSystemURL() const { ASSERT(hasValidFileSystemURL()); return m_fileSystemURL; }
 
     // Create a file with a name exposed to the author (via File.name and associated DOM properties) that differs from the one provided in the path.
-    static PassRefPtr<File> createWithName(const String& path, const String& name, ContentTypeLookupPolicy policy = WellKnownContentTypes)
+    static PassRefPtrWillBeRawPtr<File> createWithName(const String& path, const String& name, ContentTypeLookupPolicy policy = WellKnownContentTypes)
     {
         if (name.isEmpty())
-            return adoptRef(new File(path, policy));
-        return adoptRef(new File(path, name, policy));
+            return adoptRefWillBeNoop(new File(path, policy));
+        return adoptRefWillBeNoop(new File(path, name, policy));
     }
 
     virtual unsigned long long size() const OVERRIDE;
-    virtual PassRefPtr<Blob> slice(long long start = 0, long long end = std::numeric_limits<long long>::max(), const String& contentType = String()) const OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<Blob> slice(long long start, long long end, const String& contentType, ExceptionState&) const OVERRIDE;
+    virtual void close(ExecutionContext*, ExceptionState&) OVERRIDE;
 
     virtual bool isFile() const OVERRIDE { return true; }
     virtual bool hasBackingFile() const OVERRIDE { return m_hasBackingFile; }
 
     virtual void appendTo(BlobData&) const OVERRIDE;
 
-    const String& path() const { ASSERT(m_hasBackingFile); return m_path; }
-    const String& name() const { return m_name; }
+    const String& path() const { ASSERT(hasValidFilePath()); return m_path; }
+    const String name() const { return m_name; }
 
-    // This returns the current date and time if the file's last modifiecation date is not known (per spec: http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate).
+    // This returns the current date and time if the file's last modification date is not known (per spec: http://www.w3.org/TR/FileAPI/#dfn-lastModifiedDate).
     double lastModifiedDate() const;
 
     // Returns the relative path of this file in the context of a directory selection.
@@ -116,6 +120,14 @@
     File(const String& name, const FileMetadata&);
     File(const KURL& fileSystemURL, const FileMetadata&);
 
+    void invalidateSnapshotMetadata() { m_snapshotSize = -1; }
+
+#ifndef NDEBUG
+    bool hasValidFileSystemURL() const { return hasBackingFile(); }
+    // Instances not backed by a file must have an empty path set.
+    bool hasValidFilePath() const { return hasBackingFile() || m_path.isEmpty(); }
+#endif
+
     bool m_hasBackingFile;
     String m_path;
     String m_name;
@@ -124,7 +136,7 @@
 
     // If m_snapshotSize is negative (initialized to -1 by default), the snapshot metadata is invalid and we retrieve the latest metadata synchronously in size(), lastModifiedTime() and slice().
     // Otherwise, the snapshot metadata are used directly in those methods.
-    const long long m_snapshotSize;
+    long long m_snapshotSize;
     const double m_snapshotModificationTime;
 
     String m_relativePath;
diff --git a/Source/core/fileapi/FileError.h b/Source/core/fileapi/FileError.h
index 26dd392..8f9a865 100644
--- a/Source/core/fileapi/FileError.h
+++ b/Source/core/fileapi/FileError.h
@@ -33,6 +33,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/DOMError.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
@@ -70,7 +71,10 @@
     static const char syntaxErrorMessage[];
     static const char typeMismatchErrorMessage[];
 
-    static PassRefPtr<FileError> create(ErrorCode code) { return adoptRef(new FileError(code)); }
+    static PassRefPtrWillBeRawPtr<FileError> create(ErrorCode code)
+    {
+        return adoptRefWillBeNoop(new FileError(code));
+    }
 
     ErrorCode code() const { return m_code; }
 
diff --git a/Source/core/fileapi/FileList.cpp b/Source/core/fileapi/FileList.cpp
index 267a7f5..22d612b 100644
--- a/Source/core/fileapi/FileList.cpp
+++ b/Source/core/fileapi/FileList.cpp
@@ -50,4 +50,9 @@
     return paths;
 }
 
+void FileList::trace(Visitor* visitor)
+{
+    visitor->trace(m_files);
+}
+
 } // namespace WebCore
diff --git a/Source/core/fileapi/FileList.h b/Source/core/fileapi/FileList.h
index 75e07ae..736a6fc 100644
--- a/Source/core/fileapi/FileList.h
+++ b/Source/core/fileapi/FileList.h
@@ -28,6 +28,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/fileapi/File.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -35,11 +36,11 @@
 
 namespace WebCore {
 
-class FileList : public ScriptWrappable, public RefCounted<FileList> {
+class FileList : public RefCountedWillBeGarbageCollectedFinalized<FileList>, public ScriptWrappable {
 public:
-    static PassRefPtr<FileList> create()
+    static PassRefPtrWillBeRawPtr<FileList> create()
     {
-        return adoptRef(new FileList);
+        return adoptRefWillBeNoop(new FileList);
     }
 
     unsigned length() const { return m_files.size(); }
@@ -47,13 +48,15 @@
 
     bool isEmpty() const { return m_files.isEmpty(); }
     void clear() { m_files.clear(); }
-    void append(PassRefPtr<File> file) { m_files.append(file); }
+    void append(PassRefPtrWillBeRawPtr<File> file) { m_files.append(file); }
     Vector<String> paths() const;
 
+    void trace(Visitor*);
+
 private:
     FileList();
 
-    Vector<RefPtr<File> > m_files;
+    WillBeHeapVector<RefPtrWillBeMember<File> > m_files;
 };
 
 } // namespace WebCore
diff --git a/Source/core/fileapi/FileList.idl b/Source/core/fileapi/FileList.idl
index a2a2472..d822313 100644
--- a/Source/core/fileapi/FileList.idl
+++ b/Source/core/fileapi/FileList.idl
@@ -24,6 +24,7 @@
  */
 
 [
+    WillBeGarbageCollected
 ] interface FileList {
     readonly attribute unsigned long length;
     getter File item(unsigned long index);
diff --git a/Source/core/fileapi/FileReader.cpp b/Source/core/fileapi/FileReader.cpp
index c94eadb..5fb2467 100644
--- a/Source/core/fileapi/FileReader.cpp
+++ b/Source/core/fileapi/FileReader.cpp
@@ -75,12 +75,15 @@
     ThrottlingController() : m_maxRunningReaders(kMaxOutstandingRequestsPerThread) { }
     ~ThrottlingController() { }
 
+    enum FinishReaderType { DoNotRunPendingReaders, RunPendingReaders };
+
     void pushReader(FileReader* reader)
     {
         reader->setPendingActivity(reader);
         if (m_pendingReaders.isEmpty()
             && m_runningReaders.size() < m_maxRunningReaders) {
             reader->executePendingRead();
+            ASSERT(!m_runningReaders.contains(reader));
             m_runningReaders.add(reader);
             return;
         }
@@ -88,23 +91,28 @@
         executeReaders();
     }
 
-    void removeReader(FileReader* reader)
+    FinishReaderType removeReader(FileReader* reader)
     {
         HashSet<FileReader*>::const_iterator hashIter = m_runningReaders.find(reader);
         if (hashIter != m_runningReaders.end()) {
             m_runningReaders.remove(hashIter);
-            reader->unsetPendingActivity(reader);
-            executeReaders();
-            return;
+            return RunPendingReaders;
         }
         Deque<FileReader*>::const_iterator dequeEnd = m_pendingReaders.end();
         for (Deque<FileReader*>::const_iterator it = m_pendingReaders.begin(); it != dequeEnd; ++it) {
             if (*it == reader) {
                 m_pendingReaders.remove(it);
-                reader->unsetPendingActivity(reader);
-                return;
+                break;
             }
         }
+        return DoNotRunPendingReaders;
+    }
+
+    void finishReader(FileReader* reader, FinishReaderType nextStep)
+    {
+        reader->unsetPendingActivity(reader);
+        if (nextStep == RunPendingReaders)
+            executeReaders();
     }
 
 private:
@@ -124,9 +132,9 @@
     HashSet<FileReader*> m_runningReaders;
 };
 
-PassRefPtr<FileReader> FileReader::create(ExecutionContext* context)
+PassRefPtrWillBeRawPtr<FileReader> FileReader::create(ExecutionContext* context)
 {
-    RefPtr<FileReader> fileReader(adoptRef(new FileReader(context)));
+    RefPtrWillBeRawPtr<FileReader> fileReader(adoptRefWillBeRefCountedGarbageCollected(new FileReader(context)));
     fileReader->suspendIfNeeded();
     return fileReader.release();
 }
@@ -154,7 +162,7 @@
 void FileReader::stop()
 {
     if (m_loadingState == LoadingStateLoading || m_loadingState == LoadingStatePending)
-        throttlingController()->removeReader(this);
+        throttlingController()->finishReader(this, throttlingController()->removeReader(this));
     terminate();
 }
 
@@ -220,11 +228,20 @@
         return;
     }
 
-    m_blob = blob;
+    if (blob->hasBeenClosed()) {
+        exceptionState.throwDOMException(InvalidStateError, String(blob->isFile() ? "File" : "Blob") + " has been closed.");
+        return;
+    }
+
+    // "Snapshot" the Blob data rather than the Blob itself as ongoing
+    // read operations should not be affected if close() is called on
+    // the Blob being read.
+    m_blobDataHandle = blob->blobDataHandle();
+    m_blobType = blob->type();
     m_readType = type;
     m_state = LOADING;
     m_loadingState = LoadingStatePending;
-    m_error = 0;
+    m_error = nullptr;
     throttlingController()->pushReader(this);
 }
 
@@ -235,8 +252,9 @@
 
     m_loader = adoptPtr(new FileReaderLoader(m_readType, this));
     m_loader->setEncoding(m_encoding);
-    m_loader->setDataType(m_blob->type());
-    m_loader->start(executionContext(), m_blob->blobDataHandle());
+    m_loader->setDataType(m_blobType);
+    m_loader->start(executionContext(), m_blobDataHandle);
+    m_blobDataHandle = nullptr;
 }
 
 static void delayedAbort(ExecutionContext*, FileReader* reader)
@@ -267,12 +285,15 @@
 
     m_error = FileError::create(FileError::ABORT_ERR);
 
+    // Unregister the reader.
+    ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+
     fireEvent(EventTypeNames::error);
     fireEvent(EventTypeNames::abort);
     fireEvent(EventTypeNames::loadend);
 
     // All possible events have fired and we're done, no more pending activity.
-    throttlingController()->removeReader(this);
+    throttlingController()->finishReader(this, finalStep);
 }
 
 void FileReader::terminate()
@@ -318,11 +339,14 @@
     ASSERT(m_state != DONE);
     m_state = DONE;
 
+    // Unregister the reader.
+    ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+
     fireEvent(EventTypeNames::load);
     fireEvent(EventTypeNames::loadend);
 
     // All possible events have fired and we're done, no more pending activity.
-    throttlingController()->removeReader(this);
+    throttlingController()->finishReader(this, finalStep);
 }
 
 void FileReader::didFail(FileError::ErrorCode errorCode)
@@ -336,11 +360,15 @@
     m_state = DONE;
 
     m_error = FileError::create(static_cast<FileError::ErrorCode>(errorCode));
+
+    // Unregister the reader.
+    ThrottlingController::FinishReaderType finalStep = throttlingController()->removeReader(this);
+
     fireEvent(EventTypeNames::error);
     fireEvent(EventTypeNames::loadend);
 
     // All possible events have fired and we're done, no more pending activity.
-    throttlingController()->removeReader(this);
+    throttlingController()->finishReader(this, finalStep);
 }
 
 void FileReader::fireEvent(const AtomicString& type)
@@ -365,7 +393,7 @@
 PassRefPtr<ArrayBuffer> FileReader::arrayBufferResult() const
 {
     if (!m_loader || m_error)
-        return 0;
+        return nullptr;
     return m_loader->arrayBufferResult();
 }
 
@@ -376,4 +404,9 @@
     return m_loader->stringResult();
 }
 
+void FileReader::trace(Visitor* visitor)
+{
+    visitor->trace(m_error);
+}
+
 } // namespace WebCore
diff --git a/Source/core/fileapi/FileReader.h b/Source/core/fileapi/FileReader.h
index a4d46df..8cb5d3c 100644
--- a/Source/core/fileapi/FileReader.h
+++ b/Source/core/fileapi/FileReader.h
@@ -37,6 +37,7 @@
 #include "core/fileapi/FileError.h"
 #include "core/fileapi/FileReaderLoader.h"
 #include "core/fileapi/FileReaderLoaderClient.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 #include "wtf/ThreadSpecific.h"
@@ -48,10 +49,10 @@
 class ExceptionState;
 class ExecutionContext;
 
-class FileReader FINAL : public RefCounted<FileReader>, public ScriptWrappable, public ActiveDOMObject, public EventTargetWithInlineData, public FileReaderLoaderClient {
-    REFCOUNTED_EVENT_TARGET(FileReader);
+class FileReader FINAL : public RefCountedWillBeRefCountedGarbageCollected<FileReader>, public ScriptWrappable, public ActiveDOMObject, public FileReaderLoaderClient, public EventTargetWithInlineData {
+    DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<FileReader>);
 public:
-    static PassRefPtr<FileReader> create(ExecutionContext*);
+    static PassRefPtrWillBeRawPtr<FileReader> create(ExecutionContext*);
 
     virtual ~FileReader();
 
@@ -71,7 +72,7 @@
     void doAbort();
 
     ReadyState readyState() const { return m_state; }
-    PassRefPtr<FileError> error() { return m_error; }
+    PassRefPtrWillBeRawPtr<FileError> error() { return m_error; }
     FileReaderLoader::ReadType readType() const { return m_readType; }
     PassRefPtr<ArrayBuffer> arrayBufferResult() const;
     String stringResult();
@@ -96,6 +97,8 @@
     DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(loadend);
 
+    void trace(Visitor*);
+
 private:
     class ThrottlingController;
 
@@ -121,12 +124,13 @@
     };
     LoadingState m_loadingState;
 
-    RefPtr<Blob> m_blob;
+    String m_blobType;
+    RefPtr<BlobDataHandle> m_blobDataHandle;
     FileReaderLoader::ReadType m_readType;
     String m_encoding;
 
     OwnPtr<FileReaderLoader> m_loader;
-    RefPtr<FileError> m_error;
+    RefPtrWillBeMember<FileError> m_error;
     double m_lastProgressNotificationTimeMS;
 };
 
diff --git a/Source/core/fileapi/FileReader.idl b/Source/core/fileapi/FileReader.idl
index 6faafff..fd2a781 100644
--- a/Source/core/fileapi/FileReader.idl
+++ b/Source/core/fileapi/FileReader.idl
@@ -30,6 +30,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     ActiveDOMObject,
     Constructor,
     ConstructorCallWith=ExecutionContext,
diff --git a/Source/core/fileapi/FileReaderLoader.cpp b/Source/core/fileapi/FileReaderLoader.cpp
index 3b133e4..617dca7 100644
--- a/Source/core/fileapi/FileReaderLoader.cpp
+++ b/Source/core/fileapi/FileReaderLoader.cpp
@@ -135,7 +135,7 @@
     }
 
     m_urlForReadingIsStream = true;
-    startInternal(executionContext, &stream, 0);
+    startInternal(executionContext, &stream, nullptr);
 }
 
 void FileReaderLoader::cancel()
@@ -154,7 +154,7 @@
 
 void FileReaderLoader::cleanup()
 {
-    m_loader = 0;
+    m_loader = nullptr;
 
     // If we get any error, we do not need to keep a buffer around.
     if (m_errorCode) {
@@ -304,7 +304,7 @@
 
     // If the loading is not started or an error occurs, return an empty result.
     if (!m_rawData || m_errorCode)
-        return 0;
+        return nullptr;
 
     return m_rawData->toArrayBuffer();
 }
diff --git a/Source/core/fileapi/FileReaderSync.cpp b/Source/core/fileapi/FileReaderSync.cpp
index cbef4c1..7269155 100644
--- a/Source/core/fileapi/FileReaderSync.cpp
+++ b/Source/core/fileapi/FileReaderSync.cpp
@@ -50,7 +50,7 @@
 {
     if (!blob) {
         exceptionState.throwDOMException(NotFoundError, FileError::notFoundErrorMessage);
-        return 0;
+        return nullptr;
     }
 
     FileReaderLoader loader(FileReaderLoader::ReadAsArrayBuffer, 0);
diff --git a/Source/core/fileapi/FileReaderSync.h b/Source/core/fileapi/FileReaderSync.h
index 227a591..be525e7 100644
--- a/Source/core/fileapi/FileReaderSync.h
+++ b/Source/core/fileapi/FileReaderSync.h
@@ -32,6 +32,7 @@
 #define FileReaderSync_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
@@ -43,11 +44,11 @@
 class FileReaderLoader;
 class ExecutionContext;
 
-class FileReaderSync FINAL : public RefCounted<FileReaderSync>, public ScriptWrappable {
+class FileReaderSync FINAL : public RefCountedWillBeGarbageCollectedFinalized<FileReaderSync>, public ScriptWrappable {
 public:
-    static PassRefPtr<FileReaderSync> create()
+    static PassRefPtrWillBeRawPtr<FileReaderSync> create()
     {
-        return adoptRef(new FileReaderSync());
+        return adoptRefWillBeNoop(new FileReaderSync());
     }
 
     ~FileReaderSync() { }
@@ -61,6 +62,8 @@
     String readAsText(ExecutionContext*, Blob*, const String& encoding, ExceptionState&);
     String readAsDataURL(ExecutionContext*, Blob*, ExceptionState&);
 
+    void trace(Visitor*) { }
+
 private:
     FileReaderSync();
 
diff --git a/Source/core/fileapi/FileReaderSync.idl b/Source/core/fileapi/FileReaderSync.idl
index 125e002..0067a66 100644
--- a/Source/core/fileapi/FileReaderSync.idl
+++ b/Source/core/fileapi/FileReaderSync.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     GlobalContext=WorkerGlobalScope,
     Constructor
 ] interface FileReaderSync {
diff --git a/Source/core/fileapi/Stream.h b/Source/core/fileapi/Stream.h
index d3287ba..fc181b4 100644
--- a/Source/core/fileapi/Stream.h
+++ b/Source/core/fileapi/Stream.h
@@ -33,6 +33,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/ActiveDOMObject.h"
+#include "heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -42,11 +43,11 @@
 
 class ExecutionContext;
 
-class Stream FINAL : public ScriptWrappable, public ActiveDOMObject, public RefCounted<Stream> {
+class Stream FINAL : public RefCountedWillBeRefCountedGarbageCollected<Stream>, public ScriptWrappable, public ActiveDOMObject {
 public:
-    static PassRefPtr<Stream> create(ExecutionContext* context, const String& mediaType)
+    static PassRefPtrWillBeRawPtr<Stream> create(ExecutionContext* context, const String& mediaType)
     {
-        RefPtr<Stream> stream = adoptRef(new Stream(context, mediaType));
+        RefPtrWillBeRawPtr<Stream> stream = adoptRefWillBeRefCountedGarbageCollected(new Stream(context, mediaType));
         stream->suspendIfNeeded();
         return stream.release();
     }
@@ -80,6 +81,8 @@
     virtual void resume() OVERRIDE;
     virtual void stop() OVERRIDE;
 
+    void trace(Visitor*) { }
+
 protected:
     Stream(ExecutionContext*, const String& mediaType);
 
diff --git a/Source/core/fileapi/Stream.idl b/Source/core/fileapi/Stream.idl
index 1406b7b..11f03fd 100644
--- a/Source/core/fileapi/Stream.idl
+++ b/Source/core/fileapi/Stream.idl
@@ -38,7 +38,8 @@
 
 [
     RuntimeEnabled=Stream,
-    ActiveDOMObject
+    ActiveDOMObject,
+    WillBeGarbageCollected
 ] interface Stream {
     readonly attribute DOMString type;
 };
diff --git a/Source/core/frame/BarProp.cpp b/Source/core/frame/BarProp.cpp
index 2caccb1..e4de0ea 100644
--- a/Source/core/frame/BarProp.cpp
+++ b/Source/core/frame/BarProp.cpp
@@ -30,12 +30,12 @@
 #include "core/frame/BarProp.h"
 
 #include "core/page/Chrome.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
-BarProp::BarProp(Frame* frame, Type type)
+BarProp::BarProp(LocalFrame* frame, Type type)
     : DOMWindowProperty(frame)
     , m_type(type)
 {
@@ -44,7 +44,6 @@
 
 bool BarProp::visible() const
 {
-    ASSERT(m_frame);
     if (!m_frame)
         return false;
     FrameHost* host = m_frame->host();
diff --git a/Source/core/frame/BarProp.h b/Source/core/frame/BarProp.h
index 55ba5d6..84264a7 100644
--- a/Source/core/frame/BarProp.h
+++ b/Source/core/frame/BarProp.h
@@ -36,18 +36,18 @@
 
 namespace WebCore {
 
-    class Frame;
+    class LocalFrame;
 
     class BarProp : public ScriptWrappable, public RefCounted<BarProp>, public DOMWindowProperty {
     public:
         enum Type { Locationbar, Menubar, Personalbar, Scrollbars, Statusbar, Toolbar };
 
-        static PassRefPtr<BarProp> create(Frame* frame, Type type) { return adoptRef(new BarProp(frame, type)); }
+        static PassRefPtr<BarProp> create(LocalFrame* frame, Type type) { return adoptRef(new BarProp(frame, type)); }
 
         bool visible() const;
 
     private:
-        BarProp(Frame*, Type);
+        BarProp(LocalFrame*, Type);
         Type m_type;
     };
 
diff --git a/Source/core/frame/Console.cpp b/Source/core/frame/Console.cpp
index 7aaa7b2..7f88f71 100644
--- a/Source/core/frame/Console.cpp
+++ b/Source/core/frame/Console.cpp
@@ -31,8 +31,8 @@
 
 #include "bindings/v8/ScriptCallStackFactory.h"
 #include "core/frame/ConsoleTypes.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/PageConsole.h"
 #include "core/inspector/ConsoleAPITypes.h"
 #include "core/inspector/ScriptArguments.h"
@@ -46,7 +46,7 @@
 
 namespace WebCore {
 
-Console::Console(Frame* frame)
+Console::Console(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
@@ -76,7 +76,7 @@
     m_frame->host()->chrome().client().addMessageToConsole(ConsoleAPIMessageSource, level, message, callStack->at(0).lineNumber(), callStack->at(0).sourceURL(), stackTrace);
 }
 
-PassRefPtr<MemoryInfo> Console::memory() const
+PassRefPtrWillBeRawPtr<MemoryInfo> Console::memory() const
 {
     // FIXME: Because we create a new object here each time,
     // console.memory !== console.memory, which seems wrong.
diff --git a/Source/core/frame/Console.h b/Source/core/frame/Console.h
index 3b65af9..a610f48 100644
--- a/Source/core/frame/Console.h
+++ b/Source/core/frame/Console.h
@@ -39,7 +39,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class MemoryInfo;
 class Page;
 class ScriptArguments;
@@ -49,17 +49,17 @@
     using RefCounted<Console>::ref;
     using RefCounted<Console>::deref;
 
-    static PassRefPtr<Console> create(Frame* frame) { return adoptRef(new Console(frame)); }
+    static PassRefPtr<Console> create(LocalFrame* frame) { return adoptRef(new Console(frame)); }
     virtual ~Console();
 
-    PassRefPtr<MemoryInfo> memory() const;
+    PassRefPtrWillBeRawPtr<MemoryInfo> memory() const;
 
 protected:
     virtual ExecutionContext* context() OVERRIDE;
     virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtr<ScriptCallStack>) OVERRIDE;
 
 private:
-    explicit Console(Frame*);
+    explicit Console(LocalFrame*);
 
     virtual void refConsole() OVERRIDE { ref(); }
     virtual void derefConsole() OVERRIDE { deref(); }
diff --git a/Source/core/frame/ConsoleBase.cpp b/Source/core/frame/ConsoleBase.cpp
index 8f54d86..d3a078b 100644
--- a/Source/core/frame/ConsoleBase.cpp
+++ b/Source/core/frame/ConsoleBase.cpp
@@ -160,7 +160,7 @@
 
 void ConsoleBase::groupEnd()
 {
-    InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, EndGroupMessageType, LogMessageLevel, String(), 0);
+    InspectorInstrumentation::addMessageToConsole(context(), ConsoleAPIMessageSource, EndGroupMessageType, LogMessageLevel, String(), nullptr);
 }
 
 void ConsoleBase::internalAddMessage(MessageType type, MessageLevel level, ScriptState* state, PassRefPtr<ScriptArguments> scriptArguments, bool acceptNoArguments, bool printTrace)
diff --git a/Source/core/frame/ContentSecurityPolicy.cpp b/Source/core/frame/ContentSecurityPolicy.cpp
deleted file mode 100644
index 5414ba7..0000000
--- a/Source/core/frame/ContentSecurityPolicy.cpp
+++ /dev/null
@@ -1,2320 +0,0 @@
-/*
- * Copyright (C) 2011 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/ContentSecurityPolicy.h"
-
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ScriptCallStackFactory.h"
-#include "bindings/v8/ScriptController.h"
-#include "core/dom/DOMStringList.h"
-#include "core/dom/Document.h"
-#include "core/events/SecurityPolicyViolationEvent.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
-#include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
-#include "core/inspector/InspectorInstrumentation.h"
-#include "core/inspector/ScriptCallStack.h"
-#include "core/loader/DocumentLoader.h"
-#include "core/loader/PingLoader.h"
-#include "core/frame/UseCounter.h"
-#include "platform/JSONValues.h"
-#include "platform/NotImplemented.h"
-#include "platform/ParsingUtilities.h"
-#include "platform/network/FormData.h"
-#include "platform/network/ResourceResponse.h"
-#include "platform/weborigin/KURL.h"
-#include "platform/weborigin/KnownPorts.h"
-#include "platform/weborigin/SchemeRegistry.h"
-#include "platform/weborigin/SecurityOrigin.h"
-#include "wtf/SHA1.h"
-#include "wtf/StringHasher.h"
-#include "wtf/text/Base64.h"
-#include "wtf/text/StringBuilder.h"
-
-namespace WTF {
-
-struct VectorIntHash {
-    static unsigned hash(const Vector<uint8_t>& v) { return StringHasher::computeHash(v.data(), v.size()); }
-    static bool equal(const Vector<uint8_t>& a, const Vector<uint8_t>& b) { return a == b; };
-    static const bool safeToCompareToEmptyOrDeleted = true;
-};
-template<> struct DefaultHash<Vector<uint8_t> > {
-    typedef VectorIntHash Hash;
-};
-
-} // namespace WTF
-
-namespace WebCore {
-
-typedef std::pair<unsigned, Vector<uint8_t> > SourceHashValue;
-
-// Normally WebKit uses "static" for internal linkage, but using "static" for
-// these functions causes a compile error because these functions are used as
-// template parameters.
-namespace {
-
-bool isDirectiveNameCharacter(UChar c)
-{
-    return isASCIIAlphanumeric(c) || c == '-';
-}
-
-bool isDirectiveValueCharacter(UChar c)
-{
-    return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
-}
-
-// Only checks for general Base64 encoded chars, not '=' chars since '=' is
-// positional and may only appear at the end of a Base64 encoded string.
-bool isBase64EncodedCharacter(UChar c)
-{
-    return isASCIIAlphanumeric(c) || c == '+' || c == '/';
-}
-
-bool isNonceCharacter(UChar c)
-{
-    return isBase64EncodedCharacter(c) || c == '=';
-}
-
-bool isSourceCharacter(UChar c)
-{
-    return !isASCIISpace(c);
-}
-
-bool isPathComponentCharacter(UChar c)
-{
-    return c != '?' && c != '#';
-}
-
-bool isHostCharacter(UChar c)
-{
-    return isASCIIAlphanumeric(c) || c == '-';
-}
-
-bool isSchemeContinuationCharacter(UChar c)
-{
-    return isASCIIAlphanumeric(c) || c == '+' || c == '-' || c == '.';
-}
-
-bool isNotASCIISpace(UChar c)
-{
-    return !isASCIISpace(c);
-}
-
-bool isNotColonOrSlash(UChar c)
-{
-    return c != ':' && c != '/';
-}
-
-bool isMediaTypeCharacter(UChar c)
-{
-    return !isASCIISpace(c) && c != '/';
-}
-
-// CSP 1.0 Directives
-static const char connectSrc[] = "connect-src";
-static const char defaultSrc[] = "default-src";
-static const char fontSrc[] = "font-src";
-static const char frameSrc[] = "frame-src";
-static const char imgSrc[] = "img-src";
-static const char mediaSrc[] = "media-src";
-static const char objectSrc[] = "object-src";
-static const char reportURI[] = "report-uri";
-static const char sandbox[] = "sandbox";
-static const char scriptSrc[] = "script-src";
-static const char styleSrc[] = "style-src";
-
-// CSP 1.1 Directives
-static const char baseURI[] = "base-uri";
-static const char childSrc[] = "child-src";
-static const char formAction[] = "form-action";
-static const char frameAncestors[] = "frame-ancestors";
-static const char pluginTypes[] = "plugin-types";
-static const char reflectedXSS[] = "reflected-xss";
-static const char referrer[] = "referrer";
-
-bool isDirectiveName(const String& name)
-{
-    return (equalIgnoringCase(name, connectSrc)
-        || equalIgnoringCase(name, defaultSrc)
-        || equalIgnoringCase(name, fontSrc)
-        || equalIgnoringCase(name, frameSrc)
-        || equalIgnoringCase(name, imgSrc)
-        || equalIgnoringCase(name, mediaSrc)
-        || equalIgnoringCase(name, objectSrc)
-        || equalIgnoringCase(name, reportURI)
-        || equalIgnoringCase(name, sandbox)
-        || equalIgnoringCase(name, scriptSrc)
-        || equalIgnoringCase(name, styleSrc)
-        || equalIgnoringCase(name, baseURI)
-        || equalIgnoringCase(name, childSrc)
-        || equalIgnoringCase(name, formAction)
-        || equalIgnoringCase(name, frameAncestors)
-        || equalIgnoringCase(name, pluginTypes)
-        || equalIgnoringCase(name, reflectedXSS)
-        || equalIgnoringCase(name, referrer)
-    );
-}
-
-UseCounter::Feature getUseCounterType(ContentSecurityPolicy::HeaderType type)
-{
-    switch (type) {
-    case ContentSecurityPolicy::Enforce:
-        return UseCounter::ContentSecurityPolicy;
-    case ContentSecurityPolicy::Report:
-        return UseCounter::ContentSecurityPolicyReportOnly;
-    }
-    ASSERT_NOT_REACHED();
-    return UseCounter::NumberOfFeatures;
-}
-
-} // namespace
-
-static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b)
-{
-    if (a != b)
-        return ReferrerPolicyNever;
-    return a;
-}
-
-static bool isSourceListNone(const UChar* begin, const UChar* end)
-{
-    skipWhile<UChar, isASCIISpace>(begin, end);
-
-    const UChar* position = begin;
-    skipWhile<UChar, isSourceCharacter>(position, end);
-    if (!equalIgnoringCase("'none'", begin, position - begin))
-        return false;
-
-    skipWhile<UChar, isASCIISpace>(position, end);
-    if (position != end)
-        return false;
-
-    return true;
-}
-
-class CSPSource {
-public:
-    CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
-        : m_policy(policy)
-        , m_scheme(scheme)
-        , m_host(host)
-        , m_port(port)
-        , m_path(path)
-        , m_hostHasWildcard(hostHasWildcard)
-        , m_portHasWildcard(portHasWildcard)
-    {
-    }
-
-    bool matches(const KURL& url) const
-    {
-        if (!schemeMatches(url))
-            return false;
-        if (isSchemeOnly())
-            return true;
-        return hostMatches(url) && portMatches(url) && pathMatches(url);
-    }
-
-private:
-    bool schemeMatches(const KURL& url) const
-    {
-        if (m_scheme.isEmpty()) {
-            String protectedResourceScheme(m_policy->securityOrigin()->protocol());
-            if (equalIgnoringCase("http", protectedResourceScheme))
-                return url.protocolIs("http") || url.protocolIs("https");
-            return equalIgnoringCase(url.protocol(), protectedResourceScheme);
-        }
-        return equalIgnoringCase(url.protocol(), m_scheme);
-    }
-
-    bool hostMatches(const KURL& url) const
-    {
-        const String& host = url.host();
-        if (equalIgnoringCase(host, m_host))
-            return true;
-        return m_hostHasWildcard && host.endsWith("." + m_host, false);
-
-    }
-
-    bool pathMatches(const KURL& url) const
-    {
-        if (m_path.isEmpty())
-            return true;
-
-        String path = decodeURLEscapeSequences(url.path());
-
-        if (m_path.endsWith("/"))
-            return path.startsWith(m_path, false);
-
-        return path == m_path;
-    }
-
-    bool portMatches(const KURL& url) const
-    {
-        if (m_portHasWildcard)
-            return true;
-
-        int port = url.port();
-
-        if (port == m_port)
-            return true;
-
-        if (!port)
-            return isDefaultPortForProtocol(m_port, url.protocol());
-
-        if (!m_port)
-            return isDefaultPortForProtocol(port, url.protocol());
-
-        return false;
-    }
-
-    bool isSchemeOnly() const { return m_host.isEmpty(); }
-
-    ContentSecurityPolicy* m_policy;
-    String m_scheme;
-    String m_host;
-    int m_port;
-    String m_path;
-
-    bool m_hostHasWildcard;
-    bool m_portHasWildcard;
-};
-
-class CSPSourceList {
-public:
-    CSPSourceList(ContentSecurityPolicy*, const String& directiveName);
-
-    void parse(const UChar* begin, const UChar* end);
-
-    bool matches(const KURL&);
-    bool allowInline() const { return m_allowInline; }
-    bool allowScriptEval() const { return m_allowScriptEval; }
-    bool allowNonce(const String& nonce) const { return !nonce.isNull() && m_nonces.contains(nonce); }
-    bool allowHash(const SourceHashValue& hashValue) const { return m_hashes.contains(hashValue); }
-    uint8_t hashAlgorithmsUsed() const { return m_hashAlgorithmsUsed; }
-
-    bool isHashOrNoncePresent() const { return !m_nonces.isEmpty() || m_hashAlgorithmsUsed != ContentSecurityPolicy::HashAlgorithmsNone; }
-
-private:
-    bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
-    bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
-    bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
-    bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
-    bool parsePath(const UChar* begin, const UChar* end, String& path);
-    bool parseNonce(const UChar* begin, const UChar* end, String& nonce);
-    bool parseHash(const UChar* begin, const UChar* end, Vector<uint8_t>& hash, ContentSecurityPolicy::HashAlgorithms&);
-
-    void addSourceSelf();
-    void addSourceStar();
-    void addSourceUnsafeInline();
-    void addSourceUnsafeEval();
-    void addSourceNonce(const String& nonce);
-    void addSourceHash(const ContentSecurityPolicy::HashAlgorithms&, const Vector<uint8_t>& hash);
-
-    ContentSecurityPolicy* m_policy;
-    Vector<CSPSource> m_list;
-    String m_directiveName;
-    bool m_allowStar;
-    bool m_allowInline;
-    bool m_allowScriptEval;
-    HashSet<String> m_nonces;
-    HashSet<SourceHashValue> m_hashes;
-    uint8_t m_hashAlgorithmsUsed;
-};
-
-CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& directiveName)
-    : m_policy(policy)
-    , m_directiveName(directiveName)
-    , m_allowStar(false)
-    , m_allowInline(false)
-    , m_allowScriptEval(false)
-    , m_hashAlgorithmsUsed(0)
-{
-}
-
-bool CSPSourceList::matches(const KURL& url)
-{
-    if (m_allowStar)
-        return true;
-
-    KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
-
-    for (size_t i = 0; i < m_list.size(); ++i) {
-        if (m_list[i].matches(effectiveURL))
-            return true;
-    }
-
-    return false;
-}
-
-// source-list       = *WSP [ source *( 1*WSP source ) *WSP ]
-//                   / *WSP "'none'" *WSP
-//
-void CSPSourceList::parse(const UChar* begin, const UChar* end)
-{
-    // We represent 'none' as an empty m_list.
-    if (isSourceListNone(begin, end))
-        return;
-
-    const UChar* position = begin;
-    while (position < end) {
-        skipWhile<UChar, isASCIISpace>(position, end);
-        if (position == end)
-            return;
-
-        const UChar* beginSource = position;
-        skipWhile<UChar, isSourceCharacter>(position, end);
-
-        String scheme, host, path;
-        int port = 0;
-        bool hostHasWildcard = false;
-        bool portHasWildcard = false;
-
-        if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) {
-            // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
-            // etc.) aren't stored in m_list, but as attributes on the source
-            // list itself.
-            if (scheme.isEmpty() && host.isEmpty())
-                continue;
-            if (isDirectiveName(host))
-                m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
-            m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
-        } else {
-            m_policy->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
-        }
-
-        ASSERT(position == end || isASCIISpace(*position));
-    }
-}
-
-// source            = scheme ":"
-//                   / ( [ scheme "://" ] host [ port ] [ path ] )
-//                   / "'self'"
-bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
-{
-    if (begin == end)
-        return false;
-
-    if (equalIgnoringCase("'none'", begin, end - begin))
-        return false;
-
-    if (end - begin == 1 && *begin == '*') {
-        addSourceStar();
-        return true;
-    }
-
-    if (equalIgnoringCase("'self'", begin, end - begin)) {
-        addSourceSelf();
-        return true;
-    }
-
-    if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) {
-        addSourceUnsafeInline();
-        return true;
-    }
-
-    if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) {
-        addSourceUnsafeEval();
-        return true;
-    }
-
-    if (m_policy->experimentalFeaturesEnabled()) {
-        String nonce;
-        if (!parseNonce(begin, end, nonce))
-            return false;
-
-        if (!nonce.isNull()) {
-            addSourceNonce(nonce);
-            return true;
-        }
-
-        Vector<uint8_t> hash;
-        ContentSecurityPolicy::HashAlgorithms algorithm = ContentSecurityPolicy::HashAlgorithmsNone;
-        if (!parseHash(begin, end, hash, algorithm))
-            return false;
-
-        if (hash.size() > 0) {
-            addSourceHash(algorithm, hash);
-            return true;
-        }
-    }
-
-    const UChar* position = begin;
-    const UChar* beginHost = begin;
-    const UChar* beginPath = end;
-    const UChar* beginPort = 0;
-
-    skipWhile<UChar, isNotColonOrSlash>(position, end);
-
-    if (position == end) {
-        // host
-        //     ^
-        return parseHost(beginHost, position, host, hostHasWildcard);
-    }
-
-    if (position < end && *position == '/') {
-        // host/path || host/ || /
-        //     ^            ^    ^
-        return parseHost(beginHost, position, host, hostHasWildcard) && parsePath(position, end, path);
-    }
-
-    if (position < end && *position == ':') {
-        if (end - position == 1) {
-            // scheme:
-            //       ^
-            return parseScheme(begin, position, scheme);
-        }
-
-        if (position[1] == '/') {
-            // scheme://host || scheme://
-            //       ^                ^
-            if (!parseScheme(begin, position, scheme)
-                || !skipExactly<UChar>(position, end, ':')
-                || !skipExactly<UChar>(position, end, '/')
-                || !skipExactly<UChar>(position, end, '/'))
-                return false;
-            if (position == end)
-                return true;
-            beginHost = position;
-            skipWhile<UChar, isNotColonOrSlash>(position, end);
-        }
-
-        if (position < end && *position == ':') {
-            // host:port || scheme://host:port
-            //     ^                     ^
-            beginPort = position;
-            skipUntil<UChar>(position, end, '/');
-        }
-    }
-
-    if (position < end && *position == '/') {
-        // scheme://host/path || scheme://host:port/path
-        //              ^                          ^
-        if (position == beginHost)
-            return false;
-        beginPath = position;
-    }
-
-    if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostHasWildcard))
-        return false;
-
-    if (beginPort) {
-        if (!parsePort(beginPort, beginPath, port, portHasWildcard))
-            return false;
-    } else {
-        port = 0;
-    }
-
-    if (beginPath != end) {
-        if (!parsePath(beginPath, end, path))
-            return false;
-    }
-
-    return true;
-}
-
-// nonce-source      = "'nonce-" nonce-value "'"
-// nonce-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
-//
-bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& nonce)
-{
-    DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-"));
-
-    if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length()))
-        return true;
-
-    const UChar* position = begin + noncePrefix.length();
-    const UChar* nonceBegin = position;
-
-    skipWhile<UChar, isNonceCharacter>(position, end);
-    ASSERT(nonceBegin <= position);
-
-    if ((position + 1) != end  || *position != '\'' || !(position - nonceBegin))
-        return false;
-
-    nonce = String(nonceBegin, position - nonceBegin);
-    return true;
-}
-
-// hash-source       = "'" hash-algorithm "-" hash-value "'"
-// hash-algorithm    = "sha1" / "sha256"
-// hash-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
-//
-bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, Vector<uint8_t>& hash, ContentSecurityPolicy::HashAlgorithms& hashAlgorithm)
-{
-    DEFINE_STATIC_LOCAL(const String, sha1Prefix, ("'sha1-"));
-    DEFINE_STATIC_LOCAL(const String, sha256Prefix, ("'sha256-"));
-
-    String prefix;
-    if (equalIgnoringCase(sha1Prefix.characters8(), begin, sha1Prefix.length())) {
-        prefix = sha1Prefix;
-        hashAlgorithm = ContentSecurityPolicy::HashAlgorithmsSha1;
-    } else if (equalIgnoringCase(sha256Prefix.characters8(), begin, sha256Prefix.length())) {
-        notImplemented();
-    } else {
-        return true;
-    }
-
-    const UChar* position = begin + prefix.length();
-    const UChar* hashBegin = position;
-
-    skipWhile<UChar, isBase64EncodedCharacter>(position, end);
-    ASSERT(hashBegin <= position);
-
-    // Base64 encodings may end with exactly one or two '=' characters
-    skipExactly<UChar>(position, position + 1, '=');
-    skipExactly<UChar>(position, position + 1, '=');
-
-    if ((position + 1) != end  || *position != '\'' || !(position - hashBegin))
-        return false;
-
-    Vector<char> hashVector;
-    base64Decode(hashBegin, position - hashBegin, hashVector);
-    hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size());
-    return true;
-}
-
-//                     ; <scheme> production from RFC 3986
-// scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
-//
-bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
-{
-    ASSERT(begin <= end);
-    ASSERT(scheme.isEmpty());
-
-    if (begin == end)
-        return false;
-
-    const UChar* position = begin;
-
-    if (!skipExactly<UChar, isASCIIAlpha>(position, end))
-        return false;
-
-    skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
-
-    if (position != end)
-        return false;
-
-    scheme = String(begin, end - begin);
-    return true;
-}
-
-// host              = [ "*." ] 1*host-char *( "." 1*host-char )
-//                   / "*"
-// host-char         = ALPHA / DIGIT / "-"
-//
-bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard)
-{
-    ASSERT(begin <= end);
-    ASSERT(host.isEmpty());
-    ASSERT(!hostHasWildcard);
-
-    if (begin == end)
-        return false;
-
-    const UChar* position = begin;
-
-    if (skipExactly<UChar>(position, end, '*')) {
-        hostHasWildcard = true;
-
-        if (position == end)
-            return true;
-
-        if (!skipExactly<UChar>(position, end, '.'))
-            return false;
-    }
-
-    const UChar* hostBegin = position;
-
-    while (position < end) {
-        if (!skipExactly<UChar, isHostCharacter>(position, end))
-            return false;
-
-        skipWhile<UChar, isHostCharacter>(position, end);
-
-        if (position < end && !skipExactly<UChar>(position, end, '.'))
-            return false;
-    }
-
-    ASSERT(position == end);
-    host = String(hostBegin, end - hostBegin);
-    return true;
-}
-
-bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path)
-{
-    ASSERT(begin <= end);
-    ASSERT(path.isEmpty());
-
-    const UChar* position = begin;
-    skipWhile<UChar, isPathComponentCharacter>(position, end);
-    // path/to/file.js?query=string || path/to/file.js#anchor
-    //                ^                               ^
-    if (position < end)
-        m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
-
-    path = decodeURLEscapeSequences(String(begin, position - begin));
-
-    ASSERT(position <= end);
-    ASSERT(position == end || (*position == '#' || *position == '?'));
-    return true;
-}
-
-// port              = ":" ( 1*DIGIT / "*" )
-//
-bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
-{
-    ASSERT(begin <= end);
-    ASSERT(!port);
-    ASSERT(!portHasWildcard);
-
-    if (!skipExactly<UChar>(begin, end, ':'))
-        ASSERT_NOT_REACHED();
-
-    if (begin == end)
-        return false;
-
-    if (end - begin == 1 && *begin == '*') {
-        port = 0;
-        portHasWildcard = true;
-        return true;
-    }
-
-    const UChar* position = begin;
-    skipWhile<UChar, isASCIIDigit>(position, end);
-
-    if (position != end)
-        return false;
-
-    bool ok;
-    port = charactersToIntStrict(begin, end - begin, &ok);
-    return ok;
-}
-
-void CSPSourceList::addSourceSelf()
-{
-    m_list.append(CSPSource(m_policy, m_policy->securityOrigin()->protocol(), m_policy->securityOrigin()->host(), m_policy->securityOrigin()->port(), String(), false, false));
-}
-
-void CSPSourceList::addSourceStar()
-{
-    m_allowStar = true;
-}
-
-void CSPSourceList::addSourceUnsafeInline()
-{
-    m_allowInline = true;
-}
-
-void CSPSourceList::addSourceUnsafeEval()
-{
-    m_allowScriptEval = true;
-}
-
-void CSPSourceList::addSourceNonce(const String& nonce)
-{
-    m_nonces.add(nonce);
-}
-
-void CSPSourceList::addSourceHash(const ContentSecurityPolicy::HashAlgorithms& algorithm, const Vector<uint8_t>& hash)
-{
-    m_hashes.add(SourceHashValue(algorithm, hash));
-    m_hashAlgorithmsUsed |= algorithm;
-}
-
-class CSPDirective {
-public:
-    CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
-        : m_name(name)
-        , m_text(name + ' ' + value)
-        , m_policy(policy)
-    {
-    }
-
-    const String& text() const { return m_text; }
-
-protected:
-    const ContentSecurityPolicy* policy() const { return m_policy; }
-
-private:
-    String m_name;
-    String m_text;
-    ContentSecurityPolicy* m_policy;
-};
-
-class MediaListDirective : public CSPDirective {
-public:
-    MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
-        : CSPDirective(name, value, policy)
-    {
-        Vector<UChar> characters;
-        value.appendTo(characters);
-        parse(characters.data(), characters.data() + characters.size());
-    }
-
-    bool allows(const String& type)
-    {
-        return m_pluginTypes.contains(type);
-    }
-
-private:
-    void parse(const UChar* begin, const UChar* end)
-    {
-        const UChar* position = begin;
-
-        // 'plugin-types ____;' OR 'plugin-types;'
-        if (position == end) {
-            policy()->reportInvalidPluginTypes(String());
-            return;
-        }
-
-        while (position < end) {
-            // _____ OR _____mime1/mime1
-            // ^        ^
-            skipWhile<UChar, isASCIISpace>(position, end);
-            if (position == end)
-                return;
-
-            // mime1/mime1 mime2/mime2
-            // ^
-            begin = position;
-            if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
-                skipWhile<UChar, isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
-                continue;
-            }
-            skipWhile<UChar, isMediaTypeCharacter>(position, end);
-
-            // mime1/mime1 mime2/mime2
-            //      ^
-            if (!skipExactly<UChar>(position, end, '/')) {
-                skipWhile<UChar, isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
-                continue;
-            }
-
-            // mime1/mime1 mime2/mime2
-            //       ^
-            if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
-                skipWhile<UChar, isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
-                continue;
-            }
-            skipWhile<UChar, isMediaTypeCharacter>(position, end);
-
-            // mime1/mime1 mime2/mime2 OR mime1/mime1  OR mime1/mime1/error
-            //            ^                          ^               ^
-            if (position < end && isNotASCIISpace(*position)) {
-                skipWhile<UChar, isNotASCIISpace>(position, end);
-                policy()->reportInvalidPluginTypes(String(begin, position - begin));
-                continue;
-            }
-            m_pluginTypes.add(String(begin, position - begin));
-
-            ASSERT(position == end || isASCIISpace(*position));
-        }
-    }
-
-    HashSet<String> m_pluginTypes;
-};
-
-class SourceListDirective : public CSPDirective {
-public:
-    SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
-        : CSPDirective(name, value, policy)
-        , m_sourceList(policy, name)
-    {
-        Vector<UChar> characters;
-        value.appendTo(characters);
-
-        m_sourceList.parse(characters.data(), characters.data() + characters.size());
-    }
-
-    bool allows(const KURL& url)
-    {
-        return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
-    }
-
-    bool allowInline() const { return m_sourceList.allowInline(); }
-    bool allowScriptEval() const { return m_sourceList.allowScriptEval(); }
-    bool allowNonce(const String& nonce) const { return m_sourceList.allowNonce(nonce.stripWhiteSpace()); }
-    bool allowHash(const SourceHashValue& hashValue) const { return m_sourceList.allowHash(hashValue); }
-    bool isHashOrNoncePresent() const { return m_sourceList.isHashOrNoncePresent(); }
-
-    uint8_t hashAlgorithmsUsed() const { return m_sourceList.hashAlgorithmsUsed(); }
-
-private:
-    CSPSourceList m_sourceList;
-};
-
-class CSPDirectiveList {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType, ContentSecurityPolicy::HeaderSource);
-
-    void parse(const UChar* begin, const UChar* end);
-
-    const String& header() const { return m_header; }
-    ContentSecurityPolicy::HeaderType headerType() const { return m_headerType; }
-    ContentSecurityPolicy::HeaderSource headerSource() const { return m_headerSource; }
-
-    bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowScriptEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowStyleEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-
-    bool allowScriptFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowObjectFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowAncestors(Frame*, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowChildContextFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
-    bool allowScriptNonce(const String&) const;
-    bool allowStyleNonce(const String&) const;
-    bool allowScriptHash(const SourceHashValue&) const;
-    bool allowStyleHash(const SourceHashValue&) const;
-
-    const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
-    const String& styleEvalDisabledErrorMessage() const { return m_styleEvalDisabledErrorMessage; }
-    ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
-    ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
-    bool didSetReferrerPolicy() const { return m_didSetReferrerPolicy; }
-    bool isReportOnly() const { return m_reportOnly; }
-    const Vector<KURL>& reportURIs() const { return m_reportURIs; }
-
-private:
-    CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicy::HeaderType, ContentSecurityPolicy::HeaderSource);
-
-    bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
-    void parseReportURI(const String& name, const String& value);
-    void parsePluginTypes(const String& name, const String& value);
-    void parseReflectedXSS(const String& name, const String& value);
-    void parseReferrer(const String& name, const String& value);
-    void addDirective(const String& name, const String& value);
-    void applySandboxPolicy(const String& name, const String& sandboxPolicy);
-
-    template <class CSPDirectiveType>
-    void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
-
-    SourceListDirective* operativeDirective(SourceListDirective*) const;
-    SourceListDirective* operativeDirective(SourceListDirective*, SourceListDirective* override) const;
-    void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const;
-    void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
-    void reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState*) const;
-
-    bool checkEval(SourceListDirective*) const;
-    bool checkInline(SourceListDirective*) const;
-    bool checkNonce(SourceListDirective*, const String&) const;
-    bool checkHash(SourceListDirective*, const SourceHashValue&) const;
-    bool checkSource(SourceListDirective*, const KURL&) const;
-    bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
-    bool checkAncestors(SourceListDirective*, Frame*) const;
-
-    void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
-    void setStyleEvalDisabledErrorMessage(const String& errorMessage) { m_styleEvalDisabledErrorMessage = errorMessage; }
-
-    bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, ScriptState*) const;
-    bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
-
-    bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const;
-    bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
-    bool checkAncestorsAndReportViolation(SourceListDirective*, Frame*) const;
-
-    bool denyIfEnforcingPolicy() const { return m_reportOnly; }
-
-    ContentSecurityPolicy* m_policy;
-
-    String m_header;
-    ContentSecurityPolicy::HeaderType m_headerType;
-    ContentSecurityPolicy::HeaderSource m_headerSource;
-
-    bool m_reportOnly;
-    bool m_haveSandboxPolicy;
-    ReflectedXSSDisposition m_reflectedXSSDisposition;
-
-    bool m_didSetReferrerPolicy;
-    ReferrerPolicy m_referrerPolicy;
-
-    OwnPtr<MediaListDirective> m_pluginTypes;
-    OwnPtr<SourceListDirective> m_baseURI;
-    OwnPtr<SourceListDirective> m_childSrc;
-    OwnPtr<SourceListDirective> m_connectSrc;
-    OwnPtr<SourceListDirective> m_defaultSrc;
-    OwnPtr<SourceListDirective> m_fontSrc;
-    OwnPtr<SourceListDirective> m_formAction;
-    OwnPtr<SourceListDirective> m_frameAncestors;
-    OwnPtr<SourceListDirective> m_frameSrc;
-    OwnPtr<SourceListDirective> m_imgSrc;
-    OwnPtr<SourceListDirective> m_mediaSrc;
-    OwnPtr<SourceListDirective> m_objectSrc;
-    OwnPtr<SourceListDirective> m_scriptSrc;
-    OwnPtr<SourceListDirective> m_styleSrc;
-
-    Vector<KURL> m_reportURIs;
-
-    String m_evalDisabledErrorMessage;
-    String m_styleEvalDisabledErrorMessage;
-};
-
-CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicy::HeaderType type, ContentSecurityPolicy::HeaderSource source)
-    : m_policy(policy)
-    , m_headerType(type)
-    , m_headerSource(source)
-    , m_reportOnly(false)
-    , m_haveSandboxPolicy(false)
-    , m_reflectedXSSDisposition(ReflectedXSSUnset)
-    , m_didSetReferrerPolicy(false)
-    , m_referrerPolicy(ReferrerPolicyDefault)
-{
-    m_reportOnly = type == ContentSecurityPolicy::Report;
-}
-
-PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicy::HeaderType type, ContentSecurityPolicy::HeaderSource source)
-{
-    OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type, source));
-    directives->parse(begin, end);
-
-    if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get())))
-        directives->setEvalDisabledErrorMessage("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"" + directives->operativeDirective(directives->m_scriptSrc.get())->text() + "\".\n");
-    if (!directives->checkEval(directives->operativeDirective(directives->m_styleSrc.get())))
-        directives->setStyleEvalDisabledErrorMessage("Refused to evaluate a string as CSS because 'unsafe-eval' is not an allowed source of style in the following Content Security Policy directive: \"" + directives->operativeDirective(directives->m_styleSrc.get())->text() + "\".\n");
-
-    if (directives->isReportOnly() && directives->reportURIs().isEmpty())
-        policy->reportMissingReportURI(String(begin, end - begin));
-
-    return directives.release();
-}
-
-void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const
-{
-    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
-    m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
-    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
-{
-    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
-    m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt());
-    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-void CSPDirectiveList::reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState* state) const
-{
-    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
-    m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, state);
-    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
-}
-
-bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
-{
-    return !directive || directive->allowScriptEval();
-}
-
-bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
-{
-    return !directive || (directive->allowInline() && !directive->isHashOrNoncePresent());
-}
-
-bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const
-{
-    return !directive || directive->allowNonce(nonce);
-}
-
-bool CSPDirectiveList::checkHash(SourceListDirective* directive, const SourceHashValue& hashValue) const
-{
-    return !directive || directive->allowHash(hashValue);
-}
-
-bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
-{
-    return !directive || directive->allows(url);
-}
-
-bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, Frame* frame) const
-{
-    if (!frame || !directive)
-        return true;
-
-    for (Frame* current = frame->tree().parent(); current; current = current->tree().parent()) {
-        if (!directive->allows(current->document()->url()))
-            return false;
-    }
-    return true;
-}
-
-bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
-{
-    if (!directive)
-        return true;
-    if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
-        return false;
-    return directive->allows(type);
-}
-
-SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
-{
-    return directive ? directive : m_defaultSrc.get();
-}
-
-SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive, SourceListDirective* override) const
-{
-    return directive ? directive : override;
-}
-
-bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, ScriptState* state) const
-{
-    if (checkEval(directive))
-        return true;
-
-    String suffix = String();
-    if (directive == m_defaultSrc)
-        suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
-
-    reportViolationWithState(directive->text(), scriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), state);
-    if (!m_reportOnly) {
-        m_policy->reportBlockedScriptExecutionToInspector(directive->text());
-        return false;
-    }
-    return true;
-}
-
-bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
-{
-    if (checkMediaType(directive, type, typeAttribute))
-        return true;
-
-    String message = consoleMessage + "\'" + directive->text() + "\'.";
-    if (typeAttribute.isEmpty())
-        message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
-
-    reportViolation(directive->text(), pluginTypes, message + "\n", KURL());
-    return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
-{
-    if (checkInline(directive))
-        return true;
-
-    String suffix = String();
-    if (directive->allowInline() && directive->isHashOrNoncePresent()) {
-        // If inline is allowed, but a hash or nonce is present, we ignore 'unsafe-inline'. Throw a reasonable error.
-        suffix = " Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.";
-    } else {
-        suffix = " Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.";
-        if (directive == m_defaultSrc)
-            suffix = suffix + " Note also that '" + String(isScript ? "script" : "style") + "-src' was not explicitly set, so 'default-src' is used as a fallback.";
-    }
-
-    reportViolationWithLocation(directive->text(), isScript ? scriptSrc : styleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine);
-
-    if (!m_reportOnly) {
-        if (isScript)
-            m_policy->reportBlockedScriptExecutionToInspector(directive->text());
-        return false;
-    }
-    return true;
-}
-
-bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& effectiveDirective) const
-{
-    if (checkSource(directive, url))
-        return true;
-
-    String prefix;
-    if (baseURI == effectiveDirective)
-        prefix = "Refused to set the document's base URI to '";
-    else if (childSrc == effectiveDirective)
-        prefix = "Refused to create a child context containing '";
-    else if (connectSrc == effectiveDirective)
-        prefix = "Refused to connect to '";
-    else if (fontSrc == effectiveDirective)
-        prefix = "Refused to load the font '";
-    else if (formAction == effectiveDirective)
-        prefix = "Refused to send form data to '";
-    else if (frameSrc == effectiveDirective)
-        prefix = "Refused to frame '";
-    else if (imgSrc == effectiveDirective)
-        prefix = "Refused to load the image '";
-    else if (mediaSrc == effectiveDirective)
-        prefix = "Refused to load media from '";
-    else if (objectSrc == effectiveDirective)
-        prefix = "Refused to load plugin data from '";
-    else if (scriptSrc == effectiveDirective)
-        prefix = "Refused to load the script '";
-    else if (styleSrc == effectiveDirective)
-        prefix = "Refused to load the stylesheet '";
-
-    String suffix = String();
-    if (directive == m_defaultSrc)
-        suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
-
-    reportViolation(directive->text(), effectiveDirective, prefix + url.elidedString() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url);
-    return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::checkAncestorsAndReportViolation(SourceListDirective* directive, Frame* frame) const
-{
-    if (checkAncestors(directive, frame))
-        return true;
-
-    reportViolation(directive->text(), "frame-ancestors", "Refused to display '" + frame->document()->url().elidedString() + " in a frame because an ancestor violates the following Content Security Policy directive: \"" + directive->text() + "\".", frame->document()->url());
-    return denyIfEnforcingPolicy();
-}
-
-bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
-    if (reportingStatus == ContentSecurityPolicy::SendReport)
-        return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
-
-    return checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
-    if (reportingStatus == ContentSecurityPolicy::SendReport)
-        return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
-    return checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline script because it violates the following Content Security Policy directive: "));
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
-        checkInline(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: "));
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
-        checkInline(operativeDirective(m_styleSrc.get()));
-}
-
-bool CSPDirectiveList::allowScriptEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "));
-
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, state) :
-        checkEval(operativeDirective(m_scriptSrc.get()));
-}
-
-bool CSPDirectiveList::allowStyleEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate a string as CSS because 'unsafe-eval' is not an allowed source of style in the following Content Security Policy directive: "));
-
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkEvalAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, state) :
-        checkEval(operativeDirective(m_styleSrc.get()));
-}
-
-bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.elidedString() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
-        checkMediaType(m_pluginTypes.get(), type, typeAttribute);
-}
-
-bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, scriptSrc) :
-        checkSource(operativeDirective(m_scriptSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    if (url.isBlankURL())
-        return true;
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, objectSrc) :
-        checkSource(operativeDirective(m_objectSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    if (url.isBlankURL())
-        return true;
-
-    // 'frame-src' is the only directive which overrides something other than the default sources.
-    // It overrides 'child-src', which overrides the default sources. So, we do this nested set
-    // of calls to 'operativeDirective()' to grab 'frame-src' if it exists, 'child-src' if it
-    // doesn't, and 'defaut-src' if neither are available.
-    //
-    // All of this only applies, of course, if we're in CSP 1.1. In CSP 1.0, 'frame-src'
-    // overrides 'default-src' directly.
-    SourceListDirective* whichDirective = m_policy->experimentalFeaturesEnabled() ?
-        operativeDirective(m_frameSrc.get(), operativeDirective(m_childSrc.get())) :
-        operativeDirective(m_frameSrc.get());
-
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(whichDirective, url, frameSrc) :
-        checkSource(whichDirective, url);
-}
-
-bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, imgSrc) :
-        checkSource(operativeDirective(m_imgSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, styleSrc) :
-        checkSource(operativeDirective(m_styleSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, fontSrc) :
-        checkSource(operativeDirective(m_fontSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, mediaSrc) :
-        checkSource(operativeDirective(m_mediaSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, connectSrc) :
-        checkSource(operativeDirective(m_connectSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(m_formAction.get(), url, formAction) :
-        checkSource(m_formAction.get(), url);
-}
-
-bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(m_baseURI.get(), url, baseURI) :
-        checkSource(m_baseURI.get(), url);
-}
-
-bool CSPDirectiveList::allowAncestors(Frame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkAncestorsAndReportViolation(m_frameAncestors.get(), frame) :
-        checkAncestors(m_frameAncestors.get(), frame);
-}
-
-bool CSPDirectiveList::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return reportingStatus == ContentSecurityPolicy::SendReport ?
-        checkSourceAndReportViolation(operativeDirective(m_childSrc.get()), url, childSrc) :
-        checkSource(operativeDirective(m_childSrc.get()), url);
-}
-
-bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
-{
-    return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
-}
-
-bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
-{
-    return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
-}
-
-bool CSPDirectiveList::allowScriptHash(const SourceHashValue& hashValue) const
-{
-    return checkHash(operativeDirective(m_scriptSrc.get()), hashValue);
-}
-
-bool CSPDirectiveList::allowStyleHash(const SourceHashValue& hashValue) const
-{
-    return checkHash(operativeDirective(m_styleSrc.get()), hashValue);
-}
-
-// policy            = directive-list
-// directive-list    = [ directive *( ";" [ directive ] ) ]
-//
-void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
-{
-    m_header = String(begin, end - begin);
-
-    if (begin == end)
-        return;
-
-    const UChar* position = begin;
-    while (position < end) {
-        const UChar* directiveBegin = position;
-        skipUntil<UChar>(position, end, ';');
-
-        String name, value;
-        if (parseDirective(directiveBegin, position, name, value)) {
-            ASSERT(!name.isEmpty());
-            addDirective(name, value);
-        }
-
-        ASSERT(position == end || *position == ';');
-        skipExactly<UChar>(position, end, ';');
-    }
-}
-
-// directive         = *WSP [ directive-name [ WSP directive-value ] ]
-// directive-name    = 1*( ALPHA / DIGIT / "-" )
-// directive-value   = *( WSP / <VCHAR except ";"> )
-//
-bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
-{
-    ASSERT(name.isEmpty());
-    ASSERT(value.isEmpty());
-
-    const UChar* position = begin;
-    skipWhile<UChar, isASCIISpace>(position, end);
-
-    // Empty directive (e.g. ";;;"). Exit early.
-    if (position == end)
-        return false;
-
-    const UChar* nameBegin = position;
-    skipWhile<UChar, isDirectiveNameCharacter>(position, end);
-
-    // The directive-name must be non-empty.
-    if (nameBegin == position) {
-        skipWhile<UChar, isNotASCIISpace>(position, end);
-        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
-        return false;
-    }
-
-    name = String(nameBegin, position - nameBegin);
-
-    if (position == end)
-        return true;
-
-    if (!skipExactly<UChar, isASCIISpace>(position, end)) {
-        skipWhile<UChar, isNotASCIISpace>(position, end);
-        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
-        return false;
-    }
-
-    skipWhile<UChar, isASCIISpace>(position, end);
-
-    const UChar* valueBegin = position;
-    skipWhile<UChar, isDirectiveValueCharacter>(position, end);
-
-    if (position != end) {
-        m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
-        return false;
-    }
-
-    // The directive-value may be empty.
-    if (valueBegin == position)
-        return true;
-
-    value = String(valueBegin, position - valueBegin);
-    return true;
-}
-
-void CSPDirectiveList::parseReportURI(const String& name, const String& value)
-{
-    if (!m_reportURIs.isEmpty()) {
-        m_policy->reportDuplicateDirective(name);
-        return;
-    }
-
-    Vector<UChar> characters;
-    value.appendTo(characters);
-
-    const UChar* position = characters.data();
-    const UChar* end = position + characters.size();
-
-    while (position < end) {
-        skipWhile<UChar, isASCIISpace>(position, end);
-
-        const UChar* urlBegin = position;
-        skipWhile<UChar, isNotASCIISpace>(position, end);
-
-        if (urlBegin < position) {
-            String url = String(urlBegin, position - urlBegin);
-            m_reportURIs.append(m_policy->completeURL(url));
-        }
-    }
-}
-
-
-template<class CSPDirectiveType>
-void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
-{
-    if (directive) {
-        m_policy->reportDuplicateDirective(name);
-        return;
-    }
-    directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
-}
-
-void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
-{
-    if (m_reportOnly) {
-        m_policy->reportInvalidInReportOnly(name);
-        return;
-    }
-    if (m_haveSandboxPolicy) {
-        m_policy->reportDuplicateDirective(name);
-        return;
-    }
-    m_haveSandboxPolicy = true;
-    String invalidTokens;
-    m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidTokens));
-    if (!invalidTokens.isNull())
-        m_policy->reportInvalidSandboxFlags(invalidTokens);
-}
-
-void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
-{
-    if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
-        m_policy->reportDuplicateDirective(name);
-        m_reflectedXSSDisposition = ReflectedXSSInvalid;
-        return;
-    }
-
-    if (value.isEmpty()) {
-        m_reflectedXSSDisposition = ReflectedXSSInvalid;
-        m_policy->reportInvalidReflectedXSS(value);
-        return;
-    }
-
-    Vector<UChar> characters;
-    value.appendTo(characters);
-
-    const UChar* position = characters.data();
-    const UChar* end = position + characters.size();
-
-    skipWhile<UChar, isASCIISpace>(position, end);
-    const UChar* begin = position;
-    skipWhile<UChar, isNotASCIISpace>(position, end);
-
-    // value1
-    //       ^
-    if (equalIgnoringCase("allow", begin, position - begin)) {
-        m_reflectedXSSDisposition = AllowReflectedXSS;
-    } else if (equalIgnoringCase("filter", begin, position - begin)) {
-        m_reflectedXSSDisposition = FilterReflectedXSS;
-    } else if (equalIgnoringCase("block", begin, position - begin)) {
-        m_reflectedXSSDisposition = BlockReflectedXSS;
-    } else {
-        m_reflectedXSSDisposition = ReflectedXSSInvalid;
-        m_policy->reportInvalidReflectedXSS(value);
-        return;
-    }
-
-    skipWhile<UChar, isASCIISpace>(position, end);
-    if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset)
-        return;
-
-    // value1 value2
-    //        ^
-    m_reflectedXSSDisposition = ReflectedXSSInvalid;
-    m_policy->reportInvalidReflectedXSS(value);
-}
-
-void CSPDirectiveList::parseReferrer(const String& name, const String& value)
-{
-    if (m_didSetReferrerPolicy) {
-        m_policy->reportDuplicateDirective(name);
-        m_referrerPolicy = ReferrerPolicyNever;
-        return;
-    }
-
-    m_didSetReferrerPolicy = true;
-
-    if (value.isEmpty()) {
-        m_policy->reportInvalidReferrer(value);
-        m_referrerPolicy = ReferrerPolicyNever;
-        return;
-    }
-
-    Vector<UChar> characters;
-    value.appendTo(characters);
-
-    const UChar* position = characters.data();
-    const UChar* end = position + characters.size();
-
-    skipWhile<UChar, isASCIISpace>(position, end);
-    const UChar* begin = position;
-    skipWhile<UChar, isNotASCIISpace>(position, end);
-
-    // value1
-    //       ^
-    if (equalIgnoringCase("always", begin, position - begin)) {
-        m_referrerPolicy = ReferrerPolicyAlways;
-    } else if (equalIgnoringCase("default", begin, position - begin)) {
-        m_referrerPolicy = ReferrerPolicyDefault;
-    } else if (equalIgnoringCase("never", begin, position - begin)) {
-        m_referrerPolicy = ReferrerPolicyNever;
-    } else if (equalIgnoringCase("origin", begin, position - begin)) {
-        m_referrerPolicy = ReferrerPolicyOrigin;
-    } else {
-        m_referrerPolicy = ReferrerPolicyNever;
-        m_policy->reportInvalidReferrer(value);
-        return;
-    }
-
-    skipWhile<UChar, isASCIISpace>(position, end);
-    if (position == end)
-        return;
-
-    // value1 value2
-    //        ^
-    m_referrerPolicy = ReferrerPolicyNever;
-    m_policy->reportInvalidReferrer(value);
-
-}
-
-void CSPDirectiveList::addDirective(const String& name, const String& value)
-{
-    ASSERT(!name.isEmpty());
-
-    if (equalIgnoringCase(name, defaultSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
-    } else if (equalIgnoringCase(name, scriptSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
-        m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed());
-    } else if (equalIgnoringCase(name, objectSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
-    } else if (equalIgnoringCase(name, frameSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
-    } else if (equalIgnoringCase(name, imgSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
-    } else if (equalIgnoringCase(name, styleSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
-        m_policy->usesStyleHashAlgorithms(m_styleSrc->hashAlgorithmsUsed());
-    } else if (equalIgnoringCase(name, fontSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
-    } else if (equalIgnoringCase(name, mediaSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
-    } else if (equalIgnoringCase(name, connectSrc)) {
-        setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
-    } else if (equalIgnoringCase(name, sandbox)) {
-        applySandboxPolicy(name, value);
-    } else if (equalIgnoringCase(name, reportURI)) {
-        parseReportURI(name, value);
-    } else if (m_policy->experimentalFeaturesEnabled()) {
-        if (equalIgnoringCase(name, baseURI))
-            setCSPDirective<SourceListDirective>(name, value, m_baseURI);
-        else if (equalIgnoringCase(name, childSrc))
-            setCSPDirective<SourceListDirective>(name, value, m_childSrc);
-        else if (equalIgnoringCase(name, formAction))
-            setCSPDirective<SourceListDirective>(name, value, m_formAction);
-        else if (equalIgnoringCase(name, frameAncestors))
-            setCSPDirective<SourceListDirective>(name, value, m_frameAncestors);
-        else if (equalIgnoringCase(name, pluginTypes))
-            setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
-        else if (equalIgnoringCase(name, reflectedXSS))
-            parseReflectedXSS(name, value);
-        else if (equalIgnoringCase(name, referrer))
-            parseReferrer(name, value);
-        else
-            m_policy->reportUnsupportedDirective(name);
-    } else {
-        m_policy->reportUnsupportedDirective(name);
-    }
-}
-
-ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContextClient* client)
-    : m_client(client)
-    , m_overrideInlineStyleAllowed(false)
-    , m_scriptHashAlgorithmsUsed(HashAlgorithmsNone)
-    , m_styleHashAlgorithmsUsed(HashAlgorithmsNone)
-{
-}
-
-ContentSecurityPolicy::~ContentSecurityPolicy()
-{
-}
-
-void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
-{
-    ASSERT(m_policies.isEmpty());
-    for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter)
-        addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType(), (*iter)->headerSource());
-}
-
-void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
-{
-    if (!headers.contentSecurityPolicy().isEmpty())
-        didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicy::Enforce, ContentSecurityPolicy::HeaderSourceHTTP);
-    if (!headers.contentSecurityPolicyReportOnly().isEmpty())
-        didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicy::Report, ContentSecurityPolicy::HeaderSourceHTTP);
-}
-
-void ContentSecurityPolicy::didReceiveHeader(const String& header, HeaderType type, HeaderSource source)
-{
-    addPolicyFromHeaderValue(header, type, source);
-}
-
-void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, HeaderType type, HeaderSource source)
-{
-    Document* document = this->document();
-    if (document) {
-        UseCounter::count(*document, getUseCounterType(type));
-
-        // CSP 1.1 defines report-only in a <meta> element as invalid. Measure for now, disable in experimental mode.
-        if (source == ContentSecurityPolicy::HeaderSourceMeta && type == ContentSecurityPolicy::Report) {
-            UseCounter::count(*document, UseCounter::ContentSecurityPolicyReportOnlyInMeta);
-            if (experimentalFeaturesEnabled()) {
-                reportReportOnlyInMeta(header);
-                return;
-            }
-        }
-    }
-
-
-    Vector<UChar> characters;
-    header.appendTo(characters);
-
-    const UChar* begin = characters.data();
-    const UChar* end = begin + characters.size();
-
-    // RFC2616, section 4.2 specifies that headers appearing multiple times can
-    // be combined with a comma. Walk the header string, and parse each comma
-    // separated chunk as a separate header.
-    const UChar* position = begin;
-    while (position < end) {
-        skipUntil<UChar>(position, end, ',');
-
-        // header1,header2 OR header1
-        //        ^                  ^
-        OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type, source);
-
-        // We disable 'eval()' even in the case of report-only policies, and rely on the check in the V8Initializer::codeGenerationCheckCallbackInMainThread callback to determine whether the call should execute or not.
-        if (!policy->allowScriptEval(0, SuppressReport))
-            m_client->disableEval(policy->evalDisabledErrorMessage());
-
-        m_policies.append(policy.release());
-
-        // Skip the comma, and begin the next header from the current position.
-        ASSERT(position == end || *position == ',');
-        skipExactly<UChar>(position, end, ',');
-        begin = position;
-    }
-
-    if (document && type != Report && didSetReferrerPolicy())
-        document->setReferrerPolicy(referrerPolicy());
-}
-
-void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
-{
-    m_overrideInlineStyleAllowed = value;
-}
-
-const String& ContentSecurityPolicy::deprecatedHeader() const
-{
-    return m_policies.isEmpty() ? emptyString() : m_policies[0]->header();
-}
-
-ContentSecurityPolicy::HeaderType ContentSecurityPolicy::deprecatedHeaderType() const
-{
-    return m_policies.isEmpty() ? Enforce : m_policies[0]->headerType();
-}
-
-template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
-    for (size_t i = 0; i < policies.size(); ++i) {
-        if (!(policies[i].get()->*allowed)(reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(ScriptState* state, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
-    for (size_t i = 0; i < policies.size(); ++i) {
-        if (!(policies[i].get()->*allowed)(state, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
-    for (size_t i = 0; i < policies.size(); ++i) {
-        if (!(policies[i].get()->*allowed)(contextURL, contextLine, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(const String&) const>
-bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
-{
-    for (size_t i = 0; i < policies.size(); ++i) {
-        if (!(policies[i].get()->*allowed)(nonce))
-            return false;
-    }
-    return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(const SourceHashValue&) const>
-bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const SourceHashValue& hashValue)
-{
-    for (size_t i = 0; i < policies.size(); ++i) {
-        if (!(policies[i].get()->*allowed)(hashValue))
-            return false;
-    }
-    return true;
-}
-
-template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
-    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
-        return true;
-
-    for (size_t i = 0; i < policies.size(); ++i) {
-        if (!(policies[i].get()->*allowFromURL)(url, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (CSPDirectiveList::*allowed)(Frame*, ContentSecurityPolicy::ReportingStatus) const>
-bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, Frame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus)
-{
-    for (size_t i = 0; i < policies.size(); ++i) {
-        if (!(policies[i].get()->*allowed)(frame, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    if (m_overrideInlineStyleAllowed)
-        return true;
-    return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowScriptEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithState<&CSPDirectiveList::allowScriptEval>(m_policies, state, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowStyleEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    if (!experimentalFeaturesEnabled()) {
-        if (Document* document = this->document())
-            UseCounter::count(*document, UseCounter::UnsafeEvalBlocksCSSOM);
-        return true;
-    }
-    return isAllowedByAllWithState<&CSPDirectiveList::allowStyleEval>(m_policies, state, reportingStatus);
-}
-
-String ContentSecurityPolicy::evalDisabledErrorMessage() const
-{
-    for (size_t i = 0; i < m_policies.size(); ++i) {
-        if (!m_policies[i]->allowScriptEval(0, SuppressReport))
-            return m_policies[i]->evalDisabledErrorMessage();
-    }
-    return String();
-}
-
-String ContentSecurityPolicy::styleEvalDisabledErrorMessage() const
-{
-    for (size_t i = 0; i < m_policies.size(); ++i) {
-        if (!m_policies[i]->allowStyleEval(0, SuppressReport))
-            return m_policies[i]->styleEvalDisabledErrorMessage();
-    }
-    return String();
-}
-
-bool ContentSecurityPolicy::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    for (size_t i = 0; i < m_policies.size(); ++i) {
-        if (!m_policies[i]->allowPluginType(type, typeAttribute, url, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowScriptNonce(const String& nonce) const
-{
-    return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_policies, nonce);
-}
-
-bool ContentSecurityPolicy::allowStyleNonce(const String& nonce) const
-{
-    return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policies, nonce);
-}
-
-// TODO(jww) We don't currently have a WTF SHA256 implementation. Once we
-// have that, we should implement a proper check for sha256 hash values in
-// both allowScriptHash and allowStyleHash.
-bool ContentSecurityPolicy::allowScriptHash(const String& source) const
-{
-    if (HashAlgorithmsSha1 & m_scriptHashAlgorithmsUsed) {
-        Vector<uint8_t, 20> digest;
-        SHA1 sourceSha1;
-        sourceSha1.addBytes(UTF8Encoding().normalizeAndEncode(source, WTF::EntitiesForUnencodables));
-        sourceSha1.computeHash(digest);
-
-        if (isAllowedByAllWithHash<&CSPDirectiveList::allowScriptHash>(m_policies, SourceHashValue(HashAlgorithmsSha1, Vector<uint8_t>(digest))))
-            return true;
-    }
-
-    return false;
-}
-
-bool ContentSecurityPolicy::allowStyleHash(const String& source) const
-{
-    if (HashAlgorithmsSha1 & m_styleHashAlgorithmsUsed) {
-        Vector<uint8_t, 20> digest;
-        SHA1 sourceSha1;
-        sourceSha1.addBytes(UTF8Encoding().normalizeAndEncode(source, WTF::EntitiesForUnencodables));
-        sourceSha1.computeHash(digest);
-
-        if (isAllowedByAllWithHash<&CSPDirectiveList::allowStyleHash>(m_policies, SourceHashValue(HashAlgorithmsSha1, Vector<uint8_t>(digest))))
-            return true;
-    }
-
-    return false;
-}
-
-void ContentSecurityPolicy::usesScriptHashAlgorithms(uint8_t algorithms)
-{
-    m_scriptHashAlgorithmsUsed |= algorithms;
-}
-
-void ContentSecurityPolicy::usesStyleHashAlgorithms(uint8_t algorithms)
-{
-    m_styleHashAlgorithmsUsed |= algorithms;
-}
-
-bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowAncestors(Frame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(m_policies, frame, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    return isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::allowWorkerContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
-{
-    // CSP 1.1 moves workers from 'script-src' to the new 'child-src'. Measure the impact of this backwards-incompatible change.
-    if (m_client->isDocument()) {
-        Document* document = static_cast<Document*>(m_client);
-        UseCounter::count(*document, UseCounter::WorkerSubjectToCSP);
-        if (isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, SuppressReport) && !isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, SuppressReport))
-            UseCounter::count(*document, UseCounter::WorkerAllowedByChildBlockedByScript);
-    }
-
-    return experimentalFeaturesEnabled() ?
-        isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, reportingStatus) :
-        isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
-}
-
-bool ContentSecurityPolicy::isActive() const
-{
-    return !m_policies.isEmpty();
-}
-
-ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const
-{
-    ReflectedXSSDisposition disposition = ReflectedXSSUnset;
-    for (size_t i = 0; i < m_policies.size(); ++i) {
-        if (m_policies[i]->reflectedXSSDisposition() > disposition)
-            disposition = std::max(disposition, m_policies[i]->reflectedXSSDisposition());
-    }
-    return disposition;
-}
-
-ReferrerPolicy ContentSecurityPolicy::referrerPolicy() const
-{
-    ReferrerPolicy policy = ReferrerPolicyDefault;
-    bool first = true;
-    for (size_t i = 0; i < m_policies.size(); ++i) {
-        if (m_policies[i]->didSetReferrerPolicy()) {
-            if (first)
-                policy = m_policies[i]->referrerPolicy();
-            else
-                policy = mergeReferrerPolicies(policy, m_policies[i]->referrerPolicy());
-        }
-    }
-    return policy;
-}
-
-bool ContentSecurityPolicy::didSetReferrerPolicy() const
-{
-    for (size_t i = 0; i < m_policies.size(); ++i) {
-        if (m_policies[i]->didSetReferrerPolicy())
-            return true;
-    }
-    return false;
-}
-
-SecurityOrigin* ContentSecurityPolicy::securityOrigin() const
-{
-    return m_client->securityContext().securityOrigin();
-}
-
-const KURL ContentSecurityPolicy::url() const
-{
-    return m_client->contextURL();
-}
-
-KURL ContentSecurityPolicy::completeURL(const String& url) const
-{
-    return m_client->contextCompleteURL(url);
-}
-
-void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const
-{
-    if (Document* document = this->document())
-        document->enforceSandboxFlags(mask);
-}
-
-static String stripURLForUseInReport(Document* document, const KURL& url)
-{
-    if (!url.isValid())
-        return String();
-    if (!url.isHierarchical() || url.protocolIs("file"))
-        return url.protocol();
-    return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsReferrer() : SecurityOrigin::create(url)->toString();
-}
-
-static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventInit& init, Document* document, const String& directiveText, const String& effectiveDirective, const KURL& blockedURL, const String& header)
-{
-    init.documentURI = document->url().string();
-    init.referrer = document->referrer();
-    init.blockedURI = stripURLForUseInReport(document, blockedURL);
-    init.violatedDirective = directiveText;
-    init.effectiveDirective = effectiveDirective;
-    init.originalPolicy = header;
-    init.sourceFile = String();
-    init.lineNumber = 0;
-    init.columnNumber = 0;
-    init.statusCode = 0;
-
-    if (!SecurityOrigin::isSecure(document->url()) && document->loader())
-        init.statusCode = document->loader()->response().httpStatusCode();
-
-    RefPtr<ScriptCallStack> stack = createScriptCallStack(1, false);
-    if (!stack)
-        return;
-
-    const ScriptCallFrame& callFrame = stack->at(0);
-
-    if (callFrame.lineNumber()) {
-        KURL source = KURL(ParsedURLString, callFrame.sourceURL());
-        init.sourceFile = stripURLForUseInReport(document, source);
-        init.lineNumber = callFrame.lineNumber();
-        init.columnNumber = callFrame.columnNumber();
-    }
-}
-
-void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header)
-{
-    // FIXME: Support sending reports from worker.
-    if (!m_client->isDocument())
-        return;
-
-    Document* document = this->document();
-    Frame* frame = document->frame();
-    if (!frame)
-        return;
-
-    SecurityPolicyViolationEventInit violationData;
-    gatherSecurityPolicyViolationEventData(violationData, document, directiveText, effectiveDirective, blockedURL, header);
-
-    if (experimentalFeaturesEnabled())
-        frame->domWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(EventTypeNames::securitypolicyviolation, violationData));
-
-    if (reportURIs.isEmpty())
-        return;
-
-    // We need to be careful here when deciding what information to send to the
-    // report-uri. Currently, we send only the current document's URL and the
-    // directive that was violated. The document's URL is safe to send because
-    // it's the document itself that's requesting that it be sent. You could
-    // make an argument that we shouldn't send HTTPS document URLs to HTTP
-    // report-uris (for the same reasons that we supress the Referer in that
-    // case), but the Referer is sent implicitly whereas this request is only
-    // sent explicitly. As for which directive was violated, that's pretty
-    // harmless information.
-
-    RefPtr<JSONObject> cspReport = JSONObject::create();
-    cspReport->setString("document-uri", violationData.documentURI);
-    cspReport->setString("referrer", violationData.referrer);
-    cspReport->setString("violated-directive", violationData.violatedDirective);
-    if (experimentalFeaturesEnabled())
-        cspReport->setString("effective-directive", violationData.effectiveDirective);
-    cspReport->setString("original-policy", violationData.originalPolicy);
-    cspReport->setString("blocked-uri", violationData.blockedURI);
-    if (!violationData.sourceFile.isEmpty() && violationData.lineNumber) {
-        cspReport->setString("source-file", violationData.sourceFile);
-        cspReport->setNumber("line-number", violationData.lineNumber);
-        cspReport->setNumber("column-number", violationData.columnNumber);
-    }
-    cspReport->setNumber("status-code", violationData.statusCode);
-
-    RefPtr<JSONObject> reportObject = JSONObject::create();
-    reportObject->setObject("csp-report", cspReport.release());
-    String stringifiedReport = reportObject->toJSONString();
-
-    if (!shouldSendViolationReport(stringifiedReport))
-        return;
-
-    RefPtr<FormData> report = FormData::create(stringifiedReport.utf8());
-
-    for (size_t i = 0; i < reportURIs.size(); ++i)
-        PingLoader::sendViolationReport(frame, reportURIs[i], report, PingLoader::ContentSecurityPolicyViolationReport);
-
-    didSendViolationReport(stringifiedReport);
-}
-
-void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) const
-{
-    logToConsole("The 'referrer' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"always\", \"default\", \"never\", and \"origin\".");
-}
-
-void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) const
-{
-    logToConsole("The report-only Content Security Policy '" + header + "' was delivered via a <meta> element, which is disallowed. The policy has been ignored.");
-}
-
-void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) const
-{
-    logToConsole("The Content Security Policy '" + header + "' was delivered via a <meta> element outside the document's <head>, which is disallowed. The policy has been ignored.");
-}
-
-void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) const
-{
-    logToConsole("The Content Security Policy directive '" + name + "' is ignored when delivered in a report-only policy.");
-}
-
-void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const
-{
-    DEFINE_STATIC_LOCAL(String, allow, ("allow"));
-    DEFINE_STATIC_LOCAL(String, options, ("options"));
-    DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri"));
-    DEFINE_STATIC_LOCAL(String, allowMessage, ("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect."));
-    DEFINE_STATIC_LOCAL(String, optionsMessage, ("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect."));
-    DEFINE_STATIC_LOCAL(String, policyURIMessage, ("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header."));
-
-    String message = "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
-    if (equalIgnoringCase(name, allow))
-        message = allowMessage;
-    else if (equalIgnoringCase(name, options))
-        message = optionsMessage;
-    else if (equalIgnoringCase(name, policyURI))
-        message = policyURIMessage;
-
-    logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const
-{
-    String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?";
-    logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const
-{
-    String message = "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
-    logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) const
-{
-    String message;
-    if (pluginType.isNull())
-        message = "'plugin-types' Content Security Policy directive is empty; all plugins will be blocked.\n";
-    else
-        message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n";
-    logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags) const
-{
-    logToConsole("Error while parsing the 'sandbox' Content Security Policy directive: " + invalidFlags);
-}
-
-void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue) const
-{
-    logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\".");
-}
-
-void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const
-{
-    String message = "The value for Content Security Policy directive '" + directiveName + "' contains an invalid character: '" + value + "'. Non-whitespace characters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.";
-    logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveName, const String& value, const char invalidChar) const
-{
-    ASSERT(invalidChar == '#' || invalidChar == '?');
-
-    String ignoring = "The fragment identifier, including the '#', will be ignored.";
-    if (invalidChar == '?')
-        ignoring = "The query component, including the '?', will be ignored.";
-    String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring;
-    logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const
-{
-    String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ignored.";
-    if (equalIgnoringCase(source, "'none'"))
-        message = message + " Note that 'none' has no effect unless it is the only expression in the source list.";
-    logToConsole(message);
-}
-
-void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const
-{
-    logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.");
-}
-
-void ContentSecurityPolicy::logToConsole(const String& message) const
-{
-    m_client->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
-}
-
-void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const
-{
-    m_client->reportBlockedScriptExecutionToInspector(directiveText);
-}
-
-bool ContentSecurityPolicy::experimentalFeaturesEnabled() const
-{
-    return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled();
-}
-
-bool ContentSecurityPolicy::shouldBypassMainWorld(ExecutionContext* context)
-{
-    if (context && context->isDocument()) {
-        Document* document = toDocument(context);
-        if (document->frame())
-            return document->frame()->script().shouldBypassMainWorldContentSecurityPolicy();
-    }
-    return false;
-}
-
-bool ContentSecurityPolicy::shouldSendViolationReport(const String& report) const
-{
-    // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
-    return !m_violationReportsSent.contains(report.impl()->hash());
-}
-
-void ContentSecurityPolicy::didSendViolationReport(const String& report)
-{
-    m_violationReportsSent.add(report.impl()->hash());
-}
-
-} // namespace WebCore
diff --git a/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp b/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp
deleted file mode 100644
index 0cd8808..0000000
--- a/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
-
-#include "platform/network/ResourceResponse.h"
-
-namespace WebCore {
-
-ContentSecurityPolicyResponseHeaders::ContentSecurityPolicyResponseHeaders(const ResourceResponse& response)
-    : m_contentSecurityPolicy(response.httpHeaderField("Content-Security-Policy"))
-    , m_contentSecurityPolicyReportOnly(response.httpHeaderField("Content-Security-Policy-Report-Only"))
-{
-}
-
-}
diff --git a/Source/core/frame/ContentSecurityPolicyResponseHeaders.h b/Source/core/frame/ContentSecurityPolicyResponseHeaders.h
deleted file mode 100644
index 404fb38..0000000
--- a/Source/core/frame/ContentSecurityPolicyResponseHeaders.h
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2013 Google, Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef ContentSecurityPolicyResponseHeaders_h
-#define ContentSecurityPolicyResponseHeaders_h
-
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-class ResourceResponse;
-
-class ContentSecurityPolicyResponseHeaders {
-public:
-    ContentSecurityPolicyResponseHeaders() { }
-    explicit ContentSecurityPolicyResponseHeaders(const ResourceResponse&);
-
-    const String& contentSecurityPolicy() const { return m_contentSecurityPolicy; }
-    const String& contentSecurityPolicyReportOnly() const { return m_contentSecurityPolicyReportOnly; }
-
-private:
-    String m_contentSecurityPolicy;
-    String m_contentSecurityPolicyReportOnly;
-};
-
-}
-
-#endif
diff --git a/Source/core/frame/DOMTimer.cpp b/Source/core/frame/DOMTimer.cpp
index a41845d..26a2133 100644
--- a/Source/core/frame/DOMTimer.cpp
+++ b/Source/core/frame/DOMTimer.cpp
@@ -94,9 +94,9 @@
     if (intervalMilliseconds < minimumInterval && m_nestingLevel >= maxTimerNestingLevel)
         intervalMilliseconds = minimumInterval;
     if (singleShot)
-        startOneShot(intervalMilliseconds);
+        startOneShot(intervalMilliseconds, FROM_HERE);
     else
-        startRepeating(intervalMilliseconds);
+        startRepeating(intervalMilliseconds, FROM_HERE);
 }
 
 DOMTimer::~DOMTimer()
diff --git a/Source/core/frame/DOMWindow.cpp b/Source/core/frame/DOMWindow.cpp
index abf4901..f6b928f 100644
--- a/Source/core/frame/DOMWindow.cpp
+++ b/Source/core/frame/DOMWindow.cpp
@@ -60,10 +60,10 @@
 #include "core/frame/Console.h"
 #include "core/frame/DOMPoint.h"
 #include "core/frame/DOMWindowLifecycleNotifier.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/History.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Location.h"
 #include "core/frame/Navigator.h"
 #include "core/frame/PageConsole.h"
@@ -85,7 +85,6 @@
 #include "core/page/EventHandler.h"
 #include "core/page/FrameTree.h"
 #include "core/page/Page.h"
-#include "core/page/PageGroup.h"
 #include "core/page/WindowFeatures.h"
 #include "core/page/WindowFocusAllowedIndicator.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
@@ -111,10 +110,11 @@
 
 namespace WebCore {
 
-class PostMessageTimer FINAL : public TimerBase {
+class PostMessageTimer FINAL : public SuspendableTimer {
 public:
-    PostMessageTimer(DOMWindow* window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin, PassRefPtr<ScriptCallStack> stackTrace)
-        : m_window(window)
+    PostMessageTimer(DOMWindow& window, PassRefPtr<SerializedScriptValue> message, const String& sourceOrigin, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortChannelArray> channels, SecurityOrigin* targetOrigin, PassRefPtr<ScriptCallStack> stackTrace)
+        : SuspendableTimer(window.document())
+        , m_window(window)
         , m_message(message)
         , m_origin(sourceOrigin)
         , m_source(source)
@@ -235,7 +235,7 @@
 static bool allowsBeforeUnloadListeners(DOMWindow* window)
 {
     ASSERT_ARG(window, window);
-    Frame* frame = window->frame();
+    LocalFrame* frame = window->frame();
     if (!frame)
         return false;
     return frame->isMainFrame();
@@ -252,13 +252,12 @@
 // 3) Constrains the window rect to within the top and left boundaries of the available screen rect.
 // 4) Constrains the window rect to within the bottom and right boundaries of the available screen rect.
 // 5) Translate the window rect coordinates to be within the coordinate space of the screen.
-FloatRect DOMWindow::adjustWindowRect(Frame* frame, const FloatRect& pendingChanges)
+FloatRect DOMWindow::adjustWindowRect(LocalFrame& frame, const FloatRect& pendingChanges)
 {
-    ASSERT(frame);
-    FrameHost* host = frame->host();
+    FrameHost* host = frame.host();
     ASSERT(host);
 
-    FloatRect screen = screenAvailableRect(frame->view());
+    FloatRect screen = screenAvailableRect(frame.view());
     FloatRect window = host->chrome().windowRect();
 
     // Make sure we're in a valid state before adjusting dimensions.
@@ -295,23 +294,21 @@
     return window;
 }
 
-bool DOMWindow::allowPopUp(Frame* firstFrame)
+bool DOMWindow::allowPopUp(LocalFrame& firstFrame)
 {
-    ASSERT(firstFrame);
-
     if (UserGestureIndicator::processingUserGesture())
         return true;
 
-    Settings* settings = firstFrame->settings();
+    Settings* settings = firstFrame.settings();
     return settings && settings->javaScriptCanOpenWindowsAutomatically();
 }
 
 bool DOMWindow::allowPopUp()
 {
-    return m_frame && allowPopUp(m_frame);
+    return m_frame && allowPopUp(*m_frame);
 }
 
-bool DOMWindow::canShowModalDialog(const Frame* frame)
+bool DOMWindow::canShowModalDialog(const LocalFrame* frame)
 {
     if (!frame)
         return false;
@@ -321,7 +318,7 @@
     return host->chrome().canRunModal();
 }
 
-bool DOMWindow::canShowModalDialogNow(const Frame* frame)
+bool DOMWindow::canShowModalDialogNow(const LocalFrame* frame)
 {
     if (!frame)
         return false;
@@ -331,11 +328,10 @@
     return host->chrome().canRunModalNow();
 }
 
-DOMWindow::DOMWindow(Frame* frame)
-    : FrameDestructionObserver(frame)
+DOMWindow::DOMWindow(LocalFrame& frame)
+    : FrameDestructionObserver(&frame)
     , m_shouldPrintWhenFinishedLoading(false)
 {
-    ASSERT(frame);
     ScriptWrappable::init(this);
 }
 
@@ -358,7 +354,7 @@
     clearEventQueue();
 
     m_document->clearDOMWindow();
-    m_document = 0;
+    m_document = nullptr;
 }
 
 void DOMWindow::clearEventQueue()
@@ -471,7 +467,7 @@
         return;
 
     // FIXME: https://bugs.webkit.org/show_bug.cgi?id=36202 Popstate event needs to fire asynchronously
-    dispatchEvent(PopStateEvent::create(stateObject, history()));
+    dispatchEvent(PopStateEvent::create(stateObject, &history()));
 }
 
 void DOMWindow::statePopped(PassRefPtr<SerializedScriptValue> stateObject)
@@ -529,9 +525,9 @@
     return this;
 }
 
-PassRefPtr<MediaQueryList> DOMWindow::matchMedia(const String& media)
+PassRefPtrWillBeRawPtr<MediaQueryList> DOMWindow::matchMedia(const String& media)
 {
-    return document() ? document()->mediaQueryMatcher().matchMedia(media) : 0;
+    return document() ? document()->mediaQueryMatcher().matchMedia(media) : nullptr;
 }
 
 Page* DOMWindow::page()
@@ -590,124 +586,108 @@
 {
     m_properties.clear();
 
-    m_screen = 0;
-    m_history = 0;
-    m_locationbar = 0;
-    m_menubar = 0;
-    m_personalbar = 0;
-    m_scrollbars = 0;
-    m_statusbar = 0;
-    m_toolbar = 0;
-    m_console = 0;
-    m_navigator = 0;
-    m_performance = 0;
-    m_location = 0;
-    m_media = 0;
-    m_sessionStorage = 0;
-    m_localStorage = 0;
-    m_applicationCache = 0;
+    m_screen = nullptr;
+    m_history = nullptr;
+    m_locationbar = nullptr;
+    m_menubar = nullptr;
+    m_personalbar = nullptr;
+    m_scrollbars = nullptr;
+    m_statusbar = nullptr;
+    m_toolbar = nullptr;
+    m_console = nullptr;
+    m_navigator = nullptr;
+    m_performance = nullptr;
+    m_location = nullptr;
+    m_media = nullptr;
+    m_sessionStorage = nullptr;
+    m_localStorage = nullptr;
+    m_applicationCache = nullptr;
 }
 
 bool DOMWindow::isCurrentlyDisplayedInFrame() const
 {
-    return m_frame && m_frame->domWindow() == this;
+    return m_frame && m_frame->domWindow() == this && m_frame->host();
 }
 
 int DOMWindow::orientation() const
 {
     ASSERT(RuntimeEnabledFeatures::orientationEventEnabled());
 
+    UseCounter::count(document(), UseCounter::WindowOrientation);
+
     if (!m_frame)
         return 0;
 
     return m_frame->orientation();
 }
 
-Screen* DOMWindow::screen() const
+Screen& DOMWindow::screen() const
 {
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_screen)
         m_screen = Screen::create(m_frame);
-    return m_screen.get();
+    return *m_screen;
 }
 
-History* DOMWindow::history() const
+History& DOMWindow::history() const
 {
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_history)
         m_history = History::create(m_frame);
-    return m_history.get();
+    return *m_history;
 }
 
-BarProp* DOMWindow::locationbar() const
+BarProp& DOMWindow::locationbar() const
 {
     UseCounter::count(document(), UseCounter::BarPropLocationbar);
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_locationbar)
         m_locationbar = BarProp::create(m_frame, BarProp::Locationbar);
-    return m_locationbar.get();
+    return *m_locationbar;
 }
 
-BarProp* DOMWindow::menubar() const
+BarProp& DOMWindow::menubar() const
 {
     UseCounter::count(document(), UseCounter::BarPropMenubar);
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_menubar)
         m_menubar = BarProp::create(m_frame, BarProp::Menubar);
-    return m_menubar.get();
+    return *m_menubar;
 }
 
-BarProp* DOMWindow::personalbar() const
+BarProp& DOMWindow::personalbar() const
 {
     UseCounter::count(document(), UseCounter::BarPropPersonalbar);
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_personalbar)
         m_personalbar = BarProp::create(m_frame, BarProp::Personalbar);
-    return m_personalbar.get();
+    return *m_personalbar;
 }
 
-BarProp* DOMWindow::scrollbars() const
+BarProp& DOMWindow::scrollbars() const
 {
     UseCounter::count(document(), UseCounter::BarPropScrollbars);
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_scrollbars)
         m_scrollbars = BarProp::create(m_frame, BarProp::Scrollbars);
-    return m_scrollbars.get();
+    return *m_scrollbars;
 }
 
-BarProp* DOMWindow::statusbar() const
+BarProp& DOMWindow::statusbar() const
 {
     UseCounter::count(document(), UseCounter::BarPropStatusbar);
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_statusbar)
         m_statusbar = BarProp::create(m_frame, BarProp::Statusbar);
-    return m_statusbar.get();
+    return *m_statusbar;
 }
 
-BarProp* DOMWindow::toolbar() const
+BarProp& DOMWindow::toolbar() const
 {
     UseCounter::count(document(), UseCounter::BarPropToolbar);
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_toolbar)
         m_toolbar = BarProp::create(m_frame, BarProp::Toolbar);
-    return m_toolbar.get();
+    return *m_toolbar;
 }
 
-Console* DOMWindow::console() const
+Console& DOMWindow::console() const
 {
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_console)
         m_console = Console::create(m_frame);
-    return m_console.get();
+    return *m_console;
 }
 
 PageConsole* DOMWindow::pageConsole() const
@@ -726,31 +706,25 @@
     return m_applicationCache.get();
 }
 
-Navigator* DOMWindow::navigator() const
+Navigator& DOMWindow::navigator() const
 {
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_navigator)
         m_navigator = Navigator::create(m_frame);
-    return m_navigator.get();
+    return *m_navigator;
 }
 
-Performance* DOMWindow::performance() const
+Performance& DOMWindow::performance() const
 {
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_performance)
         m_performance = Performance::create(m_frame);
-    return m_performance.get();
+    return *m_performance;
 }
 
-Location* DOMWindow::location() const
+Location& DOMWindow::location() const
 {
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_location)
         m_location = Location::create(m_frame);
-    return m_location.get();
+    return *m_location;
 }
 
 Storage* DOMWindow::sessionStorage(ExceptionState& exceptionState) const
@@ -878,18 +852,16 @@
         stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
 
     // Schedule the message.
-    PostMessageTimer* timer = new PostMessageTimer(this, message, sourceOrigin, source, channels.release(), target.get(), stackTrace.release());
-    timer->startOneShot(0);
+    PostMessageTimer* timer = new PostMessageTimer(*this, message, sourceOrigin, source, channels.release(), target.get(), stackTrace.release());
+    timer->startOneShot(0, FROM_HERE);
+    timer->suspendIfNeeded();
 }
 
 void DOMWindow::postMessageTimerFired(PassOwnPtr<PostMessageTimer> t)
 {
     OwnPtr<PostMessageTimer> timer(t);
 
-    // FIXME: The frame()->host() check really does not belong here. We should
-    // move it up into isCurrentlyDisplayedInFrame(); however, doing so breaks a
-    // number of window properties like window.toolbar.
-    if (!isCurrentlyDisplayedInFrame() || !frame()->host())
+    if (!isCurrentlyDisplayedInFrame())
         return;
 
     RefPtr<MessageEvent> event = timer->event();
@@ -1075,7 +1047,7 @@
 
     // |m_frame| can be destructed during |Editor::findString()| via
     // |Document::updateLayou()|, e.g. event handler removes a frame.
-    RefPtr<Frame> protectFrame(m_frame);
+    RefPtr<LocalFrame> protectFrame(m_frame);
 
     // FIXME (13016): Support wholeWord, searchInFrames and showDialog
     return m_frame->editor().findString(string, !backwards, caseSensitive, wrap, false);
@@ -1124,10 +1096,10 @@
         return 0;
 
     // FIXME: This is potentially too much work. We really only need to know the dimensions of the parent frame's renderer.
-    if (Frame* parent = m_frame->tree().parent())
+    if (LocalFrame* parent = m_frame->tree().parent())
         parent->document()->updateLayoutIgnorePendingStylesheets();
 
-    return adjustForAbsoluteZoom(view->visibleContentRect(ScrollableArea::IncludeScrollbars).height(), m_frame->pageZoomFactor());
+    return adjustForAbsoluteZoom(view->visibleContentRect(IncludeScrollbars).height(), m_frame->pageZoomFactor());
 }
 
 int DOMWindow::innerWidth() const
@@ -1140,10 +1112,10 @@
         return 0;
 
     // FIXME: This is potentially too much work. We really only need to know the dimensions of the parent frame's renderer.
-    if (Frame* parent = m_frame->tree().parent())
+    if (LocalFrame* parent = m_frame->tree().parent())
         parent->document()->updateLayoutIgnorePendingStylesheets();
 
-    return adjustForAbsoluteZoom(view->visibleContentRect(ScrollableArea::IncludeScrollbars).width(), m_frame->pageZoomFactor());
+    return adjustForAbsoluteZoom(view->visibleContentRect(IncludeScrollbars).width(), m_frame->pageZoomFactor());
 }
 
 int DOMWindow::screenX() const
@@ -1275,7 +1247,7 @@
     if (!m_frame)
         return 0;
 
-    Frame* opener = m_frame->loader().opener();
+    LocalFrame* opener = m_frame->loader().opener();
     if (!opener)
         return 0;
 
@@ -1287,7 +1259,7 @@
     if (!m_frame)
         return 0;
 
-    Frame* parent = m_frame->tree().parent();
+    LocalFrame* parent = m_frame->tree().parent();
     if (parent)
         return parent->domWindow();
 
@@ -1311,36 +1283,34 @@
     return m_document.get();
 }
 
-PassRefPtr<StyleMedia> DOMWindow::styleMedia() const
+StyleMedia& DOMWindow::styleMedia() const
 {
-    if (!isCurrentlyDisplayedInFrame())
-        return 0;
     if (!m_media)
         m_media = StyleMedia::create(m_frame);
-    return m_media.get();
+    return *m_media;
 }
 
 PassRefPtr<CSSStyleDeclaration> DOMWindow::getComputedStyle(Element* elt, const String& pseudoElt) const
 {
     if (!elt)
-        return 0;
+        return nullptr;
 
     return CSSComputedStyleDeclaration::create(elt, false, pseudoElt);
 }
 
-PassRefPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const String& pseudoElement) const
+PassRefPtrWillBeRawPtr<CSSRuleList> DOMWindow::getMatchedCSSRules(Element* element, const String& pseudoElement) const
 {
     UseCounter::count(document(), UseCounter::GetMatchedCSSRules);
     if (!element)
-        return 0;
+        return nullptr;
 
     if (!isCurrentlyDisplayedInFrame())
-        return 0;
+        return nullptr;
 
     unsigned colonStart = pseudoElement[0] == ':' ? (pseudoElement[1] == ':' ? 2 : 1) : 0;
     CSSSelector::PseudoType pseudoType = CSSSelector::parsePseudoType(AtomicString(pseudoElement.substring(colonStart)));
     if (pseudoType == CSSSelector::PseudoUnknown && !pseudoElement.isEmpty())
-        return 0;
+        return nullptr;
 
     unsigned rulesToInclude = StyleResolver::AuthorCSSRules;
     PseudoId pseudoId = CSSSelector::pseudoId(pseudoType);
@@ -1350,10 +1320,10 @@
 PassRefPtr<DOMPoint> DOMWindow::webkitConvertPointFromNodeToPage(Node* node, const DOMPoint* p) const
 {
     if (!node || !p)
-        return 0;
+        return nullptr;
 
     if (!document())
-        return 0;
+        return nullptr;
 
     document()->updateLayoutIgnorePendingStylesheets();
 
@@ -1365,10 +1335,10 @@
 PassRefPtr<DOMPoint> DOMWindow::webkitConvertPointFromPageToNode(Node* node, const DOMPoint* p) const
 {
     if (!node || !p)
-        return 0;
+        return nullptr;
 
     if (!document())
-        return 0;
+        return nullptr;
 
     document()->updateLayoutIgnorePendingStylesheets();
 
@@ -1452,7 +1422,7 @@
     FloatRect windowRect = host->chrome().windowRect();
     windowRect.move(x, y);
     // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
-    host->chrome().setWindowRect(adjustWindowRect(m_frame, windowRect));
+    host->chrome().setWindowRect(adjustWindowRect(*m_frame, windowRect));
 }
 
 void DOMWindow::moveTo(float x, float y) const
@@ -1467,7 +1437,7 @@
     FloatRect windowRect = host->chrome().windowRect();
     windowRect.setLocation(FloatPoint(x, y));
     // Security check (the spec talks about UniversalBrowserWrite to disable this check...)
-    host->chrome().setWindowRect(adjustWindowRect(m_frame, windowRect));
+    host->chrome().setWindowRect(adjustWindowRect(*m_frame, windowRect));
 }
 
 void DOMWindow::resizeBy(float x, float y) const
@@ -1482,7 +1452,7 @@
     FloatRect fr = host->chrome().windowRect();
     FloatSize dest = fr.size() + FloatSize(x, y);
     FloatRect update(fr.location(), dest);
-    host->chrome().setWindowRect(adjustWindowRect(m_frame, update));
+    host->chrome().setWindowRect(adjustWindowRect(*m_frame, update));
 }
 
 void DOMWindow::resizeTo(float width, float height) const
@@ -1497,7 +1467,7 @@
     FloatRect fr = host->chrome().windowRect();
     FloatSize dest = FloatSize(width, height);
     FloatRect update(fr.location(), dest);
-    host->chrome().setWindowRect(adjustWindowRect(m_frame, update));
+    host->chrome().setWindowRect(adjustWindowRect(*m_frame, update));
 }
 
 int DOMWindow::requestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback> callback)
@@ -1522,11 +1492,11 @@
         d->cancelAnimationFrame(id);
 }
 
-DOMWindowCSS* DOMWindow::css()
+DOMWindowCSS& DOMWindow::css() const
 {
     if (!m_css)
         m_css = DOMWindowCSS::create();
-    return m_css.get();
+    return *m_css;
 }
 
 static void didAddStorageEventListener(DOMWindow* window)
@@ -1659,19 +1629,19 @@
     }
 }
 
-void DOMWindow::setLocation(const String& urlString, DOMWindow* activeWindow, DOMWindow* firstWindow, SetLocationLocking locking)
+void DOMWindow::setLocation(const String& urlString, DOMWindow* callingWindow, DOMWindow* enteredWindow, SetLocationLocking locking)
 {
     if (!isCurrentlyDisplayedInFrame())
         return;
 
-    Document* activeDocument = activeWindow->document();
+    Document* activeDocument = callingWindow->document();
     if (!activeDocument)
         return;
 
     if (!activeDocument->canNavigate(m_frame))
         return;
 
-    Frame* firstFrame = firstWindow->frame();
+    LocalFrame* firstFrame = enteredWindow->frame();
     if (!firstFrame)
         return;
 
@@ -1679,7 +1649,7 @@
     if (completedURL.isNull())
         return;
 
-    if (isInsecureScriptAccess(activeWindow, completedURL))
+    if (isInsecureScriptAccess(*callingWindow, completedURL))
         return;
 
     // We want a new history item if we are processing a user gesture.
@@ -1702,18 +1672,18 @@
 // exactly which details may be exposed to JavaScript.
 //
 // http://crbug.com/17325
-String DOMWindow::sanitizedCrossDomainAccessErrorMessage(DOMWindow* activeWindow)
+String DOMWindow::sanitizedCrossDomainAccessErrorMessage(DOMWindow* callingWindow)
 {
-    if (!activeWindow || !activeWindow->document())
+    if (!callingWindow || !callingWindow->document())
         return String();
 
-    const KURL& activeWindowURL = activeWindow->document()->url();
-    if (activeWindowURL.isNull())
+    const KURL& callingWindowURL = callingWindow->document()->url();
+    if (callingWindowURL.isNull())
         return String();
 
-    ASSERT(!activeWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
+    ASSERT(!callingWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
 
-    SecurityOrigin* activeOrigin = activeWindow->document()->securityOrigin();
+    SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
     String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a cross-origin frame.";
 
     // FIXME: Evaluate which details from 'crossDomainAccessErrorMessage' may safely be reported to JavaScript.
@@ -1721,28 +1691,28 @@
     return message;
 }
 
-String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* activeWindow)
+String DOMWindow::crossDomainAccessErrorMessage(DOMWindow* callingWindow)
 {
-    if (!activeWindow || !activeWindow->document())
+    if (!callingWindow || !callingWindow->document())
         return String();
 
-    const KURL& activeWindowURL = activeWindow->document()->url();
-    if (activeWindowURL.isNull())
+    const KURL& callingWindowURL = callingWindow->document()->url();
+    if (callingWindowURL.isNull())
         return String();
 
-    ASSERT(!activeWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
+    ASSERT(!callingWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()));
 
     // FIXME: This message, and other console messages, have extra newlines. Should remove them.
-    SecurityOrigin* activeOrigin = activeWindow->document()->securityOrigin();
+    SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin();
     SecurityOrigin* targetOrigin = document()->securityOrigin();
     String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a frame with origin \"" + targetOrigin->toString() + "\". ";
 
     // Sandbox errors: Use the origin of the frames' location, rather than their actual origin (since we know that at least one will be "null").
-    KURL activeURL = activeWindow->document()->url();
+    KURL activeURL = callingWindow->document()->url();
     KURL targetURL = document()->url();
-    if (document()->isSandboxed(SandboxOrigin) || activeWindow->document()->isSandboxed(SandboxOrigin)) {
+    if (document()->isSandboxed(SandboxOrigin) || callingWindow->document()->isSandboxed(SandboxOrigin)) {
         message = "Blocked a frame at \"" + SecurityOrigin::create(activeURL)->toString() + "\" from accessing a frame at \"" + SecurityOrigin::create(targetURL)->toString() + "\". ";
-        if (document()->isSandboxed(SandboxOrigin) && activeWindow->document()->isSandboxed(SandboxOrigin))
+        if (document()->isSandboxed(SandboxOrigin) && callingWindow->document()->isSandboxed(SandboxOrigin))
             return "Sandbox access violation: " + message + " Both frames are sandboxed and lack the \"allow-same-origin\" flag.";
         if (document()->isSandboxed(SandboxOrigin))
             return "Sandbox access violation: " + message + " The frame being accessed is sandboxed and lacks the \"allow-same-origin\" flag.";
@@ -1765,67 +1735,67 @@
     return message + "Protocols, domains, and ports must match.";
 }
 
-bool DOMWindow::isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString)
+bool DOMWindow::isInsecureScriptAccess(DOMWindow& callingWindow, const String& urlString)
 {
     if (!protocolIsJavaScript(urlString))
         return false;
 
-    // If this DOMWindow isn't currently active in the Frame, then there's no
+    // If this DOMWindow isn't currently active in the LocalFrame, then there's no
     // way we should allow the access.
     // FIXME: Remove this check if we're able to disconnect DOMWindow from
-    // Frame on navigation: https://bugs.webkit.org/show_bug.cgi?id=62054
+    // LocalFrame on navigation: https://bugs.webkit.org/show_bug.cgi?id=62054
     if (isCurrentlyDisplayedInFrame()) {
-        // FIXME: Is there some way to eliminate the need for a separate "activeWindow == this" check?
-        if (activeWindow == this)
+        // FIXME: Is there some way to eliminate the need for a separate "callingWindow == this" check?
+        if (&callingWindow == this)
             return false;
 
         // FIXME: The name canAccess seems to be a roundabout way to ask "can execute script".
         // Can we name the SecurityOrigin function better to make this more clear?
-        if (activeWindow->document()->securityOrigin()->canAccess(document()->securityOrigin()))
+        if (callingWindow.document()->securityOrigin()->canAccess(document()->securityOrigin()))
             return false;
     }
 
-    printErrorMessage(crossDomainAccessErrorMessage(activeWindow));
+    printErrorMessage(crossDomainAccessErrorMessage(&callingWindow));
     return true;
 }
 
 PassRefPtr<DOMWindow> DOMWindow::open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
-    DOMWindow* activeWindow, DOMWindow* firstWindow)
+    DOMWindow* callingWindow, DOMWindow* enteredWindow)
 {
     if (!isCurrentlyDisplayedInFrame())
-        return 0;
-    Document* activeDocument = activeWindow->document();
+        return nullptr;
+    Document* activeDocument = callingWindow->document();
     if (!activeDocument)
-        return 0;
-    Frame* firstFrame = firstWindow->frame();
+        return nullptr;
+    LocalFrame* firstFrame = enteredWindow->frame();
     if (!firstFrame)
-        return 0;
+        return nullptr;
 
-    if (!firstWindow->allowPopUp()) {
+    if (!enteredWindow->allowPopUp()) {
         // Because FrameTree::find() returns true for empty strings, we must check for empty frame names.
         // Otherwise, illegitimate window.open() calls with no name will pass right through the popup blocker.
         if (frameName.isEmpty() || !m_frame->tree().find(frameName))
-            return 0;
+            return nullptr;
     }
 
     // Get the target frame for the special cases of _top and _parent.
     // In those cases, we schedule a location change right now and return early.
-    Frame* targetFrame = 0;
+    LocalFrame* targetFrame = 0;
     if (frameName == "_top")
         targetFrame = m_frame->tree().top();
     else if (frameName == "_parent") {
-        if (Frame* parent = m_frame->tree().parent())
+        if (LocalFrame* parent = m_frame->tree().parent())
             targetFrame = parent;
         else
             targetFrame = m_frame;
     }
     if (targetFrame) {
         if (!activeDocument->canNavigate(targetFrame))
-            return 0;
+            return nullptr;
 
         KURL completedURL = firstFrame->document()->completeURL(urlString);
 
-        if (targetFrame->domWindow()->isInsecureScriptAccess(activeWindow, completedURL))
+        if (targetFrame->domWindow()->isInsecureScriptAccess(*callingWindow, completedURL))
             return targetFrame->domWindow();
 
         if (urlString.isEmpty())
@@ -1842,30 +1812,30 @@
     }
 
     WindowFeatures windowFeatures(windowFeaturesString);
-    Frame* result = createWindow(urlString, frameName, windowFeatures, activeWindow, firstFrame, m_frame);
+    LocalFrame* result = createWindow(urlString, frameName, windowFeatures, *callingWindow, *firstFrame, *m_frame);
     return result ? result->domWindow() : 0;
 }
 
 void DOMWindow::showModalDialog(const String& urlString, const String& dialogFeaturesString,
-    DOMWindow* activeWindow, DOMWindow* firstWindow, PrepareDialogFunction function, void* functionContext)
+    DOMWindow* callingWindow, DOMWindow* enteredWindow, PrepareDialogFunction function, void* functionContext)
 {
     if (!isCurrentlyDisplayedInFrame())
         return;
-    Frame* activeFrame = activeWindow->frame();
+    LocalFrame* activeFrame = callingWindow->frame();
     if (!activeFrame)
         return;
-    Frame* firstFrame = firstWindow->frame();
+    LocalFrame* firstFrame = enteredWindow->frame();
     if (!firstFrame)
         return;
 
-    if (!canShowModalDialogNow(m_frame) || !firstWindow->allowPopUp())
+    if (!canShowModalDialogNow(m_frame) || !enteredWindow->allowPopUp())
         return;
 
     UseCounter::countDeprecation(this, UseCounter::ShowModalDialog);
 
     WindowFeatures windowFeatures(dialogFeaturesString, screenAvailableRect(m_frame->view()));
-    Frame* dialogFrame = createWindow(urlString, emptyAtom, windowFeatures,
-        activeWindow, firstFrame, m_frame, function, functionContext);
+    LocalFrame* dialogFrame = createWindow(urlString, emptyAtom, windowFeatures,
+        *callingWindow, *firstFrame, *m_frame, function, functionContext);
     if (!dialogFrame)
         return;
     UserGestureIndicatorDisabler disabler;
@@ -1874,11 +1844,11 @@
 
 DOMWindow* DOMWindow::anonymousIndexedGetter(uint32_t index)
 {
-    Frame* frame = this->frame();
+    LocalFrame* frame = this->frame();
     if (!frame)
         return 0;
 
-    Frame* child = frame->tree().scopedChild(index);
+    LocalFrame* child = frame->tree().scopedChild(index);
     if (child)
         return child->domWindow();
 
diff --git a/Source/core/frame/DOMWindow.h b/Source/core/frame/DOMWindow.h
index b0a1580..37cea69 100644
--- a/Source/core/frame/DOMWindow.h
+++ b/Source/core/frame/DOMWindow.h
@@ -31,6 +31,7 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/events/EventTarget.h"
 #include "core/frame/FrameDestructionObserver.h"
+#include "heap/Handle.h"
 #include "platform/LifecycleContext.h"
 #include "platform/Supplementable.h"
 
@@ -57,7 +58,7 @@
     class EventQueue;
     class ExceptionState;
     class FloatRect;
-    class Frame;
+    class LocalFrame;
     class History;
     class IDBFactory;
     class Location;
@@ -94,7 +95,7 @@
         REFCOUNTED_EVENT_TARGET(DOMWindow);
     public:
         static PassRefPtr<Document> createDocument(const String& mimeType, const DocumentInit&, bool forceXHTML);
-        static PassRefPtr<DOMWindow> create(Frame* frame) { return adoptRef(new DOMWindow(frame)); }
+        static PassRefPtr<DOMWindow> create(LocalFrame& frame) { return adoptRef(new DOMWindow(frame)); }
         virtual ~DOMWindow();
 
         PassRefPtr<Document> installNewDocument(const String& mimeType, const DocumentInit&, bool forceXHTML = false);
@@ -109,32 +110,32 @@
 
         void reset();
 
-        PassRefPtr<MediaQueryList> matchMedia(const String&);
+        PassRefPtrWillBeRawPtr<MediaQueryList> matchMedia(const String&);
 
         unsigned pendingUnloadEventListeners() const;
 
-        static FloatRect adjustWindowRect(Frame*, const FloatRect& pendingChanges);
+        static FloatRect adjustWindowRect(LocalFrame&, const FloatRect& pendingChanges);
 
         bool allowPopUp(); // Call on first window, not target window.
-        static bool allowPopUp(Frame* firstFrame);
-        static bool canShowModalDialog(const Frame*);
-        static bool canShowModalDialogNow(const Frame*);
+        static bool allowPopUp(LocalFrame& firstFrame);
+        static bool canShowModalDialog(const LocalFrame*);
+        static bool canShowModalDialogNow(const LocalFrame*);
 
         // DOM Level 0
 
-        Screen* screen() const;
-        History* history() const;
-        BarProp* locationbar() const;
-        BarProp* menubar() const;
-        BarProp* personalbar() const;
-        BarProp* scrollbars() const;
-        BarProp* statusbar() const;
-        BarProp* toolbar() const;
-        Navigator* navigator() const;
-        Navigator* clientInformation() const { return navigator(); }
+        Screen& screen() const;
+        History& history() const;
+        BarProp& locationbar() const;
+        BarProp& menubar() const;
+        BarProp& personalbar() const;
+        BarProp& scrollbars() const;
+        BarProp& statusbar() const;
+        BarProp& toolbar() const;
+        Navigator& navigator() const;
+        Navigator& clientInformation() const { return navigator(); }
 
-        Location* location() const;
-        void setLocation(const String& location, DOMWindow* activeWindow, DOMWindow* firstWindow,
+        Location& location() const;
+        void setLocation(const String& location, DOMWindow* callingWindow, DOMWindow* enteredWindow,
             SetLocationLocking = LockHistoryBasedOnGestureState);
 
         DOMSelection* getSelection();
@@ -148,11 +149,11 @@
         void stop();
 
         PassRefPtr<DOMWindow> open(const String& urlString, const AtomicString& frameName, const String& windowFeaturesString,
-            DOMWindow* activeWindow, DOMWindow* firstWindow);
+            DOMWindow* callingWindow, DOMWindow* enteredWindow);
 
         typedef void (*PrepareDialogFunction)(DOMWindow*, void* context);
         void showModalDialog(const String& urlString, const String& dialogFeaturesString,
-            DOMWindow* activeWindow, DOMWindow* firstWindow, PrepareDialogFunction, void* functionContext);
+            DOMWindow* callingWindow, DOMWindow* enteredWindow, PrepareDialogFunction, void* functionContext);
 
         void alert(const String& message);
         bool confirm(const String& message);
@@ -203,7 +204,7 @@
 
         // CSSOM View Module
 
-        PassRefPtr<StyleMedia> styleMedia() const;
+        StyleMedia& styleMedia() const;
 
         // DOM Level 2 Style Interface
 
@@ -211,18 +212,18 @@
 
         // WebKit extensions
 
-        PassRefPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt) const;
+        PassRefPtrWillBeRawPtr<CSSRuleList> getMatchedCSSRules(Element*, const String& pseudoElt) const;
         double devicePixelRatio() const;
 
         PassRefPtr<DOMPoint> webkitConvertPointFromPageToNode(Node*, const DOMPoint*) const;
         PassRefPtr<DOMPoint> webkitConvertPointFromNodeToPage(Node*, const DOMPoint*) const;
 
-        Console* console() const;
+        Console& console() const;
         PageConsole* pageConsole() const;
 
         void printErrorMessage(const String&);
-        String crossDomainAccessErrorMessage(DOMWindow* activeWindow);
-        String sanitizedCrossDomainAccessErrorMessage(DOMWindow* activeWindow);
+        String crossDomainAccessErrorMessage(DOMWindow* callingWindow);
+        String sanitizedCrossDomainAccessErrorMessage(DOMWindow* callingWindow);
 
         void postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray*, const String& targetOrigin, DOMWindow* source, ExceptionState&);
         void postMessageTimerFired(PassOwnPtr<PostMessageTimer>);
@@ -243,7 +244,7 @@
         int webkitRequestAnimationFrame(PassOwnPtr<RequestAnimationFrameCallback>);
         void cancelAnimationFrame(int id);
 
-        DOMWindowCSS* css();
+        DOMWindowCSS& css() const;
 
         // Events
         // EventTarget API
@@ -273,9 +274,6 @@
 
         void finishedLoading();
 
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(devicemotion);
-        DEFINE_ATTRIBUTE_EVENT_LISTENER(deviceorientation);
-
         // HTML 5 key/value storage
         Storage* sessionStorage(ExceptionState&) const;
         Storage* localStorage(ExceptionState&) const;
@@ -296,7 +294,7 @@
         DEFINE_ATTRIBUTE_EVENT_LISTENER(touchend);
         DEFINE_ATTRIBUTE_EVENT_LISTENER(touchcancel);
 
-        Performance* performance() const;
+        Performance& performance() const;
 
         // FIXME: When this DOMWindow is no longer the active DOMWindow (i.e.,
         // when its document is no longer the document that is displayed in its
@@ -307,7 +305,7 @@
         void willDetachDocumentFromFrame();
         DOMWindow* anonymousIndexedGetter(uint32_t);
 
-        bool isInsecureScriptAccess(DOMWindow* activeWindow, const String& urlString);
+        bool isInsecureScriptAccess(DOMWindow& callingWindow, const String& urlString);
 
         PassOwnPtr<LifecycleNotifier<DOMWindow> > createLifecycleNotifier();
 
@@ -328,7 +326,7 @@
         DOMWindowLifecycleNotifier& lifecycleNotifier();
 
     private:
-        explicit DOMWindow(Frame*);
+        explicit DOMWindow(LocalFrame&);
 
         Page* page();
 
@@ -345,7 +343,7 @@
 
         HashSet<DOMWindowProperty*> m_properties;
 
-        mutable RefPtr<Screen> m_screen;
+        mutable RefPtrWillBePersistent<Screen> m_screen;
         mutable RefPtr<History> m_history;
         mutable RefPtr<BarProp> m_locationbar;
         mutable RefPtr<BarProp> m_menubar;
diff --git a/Source/core/frame/DOMWindowBase64.cpp b/Source/core/frame/DOMWindowBase64.cpp
index 2f43d50..a5ba636 100644
--- a/Source/core/frame/DOMWindowBase64.cpp
+++ b/Source/core/frame/DOMWindowBase64.cpp
@@ -42,7 +42,7 @@
 
 namespace DOMWindowBase64 {
 
-String btoa(void*, const String& stringToEncode, ExceptionState& exceptionState)
+String btoa(ScriptWrappable&, const String& stringToEncode, ExceptionState& exceptionState)
 {
     if (stringToEncode.isNull())
         return String();
@@ -55,7 +55,7 @@
     return base64Encode(stringToEncode.latin1());
 }
 
-String atob(void*, const String& encodedString, ExceptionState& exceptionState)
+String atob(ScriptWrappable&, const String& encodedString, ExceptionState& exceptionState)
 {
     if (encodedString.isNull())
         return String();
diff --git a/Source/core/frame/DOMWindowBase64.h b/Source/core/frame/DOMWindowBase64.h
index 21001e0..90b4746 100644
--- a/Source/core/frame/DOMWindowBase64.h
+++ b/Source/core/frame/DOMWindowBase64.h
@@ -38,10 +38,11 @@
 namespace WebCore {
 
 class ExceptionState;
+class ScriptWrappable;
 
 namespace DOMWindowBase64 {
-String btoa(void*, const String& stringToEncode, ExceptionState&);
-String atob(void*, const String& encodedString, ExceptionState&);
+String btoa(ScriptWrappable&, const String& stringToEncode, ExceptionState&);
+String atob(ScriptWrappable&, const String& encodedString, ExceptionState&);
 }
 
 } // namespace WebCore
diff --git a/Source/core/frame/DOMWindowProperty.cpp b/Source/core/frame/DOMWindowProperty.cpp
index 6649a2f..5f925fb 100644
--- a/Source/core/frame/DOMWindowProperty.cpp
+++ b/Source/core/frame/DOMWindowProperty.cpp
@@ -29,11 +29,11 @@
 
 #include "core/dom/Document.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
-DOMWindowProperty::DOMWindowProperty(Frame* frame)
+DOMWindowProperty::DOMWindowProperty(LocalFrame* frame)
     : m_frame(frame)
     , m_associatedDOMWindow(0)
 {
@@ -57,7 +57,7 @@
 
 void DOMWindowProperty::willDestroyGlobalObjectInFrame()
 {
-    // If the property is getting this callback it must have been created with a Frame/DOMWindow and it should still have them.
+    // If the property is getting this callback it must have been created with a LocalFrame/DOMWindow and it should still have them.
     ASSERT(m_frame);
     ASSERT(m_associatedDOMWindow);
 
@@ -71,7 +71,7 @@
 
 void DOMWindowProperty::willDetachGlobalObjectFromFrame()
 {
-    // If the property is getting this callback it must have been created with a Frame/DOMWindow and it should still have them.
+    // If the property is getting this callback it must have been created with a LocalFrame/DOMWindow and it should still have them.
     ASSERT(m_frame);
     ASSERT(m_associatedDOMWindow);
 }
diff --git a/Source/core/frame/DOMWindowProperty.h b/Source/core/frame/DOMWindowProperty.h
index 3a4645c..3281126 100644
--- a/Source/core/frame/DOMWindowProperty.h
+++ b/Source/core/frame/DOMWindowProperty.h
@@ -29,21 +29,21 @@
 namespace WebCore {
 
 class DOMWindow;
-class Frame;
+class LocalFrame;
 
 class DOMWindowProperty {
 public:
-    explicit DOMWindowProperty(Frame*);
+    explicit DOMWindowProperty(LocalFrame*);
 
     virtual void willDestroyGlobalObjectInFrame();
     virtual void willDetachGlobalObjectFromFrame();
 
-    Frame* frame() const { return m_frame; }
+    LocalFrame* frame() const { return m_frame; }
 
 protected:
     virtual ~DOMWindowProperty();
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
     DOMWindow* m_associatedDOMWindow;
 };
 
diff --git a/Source/core/frame/DOMWindowTimers.cpp b/Source/core/frame/DOMWindowTimers.cpp
index b0e082c..af3e06b 100644
--- a/Source/core/frame/DOMWindowTimers.cpp
+++ b/Source/core/frame/DOMWindowTimers.cpp
@@ -40,25 +40,25 @@
 
 namespace DOMWindowTimers {
 
-int setTimeout(EventTarget* eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
+int setTimeout(EventTarget& eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
 {
-    return DOMTimer::install(eventTarget->executionContext(), action, timeout, true);
+    return DOMTimer::install(eventTarget.executionContext(), action, timeout, true);
 }
 
-int setInterval(EventTarget* eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
+int setInterval(EventTarget& eventTarget, PassOwnPtr<ScheduledAction> action, int timeout)
 {
-    return DOMTimer::install(eventTarget->executionContext(), action, timeout, false);
+    return DOMTimer::install(eventTarget.executionContext(), action, timeout, false);
 }
 
-void clearTimeout(EventTarget* eventTarget, int timeoutID)
+void clearTimeout(EventTarget& eventTarget, int timeoutID)
 {
-    if (ExecutionContext* context = eventTarget->executionContext())
+    if (ExecutionContext* context = eventTarget.executionContext())
         DOMTimer::removeByID(context, timeoutID);
 }
 
-void clearInterval(EventTarget* eventTarget, int timeoutID)
+void clearInterval(EventTarget& eventTarget, int timeoutID)
 {
-    if (ExecutionContext* context = eventTarget->executionContext())
+    if (ExecutionContext* context = eventTarget.executionContext())
         DOMTimer::removeByID(context, timeoutID);
 }
 
diff --git a/Source/core/frame/DOMWindowTimers.h b/Source/core/frame/DOMWindowTimers.h
index 2a28f81..0465cf2 100644
--- a/Source/core/frame/DOMWindowTimers.h
+++ b/Source/core/frame/DOMWindowTimers.h
@@ -41,10 +41,10 @@
 class ScheduledAction;
 
 namespace DOMWindowTimers {
-int setTimeout(EventTarget*, PassOwnPtr<ScheduledAction>, int timeout);
-int setInterval(EventTarget*, PassOwnPtr<ScheduledAction>, int timeout);
-void clearTimeout(EventTarget*, int timeoutId);
-void clearInterval(EventTarget*, int timeoutId);
+int setTimeout(EventTarget&, PassOwnPtr<ScheduledAction>, int timeout);
+int setInterval(EventTarget&, PassOwnPtr<ScheduledAction>, int timeout);
+void clearTimeout(EventTarget&, int timeoutId);
+void clearInterval(EventTarget&, int timeoutId);
 }
 
 } // namespace WebCore
diff --git a/Source/core/frame/DeviceSensorEventController.cpp b/Source/core/frame/DeviceSensorEventController.cpp
new file mode 100644
index 0000000..b68944d
--- /dev/null
+++ b/Source/core/frame/DeviceSensorEventController.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2012 Samsung Electronics. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *  * Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *  * Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/DeviceSensorEventController.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/DOMWindow.h"
+#include "core/page/Page.h"
+
+namespace WebCore {
+
+DeviceSensorEventController::DeviceSensorEventController(Document& document)
+    : PageLifecycleObserver(document.page())
+    , m_hasEventListener(false)
+    , m_document(document)
+    , m_isActive(false)
+    , m_needsCheckingNullEvents(true)
+    , m_timer(this, &DeviceSensorEventController::fireDeviceEvent)
+{
+}
+
+DeviceSensorEventController::~DeviceSensorEventController()
+{
+}
+
+void DeviceSensorEventController::fireDeviceEvent(Timer<DeviceSensorEventController>* timer)
+{
+    ASSERT_UNUSED(timer, timer == &m_timer);
+    ASSERT(hasLastData());
+
+    m_timer.stop();
+    dispatchDeviceEvent(getLastEvent());
+}
+
+void DeviceSensorEventController::dispatchDeviceEvent(PassRefPtr<Event> prpEvent)
+{
+    RefPtr<Event> event = prpEvent;
+    if (m_document.domWindow()
+        && !m_document.activeDOMObjectsAreSuspended()
+        && !m_document.activeDOMObjectsAreStopped())
+        m_document.domWindow()->dispatchEvent(event);
+
+    if (m_needsCheckingNullEvents) {
+        if (isNullEvent(event.get()))
+            stopUpdating();
+        else
+            m_needsCheckingNullEvents = false;
+    }
+}
+
+void DeviceSensorEventController::startUpdating()
+{
+    if (m_isActive)
+        return;
+
+    if (hasLastData() && !m_timer.isActive()) {
+        // Make sure to fire the data as soon as possible.
+        m_timer.startOneShot(0, FROM_HERE);
+    }
+
+    registerWithDispatcher();
+    m_isActive = true;
+}
+
+void DeviceSensorEventController::stopUpdating()
+{
+    if (!m_isActive)
+        return;
+
+    if (m_timer.isActive())
+        m_timer.stop();
+
+    unregisterWithDispatcher();
+    m_isActive = false;
+}
+
+void DeviceSensorEventController::pageVisibilityChanged()
+{
+    if (!m_hasEventListener)
+        return;
+
+    if (page()->visibilityState() == PageVisibilityStateVisible)
+        startUpdating();
+    else
+        stopUpdating();
+}
+
+} // namespace WebCore
diff --git a/Source/core/frame/DeviceSensorEventController.h b/Source/core/frame/DeviceSensorEventController.h
new file mode 100644
index 0000000..0b0950c
--- /dev/null
+++ b/Source/core/frame/DeviceSensorEventController.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef DeviceSensorEventController_h
+#define DeviceSensorEventController_h
+
+#include "core/events/Event.h"
+#include "core/page/PageLifecycleObserver.h"
+#include "platform/Timer.h"
+
+namespace WebCore {
+
+class Document;
+
+class DeviceSensorEventController : public PageLifecycleObserver {
+
+public:
+    void startUpdating();
+    void stopUpdating();
+
+protected:
+    explicit DeviceSensorEventController(Document&);
+    virtual ~DeviceSensorEventController();
+
+    void dispatchDeviceEvent(const PassRefPtr<Event>);
+
+    virtual bool hasLastData() = 0;
+    virtual PassRefPtr<Event> getLastEvent() = 0;
+    virtual void registerWithDispatcher() = 0;
+    virtual void unregisterWithDispatcher() = 0;
+    virtual bool isNullEvent(Event*) = 0;
+
+    bool m_hasEventListener;
+
+private:
+    // Inherited from PageLifecycleObserver.
+    virtual void pageVisibilityChanged() OVERRIDE FINAL;
+
+    void fireDeviceEvent(Timer<DeviceSensorEventController>*);
+
+    Document& m_document;
+    bool m_isActive;
+    bool m_needsCheckingNullEvents;
+    Timer<DeviceSensorEventController> m_timer;
+};
+
+} // namespace WebCore
+
+#endif // DeviceSensorEventController_h
diff --git a/Source/core/frame/DeviceSensorEventDispatcher.cpp b/Source/core/frame/DeviceSensorEventDispatcher.cpp
new file mode 100644
index 0000000..a992f0a
--- /dev/null
+++ b/Source/core/frame/DeviceSensorEventDispatcher.cpp
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/DeviceSensorEventDispatcher.h"
+
+namespace WebCore {
+
+DeviceSensorEventDispatcher::DeviceSensorEventDispatcher()
+    : m_needsPurge(false)
+    , m_isDispatching(false)
+{
+}
+
+DeviceSensorEventDispatcher::~DeviceSensorEventDispatcher()
+{
+}
+
+void DeviceSensorEventDispatcher::addController(DeviceSensorEventController* controller)
+{
+    bool wasEmpty = m_controllers.isEmpty();
+    if (!m_controllers.contains(controller))
+        m_controllers.append(controller);
+    if (wasEmpty)
+        startListening();
+}
+
+void DeviceSensorEventDispatcher::removeController(DeviceSensorEventController* controller)
+{
+    // Do not actually remove the controller from the vector, instead zero them out.
+    // The zeros are removed in these two cases:
+    // 1. either immediately if we are not dispatching any events,
+    // 2. or after events to all controllers have dispatched
+    // (see e.g. DeviceOrientationDispatcher::didChangeDeviceOrientation).
+    // This is to correctly handle the re-entrancy case when a controller is destroyed
+    // while the events are still being dispatched.
+    size_t index = m_controllers.find(controller);
+    if (index == kNotFound)
+        return;
+
+    m_controllers[index] = 0;
+    m_needsPurge = true;
+
+    if (!m_isDispatching)
+        purgeControllers();
+}
+
+void DeviceSensorEventDispatcher::purgeControllers()
+{
+    ASSERT(m_needsPurge);
+
+    size_t i = 0;
+    while (i < m_controllers.size()) {
+        if (!m_controllers[i]) {
+            m_controllers[i] = m_controllers.last();
+            m_controllers.removeLast();
+        } else {
+            ++i;
+        }
+    }
+
+    m_needsPurge = false;
+
+    if (m_controllers.isEmpty())
+        stopListening();
+}
+
+} // namespace WebCore
diff --git a/Source/core/html/HTMLImportChildClient.h b/Source/core/frame/DeviceSensorEventDispatcher.h
similarity index 71%
copy from Source/core/html/HTMLImportChildClient.h
copy to Source/core/frame/DeviceSensorEventDispatcher.h
index be3177d..26c2695 100644
--- a/Source/core/html/HTMLImportChildClient.h
+++ b/Source/core/frame/DeviceSensorEventDispatcher.h
@@ -28,23 +28,31 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef HTMLImportChildClient_h
-#define HTMLImportChildClient_h
+#ifndef DeviceSensorEventDispatcher_h
+#define DeviceSensorEventDispatcher_h
+
+#include "wtf/Vector.h"
 
 namespace WebCore {
+class DeviceSensorEventController;
 
-class HTMLImportChild;
-class HTMLLinkElement;
+class DeviceSensorEventDispatcher {
+protected:
+    DeviceSensorEventDispatcher();
+    virtual ~DeviceSensorEventDispatcher();
 
-class HTMLImportChildClient {
-public:
-    virtual ~HTMLImportChildClient() { }
-    virtual void didFinish() = 0;
-    virtual void importChildWasDestroyed(HTMLImportChild*) = 0;
-    virtual bool isCreatedByParser() const = 0;
-    virtual HTMLLinkElement* link() = 0;
+    void addController(DeviceSensorEventController*);
+    void removeController(DeviceSensorEventController*);
+    void purgeControllers();
+
+    virtual void startListening() = 0;
+    virtual void stopListening() = 0;
+
+    Vector<DeviceSensorEventController*> m_controllers;
+    bool m_needsPurge;
+    bool m_isDispatching;
 };
 
 } // namespace WebCore
 
-#endif // HTMLImportChildClient_h
+#endif // DeviceSensorEventDispatcher_h
diff --git a/Source/core/frame/Frame.cpp b/Source/core/frame/Frame.cpp
index a39b74c..3502201 100644
--- a/Source/core/frame/Frame.cpp
+++ b/Source/core/frame/Frame.cpp
@@ -30,22 +30,11 @@
 #include "config.h"
 #include "core/frame/Frame.h"
 
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ScriptController.h"
 #include "core/dom/DocumentType.h"
-#include "core/dom/WheelController.h"
-#include "core/editing/Editor.h"
-#include "core/editing/FrameSelection.h"
-#include "core/editing/InputMethodController.h"
-#include "core/editing/SpellChecker.h"
-#include "core/editing/htmlediting.h"
-#include "core/editing/markup.h"
 #include "core/events/Event.h"
-#include "core/fetch/ResourceFetcher.h"
 #include "core/frame/DOMWindow.h"
 #include "core/frame/FrameDestructionObserver.h"
 #include "core/frame/FrameHost.h"
-#include "core/frame/FrameView.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/inspector/InspectorInstrumentation.h"
@@ -56,89 +45,45 @@
 #include "core/page/EventHandler.h"
 #include "core/page/FocusController.h"
 #include "core/page/Page.h"
-#include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/HitTestResult.h"
-#include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
-#include "core/rendering/RenderPart.h"
 #include "core/rendering/RenderView.h"
-#include "core/svg/SVGDocument.h"
-#include "platform/DragImage.h"
-#include "platform/graphics/GraphicsContext.h"
-#include "platform/graphics/ImageBuffer.h"
 #include "public/platform/WebLayer.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/RefCountedLeakCounter.h"
-#include "wtf/StdLibExtras.h"
-
-using namespace std;
 
 namespace WebCore {
 
 using namespace HTMLNames;
 
+namespace {
+
+int64_t generateFrameID()
+{
+    // Initialize to the current time to reduce the likelihood of generating
+    // identifiers that overlap with those from past/future browser sessions.
+    static int64_t next = static_cast<int64_t>(currentTime() * 1000000.0);
+    return ++next;
+}
+
+} // namespace
+
 DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, frameCounter, ("Frame"));
 
-static inline float parentPageZoomFactor(Frame* frame)
-{
-    Frame* parent = frame->tree().parent();
-    if (!parent)
-        return 1;
-    return parent->pageZoomFactor();
-}
-
-static inline float parentTextZoomFactor(Frame* frame)
-{
-    Frame* parent = frame->tree().parent();
-    if (!parent)
-        return 1;
-    return parent->textZoomFactor();
-}
-
-inline Frame::Frame(PassRefPtr<FrameInit> frameInit)
-    : m_host(frameInit->frameHost())
-    , m_treeNode(this)
-    , m_loader(this, frameInit->frameLoaderClient())
-    , m_navigationScheduler(this)
-    , m_script(adoptPtr(new ScriptController(this)))
-    , m_editor(Editor::create(*this))
-    , m_spellChecker(SpellChecker::create(*this))
-    , m_selection(adoptPtr(new FrameSelection(this)))
-    , m_eventHandler(adoptPtr(new EventHandler(this)))
-    , m_inputMethodController(InputMethodController::create(*this))
-    , m_frameInit(frameInit)
-    , m_pageZoomFactor(parentPageZoomFactor(this))
-    , m_textZoomFactor(parentTextZoomFactor(this))
-    , m_orientation(0)
-    , m_inViewSourceMode(false)
+Frame::Frame(FrameHost* host, HTMLFrameOwnerElement* ownerElement)
+    : m_host(host)
+    , m_ownerElement(ownerElement)
+    , m_frameID(generateFrameID())
     , m_remotePlatformLayer(0)
 {
     ASSERT(page());
 
-    if (ownerElement()) {
-        page()->incrementSubframeCount();
-        ownerElement()->setContentFrame(*this);
-    }
-
 #ifndef NDEBUG
     frameCounter.increment();
 #endif
 }
 
-PassRefPtr<Frame> Frame::create(PassRefPtr<FrameInit> frameInit)
-{
-    RefPtr<Frame> frame = adoptRef(new Frame(frameInit));
-    if (!frame->ownerElement())
-        frame->page()->setMainFrame(frame);
-    InspectorInstrumentation::frameAttachedToParent(frame.get());
-    return frame.release();
-}
-
 Frame::~Frame()
 {
-    setView(0);
-    loader().clear();
-    setDOMWindow(0);
+    setDOMWindow(nullptr);
 
     // FIXME: We should not be doing all this work inside the destructor
 
@@ -146,25 +91,11 @@
     frameCounter.decrement();
 #endif
 
-    disconnectOwnerElement();
-
     HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
     for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
         (*it)->frameDestroyed();
 }
 
-bool Frame::inScope(TreeScope* scope) const
-{
-    ASSERT(scope);
-    Document* doc = document();
-    if (!doc)
-        return false;
-    HTMLFrameOwnerElement* owner = doc->ownerElement();
-    if (!owner)
-        return false;
-    return owner->treeScope() == scope;
-}
-
 void Frame::addDestructionObserver(FrameDestructionObserver* observer)
 {
     m_destructionObservers.add(observer);
@@ -175,40 +106,6 @@
     m_destructionObservers.remove(observer);
 }
 
-void Frame::setView(PassRefPtr<FrameView> view)
-{
-    // We the custom scroll bars as early as possible to prevent m_doc->detach()
-    // from messing with the view such that its scroll bars won't be torn down.
-    // FIXME: We should revisit this.
-    if (m_view)
-        m_view->prepareForDetach();
-
-    // Prepare for destruction now, so any unload event handlers get run and the DOMWindow is
-    // notified. If we wait until the view is destroyed, then things won't be hooked up enough for
-    // these calls to work.
-    if (!view && document() && document()->isActive()) {
-        // FIXME: We don't call willRemove here. Why is that OK?
-        document()->prepareForDestruction();
-    }
-
-    eventHandler().clear();
-
-    m_view = view;
-
-    if (m_view && isMainFrame())
-        m_view->setVisibleContentScaleFactor(page()->pageScaleFactor());
-}
-
-void Frame::sendOrientationChangeEvent(int orientation)
-{
-    if (!RuntimeEnabledFeatures::orientationEventEnabled())
-        return;
-
-    m_orientation = orientation;
-    if (DOMWindow* window = domWindow())
-        window->dispatchEvent(Event::create(EventTypeNames::orientationchange));
-}
-
 FrameHost* Frame::host() const
 {
     return m_host;
@@ -228,62 +125,10 @@
     return 0;
 }
 
-void Frame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio)
-{
-    // In setting printing, we should not validate resources already cached for the document.
-    // See https://bugs.webkit.org/show_bug.cgi?id=43704
-    ResourceCacheValidationSuppressor validationSuppressor(document()->fetcher());
-
-    document()->setPrinting(printing);
-    view()->adjustMediaTypeForPrinting(printing);
-
-    document()->styleResolverChanged(RecalcStyleImmediately);
-    if (shouldUsePrintingLayout()) {
-        view()->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio);
-    } else {
-        view()->forceLayout();
-        view()->adjustViewSize();
-    }
-
-    // Subframes of the one we're printing don't lay out to the page size.
-    for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
-        child->setPrinting(printing, FloatSize(), FloatSize(), 0);
-}
-
-bool Frame::shouldUsePrintingLayout() const
-{
-    // Only top frame being printed should be fit to page size.
-    // Subframes should be constrained by parents only.
-    return document()->printing() && (!tree().parent() || !tree().parent()->document()->printing());
-}
-
-FloatSize Frame::resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize)
-{
-    FloatSize resultSize;
-    if (!contentRenderer())
-        return FloatSize();
-
-    if (contentRenderer()->style()->isHorizontalWritingMode()) {
-        ASSERT(fabs(originalSize.width()) > numeric_limits<float>::epsilon());
-        float ratio = originalSize.height() / originalSize.width();
-        resultSize.setWidth(floorf(expectedSize.width()));
-        resultSize.setHeight(floorf(resultSize.width() * ratio));
-    } else {
-        ASSERT(fabs(originalSize.height()) > numeric_limits<float>::epsilon());
-        float ratio = originalSize.width() / originalSize.height();
-        resultSize.setHeight(floorf(expectedSize.height()));
-        resultSize.setWidth(floorf(resultSize.height() * ratio));
-    }
-    return resultSize;
-}
-
 void Frame::setDOMWindow(PassRefPtr<DOMWindow> domWindow)
 {
-    InspectorInstrumentation::frameWindowDiscarded(this, m_domWindow.get());
     if (m_domWindow)
         m_domWindow->reset();
-    if (domWindow)
-        script().clearWindowShell();
     m_domWindow = domWindow;
 }
 
@@ -310,424 +155,28 @@
     return document() ? document()->renderView() : 0;
 }
 
-RenderPart* Frame::ownerRenderer() const
-{
-    if (!ownerElement())
-        return 0;
-    RenderObject* object = ownerElement()->renderer();
-    if (!object)
-        return 0;
-    // FIXME: If <object> is ever fixed to disassociate itself from frames
-    // that it has started but canceled, then this can turn into an ASSERT
-    // since ownerElement() would be 0 when the load is canceled.
-    // https://bugs.webkit.org/show_bug.cgi?id=18585
-    if (!object->isRenderPart())
-        return 0;
-    return toRenderPart(object);
-}
-
-void Frame::didChangeVisibilityState()
-{
-    if (document())
-        document()->didChangeVisibilityState();
-
-    Vector<RefPtr<Frame> > childFrames;
-    for (Frame* child = tree().firstChild(); child; child = child->tree().nextSibling())
-        childFrames.append(child);
-
-    for (size_t i = 0; i < childFrames.size(); ++i)
-        childFrames[i]->didChangeVisibilityState();
-}
-
 void Frame::willDetachFrameHost()
 {
-    // We should never be detatching the page during a Layout.
-    RELEASE_ASSERT(!m_view || !m_view->isInPerformLayout());
-
-    if (Frame* parent = tree().parent())
-        parent->loader().checkLoadComplete();
-
     HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
     for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
         (*it)->willDetachFrameHost();
 
     // FIXME: Page should take care of updating focus/scrolling instead of Frame.
     // FIXME: It's unclear as to why this is called more than once, but it is,
-    // so page() could be NULL.
+    // so page() could be null.
     if (page() && page()->focusController().focusedFrame() == this)
-        page()->focusController().setFocusedFrame(0);
-
-    if (page() && page()->scrollingCoordinator() && m_view)
-        page()->scrollingCoordinator()->willDestroyScrollableArea(m_view.get());
-
-    script().clearScriptObjects();
+        page()->focusController().setFocusedFrame(nullptr);
 }
 
 void Frame::detachFromFrameHost()
 {
-    // We should never be detatching the page during a Layout.
-    RELEASE_ASSERT(!m_view || !m_view->isInPerformLayout());
     m_host = 0;
 }
 
-void Frame::disconnectOwnerElement()
-{
-    if (ownerElement()) {
-        if (Document* doc = document())
-            doc->topDocument()->clearAXObjectCache();
-        ownerElement()->clearContentFrame();
-        if (page())
-            page()->decrementSubframeCount();
-    }
-    m_frameInit->setOwnerElement(0);
-}
-
 bool Frame::isMainFrame() const
 {
     Page* page = this->page();
     return page && this == page->mainFrame();
 }
 
-String Frame::documentTypeString() const
-{
-    if (DocumentType* doctype = document()->doctype())
-        return createMarkup(doctype);
-
-    return String();
-}
-
-String Frame::selectedText() const
-{
-    return selection().selectedText();
-}
-
-String Frame::selectedTextForClipboard() const
-{
-    return selection().selectedTextForClipboard();
-}
-
-VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
-{
-    HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint);
-    Node* node = result.innerNonSharedNode();
-    if (!node)
-        return VisiblePosition();
-    RenderObject* renderer = node->renderer();
-    if (!renderer)
-        return VisiblePosition();
-    VisiblePosition visiblePos = VisiblePosition(renderer->positionForPoint(result.localPoint()));
-    if (visiblePos.isNull())
-        visiblePos = firstPositionInOrBeforeNode(node);
-    return visiblePos;
-}
-
-Document* Frame::documentAtPoint(const IntPoint& point)
-{
-    if (!view())
-        return 0;
-
-    IntPoint pt = view()->windowToContents(point);
-    HitTestResult result = HitTestResult(pt);
-
-    if (contentRenderer())
-        result = eventHandler().hitTestResultAtPoint(pt, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
-    return result.innerNode() ? &result.innerNode()->document() : 0;
-}
-
-PassRefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint)
-{
-    VisiblePosition position = visiblePositionForPoint(framePoint);
-    if (position.isNull())
-        return 0;
-
-    VisiblePosition previous = position.previous();
-    if (previous.isNotNull()) {
-        RefPtr<Range> previousCharacterRange = makeRange(previous, position);
-        LayoutRect rect = editor().firstRectForRange(previousCharacterRange.get());
-        if (rect.contains(framePoint))
-            return previousCharacterRange.release();
-    }
-
-    VisiblePosition next = position.next();
-    if (RefPtr<Range> nextCharacterRange = makeRange(position, next)) {
-        LayoutRect rect = editor().firstRectForRange(nextCharacterRange.get());
-        if (rect.contains(framePoint))
-            return nextCharacterRange.release();
-    }
-
-    return 0;
-}
-
-void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent,
-    ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
-    ScrollbarMode verticalScrollbarMode, bool verticalLock)
-{
-    ASSERT(this);
-    ASSERT(page());
-
-    bool isMainFrame = this->isMainFrame();
-
-    if (isMainFrame && view())
-        view()->setParentVisible(false);
-
-    setView(0);
-
-    RefPtr<FrameView> frameView;
-    if (isMainFrame) {
-        frameView = FrameView::create(this, viewportSize);
-
-        // The layout size is set by WebViewImpl to support @viewport
-        frameView->setLayoutSizeFixedToFrameSize(false);
-    } else
-        frameView = FrameView::create(this);
-
-    frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
-
-    setView(frameView);
-
-    if (backgroundColor.alpha())
-        frameView->updateBackgroundRecursively(backgroundColor, transparent);
-
-    if (isMainFrame)
-        frameView->setParentVisible(true);
-
-    if (ownerRenderer())
-        ownerRenderer()->setWidget(frameView);
-
-    if (HTMLFrameOwnerElement* owner = ownerElement())
-        view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
-}
-
-
-void Frame::countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned& totalObjects, bool& isPartial)
-{
-    RenderObject* root = view()->layoutRoot();
-    isPartial = true;
-    if (!root) {
-        isPartial = false;
-        root = contentRenderer();
-    }
-
-    needsLayoutObjects = 0;
-    totalObjects = 0;
-
-    for (RenderObject* o = root; o; o = o->nextInPreOrder(root)) {
-        ++totalObjects;
-        if (o->needsLayout())
-            ++needsLayoutObjects;
-    }
-}
-
-String Frame::layerTreeAsText(unsigned flags) const
-{
-    document()->updateLayout();
-
-    if (!contentRenderer())
-        return String();
-
-    return contentRenderer()->compositor()->layerTreeAsText(static_cast<LayerTreeFlags>(flags));
-}
-
-String Frame::trackedRepaintRectsAsText() const
-{
-    if (!m_view)
-        return String();
-    return m_view->trackedRepaintRectsAsText();
-}
-
-void Frame::setPageZoomFactor(float factor)
-{
-    setPageAndTextZoomFactors(factor, m_textZoomFactor);
-}
-
-void Frame::setTextZoomFactor(float factor)
-{
-    setPageAndTextZoomFactors(m_pageZoomFactor, factor);
-}
-
-void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)
-{
-    if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
-        return;
-
-    Page* page = this->page();
-    if (!page)
-        return;
-
-    Document* document = this->document();
-    if (!document)
-        return;
-
-    // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
-    // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
-    if (document->isSVGDocument()) {
-        if (!toSVGDocument(document)->zoomAndPanEnabled())
-            return;
-    }
-
-    if (m_pageZoomFactor != pageZoomFactor) {
-        if (FrameView* view = this->view()) {
-            // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
-            LayoutPoint scrollPosition = view->scrollPosition();
-            float percentDifference = (pageZoomFactor / m_pageZoomFactor);
-            view->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
-        }
-    }
-
-    m_pageZoomFactor = pageZoomFactor;
-    m_textZoomFactor = textZoomFactor;
-
-    for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
-        child->setPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor);
-
-    document->setNeedsStyleRecalc(SubtreeStyleChange);
-    document->updateLayoutIgnorePendingStylesheets();
-}
-
-void Frame::deviceOrPageScaleFactorChanged()
-{
-    document()->mediaQueryAffectingValueChanged();
-    for (RefPtr<Frame> child = tree().firstChild(); child; child = child->tree().nextSibling())
-        child->deviceOrPageScaleFactorChanged();
-}
-
-void Frame::notifyChromeClientWheelEventHandlerCountChanged() const
-{
-    // Ensure that this method is being called on the main frame of the page.
-    ASSERT(isMainFrame());
-
-    unsigned count = 0;
-    for (const Frame* frame = this; frame; frame = frame->tree().traverseNext()) {
-        if (frame->document())
-            count += WheelController::from(frame->document())->wheelEventHandlerCount();
-    }
-
-    m_host->chrome().client().numWheelEventHandlersChanged(count);
-}
-
-bool Frame::isURLAllowed(const KURL& url) const
-{
-    // We allow one level of self-reference because some sites depend on that,
-    // but we don't allow more than one.
-    if (page()->subframeCount() >= Page::maxNumberOfFrames)
-        return false;
-    bool foundSelfReference = false;
-    for (const Frame* frame = this; frame; frame = frame->tree().parent()) {
-        if (equalIgnoringFragmentIdentifier(frame->document()->url(), url)) {
-            if (foundSelfReference)
-                return false;
-            foundSelfReference = true;
-        }
-    }
-    return true;
-}
-
-struct ScopedFramePaintingState {
-    ScopedFramePaintingState(Frame* frame, Node* node)
-        : frame(frame)
-        , node(node)
-        , paintBehavior(frame->view()->paintBehavior())
-        , backgroundColor(frame->view()->baseBackgroundColor())
-    {
-        ASSERT(!node || node->renderer());
-        if (node)
-            node->renderer()->updateDragState(true);
-    }
-
-    ~ScopedFramePaintingState()
-    {
-        if (node && node->renderer())
-            node->renderer()->updateDragState(false);
-        frame->view()->setPaintBehavior(paintBehavior);
-        frame->view()->setBaseBackgroundColor(backgroundColor);
-        frame->view()->setNodeToDraw(0);
-    }
-
-    Frame* frame;
-    Node* node;
-    PaintBehavior paintBehavior;
-    Color backgroundColor;
-};
-
-PassOwnPtr<DragImage> Frame::nodeImage(Node* node)
-{
-    if (!node->renderer())
-        return nullptr;
-
-    const ScopedFramePaintingState state(this, node);
-
-    m_view->setPaintBehavior(state.paintBehavior | PaintBehaviorFlattenCompositingLayers);
-
-    // When generating the drag image for an element, ignore the document background.
-    m_view->setBaseBackgroundColor(Color::transparent);
-    document()->updateLayout();
-    m_view->setNodeToDraw(node); // Enable special sub-tree drawing mode.
-
-    // Document::updateLayout may have blown away the original RenderObject.
-    RenderObject* renderer = node->renderer();
-    if (!renderer)
-        return nullptr;
-
-    LayoutRect topLevelRect;
-    IntRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect));
-
-    ASSERT(document()->isActive());
-    float deviceScaleFactor = m_host->deviceScaleFactor();
-    paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
-    paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
-
-    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
-    if (!buffer)
-        return nullptr;
-    buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
-    buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
-    buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
-
-    // https://code.google.com/p/chromium/issues/detail?id=343755
-    DisableCompositingQueryAsserts disabler;
-    m_view->paintContents(buffer->context(), paintingRect);
-
-    RefPtr<Image> image = buffer->copyImage();
-    return DragImage::create(image.get(), renderer->shouldRespectImageOrientation(), deviceScaleFactor);
-}
-
-PassOwnPtr<DragImage> Frame::dragImageForSelection()
-{
-    if (!selection().isRange())
-        return nullptr;
-
-    const ScopedFramePaintingState state(this, 0);
-    m_view->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorFlattenCompositingLayers);
-    document()->updateLayout();
-
-    IntRect paintingRect = enclosingIntRect(selection().bounds());
-
-    ASSERT(document()->isActive());
-    float deviceScaleFactor = m_host->deviceScaleFactor();
-    paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
-    paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
-
-    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
-    if (!buffer)
-        return nullptr;
-    buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
-    buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
-    buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
-
-    m_view->paintContents(buffer->context(), paintingRect);
-
-    RefPtr<Image> image = buffer->copyImage();
-    return DragImage::create(image.get(), DoNotRespectImageOrientation, deviceScaleFactor);
-}
-
-double Frame::devicePixelRatio() const
-{
-    if (!m_host)
-        return 0;
-
-    double ratio = m_host->deviceScaleFactor();
-    ratio *= pageZoomFactor();
-    return ratio;
-}
-
 } // namespace WebCore
diff --git a/Source/core/frame/Frame.h b/Source/core/frame/Frame.h
index 62276ad..82edd69 100644
--- a/Source/core/frame/Frame.h
+++ b/Source/core/frame/Frame.h
@@ -28,12 +28,8 @@
 #ifndef Frame_h
 #define Frame_h
 
-#include "core/loader/FrameLoader.h"
-#include "core/loader/NavigationScheduler.h"
-#include "core/page/FrameTree.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/scroll/ScrollTypes.h"
 #include "wtf/Forward.h"
+#include "wtf/HashSet.h"
 #include "wtf/RefCounted.h"
 
 namespace blink {
@@ -42,290 +38,77 @@
 
 namespace WebCore {
 
-    class ChromeClient;
-    class Color;
-    class DOMWindow;
-    class Document;
-    class DragImage;
-    class Editor;
-    class Element;
-    class EventHandler;
-    class FetchContext;
-    class FloatSize;
-    class FrameDestructionObserver;
-    class FrameHost;
-    class FrameSelection;
-    class FrameView;
-    class HTMLFrameOwnerElement;
-    class HTMLTableCellElement;
-    class InputMethodController;
-    class IntPoint;
-    class Node;
-    class Page;
-    class Range;
-    class RenderPart;
-    class RenderView;
-    class TreeScope;
-    class ScriptController;
-    class Settings;
-    class SpellChecker;
-    class TreeScope;
-    class VisiblePosition;
-    class Widget;
+class Document;
+class DOMWindow;
+class ChromeClient;
+class FrameDestructionObserver;
+class FrameHost;
+class HTMLFrameOwnerElement;
+class Page;
+class RenderView;
+class Settings;
 
-    class FrameInit : public RefCounted<FrameInit> {
-    public:
-        // For creating a dummy Frame
-        static PassRefPtr<FrameInit> create(int64_t frameID, FrameHost* host, FrameLoaderClient* client)
-        {
-            return adoptRef(new FrameInit(frameID, host, client));
-        }
+class Frame : public RefCounted<Frame> {
+public:
+    virtual bool isLocalFrame() const { return false; }
+    virtual bool isRemoteFrame() const { return false; }
 
-        int64_t frameID() const { return m_frameID; }
+    virtual ~Frame();
 
-        void setFrameHost(FrameHost* host) { m_frameHost = host; }
-        FrameHost* frameHost() const { return m_frameHost; }
+    void addDestructionObserver(FrameDestructionObserver*);
+    void removeDestructionObserver(FrameDestructionObserver*);
 
-        void setFrameLoaderClient(FrameLoaderClient* client) { m_client = client; }
-        FrameLoaderClient* frameLoaderClient() const { return m_client; }
+    virtual void willDetachFrameHost();
+    virtual void detachFromFrameHost();
 
-        void setOwnerElement(HTMLFrameOwnerElement* ownerElement) { m_ownerElement = ownerElement; }
-        HTMLFrameOwnerElement* ownerElement() const { return m_ownerElement; }
+    // NOTE: Page is moving out of Blink up into the browser process as
+    // part of the site-isolation (out of process iframes) work.
+    // FrameHost should be used instead where possible.
+    Page* page() const;
+    FrameHost* host() const; // Null when the frame is detached.
 
-    protected:
-        FrameInit(int64_t frameID, FrameHost* host = 0, FrameLoaderClient* client = 0)
-            : m_frameID(frameID)
-            , m_client(client)
-            , m_frameHost(host)
-            , m_ownerElement(0)
-        {
-        }
+    bool isMainFrame() const;
 
-    private:
-        int64_t m_frameID;
-        FrameLoaderClient* m_client;
-        FrameHost* m_frameHost;
-        HTMLFrameOwnerElement* m_ownerElement;
-    };
+    // FIXME: DOMWindow and Document should both be moved to LocalFrame
+    // after RemoteFrame is complete enough to exist without them.
+    virtual void setDOMWindow(PassRefPtr<DOMWindow>);
+    DOMWindow* domWindow() const;
+    Document* document() const;
 
-    class Frame : public RefCounted<Frame> {
-    public:
-        static PassRefPtr<Frame> create(PassRefPtr<FrameInit>);
+    ChromeClient& chromeClient() const;
 
-        void init();
-        void setView(PassRefPtr<FrameView>);
-        void createView(const IntSize&, const Color&, bool,
-            ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
-            ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
+    RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
 
-        ~Frame();
+    int64_t frameID() const { return m_frameID; }
 
-        void addDestructionObserver(FrameDestructionObserver*);
-        void removeDestructionObserver(FrameDestructionObserver*);
+    // FIXME: These should move to RemoteFrame when that is instantiated.
+    void setRemotePlatformLayer(blink::WebLayer* remotePlatformLayer) { m_remotePlatformLayer = remotePlatformLayer; }
+    blink::WebLayer* remotePlatformLayer() const { return m_remotePlatformLayer; }
 
-        void willDetachFrameHost();
-        void detachFromFrameHost();
-        void disconnectOwnerElement();
+    Settings* settings() const; // can be null
 
-        // NOTE: Page is moving out of Blink up into the browser process as
-        // part of the site-isolation (out of process iframes) work.
-        // FrameHost should be used instead where possible.
-        Page* page() const;
-        FrameHost* host() const; // Null when the frame is detached.
+protected:
+    Frame(FrameHost*, HTMLFrameOwnerElement*);
 
-        HTMLFrameOwnerElement* ownerElement() const;
-        bool isMainFrame() const;
+    FrameHost* m_host;
+    HTMLFrameOwnerElement* m_ownerElement;
 
-        void setDOMWindow(PassRefPtr<DOMWindow>);
-        DOMWindow* domWindow() const;
-        Document* document() const;
-        FrameView* view() const;
+    RefPtr<DOMWindow> m_domWindow;
 
-        ChromeClient& chromeClient() const;
-        Editor& editor() const;
-        EventHandler& eventHandler() const;
-        FrameLoader& loader() const;
-        NavigationScheduler& navigationScheduler() const;
-        FrameSelection& selection() const;
-        FrameTree& tree() const;
-        InputMethodController& inputMethodController() const;
-        FetchContext& fetchContext() const { return loader().fetchContext(); }
-        ScriptController& script();
-        SpellChecker& spellChecker() const;
+private:
 
-        RenderView* contentRenderer() const; // Root of the render tree for the document contained in this frame.
-        RenderPart* ownerRenderer() const; // Renderer for the element that contains this frame.
+    HashSet<FrameDestructionObserver*> m_destructionObservers;
 
-        void didChangeVisibilityState();
+    // Temporary hack for history.
+    int64_t m_frameID;
 
-        int64_t frameID() const { return m_frameInit->frameID(); }
+    blink::WebLayer* m_remotePlatformLayer;
+};
 
-        // FIXME: These should move to RemoteFrame once that exists.
-        // RemotePlatformLayer is only ever set for Frames which exist in another process.
-        void setRemotePlatformLayer(blink::WebLayer* remotePlatformLayer) { m_remotePlatformLayer = remotePlatformLayer; }
-        blink::WebLayer* remotePlatformLayer() const { return m_remotePlatformLayer; }
-
-    // ======== All public functions below this point are candidates to move out of Frame into another class. ========
-
-        bool inScope(TreeScope*) const;
-
-        void countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned& totalObjects, bool& isPartial);
-
-        // See GraphicsLayerClient.h for accepted flags.
-        String layerTreeAsText(unsigned flags = 0) const;
-        String trackedRepaintRectsAsText() const;
-
-        Settings* settings() const; // can be NULL
-
-        void setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio);
-        bool shouldUsePrintingLayout() const;
-        FloatSize resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize);
-
-        bool inViewSourceMode() const;
-        void setInViewSourceMode(bool = true);
-
-        void setPageZoomFactor(float factor);
-        float pageZoomFactor() const { return m_pageZoomFactor; }
-        void setTextZoomFactor(float factor);
-        float textZoomFactor() const { return m_textZoomFactor; }
-        void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);
-
-        void deviceOrPageScaleFactorChanged();
-        double devicePixelRatio() const;
-
-        // Orientation is the interface orientation in degrees. Some examples are:
-        //  0 is straight up; -90 is when the device is rotated 90 clockwise;
-        //  90 is when rotated counter clockwise.
-        void sendOrientationChangeEvent(int orientation);
-        int orientation() const { return m_orientation; }
-
-        String documentTypeString() const;
-
-        PassOwnPtr<DragImage> nodeImage(Node*);
-        PassOwnPtr<DragImage> dragImageForSelection();
-
-        String selectedText() const;
-        String selectedTextForClipboard() const;
-
-        VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
-        Document* documentAtPoint(const IntPoint& windowPoint);
-        PassRefPtr<Range> rangeForPoint(const IntPoint& framePoint);
-
-        // Should only be called on the main frame of a page.
-        void notifyChromeClientWheelEventHandlerCountChanged() const;
-
-        bool isURLAllowed(const KURL&) const;
-
-    // ========
-
-    private:
-        Frame(PassRefPtr<FrameInit>);
-
-        HashSet<FrameDestructionObserver*> m_destructionObservers;
-
-        FrameHost* m_host;
-        mutable FrameTree m_treeNode;
-        mutable FrameLoader m_loader;
-        mutable NavigationScheduler m_navigationScheduler;
-
-        RefPtr<FrameView> m_view;
-        RefPtr<DOMWindow> m_domWindow;
-
-        OwnPtr<ScriptController> m_script;
-        const OwnPtr<Editor> m_editor;
-        const OwnPtr<SpellChecker> m_spellChecker;
-        const OwnPtr<FrameSelection> m_selection;
-        const OwnPtr<EventHandler> m_eventHandler;
-        OwnPtr<InputMethodController> m_inputMethodController;
-
-        RefPtr<FrameInit> m_frameInit;
-
-        float m_pageZoomFactor;
-        float m_textZoomFactor;
-
-        int m_orientation;
-
-        bool m_inViewSourceMode;
-
-        blink::WebLayer* m_remotePlatformLayer;
-    };
-
-    inline void Frame::init()
-    {
-        m_loader.init();
-    }
-
-    inline FrameLoader& Frame::loader() const
-    {
-        return m_loader;
-    }
-
-    inline NavigationScheduler& Frame::navigationScheduler() const
-    {
-        return m_navigationScheduler;
-    }
-
-    inline FrameView* Frame::view() const
-    {
-        return m_view.get();
-    }
-
-    inline ScriptController& Frame::script()
-    {
-        return *m_script;
-    }
-
-    inline DOMWindow* Frame::domWindow() const
-    {
-        return m_domWindow.get();
-    }
-
-    inline FrameSelection& Frame::selection() const
-    {
-        return *m_selection;
-    }
-
-    inline Editor& Frame::editor() const
-    {
-        return *m_editor;
-    }
-
-    inline SpellChecker& Frame::spellChecker() const
-    {
-        return *m_spellChecker;
-    }
-
-    inline InputMethodController& Frame::inputMethodController() const
-    {
-        return *m_inputMethodController;
-    }
-
-    inline HTMLFrameOwnerElement* Frame::ownerElement() const
-    {
-        return m_frameInit->ownerElement();
-    }
-
-    inline bool Frame::inViewSourceMode() const
-    {
-        return m_inViewSourceMode;
-    }
-
-    inline void Frame::setInViewSourceMode(bool mode)
-    {
-        m_inViewSourceMode = mode;
-    }
-
-    inline FrameTree& Frame::tree() const
-    {
-        return m_treeNode;
-    }
-
-    inline EventHandler& Frame::eventHandler() const
-    {
-        ASSERT(m_eventHandler);
-        return *m_eventHandler;
-    }
-
+inline DOMWindow* Frame::domWindow() const
+{
+    return m_domWindow.get();
+}
 } // namespace WebCore
 
 #endif // Frame_h
diff --git a/Source/core/frame/FrameClient.h b/Source/core/frame/FrameClient.h
new file mode 100644
index 0000000..7996874
--- /dev/null
+++ b/Source/core/frame/FrameClient.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef FrameClient_h
+#define FrameClient_h
+
+namespace WebCore {
+
+class Frame;
+
+class FrameClient {
+public:
+    virtual Frame* opener() const = 0;
+    virtual void setOpener(Frame*) = 0;
+
+    virtual Frame* parent() const = 0;
+    virtual Frame* top() const = 0;
+    virtual Frame* previousSibling() const = 0;
+    virtual Frame* nextSibling() const = 0;
+    virtual Frame* firstChild() const = 0;
+    virtual Frame* lastChild() const = 0;
+
+    virtual ~FrameClient() { }
+};
+
+} // namespace WebCore
+
+#endif // FrameClient_h
diff --git a/Source/core/frame/FrameDestructionObserver.cpp b/Source/core/frame/FrameDestructionObserver.cpp
index 2c41712..7ab5868 100644
--- a/Source/core/frame/FrameDestructionObserver.cpp
+++ b/Source/core/frame/FrameDestructionObserver.cpp
@@ -26,11 +26,11 @@
 #include "config.h"
 #include "core/frame/FrameDestructionObserver.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
-FrameDestructionObserver::FrameDestructionObserver(Frame* frame)
+FrameDestructionObserver::FrameDestructionObserver(LocalFrame* frame)
     : m_frame(0)
 {
     observeFrame(frame);
@@ -42,7 +42,7 @@
 
 }
 
-void FrameDestructionObserver::observeFrame(Frame* frame)
+void FrameDestructionObserver::observeFrame(LocalFrame* frame)
 {
     if (m_frame)
         m_frame->removeDestructionObserver(this);
diff --git a/Source/core/frame/FrameDestructionObserver.h b/Source/core/frame/FrameDestructionObserver.h
index ed75a2f..db7341f 100644
--- a/Source/core/frame/FrameDestructionObserver.h
+++ b/Source/core/frame/FrameDestructionObserver.h
@@ -28,22 +28,22 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 
 class FrameDestructionObserver {
 public:
-    explicit FrameDestructionObserver(Frame*);
+    explicit FrameDestructionObserver(LocalFrame*);
 
     virtual void frameDestroyed();
     virtual void willDetachFrameHost();
 
-    Frame* frame() const { return m_frame; }
+    LocalFrame* frame() const { return m_frame; }
 
 protected:
     virtual ~FrameDestructionObserver();
-    void observeFrame(Frame*);
+    void observeFrame(LocalFrame*);
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
 };
 
 }
diff --git a/Source/core/frame/FrameHost.cpp b/Source/core/frame/FrameHost.cpp
index 8e7ac5d..154bfc0 100644
--- a/Source/core/frame/FrameHost.cpp
+++ b/Source/core/frame/FrameHost.cpp
@@ -32,6 +32,8 @@
 #include "core/frame/FrameHost.h"
 
 #include "core/frame/PageConsole.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
 #include "core/page/Page.h"
 
 namespace WebCore {
@@ -44,6 +46,7 @@
 FrameHost::FrameHost(Page& page)
     : m_page(page)
     , m_console(PageConsole::create(*this))
+    , m_pinchViewport(*this)
 {
 }
 
@@ -77,4 +80,9 @@
     return m_page.deviceScaleFactor();
 }
 
+PinchViewport& FrameHost::pinchViewport()
+{
+    return m_pinchViewport;
+}
+
 }
diff --git a/Source/core/frame/FrameHost.h b/Source/core/frame/FrameHost.h
index 0438b4c..99fb15e 100644
--- a/Source/core/frame/FrameHost.h
+++ b/Source/core/frame/FrameHost.h
@@ -31,6 +31,7 @@
 #ifndef FrameHost_h
 #define FrameHost_h
 
+#include "core/frame/PinchViewport.h"
 #include "wtf/FastAllocBase.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/OwnPtr.h"
@@ -38,9 +39,10 @@
 
 namespace WebCore {
 
+class Chrome;
 class Page;
 class PageConsole;
-class Chrome;
+class PinchViewport;
 class Settings;
 class UseCounter;
 
@@ -50,7 +52,7 @@
 // however the concept of a Page is moving up out of Blink.
 // In an out-of-process iframe world, a single Page may have
 // multiple frames in different process, thus Page becomes a
-// browser-level concept and Blink core/ only knows about its Frame (and FrameHost).
+// browser-level concept and Blink core/ only knows about its LocalFrame (and FrameHost).
 // Separating Page from the rest of core/ through this indirection
 // allows us to slowly refactor Page without breaking the rest of core.
 class FrameHost {
@@ -69,14 +71,17 @@
 
     // Corresponds to pixel density of the device where this Page is
     // being displayed. In multi-monitor setups this can vary between pages.
-    // This value does not account for Page zoom, use Frame::devicePixelRatio instead.
+    // This value does not account for Page zoom, use LocalFrame::devicePixelRatio instead.
     float deviceScaleFactor() const;
 
+    PinchViewport& pinchViewport();
+
 private:
     explicit FrameHost(Page&);
 
     Page& m_page;
     const OwnPtr<PageConsole> m_console;
+    PinchViewport m_pinchViewport;
 };
 
 }
diff --git a/Source/core/frame/FrameView.cpp b/Source/core/frame/FrameView.cpp
index 421f8fa..3596a61 100644
--- a/Source/core/frame/FrameView.cpp
+++ b/Source/core/frame/FrameView.cpp
@@ -30,7 +30,6 @@
 #include "HTMLNames.h"
 #include "RuntimeEnabledFeatures.h"
 #include "core/accessibility/AXObjectCache.h"
-#include "core/animation/DocumentAnimations.h"
 #include "core/css/FontFaceSet.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/DocumentMarkerController.h"
@@ -38,7 +37,7 @@
 #include "core/events/OverflowEvent.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameElement.h"
 #include "core/html/HTMLPlugInElement.h"
@@ -52,12 +51,10 @@
 #include "core/page/FocusController.h"
 #include "core/page/FrameTree.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/FastTextAutosizer.h"
 #include "core/rendering/RenderCounter.h"
 #include "core/rendering/RenderEmbeddedObject.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderListBox.h"
 #include "core/rendering/RenderPart.h"
 #include "core/rendering/RenderScrollbar.h"
@@ -66,6 +63,8 @@
 #include "core/rendering/RenderView.h"
 #include "core/rendering/RenderWidget.h"
 #include "core/rendering/TextAutosizer.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/rendering/style/RenderStyle.h"
 #include "core/rendering/svg/RenderSVGRoot.h"
 #include "core/svg/SVGDocument.h"
@@ -105,7 +104,34 @@
     return flags;
 }
 
-FrameView::FrameView(Frame* frame)
+class FrameViewLayoutStateMaintainer {
+    WTF_MAKE_NONCOPYABLE(FrameViewLayoutStateMaintainer);
+public:
+    FrameViewLayoutStateMaintainer(RenderObject& root, bool inSubtreeLayout)
+        : m_view(*root.view())
+        , m_inSubtreeLayout(inSubtreeLayout)
+        , m_disabled(inSubtreeLayout && m_view.shouldDisableLayoutStateForSubtree(root))
+    {
+        if (m_inSubtreeLayout)
+            m_view.pushLayoutState(root);
+        if (m_disabled)
+            m_view.disableLayoutState();
+    }
+
+    ~FrameViewLayoutStateMaintainer()
+    {
+        if (m_disabled)
+            m_view.enableLayoutState();
+        if (m_inSubtreeLayout)
+            m_view.popLayoutState();
+    }
+private:
+    RenderView& m_view;
+    bool m_inSubtreeLayout;
+    bool m_disabled;
+};
+
+FrameView::FrameView(LocalFrame* frame)
     : m_frame(frame)
     , m_canHaveScrollbars(true)
     , m_slowRepaintObjectCount(0)
@@ -128,10 +154,8 @@
     , m_inAutoSize(false)
     , m_didRunAutosize(false)
     , m_hasSoftwareFilters(false)
-    , m_servicingAnimations(false)
     , m_visibleContentScaleFactor(1)
     , m_inputEventsScaleFactorForEmulation(1)
-    , m_partialLayout()
     , m_layoutSizeFixedToFrameSize(true)
     , m_didScrollTimer(this, &FrameView::didScrollTimerFired)
 {
@@ -145,14 +169,14 @@
     ScrollableArea::setHorizontalScrollElasticity(ScrollElasticityAllowed);
 }
 
-PassRefPtr<FrameView> FrameView::create(Frame* frame)
+PassRefPtr<FrameView> FrameView::create(LocalFrame* frame)
 {
     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
     view->show();
     return view.release();
 }
 
-PassRefPtr<FrameView> FrameView::create(Frame* frame, const IntSize& initialSize)
+PassRefPtr<FrameView> FrameView::create(LocalFrame* frame, const IntSize& initialSize)
 {
     RefPtr<FrameView> view = adoptRef(new FrameView(frame));
     view->Widget::setFrameRect(IntRect(view->location(), initialSize));
@@ -186,7 +210,7 @@
     ASSERT(m_frame->view() != this || !m_frame->contentRenderer());
     RenderPart* renderer = m_frame->ownerRenderer();
     if (renderer && renderer->widget() == this)
-        renderer->setWidget(0);
+        renderer->setWidget(nullptr);
 }
 
 void FrameView::reset()
@@ -221,8 +245,7 @@
     m_visuallyNonEmptyPixelCount = 0;
     m_isVisuallyNonEmpty = false;
     m_firstVisuallyNonEmptyLayoutCallbackPending = true;
-    m_maintainScrollPositionAnchor = 0;
-    m_partialLayout.reset();
+    m_maintainScrollPositionAnchor = nullptr;
     m_viewportConstrainedObjects.clear();
 }
 
@@ -252,7 +275,7 @@
 
     // Propagate the marginwidth/height and scrolling modes to the view.
     Element* ownerElement = m_frame->ownerElement();
-    if (ownerElement && (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))) {
+    if (ownerElement && (isHTMLFrameElement(*ownerElement) || isHTMLIFrameElement(*ownerElement))) {
         HTMLFrameElementBase* frameElt = toHTMLFrameElementBase(ownerElement);
         if (frameElt->scrollingMode() == ScrollbarAlwaysOff)
             setCanHaveScrollbars(false);
@@ -313,10 +336,7 @@
 
 void FrameView::clear()
 {
-    setCanBlitOnScroll(true);
-
     reset();
-
     setScrollbarsSuppressed(true);
 }
 
@@ -346,20 +366,18 @@
 void FrameView::setFrameRect(const IntRect& newRect)
 {
     IntRect oldRect = frameRect();
-    bool widthChanged = oldRect.width() != newRect.width();
-    bool heightChanged = oldRect.height() != newRect.height();
-    if (!widthChanged && !heightChanged)
+    if (newRect == oldRect)
         return;
 
     // Autosized font sizes depend on the width of the viewing area.
-    if (widthChanged) {
+    if (newRect.width() != oldRect.width()) {
         if (isMainFrame()) {
             Page* page = m_frame->page();
             bool textAutosizingEnabled = m_frame->settings()->textAutosizingEnabled();
             if (textAutosizingEnabled) {
                 TextAutosizer* textAutosizer = m_frame->document()->textAutosizer();
                 if (textAutosizer) {
-                    for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
+                    for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
                         textAutosizer->recalculateMultipliers();
                 }
             }
@@ -375,7 +393,7 @@
             renderView->compositor()->frameViewDidChangeSize();
     }
 
-    viewportConstrainedVisibleContentRectChanged(widthChanged, heightChanged);
+    viewportConstrainedVisibleContentSizeChanged(newRect.width() != oldRect.width(), newRect.height() != oldRect.height());
 }
 
 bool FrameView::scheduleAnimation()
@@ -387,6 +405,11 @@
     return false;
 }
 
+Page* FrameView::page() const
+{
+    return frame().page();
+}
+
 RenderView* FrameView::renderView() const
 {
     return frame().contentRenderer();
@@ -398,7 +421,7 @@
     ScrollView::setCanHaveScrollbars(canHaveScrollbars);
 }
 
-bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, Frame*& customScrollbarFrame)
+bool FrameView::shouldUseCustomScrollbars(Element*& customScrollbarElement, LocalFrame*& customScrollbarFrame)
 {
     customScrollbarElement = 0;
     customScrollbarFrame = 0;
@@ -425,7 +448,7 @@
         return true;
     }
 
-    // If we have an owning ipage/Frame element, then it can set the custom scrollbar also.
+    // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
     RenderPart* frameRenderer = m_frame->ownerRenderer();
     if (frameRenderer && frameRenderer->style()->hasPseudoStyle(SCROLLBAR)) {
         customScrollbarFrame = m_frame.get();
@@ -438,7 +461,7 @@
 PassRefPtr<Scrollbar> FrameView::createScrollbar(ScrollbarOrientation orientation)
 {
     Element* customScrollbarElement = 0;
-    Frame* customScrollbarFrame = 0;
+    LocalFrame* customScrollbarFrame = 0;
     if (shouldUseCustomScrollbars(customScrollbarElement, customScrollbarFrame))
         return RenderScrollbar::createCustomScrollbar(this, orientation, customScrollbarElement, customScrollbarFrame);
 
@@ -463,6 +486,20 @@
     page->chrome().contentsSizeChanged(m_frame.get(), size);
 }
 
+IntPoint FrameView::clampOffsetAtScale(const IntPoint& offset, float scale) const
+{
+    IntPoint maxScrollExtent(contentsSize().width() - scrollOrigin().x(), contentsSize().height() - scrollOrigin().y());
+    FloatSize scaledSize = unscaledVisibleContentSize();
+    if (scale)
+        scaledSize.scale(1 / scale);
+
+    IntPoint clampedOffset = offset;
+    clampedOffset = clampedOffset.shrunkTo(maxScrollExtent - expandedIntSize(scaledSize));
+    clampedOffset = clampedOffset.expandedTo(-scrollOrigin());
+
+    return clampedOffset;
+}
+
 void FrameView::adjustViewSize()
 {
     RenderView* renderView = this->renderView();
@@ -557,7 +594,7 @@
     if (!isSubtreeLayout()) {
         Document* document = m_frame->document();
         Node* body = document->body();
-        if (body && body->renderer() && body->hasTagName(framesetTag)) {
+        if (isHTMLFrameSetElement(body) && body->renderer()) {
             vMode = ScrollbarAlwaysOff;
             hMode = ScrollbarAlwaysOff;
         } else if (Element* viewportElement = document->viewportDefiningElement()) {
@@ -674,12 +711,6 @@
     return false;
 }
 
-bool FrameView::isSoftwareRenderable() const
-{
-    RenderView* renderView = this->renderView();
-    return !renderView || !renderView->compositor()->has3DContent();
-}
-
 RenderObject* FrameView::layoutRoot(bool onlyDuringLayout) const
 {
     return onlyDuringLayout && layoutPending() ? 0 : m_layoutSubtreeRoot;
@@ -766,38 +797,24 @@
     // FIXME: The 300 other lines in layout() probably belong in other helper functions
     // so that a single human could understand what layout() is actually doing.
 
-    {
-        bool disableLayoutState = false;
-        if (inSubtreeLayout) {
-            RenderView* view = rootForThisLayout->view();
-            disableLayoutState = view->shouldDisableLayoutStateForSubtree(rootForThisLayout);
-            view->pushLayoutState(rootForThisLayout);
-        }
-        LayoutStateDisabler layoutStateDisabler(disableLayoutState ? rootForThisLayout->view() : 0);
+    FrameViewLayoutStateMaintainer statePusher(*rootForThisLayout, inSubtreeLayout);
+    forceLayoutParentViewIfNeeded();
 
-        forceLayoutParentViewIfNeeded();
+    // FIXME (crbug.com/256657): Do not do two layouts for text autosizing.
+    rootForThisLayout->layout();
+    gatherDebugLayoutRects(rootForThisLayout);
 
-        // Text Autosizing requires two-pass layout which is incompatible with partial layout.
-        // If enabled, only do partial layout for the second layout.
-        // FIXME (crbug.com/256657): Do not do two layouts for text autosizing.
-        PartialLayoutDisabler partialLayoutDisabler(partialLayout(), m_frame->settings() && m_frame->settings()->textAutosizingEnabled());
-        rootForThisLayout->layout();
-        gatherDebugLayoutRects(rootForThisLayout);
-
-        ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
-    }
+    ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->updateAllImageResourcePriorities();
 
     TextAutosizer* textAutosizer = frame().document()->textAutosizer();
     bool autosized = textAutosizer && textAutosizer->processSubtree(rootForThisLayout);
     if (autosized && rootForThisLayout->needsLayout()) {
         TRACE_EVENT0("webkit", "2nd layout due to Text Autosizing");
+        UseCounter::count(*frame().document(), UseCounter::TextAutosizingLayout);
         rootForThisLayout->layout();
         gatherDebugLayoutRects(rootForThisLayout);
     }
 
-    if (inSubtreeLayout)
-        rootForThisLayout->view()->popLayoutState(rootForThisLayout);
-
     lifecycle().advanceTo(DocumentLifecycle::AfterPerformLayout);
 }
 
@@ -806,9 +823,6 @@
     if (m_postLayoutTasksTimer.isActive())
         return;
 
-    // Partial layouts should not happen with synchronous post layouts.
-    ASSERT(!(m_inSynchronousPostLayout && partialLayout().isStopping()));
-
     if (!m_inSynchronousPostLayout) {
         m_inSynchronousPostLayout = true;
         // Calls resumeScheduledEvents()
@@ -821,15 +835,15 @@
         // defer widget updates and event dispatch until after we return. postLayoutTasks()
         // can make us need to update again, and we can get stuck in a nasty cycle unless
         // we call it through the timer here.
-        m_postLayoutTasksTimer.startOneShot(0);
-        if (!partialLayout().isStopping() && needsLayout())
+        m_postLayoutTasksTimer.startOneShot(0, FROM_HERE);
+        if (needsLayout())
             layout();
     }
 }
 
 void FrameView::layout(bool allowSubtree)
 {
-    // We should never layout a Document which is not in a Frame.
+    // We should never layout a Document which is not in a LocalFrame.
     ASSERT(m_frame);
     ASSERT(m_frame->view() == this);
     ASSERT(m_frame->page());
@@ -837,8 +851,6 @@
     if (isInPerformLayout() || !m_frame->document()->isActive())
         return;
 
-    ASSERT(!partialLayout().isStopping());
-
     TRACE_EVENT0("webkit", "FrameView::layout");
     TRACE_EVENT_SCOPED_SAMPLING_STATE("Blink", "Layout");
 
@@ -880,11 +892,6 @@
         return;
     }
 
-    bool isPartialLayout = partialLayout().isPartialLayout();
-
-    if (isPartialLayout)
-        lifecycleScope.setFinalState(DocumentLifecycle::StyleClean);
-
     bool shouldDoFullLayout = false;
     FontCachePurgePreventer fontCachePurgePreventer;
     RenderLayer* layer;
@@ -896,9 +903,9 @@
             Document* document = m_frame->document();
             Node* body = document->body();
             if (body && body->renderer()) {
-                if (body->hasTagName(framesetTag)) {
+                if (isHTMLFrameSetElement(*body)) {
                     body->renderer()->setChildNeedsLayout();
-                } else if (body->hasTagName(bodyTag)) {
+                } else if (isHTMLBodyElement(*body)) {
                     if (!m_firstLayout && m_size.height() != layoutSize().height() && body->renderer()->enclosingBox()->stretchesToViewport())
                         body->renderer()->setChildNeedsLayout();
                 }
@@ -911,33 +918,32 @@
         ScrollbarMode vMode;
         calculateScrollbarModesForLayoutAndSetViewportRenderer(hMode, vMode);
 
-        shouldDoFullLayout = !inSubtreeLayout && !isPartialLayout && (m_firstLayout || toRenderView(rootForThisLayout)->document().printing());
+        shouldDoFullLayout = !inSubtreeLayout && (m_firstLayout || toRenderView(rootForThisLayout)->document().printing());
 
-        if (!inSubtreeLayout && !isPartialLayout) {
+        if (!inSubtreeLayout) {
             // Now set our scrollbar state for the layout.
             ScrollbarMode currentHMode = horizontalScrollbarMode();
             ScrollbarMode currentVMode = verticalScrollbarMode();
 
-            if (m_firstLayout || (hMode != currentHMode || vMode != currentVMode)) {
-                if (m_firstLayout) {
-                    setScrollbarsSuppressed(true);
+            if (m_firstLayout) {
+                setScrollbarsSuppressed(true);
 
-                    m_firstLayout = false;
-                    m_firstLayoutCallbackPending = true;
-                    m_lastViewportSize = layoutSize(IncludeScrollbars);
-                    m_lastZoomFactor = rootForThisLayout->style()->zoom();
+                m_firstLayout = false;
+                m_firstLayoutCallbackPending = true;
+                m_lastViewportSize = layoutSize(IncludeScrollbars);
+                m_lastZoomFactor = rootForThisLayout->style()->zoom();
 
-                    // Set the initial vMode to AlwaysOn if we're auto.
-                    if (vMode == ScrollbarAuto)
-                        setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
-                    // Set the initial hMode to AlwaysOff if we're auto.
-                    if (hMode == ScrollbarAuto)
-                        setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
+                // Set the initial vMode to AlwaysOn if we're auto.
+                if (vMode == ScrollbarAuto)
+                    setVerticalScrollbarMode(ScrollbarAlwaysOn); // This causes a vertical scrollbar to appear.
+                // Set the initial hMode to AlwaysOff if we're auto.
+                if (hMode == ScrollbarAuto)
+                    setHorizontalScrollbarMode(ScrollbarAlwaysOff); // This causes a horizontal scrollbar to disappear.
 
-                    setScrollbarModes(hMode, vMode);
-                    setScrollbarsSuppressed(false, true);
-                } else
-                    setScrollbarModes(hMode, vMode);
+                setScrollbarModes(hMode, vMode);
+                setScrollbarsSuppressed(false, true);
+            } else if (hMode != currentHMode || vMode != currentVMode) {
+                setScrollbarModes(hMode, vMode);
             }
 
             LayoutSize oldSize = m_size;
@@ -968,7 +974,7 @@
         m_layoutSubtreeRoot = 0;
     } // Reset m_layoutSchedulingEnabled to its previous value.
 
-    if (!inSubtreeLayout && !isPartialLayout && !toRenderView(rootForThisLayout)->document().printing())
+    if (!inSubtreeLayout && !toRenderView(rootForThisLayout)->document().printing())
         adjustViewSize();
 
     layer->updateLayerPositionsAfterLayout(renderView()->layer(), updateLayerPositionFlags(layer, inSubtreeLayout, m_doFullRepaint));
@@ -981,9 +987,7 @@
         cache->postNotification(rootForThisLayout, AXObjectCache::AXLayoutComplete, true);
     updateAnnotatedRegions();
 
-    ASSERT(partialLayout().isStopping() || !rootForThisLayout->needsLayout());
-
-    updateCanBlitOnScrollRecursively();
+    ASSERT(!rootForThisLayout->needsLayout());
 
     if (document->hasListenerType(Document::OVERFLOWCHANGED_LISTENER))
         updateOverflowStatus(layoutSize().width() < contentsWidth(), layoutSize().height() < contentsHeight());
@@ -1000,7 +1004,7 @@
         if (m_doFullRepaint)
             renderView()->setShouldDoFullRepaintAfterLayout(true);
 
-        if (m_doFullRepaint || !partialLayout().isStopping())
+        if (m_doFullRepaint)
             repaintTree(rootForThisLayout);
 
     } else if (m_doFullRepaint) {
@@ -1012,9 +1016,6 @@
 
     m_doFullRepaint = false;
 
-    if (partialLayout().isStopping())
-        return;
-
 #ifndef NDEBUG
     // Post-layout assert that nobody was re-marked as needing layout during layout.
     document->renderer()->assertSubtreeIsLaidOut();
@@ -1022,7 +1023,7 @@
 
     // FIXME: It should be not possible to remove the FrameView from the frame/page during layout
     // however m_inPerformLayout is not set for most of this function, so none of our RELEASE_ASSERTS
-    // in Frame/Page will fire. One of the post-layout tasks is disconnecting the Frame from
+    // in LocalFrame/Page will fire. One of the post-layout tasks is disconnecting the LocalFrame from
     // the page in fast/frames/crash-remove-iframe-during-object-beforeload-2.html
     // necessitating this check here.
     // ASSERT(frame()->page());
@@ -1078,8 +1079,8 @@
             }
         }
 
-        if (!didFullRepaint && renderer->shouldRepaintOverflowIfNeeded())
-            renderer->repaintOverflow();
+        if (!didFullRepaint)
+            renderer->repaintOverflowIfNeeded();
 
         // Repaint any scrollbars if there is a scrollable area for this renderer.
         if (renderer->enclosingLayer()) {
@@ -1183,9 +1184,11 @@
 
 void FrameView::addWidgetToUpdate(RenderEmbeddedObject& object)
 {
+    ASSERT(isInPerformLayout());
     // Tell the DOM element that it needs a widget update.
     Node* node = object.node();
-    if (node->hasTagName(objectTag) || node->hasTagName(embedTag))
+    ASSERT(node);
+    if (isHTMLObjectElement(*node) || isHTMLEmbedElement(*node))
         toHTMLPlugInElement(node)->setNeedsWidgetUpdate(true);
 
     m_widgetUpdateSet.add(&object);
@@ -1223,19 +1226,24 @@
 
 bool FrameView::useSlowRepaints(bool considerOverlap) const
 {
-    bool mustBeSlow = m_slowRepaintObjectCount > 0;
+    if (m_slowRepaintObjectCount > 0)
+        return true;
 
     if (contentsInCompositedLayer())
-        return mustBeSlow;
+        return false;
 
     // The chromium compositor does not support scrolling a non-composited frame within a composited page through
     // the fast scrolling path, so force slow scrolling in that case.
     if (m_frame->ownerElement() && !hasCompositedContent() && m_frame->page() && m_frame->page()->mainFrame()->view()->hasCompositedContent())
         return true;
 
-    bool isOverlapped = m_isOverlapped && considerOverlap;
+    if (m_isOverlapped && considerOverlap)
+        return true;
 
-    if (mustBeSlow || m_cannotBlitToWindow || isOverlapped || !m_contentIsOpaque)
+    if (m_cannotBlitToWindow)
+        return true;
+
+    if (!m_contentIsOpaque)
         return true;
 
     if (FrameView* parentView = parentFrameView())
@@ -1249,17 +1257,13 @@
     return useSlowRepaints(false);
 }
 
-void FrameView::updateCanBlitOnScrollRecursively()
+bool FrameView::shouldAttemptToScrollUsingFastPath() const
 {
-    // FIXME: useSlowRepaints reads compositing state in nested frames. Compositing state on the nested
+    // FIXME: useSlowRepaints reads compositing state in parent frames. Compositing state on the parent
     // frames is not necessarily up to date.
     // https://code.google.com/p/chromium/issues/detail?id=343766
     DisableCompositingQueryAsserts disabler;
-
-    for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
-        if (FrameView* view = frame->view())
-            view->setCanBlitOnScroll(!view->useSlowRepaints());
-    }
+    return !useSlowRepaints();
 }
 
 bool FrameView::contentsInCompositedLayer() const
@@ -1277,14 +1281,11 @@
 void FrameView::setCannotBlitToWindow()
 {
     m_cannotBlitToWindow = true;
-    updateCanBlitOnScrollRecursively();
 }
 
 void FrameView::addSlowRepaintObject()
 {
     if (!m_slowRepaintObjectCount++) {
-        updateCanBlitOnScrollRecursively();
-
         if (Page* page = m_frame->page()) {
             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
@@ -1297,8 +1298,6 @@
     ASSERT(m_slowRepaintObjectCount > 0);
     m_slowRepaintObjectCount--;
     if (!m_slowRepaintObjectCount) {
-        updateCanBlitOnScrollRecursively();
-
         if (Page* page = m_frame->page()) {
             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
                 scrollingCoordinator->frameViewHasSlowRepaintObjectsDidChange(this);
@@ -1325,14 +1324,11 @@
 {
     if (m_viewportConstrainedObjects && m_viewportConstrainedObjects->contains(object)) {
         m_viewportConstrainedObjects->remove(object);
+
         if (Page* page = m_frame->page()) {
             if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
                 scrollingCoordinator->frameViewFixedObjectsDidChange(this);
         }
-
-        // FIXME: In addFixedObject() we only call this if there's a platform widget,
-        // why isn't the same check being made here?
-        updateCanBlitOnScrollRecursively();
     }
 }
 
@@ -1344,7 +1340,7 @@
     return viewportRect;
 }
 
-void FrameView::viewportConstrainedVisibleContentRectChanged(bool widthChanged, bool heightChanged)
+void FrameView::viewportConstrainedVisibleContentSizeChanged(bool widthChanged, bool heightChanged)
 {
     // If viewport is not enabled, frameRect change will cause layout size change and then layout.
     // Otherwise, viewport constrained objects need their layout flags set separately to ensure
@@ -1371,6 +1367,25 @@
     }
 }
 
+bool FrameView::shouldPlaceVerticalScrollbarOnLeft() const
+{
+    // FIXME: Mainframe scrollbar placement should respect the embedding application RTL UI policy.
+    // See crbug.com/249860.
+    if (isMainFrame())
+        return false;
+
+    Document* document = m_frame->document();
+    if (!document)
+        return false;
+
+    // <body> inherits 'direction' from <html>, so it can safaly be used
+    // to dictate the frame vertical scrollbar placement.
+    if (!document->body() || !document->body()->renderer())
+        return false;
+
+    return document->body()->renderer()->style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft();
+}
+
 IntSize FrameView::scrollOffsetForFixedPosition() const
 {
     return toIntSize(clampScrollPosition(scrollPosition()));
@@ -1502,20 +1517,12 @@
 // Note that this gets called at painting time.
 void FrameView::setIsOverlapped(bool isOverlapped)
 {
-    if (isOverlapped == m_isOverlapped)
-        return;
-
     m_isOverlapped = isOverlapped;
-    updateCanBlitOnScrollRecursively();
 }
 
 void FrameView::setContentIsOpaque(bool contentIsOpaque)
 {
-    if (contentIsOpaque == m_contentIsOpaque)
-        return;
-
     m_contentIsOpaque = contentIsOpaque;
-    updateCanBlitOnScrollRecursively();
 }
 
 void FrameView::restoreScrollbar()
@@ -1610,7 +1617,7 @@
 void FrameView::setScrollPosition(const IntPoint& scrollPoint)
 {
     TemporaryChange<bool> changeInProgrammaticScroll(m_inProgrammaticScroll, true);
-    m_maintainScrollPositionAnchor = 0;
+    m_maintainScrollPositionAnchor = nullptr;
 
     IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
 
@@ -1662,7 +1669,12 @@
 
     if (m_didScrollTimer.isActive())
         m_didScrollTimer.stop();
-    m_didScrollTimer.startOneShot(resourcePriorityUpdateDelayAfterScroll);
+    m_didScrollTimer.startOneShot(resourcePriorityUpdateDelayAfterScroll, FROM_HERE);
+
+    if (AXObjectCache* cache = m_frame->document()->existingAXObjectCache())
+        cache->handleScrollPositionChanged(this);
+
+    frame().loader().saveScrollState();
 }
 
 void FrameView::didScrollTimerFired(Timer<FrameView>*)
@@ -1744,7 +1756,7 @@
 void FrameView::scrollbarExistenceDidChange()
 {
     // We check to make sure the view is attached to a frame() as this method can
-    // be triggered before the view is attached by Frame::createView(...) setting
+    // be triggered before the view is attached by LocalFrame::createView(...) setting
     // various values such as setScrollBarModes(...) for example.  An ASSERT is
     // triggered when a view is layout before being attached to a frame().
     if (!frame().view())
@@ -1798,8 +1810,7 @@
     if (m_hasPendingLayout)
         return;
     m_hasPendingLayout = true;
-    if (!isServicingAnimations())
-        scheduleAnimation();
+    page()->animator().scheduleVisualUpdate();
 }
 
 static bool isObjectAncestorContainerOf(RenderObject* ancestor, RenderObject* descendant)
@@ -1848,8 +1859,7 @@
         ASSERT(!m_layoutSubtreeRoot->container() || !m_layoutSubtreeRoot->container()->needsLayout());
         InspectorInstrumentation::didInvalidateLayout(m_frame.get());
         m_hasPendingLayout = true;
-        if (!isServicingAnimations())
-            scheduleAnimation();
+        page()->animator().scheduleVisualUpdate();
     }
 }
 
@@ -1882,23 +1892,6 @@
         renderView->setNeedsLayout();
 }
 
-void FrameView::serviceScriptedAnimations(double monotonicAnimationStartTime)
-{
-    TemporaryChange<bool> servicing(m_servicingAnimations, true);
-
-    for (RefPtr<Frame> frame = m_frame; frame; frame = frame->tree().traverseNext()) {
-        frame->view()->serviceScrollAnimations();
-        DocumentAnimations::serviceOnAnimationFrame(*frame->document(), monotonicAnimationStartTime);
-    }
-
-    Vector<RefPtr<Document> > documents;
-    for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext())
-        documents.append(frame->document());
-
-    for (size_t i = 0; i < documents.size(); ++i)
-        documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
-}
-
 bool FrameView::isTransparent() const
 {
     return m_isTransparent;
@@ -1907,6 +1900,7 @@
 void FrameView::setTransparent(bool isTransparent)
 {
     m_isTransparent = isTransparent;
+    DisableCompositingQueryAsserts disabler;
     if (renderView() && renderView()->layer()->hasCompositedLayerMapping())
         renderView()->layer()->compositedLayerMapping()->updateContentsOpaque();
 }
@@ -1936,7 +1930,7 @@
 
 void FrameView::updateBackgroundRecursively(const Color& backgroundColor, bool transparent)
 {
-    for (Frame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
+    for (LocalFrame* frame = m_frame.get(); frame; frame = frame->tree().traverseNext(m_frame.get())) {
         if (FrameView* view = frame->view()) {
             view->setTransparent(transparent);
             view->setBaseBackgroundColor(backgroundColor);
@@ -1970,6 +1964,10 @@
 
 bool FrameView::updateWidgets()
 {
+    // This is always called from updateWidgetsTimerFired.
+    // m_updateWidgetsTimer should only be scheduled if we have widgets to update.
+    // Thus I believe we can stop checking isEmpty here, and just ASSERT isEmpty:
+    ASSERT(!m_widgetUpdateSet.isEmpty());
     if (m_nestedLayoutCount > 1 || m_widgetUpdateSet.isEmpty())
         return true;
 
@@ -2004,6 +2002,7 @@
 
 void FrameView::updateWidgetsTimerFired(Timer<FrameView>*)
 {
+    ASSERT(!isInPerformLayout());
     RefPtr<FrameView> protect(this);
     m_updateWidgetsTimer.stop();
     for (unsigned i = 0; i < maxUpdateWidgetsIterations; ++i) {
@@ -2014,27 +2013,45 @@
 
 void FrameView::flushAnyPendingPostLayoutTasks()
 {
+    ASSERT(!isInPerformLayout());
     if (m_postLayoutTasksTimer.isActive())
         performPostLayoutTasks();
     if (m_updateWidgetsTimer.isActive())
         updateWidgetsTimerFired(0);
 }
 
+void FrameView::scheduleUpdateWidgetsIfNecessary()
+{
+    ASSERT(!isInPerformLayout());
+    if (m_updateWidgetsTimer.isActive() || m_widgetUpdateSet.isEmpty())
+        return;
+    m_updateWidgetsTimer.startOneShot(0, FROM_HERE);
+}
+
 void FrameView::performPostLayoutTasks()
 {
+    // FIXME: We can reach here, even when the page is not active!
+    // http/tests/inspector/elements/html-link-import.html and many other
+    // tests hit that case.
+    // We should ASSERT(isActive()); or at least return early if we can!
+    ASSERT(!isInPerformLayout()); // Always before or after performLayout(), part of the highest-level layout() call.
     TRACE_EVENT0("webkit", "FrameView::performPostLayoutTasks");
     RefPtr<FrameView> protect(this);
 
     m_postLayoutTasksTimer.stop();
 
     m_frame->selection().setCaretRectNeedsUpdate();
-    m_frame->selection().updateAppearance();
 
+    {
+        // Hits in compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html
+        DisableCompositingQueryAsserts disabler;
+        m_frame->selection().updateAppearance();
+    }
+
+    ASSERT(m_frame->document());
     if (m_nestedLayoutCount <= 1) {
-        if (m_firstLayoutCallbackPending) {
+        if (m_firstLayoutCallbackPending)
             m_firstLayoutCallbackPending = false;
-            m_frame->loader().didFirstLayout();
-        }
 
         // Ensure that we always send this eventually.
         if (!m_frame->document()->parsing() && m_frame->loader().stateMachine()->committedFirstRealDocumentLoad())
@@ -2049,7 +2066,7 @@
         }
     }
 
-    FontFaceSet::didLayout(m_frame->document());
+    FontFaceSet::didLayout(*m_frame->document());
 
     updateWidgetPositions();
 
@@ -2057,8 +2074,7 @@
     if (!renderView())
         return;
 
-    if (!m_updateWidgetsTimer.isActive())
-        m_updateWidgetsTimer.startOneShot(0);
+    scheduleUpdateWidgetsIfNecessary();
 
     if (Page* page = m_frame->page()) {
         if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
@@ -2242,7 +2258,7 @@
 
 }
 
-IntRect FrameView::windowClipRect(bool clipToContents) const
+IntRect FrameView::windowClipRect(IncludeScrollbarsInRect scrollbarInclusion) const
 {
     ASSERT(m_frame->view() == this);
 
@@ -2250,7 +2266,7 @@
         return IntRect(IntPoint(), contentsSize());
 
     // Set our clip rect to be our contents.
-    IntRect clipRect = contentsToWindow(visibleContentRect(clipToContents ? ExcludeScrollbars : IncludeScrollbars));
+    IntRect clipRect = contentsToWindow(visibleContentRect(scrollbarInclusion));
     if (!m_frame->ownerElement())
         return clipRect;
 
@@ -2258,11 +2274,11 @@
     HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement();
     FrameView* parentView = ownerElement->document().view();
     if (parentView)
-        clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement, true));
+        clipRect.intersect(parentView->windowClipRectForFrameOwner(ownerElement));
     return clipRect;
 }
 
-IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement, bool clipToLayerContents) const
+IntRect FrameView::windowClipRectForFrameOwner(const HTMLFrameOwnerElement* ownerElement) const
 {
     // The renderer can sometimes be null when style="display:none" interacts
     // with external content and plugins.
@@ -2274,17 +2290,12 @@
     if (!enclosingLayer)
         return windowClipRect();
 
+    // FIXME: childrenClipRect relies on compositingState, which is not necessarily up to date.
+    // https://code.google.com/p/chromium/issues/detail?id=343769
+    DisableCompositingQueryAsserts disabler;
+
     // Apply the clip from the layer.
-    IntRect clipRect;
-    if (clipToLayerContents) {
-        // FIXME: childrenClipRect relies on compositingState, which is not necessarily up to date.
-        // https://code.google.com/p/chromium/issues/detail?id=343769
-        DisableCompositingQueryAsserts disabler;
-        clipRect = pixelSnappedIntRect(enclosingLayer->clipper().childrenClipRect());
-    } else {
-        clipRect = pixelSnappedIntRect(enclosingLayer->clipper().selfClipRect());
-    }
-    clipRect = contentsToWindow(clipRect);
+    IntRect clipRect = contentsToWindow(pixelSnappedIntRect(enclosingLayer->clipper().childrenClipRect()));
     return intersection(clipRect, windowClipRect());
 }
 
@@ -2324,7 +2335,7 @@
 
 void FrameView::getTickmarks(Vector<IntRect>& tickmarks) const
 {
-    tickmarks = frame().document()->markers()->renderedRectsForMarkers(DocumentMarker::TextMatch);
+    tickmarks = frame().document()->markers().renderedRectsForMarkers(DocumentMarker::TextMatch);
 }
 
 IntRect FrameView::windowResizerRect() const
@@ -2368,12 +2379,6 @@
     return !!m_frame->document();
 }
 
-ScrollableArea* FrameView::enclosingScrollableArea() const
-{
-    // FIXME: Walk up the frame tree and look for a scrollable parent frame or RenderLayer.
-    return 0;
-}
-
 IntRect FrameView::scrollableAreaBoundingBox() const
 {
     RenderPart* ownerRenderer = frame().ownerRenderer();
@@ -2464,9 +2469,7 @@
 
 bool FrameView::scrollAnimatorEnabled() const
 {
-    if (m_frame->settings())
-        return m_frame->settings()->scrollAnimatorEnabled();
-    return false;
+    return m_frame->settings() && m_frame->settings()->scrollAnimatorEnabled();
 }
 
 void FrameView::updateAnnotatedRegions()
@@ -2505,7 +2508,7 @@
         }
 
         if (!cornerStyle) {
-            // If we have an owning ipage/Frame element, then it can set the custom scrollbar also.
+            // If we have an owning ipage/LocalFrame element, then it can set the custom scrollbar also.
             if (RenderPart* renderer = m_frame->ownerRenderer())
                 cornerStyle = renderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), renderer->style());
         }
@@ -2606,7 +2609,7 @@
     if (!parent())
         return 0;
 
-    if (Frame* parentFrame = m_frame->tree().parent())
+    if (LocalFrame* parentFrame = m_frame->tree().parent())
         return parentFrame->view();
 
     return 0;
@@ -2623,14 +2626,14 @@
     if (m_frame->document()->url().isEmpty())
         return;
 
-    // FIXME: Why do we need this for hasCustomScrollbars?
-    // FIXME: supportsControlTints is currently true for a bunch of platforms.
-    // It should only be for Mac 10.6.
+    // FIXME: We shouldn't rely on the paint code to implement :window-inactive on custom scrollbars.
     if (!RenderTheme::theme().supportsControlTints() && !hasCustomScrollbars())
         return;
 
-    if (needsLayout())
-        layout();
+    // Updating layout can run script, which can tear down the FrameView.
+    RefPtr<FrameView> protector(this);
+    updateLayoutAndStyleForPainting();
+
     // FIXME: The use of paint seems like overkill: crbug.com/236892
     GraphicsContext context(0); // NULL canvas to get a non-painting context.
     context.setUpdatingControlTints(true);
@@ -2646,7 +2649,7 @@
 {
     if (m_inProgrammaticScroll)
         return;
-    m_maintainScrollPositionAnchor = 0;
+    m_maintainScrollPositionAnchor = nullptr;
     m_wasScrolledByUser = wasScrolledByUser;
 }
 
@@ -2698,7 +2701,7 @@
     }
 
     if (m_paintBehavior == PaintBehaviorNormal)
-        document->markers()->invalidateRenderedRectsForMarkersInRect(rect);
+        document->markers().invalidateRenderedRectsForMarkersInRect(rect);
 
     if (document->printing())
         m_paintBehavior |= PaintBehaviorFlattenCompositingLayers;
@@ -2776,6 +2779,16 @@
     ScrollView::paintOverhangAreas(context, horizontalOverhangArea, verticalOverhangArea, dirtyRect);
 }
 
+void FrameView::updateLayoutAndStyleForPainting()
+{
+    // Updating layout can run script, which can tear down the FrameView.
+    RefPtr<FrameView> protector(this);
+
+    updateLayoutAndStyleIfNeededRecursive();
+    if (RenderView* view = renderView())
+        view->compositor()->updateCompositingLayers();
+}
+
 void FrameView::updateLayoutAndStyleIfNeededRecursive()
 {
     // We have to crawl our entire tree looking for any FrameViews that need
@@ -2795,7 +2808,7 @@
     // FIXME: Calling layout() shouldn't trigger scripe execution or have any
     // observable effects on the frame tree but we're not quite there yet.
     Vector<RefPtr<FrameView> > frameViews;
-    for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+    for (LocalFrame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
         if (FrameView* view = child->view())
             frameViews.append(view);
     }
@@ -3038,7 +3051,7 @@
     if (trackRepaints == m_isTrackingRepaints)
         return;
 
-    for (Frame* frame = m_frame->tree().top(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = m_frame->tree().top(); frame; frame = frame->tree().traverseNext()) {
         if (RenderView* renderView = frame->contentRenderer())
             renderView->compositor()->setTracksRepaints(trackRepaints);
     }
diff --git a/Source/core/frame/FrameView.h b/Source/core/frame/FrameView.h
index 0217810..7ce9cf2 100644
--- a/Source/core/frame/FrameView.h
+++ b/Source/core/frame/FrameView.h
@@ -25,8 +25,8 @@
 #ifndef FrameView_h
 #define FrameView_h
 
+#include "RuntimeEnabledFeatures.h"
 #include "core/rendering/PaintPhase.h"
-#include "core/rendering/PartialLayoutState.h"
 #include "platform/geometry/LayoutRect.h"
 #include "platform/graphics/Color.h"
 #include "platform/scroll/ScrollView.h"
@@ -37,9 +37,12 @@
 namespace WebCore {
 
 class AXObjectCache;
+class DocumentLifecycle;
+class Cursor;
 class Element;
 class FloatSize;
-class Frame;
+class HTMLFrameOwnerElement;
+class LocalFrame;
 class KURL;
 class Node;
 class Page;
@@ -48,6 +51,7 @@
 class RenderObject;
 class RenderScrollbarPart;
 class RenderStyle;
+class RenderView;
 class RenderWidget;
 
 typedef unsigned long long DOMTimeStamp;
@@ -57,8 +61,8 @@
     friend class RenderView;
     friend class Internals;
 
-    static PassRefPtr<FrameView> create(Frame*);
-    static PassRefPtr<FrameView> create(Frame*, const IntSize& initialSize);
+    static PassRefPtr<FrameView> create(LocalFrame*);
+    static PassRefPtr<FrameView> create(LocalFrame*, const IntSize& initialSize);
 
     virtual ~FrameView();
 
@@ -69,7 +73,8 @@
 
     virtual bool scheduleAnimation() OVERRIDE;
 
-    Frame& frame() const { return *m_frame; }
+    LocalFrame& frame() const { return *m_frame; }
+    Page* page() const;
 
     RenderView* renderView() const;
 
@@ -78,6 +83,7 @@
     virtual PassRefPtr<Scrollbar> createScrollbar(ScrollbarOrientation) OVERRIDE;
 
     virtual void setContentsSize(const IntSize&) OVERRIDE;
+    IntPoint clampOffsetAtScale(const IntPoint& offset, float scale) const;
 
     void layout(bool allowSubtree = true);
     bool didFirstLayout() const;
@@ -107,18 +113,12 @@
 
     bool needsFullRepaint() const { return m_doFullRepaint; }
 
-    void serviceScriptedAnimations(double monotonicAnimationStartTime);
-
     void updateCompositingLayersAfterStyleChange();
     void updateCompositingLayersAfterLayout();
 
     bool hasCompositedContent() const;
     bool isEnclosedInCompositingLayer() const;
 
-    // Returns true when a paint with the PaintBehaviorFlattenCompositingLayers flag set gives
-    // a faithful representation of the content.
-    bool isSoftwareRenderable() const;
-
     void resetScrollbars();
     void prepareForDetach();
     void detachCustomScrollbars();
@@ -138,8 +138,8 @@
 
     void adjustViewSize();
 
-    virtual IntRect windowClipRect(bool clipToContents = true) const OVERRIDE;
-    IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*, bool clipToLayerContents) const;
+    virtual IntRect windowClipRect(IncludeScrollbarsInRect = ExcludeScrollbars) const OVERRIDE;
+    IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*) const;
 
     virtual IntRect windowResizerRect() const OVERRIDE;
 
@@ -160,7 +160,7 @@
     // This is different than visibleContentRect() in that it ignores negative (or overly positive)
     // offsets from rubber-banding, and it takes zooming into account.
     LayoutRect viewportConstrainedVisibleContentRect() const;
-    void viewportConstrainedVisibleContentRectChanged(bool viewportWidthChanged, bool viewportHeightChanged);
+    void viewportConstrainedVisibleContentSizeChanged(bool widthChanged, bool heightChanged);
 
     AtomicString mediaType() const;
     void setMediaType(const AtomicString&);
@@ -210,8 +210,6 @@
     bool hasEverPainted() const { return m_lastPaintTime; }
     void setNodeToDraw(Node*);
 
-    bool isServicingAnimations() const { return m_servicingAnimations; }
-
     virtual void paintOverhangAreas(GraphicsContext*, const IntRect& horizontalOverhangArea, const IntRect& verticalOverhangArea, const IntRect& dirtyRect) OVERRIDE;
     virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect) OVERRIDE;
     virtual void paintScrollbar(GraphicsContext*, Scrollbar*, const IntRect&) OVERRIDE;
@@ -220,6 +218,7 @@
 
     static double currentFrameTimeStamp() { return s_currentFrameTimeStamp; }
 
+    void updateLayoutAndStyleForPainting();
     void updateLayoutAndStyleIfNeededRecursive();
 
     void incrementVisuallyNonEmptyCharacterCount(unsigned);
@@ -302,12 +301,30 @@
     // DEPRECATED: Use viewportConstrainedVisibleContentRect() instead.
     IntSize scrollOffsetForFixedPosition() const;
 
-    PartialLayoutState& partialLayout() { return m_partialLayout; }
+    virtual bool shouldPlaceVerticalScrollbarOnLeft() const OVERRIDE;
 
     // Override scrollbar notifications to update the AXObject cache.
     virtual void didAddScrollbar(Scrollbar*, ScrollbarOrientation) OVERRIDE;
     virtual void willRemoveScrollbar(Scrollbar*, ScrollbarOrientation) OVERRIDE;
 
+    virtual bool shouldAttemptToScrollUsingFastPath() const OVERRIDE;
+    // FIXME: This should probably be renamed as the 'inSubtreeLayout' parameter
+    // passed around the FrameView layout methods can be true while this returns
+    // false.
+    bool isSubtreeLayout() const { return !!m_layoutSubtreeRoot; }
+
+    // ScrollableArea interface
+    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE;
+    virtual void getTickmarks(Vector<IntRect>&) const OVERRIDE;
+    virtual void scrollTo(const IntSize&) OVERRIDE;
+    virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
+    virtual bool scrollAnimatorEnabled() const OVERRIDE;
+    virtual bool usesCompositedScrolling() const OVERRIDE;
+    virtual GraphicsLayer* layerForScrolling() const OVERRIDE;
+    virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
+    virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE;
+    virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE;
+
 protected:
     virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) OVERRIDE;
     virtual void scrollContentsSlowPath(const IntRect& updateRect) OVERRIDE;
@@ -316,7 +333,7 @@
     virtual bool isFlippedDocument() const OVERRIDE;
 
 private:
-    explicit FrameView(Frame*);
+    explicit FrameView(LocalFrame*);
 
     void reset();
     void init();
@@ -327,7 +344,7 @@
     friend class RenderWidget;
     bool useSlowRepaints(bool considerOverlap = true) const;
     bool useSlowRepaintsIfNotOverlapped() const;
-    void updateCanBlitOnScrollRecursively();
+
     bool contentsInCompositedLayer() const;
 
     void applyOverflowToViewportAndSetRenderer(RenderObject*, ScrollbarMode& hMode, ScrollbarMode& vMode);
@@ -358,25 +375,13 @@
     virtual IntPoint convertToContainingView(const IntPoint&) const OVERRIDE;
     virtual IntPoint convertFromContainingView(const IntPoint&) const OVERRIDE;
 
-    // ScrollableArea interface
-    virtual void invalidateScrollbarRect(Scrollbar*, const IntRect&) OVERRIDE;
-    virtual void getTickmarks(Vector<IntRect>&) const OVERRIDE;
-    virtual void scrollTo(const IntSize&) OVERRIDE;
-    virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
-    virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
-    virtual bool scrollAnimatorEnabled() const OVERRIDE;
-    virtual bool usesCompositedScrolling() const OVERRIDE;
-    virtual GraphicsLayer* layerForScrolling() const OVERRIDE;
-    virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
-    virtual GraphicsLayer* layerForVerticalScrollbar() const OVERRIDE;
-    virtual GraphicsLayer* layerForScrollCorner() const OVERRIDE;
-
     void sendResizeEventIfNeeded();
 
     void updateScrollableAreaSet();
 
     virtual void notifyPageThatContentAreaWillPaint() const OVERRIDE;
 
+    void scheduleUpdateWidgetsIfNecessary();
     void updateWidgetsTimerFired(Timer<FrameView>*);
     bool updateWidgets();
 
@@ -385,7 +390,7 @@
     void didScrollTimerFired(Timer<FrameView>*);
 
     bool hasCustomScrollbars() const;
-    bool shouldUseCustomScrollbars(Element*& customScrollbarElement, Frame*& customScrollbarFrame);
+    bool shouldUseCustomScrollbars(Element*& customScrollbarElement, LocalFrame*& customScrollbarFrame);
 
     virtual void updateScrollCorner() OVERRIDE;
 
@@ -398,7 +403,6 @@
 
     void setLayoutSizeInternal(const IntSize&);
 
-    bool isSubtreeLayout() const { return !!m_layoutSubtreeRoot; }
     bool repaintAllowed() const
     {
         if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
@@ -418,7 +422,7 @@
     // FIXME: These are just "children" of the FrameView and should be RefPtr<Widget> instead.
     HashSet<RefPtr<RenderWidget> > m_widgets;
 
-    RefPtr<Frame> m_frame;
+    RefPtr<LocalFrame> m_frame;
 
     bool m_doFullRepaint;
 
@@ -495,13 +499,10 @@
 
     bool m_hasSoftwareFilters;
 
-    bool m_servicingAnimations;
-
     float m_visibleContentScaleFactor;
     IntSize m_inputEventsOffsetForEmulation;
     float m_inputEventsScaleFactorForEmulation;
 
-    PartialLayoutState m_partialLayout;
     IntSize m_layoutSize;
     bool m_layoutSizeFixedToFrameSize;
 
diff --git a/Source/core/frame/History.cpp b/Source/core/frame/History.cpp
index 1ee748d..3d82ad6 100644
--- a/Source/core/frame/History.cpp
+++ b/Source/core/frame/History.cpp
@@ -29,7 +29,7 @@
 #include "bindings/v8/ExceptionState.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
@@ -42,9 +42,9 @@
 
 namespace WebCore {
 
-History::History(Frame* frame)
+History::History(LocalFrame* frame)
     : DOMWindowProperty(frame)
-    , m_lastStateObjectRequested(0)
+    , m_lastStateObjectRequested(nullptr)
 {
     ScriptWrappable::init(this);
 }
diff --git a/Source/core/frame/History.h b/Source/core/frame/History.h
index 40abf0d..e330052 100644
--- a/Source/core/frame/History.h
+++ b/Source/core/frame/History.h
@@ -36,14 +36,14 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class KURL;
 class ExecutionContext;
 class ExceptionState;
 
 class History FINAL : public ScriptWrappable, public RefCounted<History>, public DOMWindowProperty {
 public:
-    static PassRefPtr<History> create(Frame* frame) { return adoptRef(new History(frame)); }
+    static PassRefPtr<History> create(LocalFrame* frame) { return adoptRef(new History(frame)); }
 
     unsigned length() const;
     SerializedScriptValue* state();
@@ -58,7 +58,7 @@
     void stateObjectAdded(PassRefPtr<SerializedScriptValue>, const String& title, const String& url, UpdateBackForwardListPolicy, ExceptionState&);
 
 private:
-    explicit History(Frame*);
+    explicit History(LocalFrame*);
 
     KURL urlForState(const String& url);
 
diff --git a/Source/core/frame/ImageBitmap.cpp b/Source/core/frame/ImageBitmap.cpp
index ec54c64..cd66f75 100644
--- a/Source/core/frame/ImageBitmap.cpp
+++ b/Source/core/frame/ImageBitmap.cpp
@@ -30,7 +30,7 @@
 {
     IntRect intersectRect = intersection(IntRect(IntPoint(), image->size()), cropRect);
     if (!intersectRect.width() || !intersectRect.height())
-        return 0;
+        return nullptr;
 
     SkBitmap cropped;
     image->nativeImageForCurrentFrame()->bitmap().extractSubset(&cropped, intersectRect);
@@ -39,7 +39,7 @@
 
 ImageBitmap::ImageBitmap(HTMLImageElement* image, const IntRect& cropRect)
     : m_imageElement(image)
-    , m_bitmap(0)
+    , m_bitmap(nullptr)
     , m_cropRect(cropRect)
 {
     IntRect srcRect = intersection(cropRect, IntRect(0, 0, image->width(), image->height()));
@@ -47,7 +47,7 @@
     m_bitmapOffset = srcRect.location();
 
     if (!srcRect.width() || !srcRect.height())
-        m_imageElement = 0;
+        m_imageElement = nullptr;
     else
         m_imageElement->addClient(this);
 
@@ -55,7 +55,7 @@
 }
 
 ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
-    : m_imageElement(0)
+    : m_imageElement(nullptr)
     , m_cropRect(cropRect)
     , m_bitmapOffset(IntPoint())
 {
@@ -77,7 +77,7 @@
 }
 
 ImageBitmap::ImageBitmap(HTMLCanvasElement* canvas, const IntRect& cropRect)
-    : m_imageElement(0)
+    : m_imageElement(nullptr)
     , m_cropRect(cropRect)
     , m_bitmapOffset(IntPoint())
 {
@@ -93,7 +93,7 @@
 }
 
 ImageBitmap::ImageBitmap(ImageData* data, const IntRect& cropRect)
-    : m_imageElement(0)
+    : m_imageElement(nullptr)
     , m_cropRect(cropRect)
     , m_bitmapOffset(IntPoint())
 {
@@ -113,7 +113,7 @@
 
 ImageBitmap::ImageBitmap(ImageBitmap* bitmap, const IntRect& cropRect)
     : m_imageElement(bitmap->imageElement())
-    , m_bitmap(0)
+    , m_bitmap(nullptr)
     , m_cropRect(cropRect)
     , m_bitmapOffset(IntPoint())
 {
@@ -133,7 +133,7 @@
 }
 
 ImageBitmap::ImageBitmap(Image* image, const IntRect& cropRect)
-    : m_imageElement(0)
+    : m_imageElement(nullptr)
     , m_cropRect(cropRect)
 {
     IntRect srcRect = intersection(cropRect, IntRect(IntPoint(), image->size()));
@@ -149,47 +149,47 @@
         m_imageElement->removeClient(this);
 }
 
-PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(HTMLImageElement* image, const IntRect& cropRect)
 {
     IntRect normalizedCropRect = normalizeRect(cropRect);
-    return adoptRef(new ImageBitmap(image, normalizedCropRect));
+    return adoptRefWillBeNoop(new ImageBitmap(image, normalizedCropRect));
 }
 
-PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLVideoElement* video, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(HTMLVideoElement* video, const IntRect& cropRect)
 {
     IntRect normalizedCropRect = normalizeRect(cropRect);
-    return adoptRef(new ImageBitmap(video, normalizedCropRect));
+    return adoptRefWillBeNoop(new ImageBitmap(video, normalizedCropRect));
 }
 
-PassRefPtr<ImageBitmap> ImageBitmap::create(HTMLCanvasElement* canvas, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(HTMLCanvasElement* canvas, const IntRect& cropRect)
 {
     IntRect normalizedCropRect = normalizeRect(cropRect);
-    return adoptRef(new ImageBitmap(canvas, normalizedCropRect));
+    return adoptRefWillBeNoop(new ImageBitmap(canvas, normalizedCropRect));
 }
 
-PassRefPtr<ImageBitmap> ImageBitmap::create(ImageData* data, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(ImageData* data, const IntRect& cropRect)
 {
     IntRect normalizedCropRect = normalizeRect(cropRect);
-    return adoptRef(new ImageBitmap(data, normalizedCropRect));
+    return adoptRefWillBeNoop(new ImageBitmap(data, normalizedCropRect));
 }
 
-PassRefPtr<ImageBitmap> ImageBitmap::create(ImageBitmap* bitmap, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(ImageBitmap* bitmap, const IntRect& cropRect)
 {
     IntRect normalizedCropRect = normalizeRect(cropRect);
-    return adoptRef(new ImageBitmap(bitmap, normalizedCropRect));
+    return adoptRefWillBeNoop(new ImageBitmap(bitmap, normalizedCropRect));
 }
 
-PassRefPtr<ImageBitmap> ImageBitmap::create(Image* image, const IntRect& cropRect)
+PassRefPtrWillBeRawPtr<ImageBitmap> ImageBitmap::create(Image* image, const IntRect& cropRect)
 {
     IntRect normalizedCropRect = normalizeRect(cropRect);
-    return adoptRef(new ImageBitmap(image, normalizedCropRect));
+    return adoptRefWillBeNoop(new ImageBitmap(image, normalizedCropRect));
 }
 
 void ImageBitmap::notifyImageSourceChanged()
 {
     m_bitmap = cropImage(m_imageElement->cachedImage()->image(), m_cropRect);
     m_bitmapOffset = IntPoint();
-    m_imageElement = 0;
+    m_imageElement = nullptr;
 }
 
 PassRefPtr<Image> ImageBitmap::bitmapImage() const
@@ -200,4 +200,32 @@
     return m_bitmap;
 }
 
+PassRefPtr<Image> ImageBitmap::getSourceImageForCanvas(SourceImageMode, SourceImageStatus* status) const
+{
+    *status = NormalSourceImageStatus;
+    return bitmapImage();
+}
+
+void ImageBitmap::adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const
+{
+    FloatRect intersectRect = intersection(m_bitmapRect, *srcRect);
+    FloatRect newSrcRect = intersectRect;
+    newSrcRect.move(m_bitmapOffset - m_bitmapRect.location());
+    FloatRect newDstRect(FloatPoint(intersectRect.location() - srcRect->location()), m_bitmapRect.size());
+    newDstRect.scale(dstRect->width() / srcRect->width() * intersectRect.width() / m_bitmapRect.width(),
+        dstRect->height() / srcRect->height() * intersectRect.height() / m_bitmapRect.height());
+    newDstRect.moveBy(dstRect->location());
+    *srcRect = newSrcRect;
+    *dstRect = newDstRect;
+}
+
+FloatSize ImageBitmap::sourceSize() const
+{
+    return FloatSize(width(), height());
+}
+
+void ImageBitmap::trace(Visitor*)
+{
+}
+
 }
diff --git a/Source/core/frame/ImageBitmap.h b/Source/core/frame/ImageBitmap.h
index 7f62bda..7afffb7 100644
--- a/Source/core/frame/ImageBitmap.h
+++ b/Source/core/frame/ImageBitmap.h
@@ -7,6 +7,8 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/html/HTMLImageElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
+#include "heap/Handle.h"
 #include "platform/geometry/IntRect.h"
 #include "platform/graphics/Image.h"
 #include "wtf/PassRefPtr.h"
@@ -18,21 +20,20 @@
 class HTMLVideoElement;
 class ImageData;
 
-class ImageBitmap FINAL : public RefCounted<ImageBitmap>, public ScriptWrappable, public ImageLoaderClient {
-
+class ImageBitmap FINAL : public RefCountedWillBeGarbageCollectedFinalized<ImageBitmap>, public ScriptWrappable, public ImageLoaderClient, public CanvasImageSource {
+    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(ImageBitmap);
 public:
-    static PassRefPtr<ImageBitmap> create(HTMLImageElement*, const IntRect&);
-    static PassRefPtr<ImageBitmap> create(HTMLVideoElement*, const IntRect&);
-    static PassRefPtr<ImageBitmap> create(HTMLCanvasElement*, const IntRect&);
-    static PassRefPtr<ImageBitmap> create(ImageData*, const IntRect&);
-    static PassRefPtr<ImageBitmap> create(ImageBitmap*, const IntRect&);
-    static PassRefPtr<ImageBitmap> create(Image*, const IntRect&);
+    static PassRefPtrWillBeRawPtr<ImageBitmap> create(HTMLImageElement*, const IntRect&);
+    static PassRefPtrWillBeRawPtr<ImageBitmap> create(HTMLVideoElement*, const IntRect&);
+    static PassRefPtrWillBeRawPtr<ImageBitmap> create(HTMLCanvasElement*, const IntRect&);
+    static PassRefPtrWillBeRawPtr<ImageBitmap> create(ImageData*, const IntRect&);
+    static PassRefPtrWillBeRawPtr<ImageBitmap> create(ImageBitmap*, const IntRect&);
+    static PassRefPtrWillBeRawPtr<ImageBitmap> create(Image*, const IntRect&);
 
     PassRefPtr<Image> bitmapImage() const;
     PassRefPtr<HTMLImageElement> imageElement() const { return m_imageElement; }
 
     IntRect bitmapRect() const { return m_bitmapRect; }
-    IntPoint bitmapOffset() const { return m_bitmapOffset; }
 
     int width() const { return m_cropRect.width(); }
     int height() const { return m_cropRect.height(); }
@@ -40,6 +41,14 @@
 
     virtual ~ImageBitmap();
 
+    // CanvasImageSource implementation
+    virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+    virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE { return false; };
+    virtual void adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const OVERRIDE;
+    virtual FloatSize sourceSize() const OVERRIDE;
+
+    virtual void trace(Visitor*);
+
 private:
     ImageBitmap(HTMLImageElement*, const IntRect&);
     ImageBitmap(HTMLVideoElement*, const IntRect&);
diff --git a/Source/core/frame/ImageBitmap.idl b/Source/core/frame/ImageBitmap.idl
index 903a2d7..b211d6e 100644
--- a/Source/core/frame/ImageBitmap.idl
+++ b/Source/core/frame/ImageBitmap.idl
@@ -3,6 +3,7 @@
 // found in the LICENSE file.
 
 [
+    WillBeGarbageCollected,
 ] interface ImageBitmap {
     readonly attribute long width;
     readonly attribute long height;
diff --git a/Source/core/frame/ImageBitmapTest.cpp b/Source/core/frame/ImageBitmapTest.cpp
index 6e48156..d6981bc 100644
--- a/Source/core/frame/ImageBitmapTest.cpp
+++ b/Source/core/frame/ImageBitmapTest.cpp
@@ -40,6 +40,7 @@
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/canvas/CanvasRenderingContext2D.h"
+#include "heap/Handle.h"
 #include "platform/graphics/BitmapImage.h"
 #include "platform/graphics/skia/NativeImageSkia.h"
 #include "platform/network/ResourceRequest.h"
@@ -69,6 +70,11 @@
     }
     virtual void TearDown()
     {
+        // Garbage collection is required prior to switching out the
+        // test's memory cache; image resources are released, evicting
+        // them from the cache.
+        Heap::collectGarbage(ThreadState::NoHeapPointersOnStack, Heap::ForcedForTesting);
+
         // Regain the ownership of testing memory cache, so that it will be
         // destroyed.
         m_testingMemoryCache = adoptPtr(memoryCache());
@@ -88,10 +94,10 @@
     RefPtr<HTMLImageElement> imageElement = HTMLImageElement::create(*Document::create().get());
     imageElement->setImageResource(new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get()));
 
-    RefPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageElement.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
-    RefPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width() / 2, m_bitmap.height() / 2));
-    RefPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
-    RefPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
+    RefPtrWillBeRawPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageElement.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
+    RefPtrWillBeRawPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width() / 2, m_bitmap.height() / 2));
+    RefPtrWillBeRawPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+    RefPtrWillBeRawPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageElement.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
 
     ASSERT_EQ(imageBitmapNoCrop->bitmapImage().get(), imageElement->cachedImage()->image());
     ASSERT_EQ(imageBitmapInteriorCrop->bitmapImage().get(), imageElement->cachedImage()->image());
@@ -142,12 +148,12 @@
     ASSERT_EQ(imageExteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
     ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
 
-    RefPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+    RefPtrWillBeRawPtr<ImageBitmap> imageBitmapInteriorCrop = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
     {
-        RefPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageNoCrop.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
-        RefPtr<ImageBitmap> imageBitmapInteriorCrop2 = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
-        RefPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageExteriorCrop.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
-        RefPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageOutsideCrop.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
+        RefPtrWillBeRawPtr<ImageBitmap> imageBitmapNoCrop = ImageBitmap::create(imageNoCrop.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
+        RefPtrWillBeRawPtr<ImageBitmap> imageBitmapInteriorCrop2 = ImageBitmap::create(imageInteriorCrop.get(), IntRect(m_bitmap.width() / 2, m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+        RefPtrWillBeRawPtr<ImageBitmap> imageBitmapExteriorCrop = ImageBitmap::create(imageExteriorCrop.get(), IntRect(-m_bitmap.width() / 2, -m_bitmap.height() / 2, m_bitmap.width(), m_bitmap.height()));
+        RefPtrWillBeRawPtr<ImageBitmap> imageBitmapOutsideCrop = ImageBitmap::create(imageOutsideCrop.get(), IntRect(-m_bitmap.width(), -m_bitmap.height(), m_bitmap.width(), m_bitmap.height()));
 
         // Images that are referenced by ImageBitmaps have CacheLiveResourcePriorityHigh.
         ASSERT_EQ(imageNoCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh);
@@ -156,6 +162,15 @@
 
         // ImageBitmaps that do not contain any of the source image do not elevate CacheLiveResourcePriority.
         ASSERT_EQ(imageOutsideCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityLow);
+
+        // Stub out references to the ImageBitmaps created and force a
+        // garbage collection to have the ImageBitmaps be collected and
+        // destructed.
+        imageBitmapNoCrop = nullptr;
+        imageBitmapInteriorCrop2 = nullptr;
+        imageBitmapExteriorCrop = nullptr;
+        imageBitmapOutsideCrop = nullptr;
+        Heap::collectGarbage(ThreadState::HeapPointersOnStack, Heap::ForcedForTesting);
     }
 
     // CacheLiveResourcePriroity should return to CacheLiveResourcePriorityLow when no ImageBitmaps reference the image.
@@ -165,6 +180,7 @@
 
     // There is still an ImageBitmap that references this image.
     ASSERT_EQ(imageInteriorCrop->cachedImage()->cacheLiveResourcePriority(), Resource::CacheLiveResourcePriorityHigh);
+    imageBitmapInteriorCrop = nullptr;
 }
 
 // Verifies that ImageBitmaps constructed from HTMLImageElements hold a reference to the original Image if the HTMLImageElement src is changed.
@@ -174,7 +190,7 @@
     ResourcePtr<ImageResource> originalImageResource = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap)).get());
     image->setImageResource(originalImageResource.get());
 
-    RefPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
+    RefPtrWillBeRawPtr<ImageBitmap> imageBitmap = ImageBitmap::create(image.get(), IntRect(0, 0, m_bitmap.width(), m_bitmap.height()));
     ASSERT_EQ(imageBitmap->bitmapImage().get(), originalImageResource->image());
 
     ResourcePtr<ImageResource> newImageResource = new ImageResource(BitmapImage::create(NativeImageSkia::create(m_bitmap2)).get());
@@ -196,9 +212,9 @@
     RefPtr<HTMLCanvasElement> canvasElement = HTMLCanvasElement::create(*Document::create().get());
     canvasElement->setHeight(40);
     canvasElement->setWidth(40);
-    RefPtr<ImageBitmap> imageBitmapDerived;
+    RefPtrWillBeRawPtr<ImageBitmap> imageBitmapDerived;
     {
-        RefPtr<ImageBitmap> imageBitmapFromCanvas = ImageBitmap::create(canvasElement.get(), IntRect(0, 0, canvasElement->width(), canvasElement->height()));
+        RefPtrWillBeRawPtr<ImageBitmap> imageBitmapFromCanvas = ImageBitmap::create(canvasElement.get(), IntRect(0, 0, canvasElement->width(), canvasElement->height()));
         imageBitmapDerived = ImageBitmap::create(imageBitmapFromCanvas.get(), IntRect(0, 0, 20, 20));
     }
     CanvasRenderingContext* context = canvasElement->getContext("2d");
diff --git a/Source/core/frame/LocalFrame.cpp b/Source/core/frame/LocalFrame.cpp
new file mode 100644
index 0000000..2add1aa
--- /dev/null
+++ b/Source/core/frame/LocalFrame.cpp
@@ -0,0 +1,641 @@
+/*
+ * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+ *                     1999 Lars Knoll <knoll@kde.org>
+ *                     1999 Antti Koivisto <koivisto@kde.org>
+ *                     2000 Simon Hausmann <hausmann@kde.org>
+ *                     2000 Stefan Schimanski <1Stein@gmx.de>
+ *                     2001 George Staikos <staikos@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Google Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/frame/LocalFrame.h"
+
+#include "RuntimeEnabledFeatures.h"
+#include "bindings/v8/ScriptController.h"
+#include "core/dom/DocumentType.h"
+#include "core/dom/WheelController.h"
+#include "core/editing/Editor.h"
+#include "core/editing/FrameSelection.h"
+#include "core/editing/InputMethodController.h"
+#include "core/editing/SpellChecker.h"
+#include "core/editing/htmlediting.h"
+#include "core/editing/markup.h"
+#include "core/events/Event.h"
+#include "core/fetch/ResourceFetcher.h"
+#include "core/frame/DOMWindow.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLFrameElementBase.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/page/Chrome.h"
+#include "core/page/EventHandler.h"
+#include "core/page/FocusController.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/rendering/HitTestResult.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderPart.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "core/svg/SVGDocument.h"
+#include "platform/DragImage.h"
+#include "platform/graphics/GraphicsContext.h"
+#include "platform/graphics/ImageBuffer.h"
+#include "wtf/PassOwnPtr.h"
+#include "wtf/StdLibExtras.h"
+
+using namespace std;
+
+namespace WebCore {
+
+using namespace HTMLNames;
+
+static inline float parentPageZoomFactor(LocalFrame* frame)
+{
+    LocalFrame* parent = frame->tree().parent();
+    if (!parent)
+        return 1;
+    return parent->pageZoomFactor();
+}
+
+static inline float parentTextZoomFactor(LocalFrame* frame)
+{
+    LocalFrame* parent = frame->tree().parent();
+    if (!parent)
+        return 1;
+    return parent->textZoomFactor();
+}
+
+inline LocalFrame::LocalFrame(FrameLoaderClient* client, FrameHost* host, HTMLFrameOwnerElement* ownerElement)
+    : Frame(host, ownerElement)
+    , m_treeNode(this)
+    , m_loader(this, client)
+    , m_navigationScheduler(this)
+    , m_script(adoptPtr(new ScriptController(this)))
+    , m_editor(Editor::create(*this))
+    , m_spellChecker(SpellChecker::create(*this))
+    , m_selection(adoptPtr(new FrameSelection(this)))
+    , m_eventHandler(adoptPtr(new EventHandler(this)))
+    , m_inputMethodController(InputMethodController::create(*this))
+    , m_pageZoomFactor(parentPageZoomFactor(this))
+    , m_textZoomFactor(parentTextZoomFactor(this))
+    , m_orientation(0)
+    , m_inViewSourceMode(false)
+{
+    if (this->ownerElement()) {
+        page()->incrementSubframeCount();
+        this->ownerElement()->setContentFrame(*this);
+    }
+}
+
+PassRefPtr<LocalFrame> LocalFrame::create(FrameLoaderClient* client, FrameHost* host, HTMLFrameOwnerElement* ownerElement)
+{
+    RefPtr<LocalFrame> frame = adoptRef(new LocalFrame(client, host, ownerElement));
+    if (!frame->ownerElement())
+        frame->page()->setMainFrame(frame);
+    InspectorInstrumentation::frameAttachedToParent(frame.get());
+    return frame.release();
+}
+
+LocalFrame::~LocalFrame()
+{
+    setView(nullptr);
+    loader().clear();
+    setDOMWindow(nullptr);
+
+    disconnectOwnerElement();
+}
+
+bool LocalFrame::inScope(TreeScope* scope) const
+{
+    ASSERT(scope);
+    Document* doc = document();
+    if (!doc)
+        return false;
+    HTMLFrameOwnerElement* owner = doc->ownerElement();
+    if (!owner)
+        return false;
+    return owner->treeScope() == scope;
+}
+
+void LocalFrame::setView(PassRefPtr<FrameView> view)
+{
+    // We the custom scroll bars as early as possible to prevent m_doc->detach()
+    // from messing with the view such that its scroll bars won't be torn down.
+    // FIXME: We should revisit this.
+    if (m_view)
+        m_view->prepareForDetach();
+
+    // Prepare for destruction now, so any unload event handlers get run and the DOMWindow is
+    // notified. If we wait until the view is destroyed, then things won't be hooked up enough for
+    // these calls to work.
+    if (!view && document() && document()->isActive()) {
+        // FIXME: We don't call willRemove here. Why is that OK?
+        document()->prepareForDestruction();
+    }
+
+    eventHandler().clear();
+
+    m_view = view;
+
+    if (m_view && isMainFrame())
+        m_view->setVisibleContentScaleFactor(page()->pageScaleFactor());
+}
+
+void LocalFrame::sendOrientationChangeEvent(int orientation)
+{
+    if (!RuntimeEnabledFeatures::orientationEventEnabled())
+        return;
+
+    m_orientation = orientation;
+    if (DOMWindow* window = domWindow())
+        window->dispatchEvent(Event::create(EventTypeNames::orientationchange));
+}
+
+void LocalFrame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio)
+{
+    // In setting printing, we should not validate resources already cached for the document.
+    // See https://bugs.webkit.org/show_bug.cgi?id=43704
+    ResourceCacheValidationSuppressor validationSuppressor(document()->fetcher());
+
+    document()->setPrinting(printing);
+    view()->adjustMediaTypeForPrinting(printing);
+
+    document()->styleResolverChanged(RecalcStyleImmediately);
+    if (shouldUsePrintingLayout()) {
+        view()->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio);
+    } else {
+        view()->forceLayout();
+        view()->adjustViewSize();
+    }
+
+    // Subframes of the one we're printing don't lay out to the page size.
+    for (RefPtr<LocalFrame> child = tree().firstChild(); child; child = child->tree().nextSibling())
+        child->setPrinting(printing, FloatSize(), FloatSize(), 0);
+}
+
+bool LocalFrame::shouldUsePrintingLayout() const
+{
+    // Only top frame being printed should be fit to page size.
+    // Subframes should be constrained by parents only.
+    return document()->printing() && (!tree().parent() || !tree().parent()->document()->printing());
+}
+
+FloatSize LocalFrame::resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize)
+{
+    FloatSize resultSize;
+    if (!contentRenderer())
+        return FloatSize();
+
+    if (contentRenderer()->style()->isHorizontalWritingMode()) {
+        ASSERT(fabs(originalSize.width()) > numeric_limits<float>::epsilon());
+        float ratio = originalSize.height() / originalSize.width();
+        resultSize.setWidth(floorf(expectedSize.width()));
+        resultSize.setHeight(floorf(resultSize.width() * ratio));
+    } else {
+        ASSERT(fabs(originalSize.height()) > numeric_limits<float>::epsilon());
+        float ratio = originalSize.width() / originalSize.height();
+        resultSize.setHeight(floorf(expectedSize.height()));
+        resultSize.setWidth(floorf(resultSize.height() * ratio));
+    }
+    return resultSize;
+}
+
+void LocalFrame::setDOMWindow(PassRefPtr<DOMWindow> domWindow)
+{
+    InspectorInstrumentation::frameWindowDiscarded(this, m_domWindow.get());
+    if (domWindow)
+        script().clearWindowShell();
+    Frame::setDOMWindow(domWindow);
+}
+
+RenderPart* LocalFrame::ownerRenderer() const
+{
+    if (!ownerElement())
+        return 0;
+    RenderObject* object = ownerElement()->renderer();
+    if (!object)
+        return 0;
+    // FIXME: If <object> is ever fixed to disassociate itself from frames
+    // that it has started but canceled, then this can turn into an ASSERT
+    // since ownerElement() would be 0 when the load is canceled.
+    // https://bugs.webkit.org/show_bug.cgi?id=18585
+    if (!object->isRenderPart())
+        return 0;
+    return toRenderPart(object);
+}
+
+void LocalFrame::didChangeVisibilityState()
+{
+    if (document())
+        document()->didChangeVisibilityState();
+
+    Vector<RefPtr<LocalFrame> > childFrames;
+    for (LocalFrame* child = tree().firstChild(); child; child = child->tree().nextSibling())
+        childFrames.append(child);
+
+    for (size_t i = 0; i < childFrames.size(); ++i)
+        childFrames[i]->didChangeVisibilityState();
+}
+
+void LocalFrame::willDetachFrameHost()
+{
+    // We should never be detatching the page during a Layout.
+    RELEASE_ASSERT(!m_view || !m_view->isInPerformLayout());
+
+    if (LocalFrame* parent = tree().parent())
+        parent->loader().checkLoadComplete();
+
+    Frame::willDetachFrameHost();
+    script().clearScriptObjects();
+
+    if (page() && page()->scrollingCoordinator() && m_view)
+        page()->scrollingCoordinator()->willDestroyScrollableArea(m_view.get());
+}
+
+void LocalFrame::detachFromFrameHost()
+{
+    // We should never be detatching the page during a Layout.
+    RELEASE_ASSERT(!m_view || !m_view->isInPerformLayout());
+    Frame::detachFromFrameHost();
+}
+
+void LocalFrame::disconnectOwnerElement()
+{
+    if (ownerElement()) {
+        if (Document* doc = document())
+            doc->topDocument().clearAXObjectCache();
+        ownerElement()->clearContentFrame();
+        if (page())
+            page()->decrementSubframeCount();
+    }
+    m_ownerElement = 0;
+}
+
+String LocalFrame::documentTypeString() const
+{
+    if (DocumentType* doctype = document()->doctype())
+        return createMarkup(doctype);
+
+    return String();
+}
+
+String LocalFrame::selectedText() const
+{
+    return selection().selectedText();
+}
+
+String LocalFrame::selectedTextForClipboard() const
+{
+    return selection().selectedTextForClipboard();
+}
+
+VisiblePosition LocalFrame::visiblePositionForPoint(const IntPoint& framePoint)
+{
+    HitTestResult result = eventHandler().hitTestResultAtPoint(framePoint);
+    Node* node = result.innerNonSharedNode();
+    if (!node)
+        return VisiblePosition();
+    RenderObject* renderer = node->renderer();
+    if (!renderer)
+        return VisiblePosition();
+    VisiblePosition visiblePos = VisiblePosition(renderer->positionForPoint(result.localPoint()));
+    if (visiblePos.isNull())
+        visiblePos = VisiblePosition(firstPositionInOrBeforeNode(node));
+    return visiblePos;
+}
+
+Document* LocalFrame::documentAtPoint(const IntPoint& point)
+{
+    if (!view())
+        return 0;
+
+    IntPoint pt = view()->windowToContents(point);
+    HitTestResult result = HitTestResult(pt);
+
+    if (contentRenderer())
+        result = eventHandler().hitTestResultAtPoint(pt, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
+    return result.innerNode() ? &result.innerNode()->document() : 0;
+}
+
+PassRefPtr<Range> LocalFrame::rangeForPoint(const IntPoint& framePoint)
+{
+    VisiblePosition position = visiblePositionForPoint(framePoint);
+    if (position.isNull())
+        return nullptr;
+
+    VisiblePosition previous = position.previous();
+    if (previous.isNotNull()) {
+        RefPtr<Range> previousCharacterRange = makeRange(previous, position);
+        LayoutRect rect = editor().firstRectForRange(previousCharacterRange.get());
+        if (rect.contains(framePoint))
+            return previousCharacterRange.release();
+    }
+
+    VisiblePosition next = position.next();
+    if (RefPtr<Range> nextCharacterRange = makeRange(position, next)) {
+        LayoutRect rect = editor().firstRectForRange(nextCharacterRange.get());
+        if (rect.contains(framePoint))
+            return nextCharacterRange.release();
+    }
+
+    return nullptr;
+}
+
+void LocalFrame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent,
+    ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
+    ScrollbarMode verticalScrollbarMode, bool verticalLock)
+{
+    ASSERT(this);
+    ASSERT(page());
+
+    bool isMainFrame = this->isMainFrame();
+
+    if (isMainFrame && view())
+        view()->setParentVisible(false);
+
+    setView(nullptr);
+
+    RefPtr<FrameView> frameView;
+    if (isMainFrame) {
+        frameView = FrameView::create(this, viewportSize);
+
+        // The layout size is set by WebViewImpl to support @viewport
+        frameView->setLayoutSizeFixedToFrameSize(false);
+    } else
+        frameView = FrameView::create(this);
+
+    frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
+
+    setView(frameView);
+
+    if (backgroundColor.alpha())
+        frameView->updateBackgroundRecursively(backgroundColor, transparent);
+
+    if (isMainFrame)
+        frameView->setParentVisible(true);
+
+    if (ownerRenderer())
+        ownerRenderer()->setWidget(frameView);
+
+    if (HTMLFrameOwnerElement* owner = ownerElement())
+        view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
+}
+
+
+void LocalFrame::countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned& totalObjects, bool& isPartial)
+{
+    RenderObject* root = view()->layoutRoot();
+    isPartial = true;
+    if (!root) {
+        isPartial = false;
+        root = contentRenderer();
+    }
+
+    needsLayoutObjects = 0;
+    totalObjects = 0;
+
+    for (RenderObject* o = root; o; o = o->nextInPreOrder(root)) {
+        ++totalObjects;
+        if (o->needsLayout())
+            ++needsLayoutObjects;
+    }
+}
+
+String LocalFrame::layerTreeAsText(unsigned flags) const
+{
+    document()->updateLayout();
+
+    if (!contentRenderer())
+        return String();
+
+    return contentRenderer()->compositor()->layerTreeAsText(static_cast<LayerTreeFlags>(flags));
+}
+
+String LocalFrame::trackedRepaintRectsAsText() const
+{
+    if (!m_view)
+        return String();
+    return m_view->trackedRepaintRectsAsText();
+}
+
+void LocalFrame::setPageZoomFactor(float factor)
+{
+    setPageAndTextZoomFactors(factor, m_textZoomFactor);
+}
+
+void LocalFrame::setTextZoomFactor(float factor)
+{
+    setPageAndTextZoomFactors(m_pageZoomFactor, factor);
+}
+
+void LocalFrame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)
+{
+    if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
+        return;
+
+    Page* page = this->page();
+    if (!page)
+        return;
+
+    Document* document = this->document();
+    if (!document)
+        return;
+
+    // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
+    // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
+    if (document->isSVGDocument()) {
+        if (!toSVGDocument(document)->zoomAndPanEnabled())
+            return;
+    }
+
+    if (m_pageZoomFactor != pageZoomFactor) {
+        if (FrameView* view = this->view()) {
+            // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
+            LayoutPoint scrollPosition = view->scrollPosition();
+            float percentDifference = (pageZoomFactor / m_pageZoomFactor);
+            view->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
+        }
+    }
+
+    m_pageZoomFactor = pageZoomFactor;
+    m_textZoomFactor = textZoomFactor;
+
+    for (RefPtr<LocalFrame> child = tree().firstChild(); child; child = child->tree().nextSibling())
+        child->setPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor);
+
+    document->setNeedsStyleRecalc(SubtreeStyleChange);
+    document->updateLayoutIgnorePendingStylesheets();
+}
+
+void LocalFrame::deviceOrPageScaleFactorChanged()
+{
+    document()->mediaQueryAffectingValueChanged();
+    for (RefPtr<LocalFrame> child = tree().firstChild(); child; child = child->tree().nextSibling())
+        child->deviceOrPageScaleFactorChanged();
+}
+
+void LocalFrame::notifyChromeClientWheelEventHandlerCountChanged() const
+{
+    // Ensure that this method is being called on the main frame of the page.
+    ASSERT(isMainFrame());
+
+    unsigned count = 0;
+    for (const LocalFrame* frame = this; frame; frame = frame->tree().traverseNext()) {
+        if (frame->document())
+            count += WheelController::from(*frame->document())->wheelEventHandlerCount();
+    }
+
+    m_host->chrome().client().numWheelEventHandlersChanged(count);
+}
+
+bool LocalFrame::isURLAllowed(const KURL& url) const
+{
+    // We allow one level of self-reference because some sites depend on that,
+    // but we don't allow more than one.
+    if (page()->subframeCount() >= Page::maxNumberOfFrames)
+        return false;
+    bool foundSelfReference = false;
+    for (const LocalFrame* frame = this; frame; frame = frame->tree().parent()) {
+        if (equalIgnoringFragmentIdentifier(frame->document()->url(), url)) {
+            if (foundSelfReference)
+                return false;
+            foundSelfReference = true;
+        }
+    }
+    return true;
+}
+
+struct ScopedFramePaintingState {
+    ScopedFramePaintingState(LocalFrame* frame, Node* node)
+        : frame(frame)
+        , node(node)
+        , paintBehavior(frame->view()->paintBehavior())
+        , backgroundColor(frame->view()->baseBackgroundColor())
+    {
+        ASSERT(!node || node->renderer());
+        if (node)
+            node->renderer()->updateDragState(true);
+    }
+
+    ~ScopedFramePaintingState()
+    {
+        if (node && node->renderer())
+            node->renderer()->updateDragState(false);
+        frame->view()->setPaintBehavior(paintBehavior);
+        frame->view()->setBaseBackgroundColor(backgroundColor);
+        frame->view()->setNodeToDraw(0);
+    }
+
+    LocalFrame* frame;
+    Node* node;
+    PaintBehavior paintBehavior;
+    Color backgroundColor;
+};
+
+PassOwnPtr<DragImage> LocalFrame::nodeImage(Node* node)
+{
+    if (!node->renderer())
+        return nullptr;
+
+    const ScopedFramePaintingState state(this, node);
+
+    m_view->setPaintBehavior(state.paintBehavior | PaintBehaviorFlattenCompositingLayers);
+
+    // When generating the drag image for an element, ignore the document background.
+    m_view->setBaseBackgroundColor(Color::transparent);
+
+    // Updating layout can tear everything down, so ref the LocalFrame and Node to keep them alive.
+    RefPtr<LocalFrame> frameProtector(this);
+    RefPtr<Node> nodeProtector(node);
+    m_view->updateLayoutAndStyleForPainting();
+
+    m_view->setNodeToDraw(node); // Enable special sub-tree drawing mode.
+
+    // Document::updateLayout may have blown away the original RenderObject.
+    RenderObject* renderer = node->renderer();
+    if (!renderer)
+        return nullptr;
+
+    LayoutRect topLevelRect;
+    IntRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect));
+
+    ASSERT(document()->isActive());
+    float deviceScaleFactor = m_host->deviceScaleFactor();
+    paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
+    paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
+
+    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
+    if (!buffer)
+        return nullptr;
+    buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
+    buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
+    buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
+
+    m_view->paintContents(buffer->context(), paintingRect);
+
+    RefPtr<Image> image = buffer->copyImage();
+    return DragImage::create(image.get(), renderer->shouldRespectImageOrientation(), deviceScaleFactor);
+}
+
+PassOwnPtr<DragImage> LocalFrame::dragImageForSelection()
+{
+    if (!selection().isRange())
+        return nullptr;
+
+    const ScopedFramePaintingState state(this, 0);
+    m_view->setPaintBehavior(PaintBehaviorSelectionOnly | PaintBehaviorFlattenCompositingLayers);
+    document()->updateLayout();
+
+    IntRect paintingRect = enclosingIntRect(selection().bounds());
+
+    ASSERT(document()->isActive());
+    float deviceScaleFactor = m_host->deviceScaleFactor();
+    paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
+    paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
+
+    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(paintingRect.size());
+    if (!buffer)
+        return nullptr;
+    buffer->context()->scale(FloatSize(deviceScaleFactor, deviceScaleFactor));
+    buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
+    buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
+
+    m_view->paintContents(buffer->context(), paintingRect);
+
+    RefPtr<Image> image = buffer->copyImage();
+    return DragImage::create(image.get(), DoNotRespectImageOrientation, deviceScaleFactor);
+}
+
+double LocalFrame::devicePixelRatio() const
+{
+    if (!m_host)
+        return 0;
+
+    double ratio = m_host->deviceScaleFactor();
+    ratio *= pageZoomFactor();
+    return ratio;
+}
+
+} // namespace WebCore
diff --git a/Source/core/frame/LocalFrame.h b/Source/core/frame/LocalFrame.h
new file mode 100644
index 0000000..718b91a
--- /dev/null
+++ b/Source/core/frame/LocalFrame.h
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
+ *                     1999-2001 Lars Knoll <knoll@kde.org>
+ *                     1999-2001 Antti Koivisto <koivisto@kde.org>
+ *                     2000-2001 Simon Hausmann <hausmann@kde.org>
+ *                     2000-2001 Dirk Mueller <mueller@kde.org>
+ *                     2000 Stefan Schimanski <1Stein@gmx.de>
+ * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#ifndef LocalFrame_h
+#define LocalFrame_h
+
+#include "core/frame/Frame.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/NavigationScheduler.h"
+#include "core/page/FrameTree.h"
+#include "platform/scroll/ScrollTypes.h"
+
+namespace WebCore {
+
+    class Color;
+    class DragImage;
+    class Editor;
+    class EventHandler;
+    class FetchContext;
+    class FloatSize;
+    class FrameSelection;
+    class FrameView;
+    class InputMethodController;
+    class IntPoint;
+    class IntSize;
+    class Node;
+    class Range;
+    class RenderPart;
+    class TreeScope;
+    class ScriptController;
+    class SpellChecker;
+    class TreeScope;
+    class VisiblePosition;
+
+    class LocalFrame : public Frame {
+    public:
+        static PassRefPtr<LocalFrame> create(FrameLoaderClient*, FrameHost*, HTMLFrameOwnerElement*);
+
+        virtual bool isLocalFrame() const OVERRIDE { return true; }
+
+        void init();
+        void setView(PassRefPtr<FrameView>);
+        void createView(const IntSize&, const Color&, bool,
+            ScrollbarMode = ScrollbarAuto, bool horizontalLock = false,
+            ScrollbarMode = ScrollbarAuto, bool verticalLock = false);
+
+        virtual ~LocalFrame();
+
+        virtual void willDetachFrameHost() OVERRIDE;
+        virtual void detachFromFrameHost() OVERRIDE;
+        void disconnectOwnerElement();
+
+        HTMLFrameOwnerElement* ownerElement() const;
+
+        virtual void setDOMWindow(PassRefPtr<DOMWindow>) OVERRIDE;
+        FrameView* view() const;
+
+        Editor& editor() const;
+        EventHandler& eventHandler() const;
+        FrameLoader& loader() const;
+        FrameTree& tree() const;
+        NavigationScheduler& navigationScheduler() const;
+        FrameSelection& selection() const;
+        InputMethodController& inputMethodController() const;
+        FetchContext& fetchContext() const { return loader().fetchContext(); }
+        ScriptController& script();
+        SpellChecker& spellChecker() const;
+
+        RenderPart* ownerRenderer() const; // Renderer for the element that contains this frame.
+
+        void didChangeVisibilityState();
+
+    // ======== All public functions below this point are candidates to move out of LocalFrame into another class. ========
+
+        bool inScope(TreeScope*) const;
+
+        void countObjectsNeedingLayout(unsigned& needsLayoutObjects, unsigned& totalObjects, bool& isPartial);
+
+        // See GraphicsLayerClient.h for accepted flags.
+        String layerTreeAsText(unsigned flags = 0) const;
+        String trackedRepaintRectsAsText() const;
+
+        void setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio);
+        bool shouldUsePrintingLayout() const;
+        FloatSize resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize);
+
+        bool inViewSourceMode() const;
+        void setInViewSourceMode(bool = true);
+
+        void setPageZoomFactor(float factor);
+        float pageZoomFactor() const { return m_pageZoomFactor; }
+        void setTextZoomFactor(float factor);
+        float textZoomFactor() const { return m_textZoomFactor; }
+        void setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor);
+
+        void deviceOrPageScaleFactorChanged();
+        double devicePixelRatio() const;
+
+        // Orientation is the interface orientation in degrees. Some examples are:
+        //  0 is straight up; -90 is when the device is rotated 90 clockwise;
+        //  90 is when rotated counter clockwise.
+        void sendOrientationChangeEvent(int orientation);
+        int orientation() const { return m_orientation; }
+
+        String documentTypeString() const;
+
+        PassOwnPtr<DragImage> nodeImage(Node*);
+        PassOwnPtr<DragImage> dragImageForSelection();
+
+        String selectedText() const;
+        String selectedTextForClipboard() const;
+
+        VisiblePosition visiblePositionForPoint(const IntPoint& framePoint);
+        Document* documentAtPoint(const IntPoint& windowPoint);
+        PassRefPtr<Range> rangeForPoint(const IntPoint& framePoint);
+
+        // Should only be called on the main frame of a page.
+        void notifyChromeClientWheelEventHandlerCountChanged() const;
+
+        bool isURLAllowed(const KURL&) const;
+
+    // ========
+
+    private:
+        LocalFrame(FrameLoaderClient*, FrameHost*, HTMLFrameOwnerElement*);
+
+        mutable FrameTree m_treeNode;
+        mutable FrameLoader m_loader;
+        mutable NavigationScheduler m_navigationScheduler;
+
+        RefPtr<FrameView> m_view;
+
+        OwnPtr<ScriptController> m_script;
+        const OwnPtr<Editor> m_editor;
+        const OwnPtr<SpellChecker> m_spellChecker;
+        const OwnPtr<FrameSelection> m_selection;
+        const OwnPtr<EventHandler> m_eventHandler;
+        OwnPtr<InputMethodController> m_inputMethodController;
+
+        float m_pageZoomFactor;
+        float m_textZoomFactor;
+
+        int m_orientation;
+
+        bool m_inViewSourceMode;
+    };
+
+    inline void LocalFrame::init()
+    {
+        m_loader.init();
+    }
+
+    inline FrameLoader& LocalFrame::loader() const
+    {
+        return m_loader;
+    }
+
+    inline NavigationScheduler& LocalFrame::navigationScheduler() const
+    {
+        return m_navigationScheduler;
+    }
+
+    inline FrameView* LocalFrame::view() const
+    {
+        return m_view.get();
+    }
+
+    inline ScriptController& LocalFrame::script()
+    {
+        return *m_script;
+    }
+
+    inline FrameSelection& LocalFrame::selection() const
+    {
+        return *m_selection;
+    }
+
+    inline Editor& LocalFrame::editor() const
+    {
+        return *m_editor;
+    }
+
+    inline SpellChecker& LocalFrame::spellChecker() const
+    {
+        return *m_spellChecker;
+    }
+
+    inline InputMethodController& LocalFrame::inputMethodController() const
+    {
+        return *m_inputMethodController;
+    }
+
+    inline HTMLFrameOwnerElement* LocalFrame::ownerElement() const
+    {
+        return m_ownerElement;
+    }
+
+    inline bool LocalFrame::inViewSourceMode() const
+    {
+        return m_inViewSourceMode;
+    }
+
+    inline void LocalFrame::setInViewSourceMode(bool mode)
+    {
+        m_inViewSourceMode = mode;
+    }
+
+    inline FrameTree& LocalFrame::tree() const
+    {
+        return m_treeNode;
+    }
+
+    inline EventHandler& LocalFrame::eventHandler() const
+    {
+        ASSERT(m_eventHandler);
+        return *m_eventHandler;
+    }
+
+    DEFINE_TYPE_CASTS(LocalFrame, Frame, localFrame, localFrame->isLocalFrame(), localFrame.isLocalFrame());
+
+} // namespace WebCore
+
+#endif // LocalFrame_h
diff --git a/Source/core/frame/Location.cpp b/Source/core/frame/Location.cpp
index 7f60ae2..0498b75 100644
--- a/Source/core/frame/Location.cpp
+++ b/Source/core/frame/Location.cpp
@@ -34,14 +34,14 @@
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoader.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace WebCore {
 
-Location::Location(Frame* frame)
+Location::Location(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
@@ -120,7 +120,7 @@
     RefPtr<DOMStringList> origins = DOMStringList::create();
     if (!m_frame)
         return origins.release();
-    for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent())
+    for (LocalFrame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent())
         origins->append(frame->document()->securityOrigin()->toString());
     return origins.release();
 }
@@ -133,14 +133,14 @@
     return DOMURLUtilsReadOnly::hash(url());
 }
 
-void Location::setHref(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& url)
+void Location::setHref(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& url)
 {
     if (!m_frame)
         return;
-    setLocation(url, activeWindow, firstWindow);
+    setLocation(url, callingWindow, enteredWindow);
 }
 
-void Location::setProtocol(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& protocol, ExceptionState& exceptionState)
+void Location::setProtocol(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& protocol, ExceptionState& exceptionState)
 {
     if (!m_frame)
         return;
@@ -149,55 +149,55 @@
         exceptionState.throwDOMException(SyntaxError, "'" + protocol + "' is an invalid protocol.");
         return;
     }
-    setLocation(url.string(), activeWindow, firstWindow);
+    setLocation(url.string(), callingWindow, enteredWindow);
 }
 
-void Location::setHost(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& host)
+void Location::setHost(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& host)
 {
     if (!m_frame)
         return;
     KURL url = m_frame->document()->url();
     url.setHostAndPort(host);
-    setLocation(url.string(), activeWindow, firstWindow);
+    setLocation(url.string(), callingWindow, enteredWindow);
 }
 
-void Location::setHostname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& hostname)
+void Location::setHostname(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& hostname)
 {
     if (!m_frame)
         return;
     KURL url = m_frame->document()->url();
     url.setHost(hostname);
-    setLocation(url.string(), activeWindow, firstWindow);
+    setLocation(url.string(), callingWindow, enteredWindow);
 }
 
-void Location::setPort(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& portString)
+void Location::setPort(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& portString)
 {
     if (!m_frame)
         return;
     KURL url = m_frame->document()->url();
     url.setPort(portString);
-    setLocation(url.string(), activeWindow, firstWindow);
+    setLocation(url.string(), callingWindow, enteredWindow);
 }
 
-void Location::setPathname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& pathname)
+void Location::setPathname(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& pathname)
 {
     if (!m_frame)
         return;
     KURL url = m_frame->document()->url();
     url.setPath(pathname);
-    setLocation(url.string(), activeWindow, firstWindow);
+    setLocation(url.string(), callingWindow, enteredWindow);
 }
 
-void Location::setSearch(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& search)
+void Location::setSearch(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& search)
 {
     if (!m_frame)
         return;
     KURL url = m_frame->document()->url();
     url.setQuery(search);
-    setLocation(url.string(), activeWindow, firstWindow);
+    setLocation(url.string(), callingWindow, enteredWindow);
 }
 
-void Location::setHash(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& hash)
+void Location::setHash(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& hash)
 {
     if (!m_frame)
         return;
@@ -212,25 +212,25 @@
     // cases where fragment identifiers are ignored or invalid.
     if (equalIgnoringNullity(oldFragmentIdentifier, url.fragmentIdentifier()))
         return;
-    setLocation(url.string(), activeWindow, firstWindow);
+    setLocation(url.string(), callingWindow, enteredWindow);
 }
 
-void Location::assign(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& url)
+void Location::assign(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& url)
 {
     if (!m_frame)
         return;
-    setLocation(url, activeWindow, firstWindow);
+    setLocation(url, callingWindow, enteredWindow);
 }
 
-void Location::replace(DOMWindow* activeWindow, DOMWindow* firstWindow, const String& url)
+void Location::replace(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String& url)
 {
     if (!m_frame)
         return;
     // Note: We call DOMWindow::setLocation directly here because replace() always operates on the current frame.
-    m_frame->domWindow()->setLocation(url, activeWindow, firstWindow, LockHistoryAndBackForwardList);
+    m_frame->domWindow()->setLocation(url, callingWindow, enteredWindow, LockHistoryAndBackForwardList);
 }
 
-void Location::reload(DOMWindow* activeWindow)
+void Location::reload(DOMWindow* callingWindow)
 {
     if (!m_frame)
         return;
@@ -239,13 +239,13 @@
     m_frame->navigationScheduler().scheduleRefresh();
 }
 
-void Location::setLocation(const String& url, DOMWindow* activeWindow, DOMWindow* firstWindow)
+void Location::setLocation(const String& url, DOMWindow* callingWindow, DOMWindow* enteredWindow)
 {
     ASSERT(m_frame);
-    Frame* frame = m_frame->loader().findFrameForNavigation(nullAtom, activeWindow->document());
+    LocalFrame* frame = m_frame->loader().findFrameForNavigation(nullAtom, callingWindow->document());
     if (!frame)
         return;
-    frame->domWindow()->setLocation(url, activeWindow, firstWindow);
+    frame->domWindow()->setLocation(url, callingWindow, enteredWindow);
 }
 
 } // namespace WebCore
diff --git a/Source/core/frame/Location.h b/Source/core/frame/Location.h
index 4acb1e2..8930ae2 100644
--- a/Source/core/frame/Location.h
+++ b/Source/core/frame/Location.h
@@ -40,42 +40,42 @@
 
 class DOMWindow;
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class KURL;
 
 class Location FINAL : public ScriptWrappable, public RefCounted<Location>, public DOMWindowProperty {
 public:
-    static PassRefPtr<Location> create(Frame* frame) { return adoptRef(new Location(frame)); }
+    static PassRefPtr<Location> create(LocalFrame* frame) { return adoptRef(new Location(frame)); }
 
-    void setHref(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+    void setHref(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
     String href() const;
 
-    void assign(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
-    void replace(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
-    void reload(DOMWindow* activeWindow);
+    void assign(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
+    void replace(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
+    void reload(DOMWindow* callingWindow);
 
-    void setProtocol(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&, ExceptionState&);
+    void setProtocol(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&, ExceptionState&);
     String protocol() const;
-    void setHost(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+    void setHost(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
     String host() const;
-    void setHostname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+    void setHostname(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
     String hostname() const;
-    void setPort(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+    void setPort(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
     String port() const;
-    void setPathname(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+    void setPathname(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
     String pathname() const;
-    void setSearch(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+    void setSearch(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
     String search() const;
-    void setHash(DOMWindow* activeWindow, DOMWindow* firstWindow, const String&);
+    void setHash(DOMWindow* callingWindow, DOMWindow* enteredWindow, const String&);
     String hash() const;
     String origin() const;
 
     PassRefPtr<DOMStringList> ancestorOrigins() const;
 
 private:
-    explicit Location(Frame*);
+    explicit Location(LocalFrame*);
 
-    void setLocation(const String&, DOMWindow* activeWindow, DOMWindow* firstWindow);
+    void setLocation(const String&, DOMWindow* callingWindow, DOMWindow* enteredWindow);
 
     const KURL& url() const;
 };
diff --git a/Source/core/frame/Navigator.cpp b/Source/core/frame/Navigator.cpp
index 5debf1d..1660234 100644
--- a/Source/core/frame/Navigator.cpp
+++ b/Source/core/frame/Navigator.cpp
@@ -25,11 +25,11 @@
 
 #include "bindings/v8/ScriptController.h"
 #include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/NavigatorID.h"
+#include "core/frame/Settings.h"
 #include "core/loader/CookieJar.h"
 #include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
 #include "core/plugins/DOMMimeTypeArray.h"
 #include "core/plugins/DOMPluginArray.h"
 #include "platform/Language.h"
@@ -48,7 +48,7 @@
 
 namespace WebCore {
 
-Navigator::Navigator(Frame* frame)
+Navigator::Navigator(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
diff --git a/Source/core/frame/Navigator.h b/Source/core/frame/Navigator.h
index 2de28ab..990c016 100644
--- a/Source/core/frame/Navigator.h
+++ b/Source/core/frame/Navigator.h
@@ -34,14 +34,14 @@
 
 class DOMMimeTypeArray;
 class DOMPluginArray;
-class Frame;
+class LocalFrame;
 class PluginData;
 
 typedef int ExceptionCode;
 
 class Navigator FINAL : public NavigatorBase, public ScriptWrappable, public RefCounted<Navigator>, public DOMWindowProperty, public Supplementable<Navigator> {
 public:
-    static PassRefPtr<Navigator> create(Frame* frame) { return adoptRef(new Navigator(frame)); }
+    static PassRefPtr<Navigator> create(LocalFrame* frame) { return adoptRef(new Navigator(frame)); }
     virtual ~Navigator();
 
     AtomicString language() const;
@@ -60,7 +60,7 @@
     void getStorageUpdates();
 
 private:
-    explicit Navigator(Frame*);
+    explicit Navigator(LocalFrame*);
 
     mutable RefPtrWillBePersistent<DOMPluginArray> m_plugins;
     mutable RefPtrWillBePersistent<DOMMimeTypeArray> m_mimeTypes;
diff --git a/Source/core/frame/NavigatorID.cpp b/Source/core/frame/NavigatorID.cpp
index 1b771dd..8a0def5 100644
--- a/Source/core/frame/NavigatorID.cpp
+++ b/Source/core/frame/NavigatorID.cpp
@@ -45,24 +45,24 @@
 
 namespace WebCore {
 
-String NavigatorID::appName(const NavigatorBase*)
+String NavigatorID::appName(const NavigatorBase&)
 {
     return "Netscape";
 }
 
-String NavigatorID::appVersion(const NavigatorBase* navigator)
+String NavigatorID::appVersion(const NavigatorBase& navigator)
 {
     // Version is everything in the user agent string past the "Mozilla/" prefix.
-    const String& agent = navigator->userAgent();
+    const String& agent = navigator.userAgent();
     return agent.substring(agent.find('/') + 1);
 }
 
-String NavigatorID::userAgent(const NavigatorBase* navigator)
+String NavigatorID::userAgent(const NavigatorBase& navigator)
 {
-    return navigator->userAgent();
+    return navigator.userAgent();
 }
 
-String NavigatorID::platform(const NavigatorBase*)
+String NavigatorID::platform(const NavigatorBase&)
 {
 #if defined(WEBCORE_NAVIGATOR_PLATFORM)
     return WEBCORE_NAVIGATOR_PLATFORM;
@@ -79,12 +79,12 @@
 #endif
 }
 
-String NavigatorID::appCodeName(const NavigatorBase*)
+String NavigatorID::appCodeName(const NavigatorBase&)
 {
     return "Mozilla";
 }
 
-String NavigatorID::product(const NavigatorBase*)
+String NavigatorID::product(const NavigatorBase&)
 {
     return WEBCORE_NAVIGATOR_PRODUCT;
 }
diff --git a/Source/core/frame/NavigatorID.h b/Source/core/frame/NavigatorID.h
index 9e31d31..a696280 100644
--- a/Source/core/frame/NavigatorID.h
+++ b/Source/core/frame/NavigatorID.h
@@ -39,12 +39,12 @@
 
 class NavigatorID {
 public:
-    static String appName(const NavigatorBase*);
-    static String appVersion(const NavigatorBase*);
-    static String userAgent(const NavigatorBase*);
-    static String platform(const NavigatorBase*);
-    static String appCodeName(const NavigatorBase*);
-    static String product(const NavigatorBase*);
+    static String appName(const NavigatorBase&);
+    static String appVersion(const NavigatorBase&);
+    static String userAgent(const NavigatorBase&);
+    static String platform(const NavigatorBase&);
+    static String appCodeName(const NavigatorBase&);
+    static String product(const NavigatorBase&);
 };
 
 } // namespace WebCore
diff --git a/Source/core/frame/NavigatorOnLine.h b/Source/core/frame/NavigatorOnLine.h
index 5ae204d..7a89aa8 100644
--- a/Source/core/frame/NavigatorOnLine.h
+++ b/Source/core/frame/NavigatorOnLine.h
@@ -35,9 +35,11 @@
 
 namespace WebCore {
 
+class NavigatorBase;
+
 class NavigatorOnLine {
 public:
-    static bool onLine(void*)
+    static bool onLine(NavigatorBase&)
     {
         return networkStateNotifier().onLine();
     }
diff --git a/Source/core/frame/PageConsole.cpp b/Source/core/frame/PageConsole.cpp
index dde7232..935f54c 100644
--- a/Source/core/frame/PageConsole.cpp
+++ b/Source/core/frame/PageConsole.cpp
@@ -53,7 +53,7 @@
 
 void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message)
 {
-    addMessage(source, level, message, String(), 0, 0, 0, 0, 0);
+    addMessage(source, level, message, String(), 0, 0, nullptr, 0, 0);
 }
 
 void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack)
@@ -63,7 +63,7 @@
 
 void PageConsole::addMessage(MessageSource source, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state, unsigned long requestIdentifier)
 {
-    if (muteCount && source != ConsoleAPIMessageSource)
+    if (muteCount)
         return;
 
     // FIXME: This should not need to reach for the main-frame.
diff --git a/Source/core/frame/PageConsole.h b/Source/core/frame/PageConsole.h
index b76447f..10b0f8e 100644
--- a/Source/core/frame/PageConsole.h
+++ b/Source/core/frame/PageConsole.h
@@ -50,7 +50,7 @@
     static PassOwnPtr<PageConsole> create(FrameHost& host) { return adoptPtr(new PageConsole(host)); }
 
     void addMessage(MessageSource, MessageLevel, const String& message);
-    void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber = 0, PassRefPtr<ScriptCallStack> = 0, ScriptState* = 0, unsigned long requestIdentifier = 0);
+    void addMessage(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, unsigned columnNumber = 0, PassRefPtr<ScriptCallStack> = nullptr, ScriptState* = 0, unsigned long requestIdentifier = 0);
     void addMessage(MessageSource, MessageLevel, const String& message, PassRefPtr<ScriptCallStack>);
     static String formatStackTraceString(const String& originalMessage, PassRefPtr<ScriptCallStack>);
 
diff --git a/Source/core/frame/PinchViewport.cpp b/Source/core/frame/PinchViewport.cpp
new file mode 100644
index 0000000..498d681
--- /dev/null
+++ b/Source/core/frame/PinchViewport.cpp
@@ -0,0 +1,253 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "PinchViewport.h"
+
+#include "core/frame/FrameHost.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+#include "core/page/scrolling/ScrollingCoordinator.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "platform/geometry/FloatSize.h"
+#include "platform/graphics/GraphicsLayer.h"
+#include "platform/graphics/GraphicsLayerFactory.h"
+#include "platform/scroll/Scrollbar.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebCompositorSupport.h"
+#include "public/platform/WebLayer.h"
+#include "public/platform/WebLayerTreeView.h"
+#include "public/platform/WebScrollbar.h"
+#include "public/platform/WebScrollbarLayer.h"
+
+using blink::WebLayer;
+using blink::WebLayerTreeView;
+using blink::WebScrollbar;
+using blink::WebScrollbarLayer;
+using WebCore::FrameHost;
+using WebCore::GraphicsLayer;
+using WebCore::GraphicsLayerFactory;
+
+namespace WebCore {
+
+PinchViewport::PinchViewport(FrameHost& owner)
+    : m_owner(owner)
+{
+}
+
+PinchViewport::~PinchViewport() { }
+
+void PinchViewport::setViewportSize(const WebCore::IntSize& newSize)
+{
+    if (!m_innerViewportContainerLayer || !m_innerViewportScrollLayer)
+        return;
+
+    m_innerViewportContainerLayer->setSize(newSize);
+    // The innerviewport scroll layer always has the same size as its clip layer, but
+    // the page scale layer lives between them, allowing for non-zero max scroll
+    // offset when page scale > 1.
+    m_innerViewportScrollLayer->setSize(newSize);
+
+    // Need to re-compute sizes for the overlay scrollbars.
+    setupScrollbar(WebScrollbar::Horizontal);
+    setupScrollbar(WebScrollbar::Vertical);
+}
+
+// Modifies the top of the graphics layer tree to add layers needed to support
+// the inner/outer viewport fixed-position model for pinch zoom. When finished,
+// the tree will look like this (with * denoting added layers):
+//
+// *innerViewportContainerLayer (fixed pos container)
+//  +- *pageScaleLayer
+//  |   +- *innerViewportScrollLayer
+//  |       +-- overflowControlsHostLayer (root layer)
+//  |           +-- rootTransformLayer (optional)
+//  |               +-- outerViewportContainerLayer (fixed pos container) [frame container layer in RenderLayerCompositor]
+//  |               |   +-- outerViewportScrollLayer [frame scroll layer in RenderLayerCompositor]
+//  |               |       +-- content layers ...
+//  |               +-- horizontal ScrollbarLayer (non-overlay)
+//  |               +-- verticalScrollbarLayer (non-overlay)
+//  |               +-- scroll corner (non-overlay)
+//  +- *horizontalScrollbarLayer (overlay)
+//  +- *verticalScrollbarLayer (overlay)
+//
+void PinchViewport::attachToLayerTree(GraphicsLayer* currentLayerTreeRoot, GraphicsLayerFactory* graphicsLayerFactory)
+{
+    if (!currentLayerTreeRoot) {
+        m_innerViewportScrollLayer->removeAllChildren();
+        return;
+    }
+
+    if (currentLayerTreeRoot->parent() && currentLayerTreeRoot->parent() == m_innerViewportScrollLayer)
+        return;
+
+    if (!m_innerViewportScrollLayer) {
+        ASSERT(!m_overlayScrollbarHorizontal
+            && !m_overlayScrollbarVertical
+            && !m_pageScaleLayer
+            && !m_innerViewportContainerLayer);
+
+        m_innerViewportContainerLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+        m_pageScaleLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+        m_innerViewportScrollLayer = GraphicsLayer::create(graphicsLayerFactory, this);
+        m_overlayScrollbarHorizontal = GraphicsLayer::create(graphicsLayerFactory, this);
+        m_overlayScrollbarVertical = GraphicsLayer::create(graphicsLayerFactory, this);
+
+        WebCore::ScrollingCoordinator* coordinator = m_owner.page().scrollingCoordinator();
+        ASSERT(coordinator);
+        coordinator->setLayerIsContainerForFixedPositionLayers(m_innerViewportScrollLayer.get(), true);
+
+        // No need for the inner viewport to clip, since the compositing
+        // surface takes care of it -- and clipping here would interfere with
+        // dynamically-sized viewports on Android.
+        m_innerViewportContainerLayer->setMasksToBounds(false);
+
+        m_innerViewportScrollLayer->platformLayer()->setScrollClipLayer(
+            m_innerViewportContainerLayer->platformLayer());
+        m_innerViewportScrollLayer->platformLayer()->setUserScrollable(true, true);
+
+        m_innerViewportContainerLayer->addChild(m_pageScaleLayer.get());
+        m_pageScaleLayer->addChild(m_innerViewportScrollLayer.get());
+        m_innerViewportContainerLayer->addChild(m_overlayScrollbarHorizontal.get());
+        m_innerViewportContainerLayer->addChild(m_overlayScrollbarVertical.get());
+
+        // Setup the inner viewport overlay scrollbars.
+        setupScrollbar(WebScrollbar::Horizontal);
+        setupScrollbar(WebScrollbar::Vertical);
+    }
+
+    m_innerViewportScrollLayer->removeAllChildren();
+    m_innerViewportScrollLayer->addChild(currentLayerTreeRoot);
+
+    // We only need to disable the existing (outer viewport) scrollbars
+    // if the existing ones are already overlay.
+    // FIXME: If we knew in advance before the overflowControlsHostLayer goes
+    // away, we would re-enable the drawing of these scrollbars.
+    // FIXME: This doesn't seem to work (at least on Android). Commenting out for now until
+    // I figure out how to access RenderLayerCompositor from here.
+    // if (GraphicsLayer* scrollbar = m_owner->compositor()->layerForHorizontalScrollbar())
+    //    scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars());
+    // if (GraphicsLayer* scrollbar = m_owner->compositor()->layerForVerticalScrollbar())
+    //    scrollbar->setDrawsContent(!page->mainFrame()->view()->hasOverlayScrollbars());
+}
+
+void PinchViewport::setupScrollbar(WebScrollbar::Orientation orientation)
+{
+    bool isHorizontal = orientation == WebScrollbar::Horizontal;
+    GraphicsLayer* scrollbarGraphicsLayer = isHorizontal ?
+        m_overlayScrollbarHorizontal.get() : m_overlayScrollbarVertical.get();
+    OwnPtr<WebScrollbarLayer>& webScrollbarLayer = isHorizontal ?
+        m_webOverlayScrollbarHorizontal : m_webOverlayScrollbarVertical;
+
+    const int overlayScrollbarThickness = m_owner.settings().pinchOverlayScrollbarThickness();
+
+    if (!webScrollbarLayer) {
+        WebCore::ScrollingCoordinator* coordinator = m_owner.page().scrollingCoordinator();
+        ASSERT(coordinator);
+        WebCore::ScrollbarOrientation webcoreOrientation = isHorizontal ? WebCore::HorizontalScrollbar : WebCore::VerticalScrollbar;
+        webScrollbarLayer = coordinator->createSolidColorScrollbarLayer(webcoreOrientation, overlayScrollbarThickness, false);
+
+        webScrollbarLayer->setClipLayer(m_innerViewportContainerLayer->platformLayer());
+        scrollbarGraphicsLayer->setContentsToPlatformLayer(webScrollbarLayer->layer());
+        scrollbarGraphicsLayer->setDrawsContent(false);
+    }
+
+    int xPosition = isHorizontal ? 0 : m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness;
+    int yPosition = isHorizontal ? m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness : 0;
+    int width = isHorizontal ? m_innerViewportContainerLayer->size().width() - overlayScrollbarThickness : overlayScrollbarThickness;
+    int height = isHorizontal ? overlayScrollbarThickness : m_innerViewportContainerLayer->size().height() - overlayScrollbarThickness;
+
+    // Use the GraphicsLayer to position the scrollbars.
+    scrollbarGraphicsLayer->setPosition(WebCore::IntPoint(xPosition, yPosition));
+    scrollbarGraphicsLayer->setSize(WebCore::IntSize(width, height));
+    scrollbarGraphicsLayer->setContentsRect(WebCore::IntRect(0, 0, width, height));
+}
+
+void PinchViewport::registerViewportLayersWithTreeView(WebLayerTreeView* layerTreeView) const
+{
+    ASSERT(layerTreeView);
+    ASSERT(m_owner.page().mainFrame());
+    ASSERT(m_owner.page().mainFrame()->contentRenderer());
+
+    WebCore::RenderLayerCompositor* compositor = m_owner.page().mainFrame()->contentRenderer()->compositor();
+    // Get the outer viewport scroll layer.
+    WebLayer* scrollLayer = compositor->scrollLayer()->platformLayer();
+
+    m_webOverlayScrollbarHorizontal->setScrollLayer(scrollLayer);
+    m_webOverlayScrollbarVertical->setScrollLayer(scrollLayer);
+
+    ASSERT(compositor);
+    layerTreeView->registerViewportLayers(
+        m_pageScaleLayer->platformLayer(),
+        m_innerViewportScrollLayer->platformLayer(),
+        scrollLayer);
+}
+
+void PinchViewport::clearViewportLayersForTreeView(WebLayerTreeView* layerTreeView) const
+{
+    ASSERT(layerTreeView);
+
+    layerTreeView->clearViewportLayers();
+}
+
+void PinchViewport::notifyAnimationStarted(const GraphicsLayer*, double monotonicTime)
+{
+}
+
+void PinchViewport::paintContents(const GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& inClip)
+{
+}
+
+String PinchViewport::debugName(const GraphicsLayer* graphicsLayer)
+{
+    String name;
+    if (graphicsLayer == m_innerViewportContainerLayer.get()) {
+        name = "Inner Viewport Container Layer";
+    } else if (graphicsLayer == m_pageScaleLayer.get()) {
+        name =  "Page Scale Layer";
+    } else if (graphicsLayer == m_innerViewportScrollLayer.get()) {
+        name =  "Inner Viewport Scroll Layer";
+    } else if (graphicsLayer == m_overlayScrollbarHorizontal.get()) {
+        name =  "Overlay Scrollbar Horizontal Layer";
+    } else if (graphicsLayer == m_overlayScrollbarVertical.get()) {
+        name =  "Overlay Scrollbar Vertical Layer";
+    } else {
+        ASSERT_NOT_REACHED();
+    }
+
+    return name;
+}
+
+} // namespace WebCore
diff --git a/Source/core/frame/PinchViewport.h b/Source/core/frame/PinchViewport.h
new file mode 100644
index 0000000..658e461
--- /dev/null
+++ b/Source/core/frame/PinchViewport.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2013 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PinchViewport_h
+#define PinchViewport_h
+
+#include "platform/geometry/IntSize.h"
+#include "platform/graphics/GraphicsLayerClient.h"
+#include "public/platform/WebScrollbar.h"
+#include "public/platform/WebSize.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/PassOwnPtr.h"
+
+namespace blink {
+class WebLayerTreeView;
+class WebScrollbarLayer;
+}
+
+namespace WebCore {
+
+class FrameHost;
+class GraphicsContext;
+class GraphicsLayer;
+class GraphicsLayerFactory;
+class IntRect;
+class IntSize;
+
+class PinchViewport FINAL : WebCore::GraphicsLayerClient {
+public:
+    PinchViewport(FrameHost&);
+    virtual ~PinchViewport();
+
+    void attachToLayerTree(WebCore::GraphicsLayer*, GraphicsLayerFactory*);
+    WebCore::GraphicsLayer* rootGraphicsLayer()
+    {
+        return m_innerViewportContainerLayer.get();
+    }
+    void setViewportSize(const WebCore::IntSize&);
+
+    void registerViewportLayersWithTreeView(blink::WebLayerTreeView*) const;
+    void clearViewportLayersForTreeView(blink::WebLayerTreeView*) const;
+
+private:
+
+    // GraphicsLayerClient implementation.
+    virtual void notifyAnimationStarted(const WebCore::GraphicsLayer*, double monotonicTime) OVERRIDE;
+    virtual void paintContents(const WebCore::GraphicsLayer*, WebCore::GraphicsContext&, WebCore::GraphicsLayerPaintingPhase, const WebCore::IntRect& inClip) OVERRIDE;
+    virtual String debugName(const WebCore::GraphicsLayer*) OVERRIDE;
+
+    void setupScrollbar(blink::WebScrollbar::Orientation);
+
+    WebCore::FrameHost& m_owner;
+    OwnPtr<WebCore::GraphicsLayer> m_innerViewportContainerLayer;
+    OwnPtr<WebCore::GraphicsLayer> m_pageScaleLayer;
+    OwnPtr<WebCore::GraphicsLayer> m_innerViewportScrollLayer;
+    OwnPtr<WebCore::GraphicsLayer> m_overlayScrollbarHorizontal;
+    OwnPtr<WebCore::GraphicsLayer> m_overlayScrollbarVertical;
+    OwnPtr<blink::WebScrollbarLayer> m_webOverlayScrollbarHorizontal;
+    OwnPtr<blink::WebScrollbarLayer> m_webOverlayScrollbarVertical;
+};
+
+} // namespace WebCore
+
+#endif // PinchViewport_h
diff --git a/Source/core/frame/RemoteFrame.cpp b/Source/core/frame/RemoteFrame.cpp
new file mode 100644
index 0000000..4a73a67
--- /dev/null
+++ b/Source/core/frame/RemoteFrame.cpp
@@ -0,0 +1,25 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/RemoteFrame.h"
+
+namespace WebCore {
+
+inline RemoteFrame::RemoteFrame(FrameHost* host, HTMLFrameOwnerElement* ownerElement)
+    : Frame(host, ownerElement)
+{
+}
+
+PassRefPtr<RemoteFrame> RemoteFrame::create(FrameHost* host, HTMLFrameOwnerElement* ownerElement)
+{
+    RefPtr<RemoteFrame> frame = adoptRef(new RemoteFrame(host, ownerElement));
+    return frame.release();
+}
+
+RemoteFrame::~RemoteFrame()
+{
+}
+
+} // namespace WebCore
diff --git a/Source/core/frame/RemoteFrame.h b/Source/core/frame/RemoteFrame.h
new file mode 100644
index 0000000..1b9629c
--- /dev/null
+++ b/Source/core/frame/RemoteFrame.h
@@ -0,0 +1,27 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef RemoteFrame_h
+#define RemoteFrame_h
+
+#include "core/frame/Frame.h"
+
+namespace WebCore {
+
+class RemoteFrame: public Frame {
+public:
+    static PassRefPtr<RemoteFrame> create(FrameHost*, HTMLFrameOwnerElement*);
+    virtual bool isRemoteFrame() const OVERRIDE { return true; }
+
+    virtual ~RemoteFrame();
+
+private:
+    RemoteFrame(FrameHost*, HTMLFrameOwnerElement*);
+};
+
+DEFINE_TYPE_CASTS(RemoteFrame, Frame, remoteFrame, remoteFrame->isRemoteFrame(), remoteFrame.isRemoteFrame());
+
+} // namespace WebCore
+
+#endif // RemoteFrame_h
diff --git a/Source/core/frame/Screen.cpp b/Source/core/frame/Screen.cpp
index 67283ac..edc3186 100644
--- a/Source/core/frame/Screen.cpp
+++ b/Source/core/frame/Screen.cpp
@@ -30,9 +30,9 @@
 #include "config.h"
 #include "core/frame/Screen.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "platform/PlatformScreen.h"
@@ -40,7 +40,7 @@
 
 namespace WebCore {
 
-Screen::Screen(Frame* frame)
+Screen::Screen(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
@@ -132,4 +132,11 @@
     return m_frame->document();
 }
 
+void Screen::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+    HeapSupplementable<Screen>::trace(visitor);
+#endif
+}
+
 } // namespace WebCore
diff --git a/Source/core/frame/Screen.h b/Source/core/frame/Screen.h
index df9e6e5..d03653e 100644
--- a/Source/core/frame/Screen.h
+++ b/Source/core/frame/Screen.h
@@ -33,18 +33,23 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/events/EventTarget.h"
 #include "core/frame/DOMWindowProperty.h"
+#include "heap/Handle.h"
 #include "platform/Supplementable.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-    class Frame;
+    class LocalFrame;
 
-    class Screen FINAL : public ScriptWrappable, public RefCounted<Screen>, public EventTargetWithInlineData, public DOMWindowProperty, public Supplementable<Screen> {
-        REFCOUNTED_EVENT_TARGET(Screen);
+    class Screen FINAL : public RefCountedWillBeRefCountedGarbageCollected<Screen>, public ScriptWrappable, public EventTargetWithInlineData, public DOMWindowProperty, public WillBeHeapSupplementable<Screen> {
+        WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(Screen);
+        DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<Screen>);
     public:
-        static PassRefPtr<Screen> create(Frame* frame) { return adoptRef(new Screen(frame)); }
+        static PassRefPtrWillBeRawPtr<Screen> create(LocalFrame* frame)
+        {
+            return adoptRefWillBeRefCountedGarbageCollected(new Screen(frame));
+        }
 
         unsigned height() const;
         unsigned width() const;
@@ -59,8 +64,10 @@
         virtual const AtomicString& interfaceName() const OVERRIDE;
         virtual ExecutionContext* executionContext() const OVERRIDE;
 
+        void trace(Visitor*);
+
     private:
-        explicit Screen(Frame*);
+        explicit Screen(LocalFrame*);
     };
 
 } // namespace WebCore
diff --git a/Source/core/frame/Screen.idl b/Source/core/frame/Screen.idl
index 8eeca83..156795f 100644
--- a/Source/core/frame/Screen.idl
+++ b/Source/core/frame/Screen.idl
@@ -27,7 +27,9 @@
  */
 
 
-interface Screen : EventTarget {
+[
+    WillBeGarbageCollected,
+] interface Screen : EventTarget {
     readonly attribute unsigned long height;
     readonly attribute unsigned long width;
     readonly attribute unsigned long colorDepth;
diff --git a/Source/core/frame/Settings.in b/Source/core/frame/Settings.in
index 5dbb12a..43a7f61 100644
--- a/Source/core/frame/Settings.in
+++ b/Source/core/frame/Settings.in
@@ -110,6 +110,7 @@
 acceleratedCompositingForOverflowScrollEnabled initial=false
 acceleratedCompositingForTransitionEnabled initial=false
 acceleratedCompositingForFixedRootBackgroundEnabled initial=false
+acceleratedCompositingForGpuRasterizationHintEnabled initial=false
 
 forceCompositingMode initial=false
 
@@ -176,7 +177,7 @@
 fixedPositionCreatesStackingContext initial=false
 syncXHRInDocumentsEnabled initial=true
 cookieEnabled initial=true
-mediaEnabled initial=true
+navigateOnDragDrop initial=true
 DOMPasteAllowed initial=false
 
 threadedHTMLParser initial=false
@@ -243,6 +244,7 @@
 # crbug.com/304869 tracks removal.
 pinchVirtualViewportEnabled initial=false
 useSolidColorScrollbars initial=false
+pinchOverlayScrollbarThickness type=int, initial=0
 
 mainFrameClipsContent initial=true
 
diff --git a/Source/core/frame/SmartClip.cpp b/Source/core/frame/SmartClip.cpp
index 52f9b03..3a95095 100644
--- a/Source/core/frame/SmartClip.cpp
+++ b/Source/core/frame/SmartClip.cpp
@@ -38,6 +38,7 @@
 #include "core/frame/FrameView.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/page/Page.h"
+#include "core/rendering/RenderObject.h"
 #include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
@@ -89,7 +90,7 @@
     return result.toString();
 }
 
-SmartClip::SmartClip(PassRefPtr<Frame> frame)
+SmartClip::SmartClip(PassRefPtr<LocalFrame> frame)
     : m_frame(frame)
 {
 }
@@ -111,7 +112,7 @@
     Vector<Node*> hitNodes;
     collectOverlappingChildNodes(bestNode, resizedCropRect, hitNodes);
 
-    if (hitNodes.isEmpty() || hitNodes.size() == bestNode->childNodeCount()) {
+    if (hitNodes.isEmpty() || hitNodes.size() == bestNode->countChildren()) {
         hitNodes.clear();
         hitNodes.append(bestNode);
     }
@@ -220,8 +221,9 @@
 // CSS background images but to skip actual backgrounds.
 bool SmartClip::shouldSkipBackgroundImage(Node* node)
 {
+    ASSERT(node);
     // Apparently we're only interested in background images on spans and divs.
-    if (!node->hasTagName(HTMLNames::spanTag) && !node->hasTagName(HTMLNames::divTag))
+    if (!isHTMLSpanElement(*node) && !isHTMLDivElement(*node))
         return true;
 
     // This check actually makes a bit of sense. If you're going to sprite an
diff --git a/Source/core/frame/SmartClip.h b/Source/core/frame/SmartClip.h
index 7481b2a..b0e9220 100644
--- a/Source/core/frame/SmartClip.h
+++ b/Source/core/frame/SmartClip.h
@@ -32,7 +32,7 @@
 #define SmartClip_h
 
 #include "core/dom/Node.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
@@ -64,7 +64,7 @@
 // selection followed by a copy operation.
 class SmartClip {
 public:
-    explicit SmartClip(PassRefPtr<Frame>);
+    explicit SmartClip(PassRefPtr<LocalFrame>);
 
     SmartClipData dataForRect(const IntRect&);
 
@@ -78,7 +78,7 @@
     IntRect convertRectToWindow(const IntRect& nodeRect);
     String extractTextFromNode(Node*);
 
-    RefPtr<Frame> m_frame;
+    RefPtr<LocalFrame> m_frame;
 };
 
 } // namespace WebCore
diff --git a/Source/core/frame/SuspendableTimer.cpp b/Source/core/frame/SuspendableTimer.cpp
index e3ffcf8..98ca635 100644
--- a/Source/core/frame/SuspendableTimer.cpp
+++ b/Source/core/frame/SuspendableTimer.cpp
@@ -74,8 +74,9 @@
     ASSERT(m_suspended);
     m_suspended = false;
 #endif
+    // FIXME: FROM_HERE is wrong here.
     if (m_active)
-        start(m_nextFireInterval, m_repeatInterval);
+        start(m_nextFireInterval, m_repeatInterval, FROM_HERE);
 }
 
 } // namespace WebCore
diff --git a/Source/core/frame/UseCounter.cpp b/Source/core/frame/UseCounter.cpp
index 1051e36..4b25f6d 100644
--- a/Source/core/frame/UseCounter.cpp
+++ b/Source/core/frame/UseCounter.cpp
@@ -40,6 +40,8 @@
 
 static int totalPagesMeasuredCSSSampleId() { return 1; }
 
+int UseCounter::m_muteCount = 0;
+
 // FIXME : This mapping should be autogenerated. This function should
 //         be moved to a separate file and a script run at build time
 //         to detect new values in CSSPropertyID and add them to the
@@ -497,6 +499,7 @@
     case CSSPropertyTouchActionDelay: return 442;
     case CSSPropertyJustifySelf: return 443;
     case CSSPropertyScrollBehavior: return 444;
+    case CSSPropertyWillChange: return 445;
 
     // Add new features above this line (don't change the assigned numbers of the existing
     // items) and update maximumCSSSampleId() with the new maximum value.
@@ -516,7 +519,17 @@
     return 0;
 }
 
-static int maximumCSSSampleId() { return 444; }
+static int maximumCSSSampleId() { return 445; }
+
+void UseCounter::muteForInspector()
+{
+    UseCounter::m_muteCount++;
+}
+
+void UseCounter::unmuteForInspector()
+{
+    UseCounter::m_muteCount--;
+}
 
 UseCounter::UseCounter()
 {
@@ -622,13 +635,6 @@
     case PrefixedPerformanceTimeline:
         return "'window.performance.webkitGet*' methods have been deprecated. Please use the unprefixed 'performance.get*' methods instead.";
 
-    case DocumentClear:
-        return "document.clear() is deprecated. This method doesn't do anything.";
-
-    // Web Components
-    case HTMLShadowElementOlderShadowRoot:
-        return "HTMLShadowElement.olderShadowRoot is deprecated.";
-
     // HTML Media Capture
     case CaptureAttributeAsEnum:
         return "Using the 'capture' attribute as an enum is deprecated. Please use it as a boolean and specify the media types that should be accepted in the 'accept' attribute.";
@@ -637,60 +643,21 @@
     case KeyboardEventKeyLocation:
         return "'KeyboardEvent.keyLocation' is deprecated. Please use 'KeyboardEvent.location' instead.";
 
-    case CaptureEvents:
-        return "captureEvents() is deprecated. This method doesn't do anything.";
-
-    case ReleaseEvents:
-        return "releaseEvents() is deprecated. This method doesn't do anything.";
-
     case ConsoleMarkTimeline:
         return "console.markTimeline is deprecated. Please use the console.timeStamp instead.";
 
     case FileError:
         return "FileError is deprecated. Please use the 'name' or 'message' attributes of DOMError rather than 'code'.";
 
-    case EventReturnValue:
-        return "event.returnValue is deprecated. Please use the standard event.preventDefault() instead.";
-
-    case ScrollTopBodyNotQuirksMode:
-        return "body.scrollTop is deprecated in strict mode. Please use 'documentElement.scrollTop' if in strict mode and 'body.scrollTop' only if in quirks mode.";
-
-    case ScrollLeftBodyNotQuirksMode:
-        return "body.scrollLeft is deprecated in strict mode. Please use 'documentElement.scrollLeft' if in strict mode and 'body.scrollLeft' only if in quirks mode.";
-
     case ShowModalDialog:
         return "Chromium is considering deprecating showModalDialog. Please use window.open and postMessage instead.";
 
     case CSSStyleSheetInsertRuleOptionalArg:
         return "Calling CSSStyleSheet.insertRule() with one argument is deprecated. Please pass the index argument as well: insertRule(x, 0).";
 
-    case AttributeSpecified:
-        return "Attr.specified is deprecated. Its value is always true.";
-
     case SVGElementGetPresentationAttribute:
         return "CSSValue and SVGElement.getPresentationAttribute are deprecated. Please use getPropertyValue and parse the return value instead.";
 
-    case TextTrackCueConstructor:
-        return "The 'TextTrackCue' constructor is deprecated. Please use 'VTTCue' instead.";
-
-    case PrefixedVideoSupportsFullscreen:
-        return "'HTMLVideoElement.webkitSupportsFullscreen' is deprecated. Its value is true if the video is loaded.";
-
-    case PrefixedVideoDisplayingFullscreen:
-        return "'HTMLVideoElement.webkitDisplayingFullscreen' is deprecated. Please use the 'fullscreenchange' and 'webkitfullscreenchange' events instead.";
-
-    case PrefixedVideoEnterFullscreen:
-        return "'HTMLVideoElement.webkitEnterFullscreen()' is deprecated. Please use 'Element.requestFullscreen()' and 'Element.webkitRequestFullscreen()' instead.";
-
-    case PrefixedVideoExitFullscreen:
-        return "'HTMLVideoElement.webkitExitFullscreen()' is deprecated. Please use 'Document.exitFullscreen()' and 'Document.webkitExitFullscreen()' instead.";
-
-    case PrefixedVideoEnterFullScreen:
-        return "'HTMLVideoElement.webkitEnterFullScreen()' is deprecated. Please use 'Element.requestFullscreen()' and 'Element.webkitRequestFullscreen()' instead.";
-
-    case PrefixedVideoExitFullScreen:
-        return "'HTMLVideoElement.webkitExitFullScreen()' is deprecated. Please use 'Document.exitFullscreen()' and 'Document.webkitExitFullscreen()' instead.";
-
     case PrefixedMediaSourceOpen:
         return "'WebKitMediaSource' is deprecated. Please use 'MediaSource' instead.";
 
@@ -715,6 +682,9 @@
     case PrefixedSpeechAttribute:
         return "The 'x-webkit-speech' input field attribute is deprecated. Please use the JavaScript API instead.";
 
+    case PrefixedGamepad:
+        return "'navigator.webkitGetGamepads' is deprecated. Please use 'navigator.getGamepads' instead.";
+
     // Features that aren't deprecated don't have a deprecation message.
     default:
         return String();
diff --git a/Source/core/frame/UseCounter.h b/Source/core/frame/UseCounter.h
index 994e91e..5caab36 100644
--- a/Source/core/frame/UseCounter.h
+++ b/Source/core/frame/UseCounter.h
@@ -63,7 +63,6 @@
         // to the end of the list.
         PageDestruction = 0,
         LegacyNotifications = 1,
-        MultipartMainResource = 2,
         PrefixedIndexedDB = 3,
         WorkerStart = 4,
         SharedWorkerStart = 5,
@@ -85,7 +84,6 @@
         IncrementalAttribute = 25,
         InputTypeColor = 26,
         InputTypeDate = 27,
-        InputTypeDateTime = 28,
         InputTypeDateTimeFallback = 29,
         InputTypeDateTimeLocal = 30,
         InputTypeEmail = 31,
@@ -132,20 +130,14 @@
         XSLProcessingInstruction = 78,
         XSLTProcessor = 79,
         SVGSwitchElement = 80,
-        HTMLShadowElementOlderShadowRoot = 82,
         DocumentAll = 83,
         FormElement = 84,
         DemotedFormElement = 85,
         CaptureAttributeAsEnum = 86,
-        ShadowDOMPrefixedPseudo = 87,
         ShadowDOMPrefixedCreateShadowRoot = 88,
         ShadowDOMPrefixedShadowRoot = 89,
         SVGAnimationElement = 90,
         KeyboardEventKeyLocation = 91,
-        CaptureEvents = 92,
-        ReleaseEvents = 93,
-        CSSDisplayRunIn = 94,
-        CSSDisplayCompact = 95,
         LineClamp = 96,
         SubFrameBeforeUnloadRegistered = 97,
         SubFrameBeforeUnloadFired = 98,
@@ -154,9 +146,7 @@
         PrefixedShadowRootConstructor = 101,
         ConsoleMarkTimeline = 102,
         CSSPseudoElementUserAgentCustomPseudo = 103,
-        DocumentTypeEntities = 104, // Removed from DOM4.
         DocumentTypeInternalSubset = 105, // Removed from DOM4.
-        DocumentTypeNotations = 106, // Removed from DOM4.
         ElementGetAttributeNode = 107, // Removed from DOM4.
         ElementSetAttributeNode = 108, // Removed from DOM4.
         ElementRemoveAttributeNode = 109, // Removed from DOM4.
@@ -168,7 +158,6 @@
         DocumentXMLStandalone = 116, // Removed from DOM4.
         DocumentXMLVersion = 117, // Removed from DOM4.
         NodeIsSameNode = 118, // Removed from DOM4.
-        NodeIsSupported = 119, // Removed from DOM4.
         NodeNamespaceURI = 120, // Removed from DOM4.
         NodeLocalName = 122, // Removed from DOM4.
         NavigatorProductSub = 123,
@@ -204,18 +193,10 @@
         BeforeLoadEvent = 154,
         GetMatchedCSSRules = 155,
         SVGFontInCSS = 156,
-        ScrollTopBodyNotQuirksMode = 157,
-        ScrollLeftBodyNotQuirksMode = 158,
         AttributeSpecified = 162, // Removed in DOM4.
         BeforeLoadEventInIsolatedWorld = 163,
         PrefixedAudioDecodedByteCount = 164,
         PrefixedVideoDecodedByteCount = 165,
-        PrefixedVideoSupportsFullscreen = 166,
-        PrefixedVideoDisplayingFullscreen = 167,
-        PrefixedVideoEnterFullscreen = 168,
-        PrefixedVideoExitFullscreen = 169,
-        PrefixedVideoEnterFullScreen = 170,
-        PrefixedVideoExitFullScreen = 171,
         PrefixedVideoDecodedFrameCount = 172,
         PrefixedVideoDroppedFrameCount = 173,
         PrefixedElementRequestFullscreen = 176,
@@ -229,9 +210,6 @@
         InputTypeEmailMultiple = 184,
         InputTypeEmailMaxLength = 185,
         InputTypeEmailMultipleMaxLength = 186,
-        TextTrackCueConstructor = 187,
-        CSSStyleDeclarationPropertyName = 188, // Removed in CSSOM.
-        CSSStyleDeclarationFloatPropertyName = 189, // Pending removal in CSSOM.
         InputTypeText = 190,
         InputTypeTextMaxLength = 191,
         InputTypePassword = 192,
@@ -247,7 +225,6 @@
         DocumentUnloadFired = 203,
         SVGLocatableNearestViewportElement = 204,
         SVGLocatableFarthestViewportElement = 205,
-        IsIndexElement = 206,
         HTMLHeadElementProfile = 207,
         OverflowChangedEvent = 208,
         SVGPointMatrixTransform = 209,
@@ -294,7 +271,6 @@
         MediaErrorEncrypted = 253,
         EventSourceURL = 254,
         WebSocketURL = 255,
-        UnsafeEvalBlocksCSSOM = 256,
         WorkerSubjectToCSP = 257,
         WorkerAllowedByChildBlockedByScript = 258,
         HTMLMediaElementControllerNotNull = 259,
@@ -312,6 +288,27 @@
         PromiseCast = 271,
         PromiseReject = 272,
         PromiseResolve = 273,
+        TextAutosizing = 274,
+        TextAutosizingLayout = 275,
+        HTMLAnchorElementPingAttribute = 276,
+        JavascriptExhaustedMemory = 277,
+        InsertAdjacentHTML = 278,
+        SVGClassName = 279,
+        HTMLAppletElement = 280,
+        HTMLMediaElementSeekToFragmentStart = 281,
+        HTMLMediaElementPauseAtFragmentEnd = 282,
+        PrefixedWindowURL = 283,
+        PrefixedWorkerURL = 284,
+        WindowOrientation = 285,
+        DOMStringListContains = 286,
+        DocumentCaptureEvents = 287,
+        DocumentReleaseEvents = 288,
+        WindowCaptureEvents = 289,
+        WindowReleaseEvents = 290,
+        PrefixedGamepad = 291,
+        ElementAnimateKeyframeListEffectObjectTiming = 292,
+        ElementAnimateKeyframeListEffectDoubleTiming = 293,
+        ElementAnimateKeyframeListEffectNoTiming = 294,
         // Add new features immediately above this line. Don't change assigned
         // numbers of any item, and don't reuse removed slots.
         NumberOfFeatures, // This enum value must be last.
@@ -341,9 +338,16 @@
 
     static int mapCSSPropertyIdToCSSSampleIdForHistogram(int id);
 
+    static void muteForInspector();
+    static void unmuteForInspector();
+
 private:
+    static int m_muteCount;
+
     bool recordMeasurement(Feature feature)
     {
+        if (UseCounter::m_muteCount)
+            return false;
         ASSERT(feature != PageDestruction); // PageDestruction is reserved as a scaling factor.
         ASSERT(feature < NumberOfFeatures);
         if (!m_countBits) {
diff --git a/Source/core/frame/Window.idl b/Source/core/frame/Window.idl
index c418b52..ac795a5 100644
--- a/Source/core/frame/Window.idl
+++ b/Source/core/frame/Window.idl
@@ -182,8 +182,6 @@
     [RuntimeEnabled=CSSAnimationUnprefixed] attribute EventHandler onanimationend;
     [RuntimeEnabled=CSSAnimationUnprefixed] attribute EventHandler onanimationiteration;
     [RuntimeEnabled=CSSAnimationUnprefixed] attribute EventHandler onanimationstart;
-    [RuntimeEnabled=DeviceMotion] attribute EventHandler ondevicemotion;
-    [RuntimeEnabled=DeviceOrientation] attribute EventHandler ondeviceorientation;
     [RuntimeEnabled=OrientationEvent] attribute EventHandler onorientationchange;
     attribute EventHandler onsearch;
     [RuntimeEnabled=Touch] attribute EventHandler ontouchcancel;
@@ -197,13 +195,13 @@
     attribute EventHandler onwebkittransitionend;
     [PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute EventHandler onwheel;
 
-    [DeprecateAs=CaptureEvents] void captureEvents();
-    [DeprecateAs=ReleaseEvents] void releaseEvents();
+    [MeasureAs=WindowCaptureEvents] void captureEvents();
+    [MeasureAs=WindowReleaseEvents] void releaseEvents();
 
     // Additional constructors.
     attribute TransitionEventConstructor WebKitTransitionEvent;
     [RuntimeEnabled=CSSAnimationUnprefixed] attribute WebKitAnimationEventConstructor AnimationEvent;
-    attribute URLConstructor webkitURL; // FIXME: deprecate this.
+    [MeasureAs=PrefixedWindowURL] attribute URLConstructor webkitURL; // FIXME: deprecate this.
     attribute MutationObserverConstructor WebKitMutationObserver; // FIXME: Add metrics to determine when we can remove this.
     attribute IDBCursorConstructor webkitIDBCursor;
     attribute IDBDatabaseConstructor webkitIDBDatabase;
@@ -217,8 +215,12 @@
     // Constructors whose name does not match the interface name.
     // FIXME: Remove these once [ImplementedAs] is used and once constructor names match interface names.
     [RuntimeEnabled=MediaStream] attribute MediaStreamConstructor webkitMediaStream;
+
+    // Support both unprefixed and prefixed AudioContext and OfflineAudioContext
     [Conditional=WEB_AUDIO, RuntimeEnabled=WebAudio] attribute AudioContextConstructor webkitAudioContext;
     [Conditional=WEB_AUDIO, RuntimeEnabled=WebAudio] attribute OfflineAudioContextConstructor webkitOfflineAudioContext;
+    [Conditional=WEB_AUDIO, RuntimeEnabled=WebAudio] attribute AudioContextConstructor AudioContext;
+    [Conditional=WEB_AUDIO, RuntimeEnabled=WebAudio] attribute OfflineAudioContextConstructor OfflineAudioContext;
     [RuntimeEnabled=PeerConnection] attribute RTCPeerConnectionConstructor webkitRTCPeerConnection;
     [RuntimeEnabled=ScriptedSpeech] attribute SpeechGrammarConstructor webkitSpeechGrammar;
     [RuntimeEnabled=ScriptedSpeech] attribute SpeechGrammarListConstructor webkitSpeechGrammarList;
diff --git a/Source/core/frame/csp/CSPDirective.h b/Source/core/frame/csp/CSPDirective.h
new file mode 100644
index 0000000..e870ccb
--- /dev/null
+++ b/Source/core/frame/csp/CSPDirective.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPDirective_h
+#define CSPDirective_h
+
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class CSPDirective {
+    WTF_MAKE_NONCOPYABLE(CSPDirective);
+public:
+    CSPDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+        : m_name(name)
+        , m_text(name + ' ' + value)
+        , m_policy(policy)
+    {
+    }
+
+    const String& text() const { return m_text; }
+
+protected:
+    const ContentSecurityPolicy* policy() const { return m_policy; }
+
+private:
+    String m_name;
+    String m_text;
+    ContentSecurityPolicy* m_policy;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/frame/csp/CSPDirectiveList.cpp b/Source/core/frame/csp/CSPDirectiveList.cpp
new file mode 100644
index 0000000..5ced854
--- /dev/null
+++ b/Source/core/frame/csp/CSPDirectiveList.cpp
@@ -0,0 +1,679 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/CSPDirectiveList.h"
+
+#include "core/frame/LocalFrame.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+CSPDirectiveList::CSPDirectiveList(ContentSecurityPolicy* policy, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+    : m_policy(policy)
+    , m_headerType(type)
+    , m_headerSource(source)
+    , m_reportOnly(false)
+    , m_haveSandboxPolicy(false)
+    , m_reflectedXSSDisposition(ReflectedXSSUnset)
+    , m_didSetReferrerPolicy(false)
+    , m_referrerPolicy(ReferrerPolicyDefault)
+{
+    m_reportOnly = type == ContentSecurityPolicyHeaderTypeReport;
+}
+
+PassOwnPtr<CSPDirectiveList> CSPDirectiveList::create(ContentSecurityPolicy* policy, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+{
+    OwnPtr<CSPDirectiveList> directives = adoptPtr(new CSPDirectiveList(policy, type, source));
+    directives->parse(begin, end);
+
+    if (!directives->checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
+        String message = "Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"" + directives->operativeDirective(directives->m_scriptSrc.get())->text() + "\".\n";
+        directives->setEvalDisabledErrorMessage(message);
+    }
+
+    if (directives->isReportOnly() && directives->reportURIs().isEmpty())
+        policy->reportMissingReportURI(String(begin, end - begin));
+
+    return directives.release();
+}
+
+void CSPDirectiveList::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const
+{
+    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
+    m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
+}
+
+void CSPDirectiveList::reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const
+{
+    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
+    m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt());
+    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
+}
+
+void CSPDirectiveList::reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState* state) const
+{
+    String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
+    m_policy->client()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message, state);
+    m_policy->reportViolation(directiveText, effectiveDirective, message, blockedURL, m_reportURIs, m_header);
+}
+
+bool CSPDirectiveList::checkEval(SourceListDirective* directive) const
+{
+    return !directive || directive->allowEval();
+}
+
+bool CSPDirectiveList::checkInline(SourceListDirective* directive) const
+{
+    return !directive || (directive->allowInline() && !directive->isHashOrNoncePresent());
+}
+
+bool CSPDirectiveList::checkNonce(SourceListDirective* directive, const String& nonce) const
+{
+    return !directive || directive->allowNonce(nonce);
+}
+
+bool CSPDirectiveList::checkHash(SourceListDirective* directive, const CSPHashValue& hashValue) const
+{
+    return !directive || directive->allowHash(hashValue);
+}
+
+bool CSPDirectiveList::checkSource(SourceListDirective* directive, const KURL& url) const
+{
+    return !directive || directive->allows(url);
+}
+
+bool CSPDirectiveList::checkAncestors(SourceListDirective* directive, LocalFrame* frame) const
+{
+    if (!frame || !directive)
+        return true;
+
+    for (LocalFrame* current = frame->tree().parent(); current; current = current->tree().parent()) {
+        if (!directive->allows(current->document()->url()))
+            return false;
+    }
+    return true;
+}
+
+bool CSPDirectiveList::checkMediaType(MediaListDirective* directive, const String& type, const String& typeAttribute) const
+{
+    if (!directive)
+        return true;
+    if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
+        return false;
+    return directive->allows(type);
+}
+
+SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive) const
+{
+    return directive ? directive : m_defaultSrc.get();
+}
+
+SourceListDirective* CSPDirectiveList::operativeDirective(SourceListDirective* directive, SourceListDirective* override) const
+{
+    return directive ? directive : override;
+}
+
+bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, ScriptState* state) const
+{
+    if (checkEval(directive))
+        return true;
+
+    String suffix = String();
+    if (directive == m_defaultSrc)
+        suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback.";
+
+    reportViolationWithState(directive->text(), ContentSecurityPolicy::ScriptSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), state);
+    if (!m_reportOnly) {
+        m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+        return false;
+    }
+    return true;
+}
+
+bool CSPDirectiveList::checkMediaTypeAndReportViolation(MediaListDirective* directive, const String& type, const String& typeAttribute, const String& consoleMessage) const
+{
+    if (checkMediaType(directive, type, typeAttribute))
+        return true;
+
+    String message = consoleMessage + "\'" + directive->text() + "\'.";
+    if (typeAttribute.isEmpty())
+        message = message + " When enforcing the 'plugin-types' directive, the plugin's media type must be explicitly declared with a 'type' attribute on the containing element (e.g. '<object type=\"[TYPE GOES HERE]\" ...>').";
+
+    reportViolation(directive->text(), ContentSecurityPolicy::PluginTypes, message + "\n", KURL());
+    return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::checkInlineAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const
+{
+    if (checkInline(directive))
+        return true;
+
+    String suffix = String();
+    if (directive->allowInline() && directive->isHashOrNoncePresent()) {
+        // If inline is allowed, but a hash or nonce is present, we ignore 'unsafe-inline'. Throw a reasonable error.
+        suffix = " Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list.";
+    } else {
+        suffix = " Either the 'unsafe-inline' keyword, a hash ('sha256-...'), or a nonce ('nonce-...') is required to enable inline execution.";
+        if (directive == m_defaultSrc)
+            suffix = suffix + " Note also that '" + String(isScript ? "script" : "style") + "-src' was not explicitly set, so 'default-src' is used as a fallback.";
+    }
+
+    reportViolationWithLocation(directive->text(), isScript ? ContentSecurityPolicy::ScriptSrc : ContentSecurityPolicy::StyleSrc, consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine);
+
+    if (!m_reportOnly) {
+        if (isScript)
+            m_policy->reportBlockedScriptExecutionToInspector(directive->text());
+        return false;
+    }
+    return true;
+}
+
+bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* directive, const KURL& url, const String& effectiveDirective) const
+{
+    if (checkSource(directive, url))
+        return true;
+
+    String prefix;
+    if (ContentSecurityPolicy::BaseURI == effectiveDirective)
+        prefix = "Refused to set the document's base URI to '";
+    else if (ContentSecurityPolicy::ChildSrc == effectiveDirective)
+        prefix = "Refused to create a child context containing '";
+    else if (ContentSecurityPolicy::ConnectSrc == effectiveDirective)
+        prefix = "Refused to connect to '";
+    else if (ContentSecurityPolicy::FontSrc == effectiveDirective)
+        prefix = "Refused to load the font '";
+    else if (ContentSecurityPolicy::FormAction == effectiveDirective)
+        prefix = "Refused to send form data to '";
+    else if (ContentSecurityPolicy::FrameSrc == effectiveDirective)
+        prefix = "Refused to frame '";
+    else if (ContentSecurityPolicy::ImgSrc == effectiveDirective)
+        prefix = "Refused to load the image '";
+    else if (ContentSecurityPolicy::MediaSrc == effectiveDirective)
+        prefix = "Refused to load media from '";
+    else if (ContentSecurityPolicy::ObjectSrc == effectiveDirective)
+        prefix = "Refused to load plugin data from '";
+    else if (ContentSecurityPolicy::ScriptSrc == effectiveDirective)
+        prefix = "Refused to load the script '";
+    else if (ContentSecurityPolicy::StyleSrc == effectiveDirective)
+        prefix = "Refused to load the stylesheet '";
+
+    String suffix = String();
+    if (directive == m_defaultSrc)
+        suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback.";
+
+    reportViolation(directive->text(), effectiveDirective, prefix + url.elidedString() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url);
+    return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::checkAncestorsAndReportViolation(SourceListDirective* directive, LocalFrame* frame) const
+{
+    if (checkAncestors(directive, frame))
+        return true;
+
+    reportViolation(directive->text(), "frame-ancestors", "Refused to display '" + frame->document()->url().elidedString() + " in a frame because an ancestor violates the following Content Security Policy directive: \"" + directive->text() + "\".", frame->document()->url());
+    return denyIfEnforcingPolicy();
+}
+
+bool CSPDirectiveList::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute JavaScript URL because it violates the following Content Security Policy directive: "));
+    if (reportingStatus == ContentSecurityPolicy::SendReport)
+        return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
+
+    return checkInline(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline event handler because it violates the following Content Security Policy directive: "));
+    if (reportingStatus == ContentSecurityPolicy::SendReport)
+        return checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true);
+    return checkInline(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to execute inline script because it violates the following Content Security Policy directive: "));
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkInlineAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, contextURL, contextLine, true) :
+        checkInline(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to apply inline style because it violates the following Content Security Policy directive: "));
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage, contextURL, contextLine, false) :
+        checkInline(operativeDirective(m_styleSrc.get()));
+}
+
+bool CSPDirectiveList::allowEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: "));
+
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, state) :
+        checkEval(operativeDirective(m_scriptSrc.get()));
+}
+
+bool CSPDirectiveList::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkMediaTypeAndReportViolation(m_pluginTypes.get(), type, typeAttribute, "Refused to load '" + url.elidedString() + "' (MIME type '" + typeAttribute + "') because it violates the following Content Security Policy Directive: ") :
+        checkMediaType(m_pluginTypes.get(), type, typeAttribute);
+}
+
+bool CSPDirectiveList::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_scriptSrc.get()), url, ContentSecurityPolicy::ScriptSrc) :
+        checkSource(operativeDirective(m_scriptSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    if (url.isBlankURL())
+        return true;
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_objectSrc.get()), url, ContentSecurityPolicy::ObjectSrc) :
+        checkSource(operativeDirective(m_objectSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    if (url.isBlankURL())
+        return true;
+
+    // 'frame-src' is the only directive which overrides something other than the default sources.
+    // It overrides 'child-src', which overrides the default sources. So, we do this nested set
+    // of calls to 'operativeDirective()' to grab 'frame-src' if it exists, 'child-src' if it
+    // doesn't, and 'defaut-src' if neither are available.
+    //
+    // All of this only applies, of course, if we're in CSP 1.1. In CSP 1.0, 'frame-src'
+    // overrides 'default-src' directly.
+    SourceListDirective* whichDirective = m_policy->experimentalFeaturesEnabled() ?
+        operativeDirective(m_frameSrc.get(), operativeDirective(m_childSrc.get())) :
+        operativeDirective(m_frameSrc.get());
+
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(whichDirective, url, ContentSecurityPolicy::FrameSrc) :
+        checkSource(whichDirective, url);
+}
+
+bool CSPDirectiveList::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_imgSrc.get()), url, ContentSecurityPolicy::ImgSrc) :
+        checkSource(operativeDirective(m_imgSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_styleSrc.get()), url, ContentSecurityPolicy::StyleSrc) :
+        checkSource(operativeDirective(m_styleSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_fontSrc.get()), url, ContentSecurityPolicy::FontSrc) :
+        checkSource(operativeDirective(m_fontSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_mediaSrc.get()), url, ContentSecurityPolicy::MediaSrc) :
+        checkSource(operativeDirective(m_mediaSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_connectSrc.get()), url, ContentSecurityPolicy::ConnectSrc) :
+        checkSource(operativeDirective(m_connectSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(m_formAction.get(), url, ContentSecurityPolicy::FormAction) :
+        checkSource(m_formAction.get(), url);
+}
+
+bool CSPDirectiveList::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(m_baseURI.get(), url, ContentSecurityPolicy::BaseURI) :
+        checkSource(m_baseURI.get(), url);
+}
+
+bool CSPDirectiveList::allowAncestors(LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkAncestorsAndReportViolation(m_frameAncestors.get(), frame) :
+        checkAncestors(m_frameAncestors.get(), frame);
+}
+
+bool CSPDirectiveList::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return reportingStatus == ContentSecurityPolicy::SendReport ?
+        checkSourceAndReportViolation(operativeDirective(m_childSrc.get()), url, ContentSecurityPolicy::ChildSrc) :
+        checkSource(operativeDirective(m_childSrc.get()), url);
+}
+
+bool CSPDirectiveList::allowScriptNonce(const String& nonce) const
+{
+    return checkNonce(operativeDirective(m_scriptSrc.get()), nonce);
+}
+
+bool CSPDirectiveList::allowStyleNonce(const String& nonce) const
+{
+    return checkNonce(operativeDirective(m_styleSrc.get()), nonce);
+}
+
+bool CSPDirectiveList::allowScriptHash(const CSPHashValue& hashValue) const
+{
+    return checkHash(operativeDirective(m_scriptSrc.get()), hashValue);
+}
+
+bool CSPDirectiveList::allowStyleHash(const CSPHashValue& hashValue) const
+{
+    return checkHash(operativeDirective(m_styleSrc.get()), hashValue);
+}
+
+// policy            = directive-list
+// directive-list    = [ directive *( ";" [ directive ] ) ]
+//
+void CSPDirectiveList::parse(const UChar* begin, const UChar* end)
+{
+    m_header = String(begin, end - begin);
+
+    if (begin == end)
+        return;
+
+    const UChar* position = begin;
+    while (position < end) {
+        const UChar* directiveBegin = position;
+        skipUntil<UChar>(position, end, ';');
+
+        String name, value;
+        if (parseDirective(directiveBegin, position, name, value)) {
+            ASSERT(!name.isEmpty());
+            addDirective(name, value);
+        }
+
+        ASSERT(position == end || *position == ';');
+        skipExactly<UChar>(position, end, ';');
+    }
+}
+
+// directive         = *WSP [ directive-name [ WSP directive-value ] ]
+// directive-name    = 1*( ALPHA / DIGIT / "-" )
+// directive-value   = *( WSP / <VCHAR except ";"> )
+//
+bool CSPDirectiveList::parseDirective(const UChar* begin, const UChar* end, String& name, String& value)
+{
+    ASSERT(name.isEmpty());
+    ASSERT(value.isEmpty());
+
+    const UChar* position = begin;
+    skipWhile<UChar, isASCIISpace>(position, end);
+
+    // Empty directive (e.g. ";;;"). Exit early.
+    if (position == end)
+        return false;
+
+    const UChar* nameBegin = position;
+    skipWhile<UChar, isCSPDirectiveNameCharacter>(position, end);
+
+    // The directive-name must be non-empty.
+    if (nameBegin == position) {
+        skipWhile<UChar, isNotASCIISpace>(position, end);
+        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+        return false;
+    }
+
+    name = String(nameBegin, position - nameBegin);
+
+    if (position == end)
+        return true;
+
+    if (!skipExactly<UChar, isASCIISpace>(position, end)) {
+        skipWhile<UChar, isNotASCIISpace>(position, end);
+        m_policy->reportUnsupportedDirective(String(nameBegin, position - nameBegin));
+        return false;
+    }
+
+    skipWhile<UChar, isASCIISpace>(position, end);
+
+    const UChar* valueBegin = position;
+    skipWhile<UChar, isCSPDirectiveValueCharacter>(position, end);
+
+    if (position != end) {
+        m_policy->reportInvalidDirectiveValueCharacter(name, String(valueBegin, end - valueBegin));
+        return false;
+    }
+
+    // The directive-value may be empty.
+    if (valueBegin == position)
+        return true;
+
+    value = String(valueBegin, position - valueBegin);
+    return true;
+}
+
+void CSPDirectiveList::parseReportURI(const String& name, const String& value)
+{
+    if (!m_reportURIs.isEmpty()) {
+        m_policy->reportDuplicateDirective(name);
+        return;
+    }
+
+    Vector<UChar> characters;
+    value.appendTo(characters);
+
+    const UChar* position = characters.data();
+    const UChar* end = position + characters.size();
+
+    while (position < end) {
+        skipWhile<UChar, isASCIISpace>(position, end);
+
+        const UChar* urlBegin = position;
+        skipWhile<UChar, isNotASCIISpace>(position, end);
+
+        if (urlBegin < position) {
+            String url = String(urlBegin, position - urlBegin);
+            m_reportURIs.append(m_policy->completeURL(url));
+        }
+    }
+}
+
+
+template<class CSPDirectiveType>
+void CSPDirectiveList::setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>& directive)
+{
+    if (directive) {
+        m_policy->reportDuplicateDirective(name);
+        return;
+    }
+    directive = adoptPtr(new CSPDirectiveType(name, value, m_policy));
+}
+
+void CSPDirectiveList::applySandboxPolicy(const String& name, const String& sandboxPolicy)
+{
+    if (m_reportOnly) {
+        m_policy->reportInvalidInReportOnly(name);
+        return;
+    }
+    if (m_haveSandboxPolicy) {
+        m_policy->reportDuplicateDirective(name);
+        return;
+    }
+    m_haveSandboxPolicy = true;
+    String invalidTokens;
+    m_policy->enforceSandboxFlags(parseSandboxPolicy(sandboxPolicy, invalidTokens));
+    if (!invalidTokens.isNull())
+        m_policy->reportInvalidSandboxFlags(invalidTokens);
+}
+
+void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
+{
+    if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
+        m_policy->reportDuplicateDirective(name);
+        m_reflectedXSSDisposition = ReflectedXSSInvalid;
+        return;
+    }
+
+    if (value.isEmpty()) {
+        m_reflectedXSSDisposition = ReflectedXSSInvalid;
+        m_policy->reportInvalidReflectedXSS(value);
+        return;
+    }
+
+    Vector<UChar> characters;
+    value.appendTo(characters);
+
+    const UChar* position = characters.data();
+    const UChar* end = position + characters.size();
+
+    skipWhile<UChar, isASCIISpace>(position, end);
+    const UChar* begin = position;
+    skipWhile<UChar, isNotASCIISpace>(position, end);
+
+    // value1
+    //       ^
+    if (equalIgnoringCase("allow", begin, position - begin)) {
+        m_reflectedXSSDisposition = AllowReflectedXSS;
+    } else if (equalIgnoringCase("filter", begin, position - begin)) {
+        m_reflectedXSSDisposition = FilterReflectedXSS;
+    } else if (equalIgnoringCase("block", begin, position - begin)) {
+        m_reflectedXSSDisposition = BlockReflectedXSS;
+    } else {
+        m_reflectedXSSDisposition = ReflectedXSSInvalid;
+        m_policy->reportInvalidReflectedXSS(value);
+        return;
+    }
+
+    skipWhile<UChar, isASCIISpace>(position, end);
+    if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset)
+        return;
+
+    // value1 value2
+    //        ^
+    m_reflectedXSSDisposition = ReflectedXSSInvalid;
+    m_policy->reportInvalidReflectedXSS(value);
+}
+
+void CSPDirectiveList::parseReferrer(const String& name, const String& value)
+{
+    if (m_didSetReferrerPolicy) {
+        m_policy->reportDuplicateDirective(name);
+        m_referrerPolicy = ReferrerPolicyNever;
+        return;
+    }
+
+    m_didSetReferrerPolicy = true;
+
+    if (value.isEmpty()) {
+        m_policy->reportInvalidReferrer(value);
+        m_referrerPolicy = ReferrerPolicyNever;
+        return;
+    }
+
+    Vector<UChar> characters;
+    value.appendTo(characters);
+
+    const UChar* position = characters.data();
+    const UChar* end = position + characters.size();
+
+    skipWhile<UChar, isASCIISpace>(position, end);
+    const UChar* begin = position;
+    skipWhile<UChar, isNotASCIISpace>(position, end);
+
+    // value1
+    //       ^
+    if (equalIgnoringCase("always", begin, position - begin)) {
+        m_referrerPolicy = ReferrerPolicyAlways;
+    } else if (equalIgnoringCase("default", begin, position - begin)) {
+        m_referrerPolicy = ReferrerPolicyDefault;
+    } else if (equalIgnoringCase("never", begin, position - begin)) {
+        m_referrerPolicy = ReferrerPolicyNever;
+    } else if (equalIgnoringCase("origin", begin, position - begin)) {
+        m_referrerPolicy = ReferrerPolicyOrigin;
+    } else {
+        m_referrerPolicy = ReferrerPolicyNever;
+        m_policy->reportInvalidReferrer(value);
+        return;
+    }
+
+    skipWhile<UChar, isASCIISpace>(position, end);
+    if (position == end)
+        return;
+
+    // value1 value2
+    //        ^
+    m_referrerPolicy = ReferrerPolicyNever;
+    m_policy->reportInvalidReferrer(value);
+
+}
+
+void CSPDirectiveList::addDirective(const String& name, const String& value)
+{
+    ASSERT(!name.isEmpty());
+
+    if (equalIgnoringCase(name, ContentSecurityPolicy::DefaultSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_defaultSrc);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ScriptSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_scriptSrc);
+        m_policy->usesScriptHashAlgorithms(m_scriptSrc->hashAlgorithmsUsed());
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ObjectSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_objectSrc);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::FrameSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_frameSrc);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ImgSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_imgSrc);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::StyleSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_styleSrc);
+        m_policy->usesStyleHashAlgorithms(m_styleSrc->hashAlgorithmsUsed());
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::FontSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_fontSrc);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::MediaSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_mediaSrc);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ConnectSrc)) {
+        setCSPDirective<SourceListDirective>(name, value, m_connectSrc);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::Sandbox)) {
+        applySandboxPolicy(name, value);
+    } else if (equalIgnoringCase(name, ContentSecurityPolicy::ReportURI)) {
+        parseReportURI(name, value);
+    } else if (m_policy->experimentalFeaturesEnabled()) {
+        if (equalIgnoringCase(name, ContentSecurityPolicy::BaseURI))
+            setCSPDirective<SourceListDirective>(name, value, m_baseURI);
+        else if (equalIgnoringCase(name, ContentSecurityPolicy::ChildSrc))
+            setCSPDirective<SourceListDirective>(name, value, m_childSrc);
+        else if (equalIgnoringCase(name, ContentSecurityPolicy::FormAction))
+            setCSPDirective<SourceListDirective>(name, value, m_formAction);
+        else if (equalIgnoringCase(name, ContentSecurityPolicy::FrameAncestors))
+            setCSPDirective<SourceListDirective>(name, value, m_frameAncestors);
+        else if (equalIgnoringCase(name, ContentSecurityPolicy::PluginTypes))
+            setCSPDirective<MediaListDirective>(name, value, m_pluginTypes);
+        else if (equalIgnoringCase(name, ContentSecurityPolicy::ReflectedXSS))
+            parseReflectedXSS(name, value);
+        else if (equalIgnoringCase(name, ContentSecurityPolicy::Referrer))
+            parseReferrer(name, value);
+        else
+            m_policy->reportUnsupportedDirective(name);
+    } else {
+        m_policy->reportUnsupportedDirective(name);
+    }
+}
+
+
+} // namespace WebCore
+
diff --git a/Source/core/frame/csp/CSPDirectiveList.h b/Source/core/frame/csp/CSPDirectiveList.h
new file mode 100644
index 0000000..b33b186
--- /dev/null
+++ b/Source/core/frame/csp/CSPDirectiveList.h
@@ -0,0 +1,141 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPDirectiveList_h
+#define CSPDirectiveList_h
+
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/frame/csp/MediaListDirective.h"
+#include "core/frame/csp/SourceListDirective.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "platform/network/HTTPParsers.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/ReferrerPolicy.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+
+class CSPDirectiveList {
+    WTF_MAKE_FAST_ALLOCATED;
+    WTF_MAKE_NONCOPYABLE(CSPDirectiveList);
+public:
+    static PassOwnPtr<CSPDirectiveList> create(ContentSecurityPolicy*, const UChar* begin, const UChar* end, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
+
+    void parse(const UChar* begin, const UChar* end);
+
+    const String& header() const { return m_header; }
+    ContentSecurityPolicyHeaderType headerType() const { return m_headerType; }
+    ContentSecurityPolicyHeaderSource headerSource() const { return m_headerSource; }
+
+    bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+
+    bool allowScriptFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowObjectFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowChildFrameFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowImageFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowStyleFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowFontFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowMediaFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowConnectToSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowFormAction(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowBaseURI(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowAncestors(LocalFrame*, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowChildContextFromSource(const KURL&, ContentSecurityPolicy::ReportingStatus) const;
+    bool allowScriptNonce(const String&) const;
+    bool allowStyleNonce(const String&) const;
+    bool allowScriptHash(const CSPHashValue&) const;
+    bool allowStyleHash(const CSPHashValue&) const;
+
+    const String& evalDisabledErrorMessage() const { return m_evalDisabledErrorMessage; }
+    ReflectedXSSDisposition reflectedXSSDisposition() const { return m_reflectedXSSDisposition; }
+    ReferrerPolicy referrerPolicy() const { return m_referrerPolicy; }
+    bool didSetReferrerPolicy() const { return m_didSetReferrerPolicy; }
+    bool isReportOnly() const { return m_reportOnly; }
+    const Vector<KURL>& reportURIs() const { return m_reportURIs; }
+
+private:
+    CSPDirectiveList(ContentSecurityPolicy*, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
+
+    bool parseDirective(const UChar* begin, const UChar* end, String& name, String& value);
+    void parseReportURI(const String& name, const String& value);
+    void parsePluginTypes(const String& name, const String& value);
+    void parseReflectedXSS(const String& name, const String& value);
+    void parseReferrer(const String& name, const String& value);
+    void addDirective(const String& name, const String& value);
+    void applySandboxPolicy(const String& name, const String& sandboxPolicy);
+
+    template <class CSPDirectiveType>
+    void setCSPDirective(const String& name, const String& value, OwnPtr<CSPDirectiveType>&);
+
+    SourceListDirective* operativeDirective(SourceListDirective*) const;
+    SourceListDirective* operativeDirective(SourceListDirective*, SourceListDirective* override) const;
+    void reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL) const;
+    void reportViolationWithLocation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const;
+    void reportViolationWithState(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, ScriptState*) const;
+
+    bool checkEval(SourceListDirective*) const;
+    bool checkInline(SourceListDirective*) const;
+    bool checkNonce(SourceListDirective*, const String&) const;
+    bool checkHash(SourceListDirective*, const CSPHashValue&) const;
+    bool checkSource(SourceListDirective*, const KURL&) const;
+    bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const;
+    bool checkAncestors(SourceListDirective*, LocalFrame*) const;
+
+    void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; }
+
+    bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, ScriptState*) const;
+    bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const;
+
+    bool checkSourceAndReportViolation(SourceListDirective*, const KURL&, const String& effectiveDirective) const;
+    bool checkMediaTypeAndReportViolation(MediaListDirective*, const String& type, const String& typeAttribute, const String& consoleMessage) const;
+    bool checkAncestorsAndReportViolation(SourceListDirective*, LocalFrame*) const;
+
+    bool denyIfEnforcingPolicy() const { return m_reportOnly; }
+
+    ContentSecurityPolicy* m_policy;
+
+    String m_header;
+    ContentSecurityPolicyHeaderType m_headerType;
+    ContentSecurityPolicyHeaderSource m_headerSource;
+
+    bool m_reportOnly;
+    bool m_haveSandboxPolicy;
+    ReflectedXSSDisposition m_reflectedXSSDisposition;
+
+    bool m_didSetReferrerPolicy;
+    ReferrerPolicy m_referrerPolicy;
+
+    OwnPtr<MediaListDirective> m_pluginTypes;
+    OwnPtr<SourceListDirective> m_baseURI;
+    OwnPtr<SourceListDirective> m_childSrc;
+    OwnPtr<SourceListDirective> m_connectSrc;
+    OwnPtr<SourceListDirective> m_defaultSrc;
+    OwnPtr<SourceListDirective> m_fontSrc;
+    OwnPtr<SourceListDirective> m_formAction;
+    OwnPtr<SourceListDirective> m_frameAncestors;
+    OwnPtr<SourceListDirective> m_frameSrc;
+    OwnPtr<SourceListDirective> m_imgSrc;
+    OwnPtr<SourceListDirective> m_mediaSrc;
+    OwnPtr<SourceListDirective> m_objectSrc;
+    OwnPtr<SourceListDirective> m_scriptSrc;
+    OwnPtr<SourceListDirective> m_styleSrc;
+
+    Vector<KURL> m_reportURIs;
+
+    String m_evalDisabledErrorMessage;
+};
+
+
+} // namespace
+
+#endif
diff --git a/Source/core/frame/csp/CSPSource.cpp b/Source/core/frame/csp/CSPSource.cpp
new file mode 100644
index 0000000..863addc
--- /dev/null
+++ b/Source/core/frame/csp/CSPSource.cpp
@@ -0,0 +1,93 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/CSPSource.h"
+
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/KnownPorts.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+CSPSource::CSPSource(ContentSecurityPolicy* policy, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard)
+    : m_policy(policy)
+    , m_scheme(scheme)
+    , m_host(host)
+    , m_port(port)
+    , m_path(path)
+    , m_hostHasWildcard(hostHasWildcard)
+    , m_portHasWildcard(portHasWildcard)
+{
+}
+
+bool CSPSource::matches(const KURL& url) const
+{
+    if (!schemeMatches(url))
+        return false;
+    if (isSchemeOnly())
+        return true;
+    return hostMatches(url) && portMatches(url) && pathMatches(url);
+}
+
+bool CSPSource::schemeMatches(const KURL& url) const
+{
+    if (m_scheme.isEmpty()) {
+        String protectedResourceScheme(m_policy->securityOrigin()->protocol());
+        if (equalIgnoringCase("http", protectedResourceScheme))
+            return url.protocolIs("http") || url.protocolIs("https");
+        return equalIgnoringCase(url.protocol(), protectedResourceScheme);
+    }
+    return equalIgnoringCase(url.protocol(), m_scheme);
+}
+
+bool CSPSource::hostMatches(const KURL& url) const
+{
+    const String& host = url.host();
+    if (equalIgnoringCase(host, m_host))
+        return true;
+    return m_hostHasWildcard && host.endsWith("." + m_host, false);
+
+}
+
+bool CSPSource::pathMatches(const KURL& url) const
+{
+    if (m_path.isEmpty())
+        return true;
+
+    String path = decodeURLEscapeSequences(url.path());
+
+    if (m_path.endsWith("/"))
+        return path.startsWith(m_path, false);
+
+    return path == m_path;
+}
+
+bool CSPSource::portMatches(const KURL& url) const
+{
+    if (m_portHasWildcard)
+        return true;
+
+    int port = url.port();
+
+    if (port == m_port)
+        return true;
+
+    if (!port)
+        return isDefaultPortForProtocol(m_port, url.protocol());
+
+    if (!m_port)
+        return isDefaultPortForProtocol(port, url.protocol());
+
+    return false;
+}
+
+bool CSPSource::isSchemeOnly() const
+{
+    return m_host.isEmpty();
+}
+
+} // namespace
diff --git a/Source/core/frame/csp/CSPSource.h b/Source/core/frame/csp/CSPSource.h
new file mode 100644
index 0000000..9088b19
--- /dev/null
+++ b/Source/core/frame/csp/CSPSource.h
@@ -0,0 +1,39 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPSource_h
+#define CSPSource_h
+
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class CSPSource {
+public:
+    CSPSource(ContentSecurityPolicy*, const String& scheme, const String& host, int port, const String& path, bool hostHasWildcard, bool portHasWildcard);
+    bool matches(const KURL&) const;
+
+private:
+    bool schemeMatches(const KURL&) const;
+    bool hostMatches(const KURL&) const;
+    bool pathMatches(const KURL&) const;
+    bool portMatches(const KURL&) const;
+    bool isSchemeOnly() const;
+
+    ContentSecurityPolicy* m_policy;
+    String m_scheme;
+    String m_host;
+    int m_port;
+    String m_path;
+
+    bool m_hostHasWildcard;
+    bool m_portHasWildcard;
+};
+
+} // namespace
+
+#endif
diff --git a/Source/core/frame/csp/CSPSourceList.cpp b/Source/core/frame/csp/CSPSourceList.cpp
new file mode 100644
index 0000000..a17c5bb
--- /dev/null
+++ b/Source/core/frame/csp/CSPSourceList.cpp
@@ -0,0 +1,516 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/CSPSourceList.h"
+
+#include "core/frame/csp/CSPSource.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "wtf/HashSet.h"
+#include "wtf/StringHasher.h"
+#include "wtf/text/Base64.h"
+#include "wtf/text/WTFString.h"
+
+namespace WTF {
+
+struct DigestValueHash {
+    static unsigned hash(const WebCore::DigestValue& v)
+    {
+        return StringHasher::computeHash(v.data(), v.size());
+    }
+    static bool equal(const WebCore::DigestValue& a, const WebCore::DigestValue& b)
+    {
+        return a == b;
+    };
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+template <>
+struct DefaultHash<WebCore::DigestValue> {
+    typedef DigestValueHash Hash;
+};
+
+template <>
+struct DefaultHash<WebCore::ContentSecurityPolicyHashAlgorithm> {
+    typedef IntHash<WebCore::ContentSecurityPolicyHashAlgorithm> Hash;
+};
+template <>
+struct HashTraits<WebCore::ContentSecurityPolicyHashAlgorithm> : UnsignedWithZeroKeyHashTraits<WebCore::ContentSecurityPolicyHashAlgorithm> {
+};
+
+} // namespace WTF
+
+namespace WebCore {
+
+static bool isSourceListNone(const UChar* begin, const UChar* end)
+{
+    skipWhile<UChar, isASCIISpace>(begin, end);
+
+    const UChar* position = begin;
+    skipWhile<UChar, isSourceCharacter>(position, end);
+    if (!equalIgnoringCase("'none'", begin, position - begin))
+        return false;
+
+    skipWhile<UChar, isASCIISpace>(position, end);
+    if (position != end)
+        return false;
+
+    return true;
+}
+
+CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& directiveName)
+    : m_policy(policy)
+    , m_directiveName(directiveName)
+    , m_allowStar(false)
+    , m_allowInline(false)
+    , m_allowEval(false)
+    , m_hashAlgorithmsUsed(0)
+{
+}
+
+bool CSPSourceList::matches(const KURL& url) const
+{
+    if (m_allowStar)
+        return true;
+
+    KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
+
+    for (size_t i = 0; i < m_list.size(); ++i) {
+        if (m_list[i].matches(effectiveURL))
+            return true;
+    }
+
+    return false;
+}
+
+bool CSPSourceList::allowInline() const
+{
+    return m_allowInline;
+}
+
+bool CSPSourceList::allowEval() const
+{
+    return m_allowEval;
+}
+
+bool CSPSourceList::allowNonce(const String& nonce) const
+{
+    return !nonce.isNull() && m_nonces.contains(nonce);
+}
+
+bool CSPSourceList::allowHash(const CSPHashValue& hashValue) const
+{
+    return m_hashes.contains(hashValue);
+}
+
+uint8_t CSPSourceList::hashAlgorithmsUsed() const
+{
+    return m_hashAlgorithmsUsed;
+}
+
+bool CSPSourceList::isHashOrNoncePresent() const
+{
+    return !m_nonces.isEmpty() || m_hashAlgorithmsUsed != ContentSecurityPolicyHashAlgorithmNone;
+}
+
+// source-list       = *WSP [ source *( 1*WSP source ) *WSP ]
+//                   / *WSP "'none'" *WSP
+//
+void CSPSourceList::parse(const UChar* begin, const UChar* end)
+{
+    // We represent 'none' as an empty m_list.
+    if (isSourceListNone(begin, end))
+        return;
+
+    const UChar* position = begin;
+    while (position < end) {
+        skipWhile<UChar, isASCIISpace>(position, end);
+        if (position == end)
+            return;
+
+        const UChar* beginSource = position;
+        skipWhile<UChar, isSourceCharacter>(position, end);
+
+        String scheme, host, path;
+        int port = 0;
+        bool hostHasWildcard = false;
+        bool portHasWildcard = false;
+
+        if (parseSource(beginSource, position, scheme, host, port, path, hostHasWildcard, portHasWildcard)) {
+            // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
+            // etc.) aren't stored in m_list, but as attributes on the source
+            // list itself.
+            if (scheme.isEmpty() && host.isEmpty())
+                continue;
+            if (m_policy->isDirectiveName(host))
+                m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
+            m_list.append(CSPSource(m_policy, scheme, host, port, path, hostHasWildcard, portHasWildcard));
+        } else {
+            m_policy->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
+        }
+
+        ASSERT(position == end || isASCIISpace(*position));
+    }
+}
+
+// source            = scheme ":"
+//                   / ( [ scheme "://" ] host [ port ] [ path ] )
+//                   / "'self'"
+bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard)
+{
+    if (begin == end)
+        return false;
+
+    if (equalIgnoringCase("'none'", begin, end - begin))
+        return false;
+
+    if (end - begin == 1 && *begin == '*') {
+        addSourceStar();
+        return true;
+    }
+
+    if (equalIgnoringCase("'self'", begin, end - begin)) {
+        addSourceSelf();
+        return true;
+    }
+
+    if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) {
+        addSourceUnsafeInline();
+        return true;
+    }
+
+    if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) {
+        addSourceUnsafeEval();
+        return true;
+    }
+
+    if (m_policy->experimentalFeaturesEnabled()) {
+        String nonce;
+        if (!parseNonce(begin, end, nonce))
+            return false;
+
+        if (!nonce.isNull()) {
+            addSourceNonce(nonce);
+            return true;
+        }
+
+        DigestValue hash;
+        ContentSecurityPolicyHashAlgorithm algorithm = ContentSecurityPolicyHashAlgorithmNone;
+        if (!parseHash(begin, end, hash, algorithm))
+            return false;
+
+        if (hash.size() > 0) {
+            addSourceHash(algorithm, hash);
+            return true;
+        }
+    }
+
+    const UChar* position = begin;
+    const UChar* beginHost = begin;
+    const UChar* beginPath = end;
+    const UChar* beginPort = 0;
+
+    skipWhile<UChar, isNotColonOrSlash>(position, end);
+
+    if (position == end) {
+        // host
+        //     ^
+        return parseHost(beginHost, position, host, hostHasWildcard);
+    }
+
+    if (position < end && *position == '/') {
+        // host/path || host/ || /
+        //     ^            ^    ^
+        return parseHost(beginHost, position, host, hostHasWildcard) && parsePath(position, end, path);
+    }
+
+    if (position < end && *position == ':') {
+        if (end - position == 1) {
+            // scheme:
+            //       ^
+            return parseScheme(begin, position, scheme);
+        }
+
+        if (position[1] == '/') {
+            // scheme://host || scheme://
+            //       ^                ^
+            if (!parseScheme(begin, position, scheme)
+                || !skipExactly<UChar>(position, end, ':')
+                || !skipExactly<UChar>(position, end, '/')
+                || !skipExactly<UChar>(position, end, '/'))
+                return false;
+            if (position == end)
+                return true;
+            beginHost = position;
+            skipWhile<UChar, isNotColonOrSlash>(position, end);
+        }
+
+        if (position < end && *position == ':') {
+            // host:port || scheme://host:port
+            //     ^                     ^
+            beginPort = position;
+            skipUntil<UChar>(position, end, '/');
+        }
+    }
+
+    if (position < end && *position == '/') {
+        // scheme://host/path || scheme://host:port/path
+        //              ^                          ^
+        if (position == beginHost)
+            return false;
+        beginPath = position;
+    }
+
+    if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostHasWildcard))
+        return false;
+
+    if (beginPort) {
+        if (!parsePort(beginPort, beginPath, port, portHasWildcard))
+            return false;
+    } else {
+        port = 0;
+    }
+
+    if (beginPath != end) {
+        if (!parsePath(beginPath, end, path))
+            return false;
+    }
+
+    return true;
+}
+
+// nonce-source      = "'nonce-" nonce-value "'"
+// nonce-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
+//
+bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& nonce)
+{
+    DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-"));
+
+    if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length()))
+        return true;
+
+    const UChar* position = begin + noncePrefix.length();
+    const UChar* nonceBegin = position;
+
+    skipWhile<UChar, isNonceCharacter>(position, end);
+    ASSERT(nonceBegin <= position);
+
+    if ((position + 1) != end || *position != '\'' || !(position - nonceBegin))
+        return false;
+
+    nonce = String(nonceBegin, position - nonceBegin);
+    return true;
+}
+
+// hash-source       = "'" hash-algorithm "-" hash-value "'"
+// hash-algorithm    = "sha1" / "sha256" / "sha384" / "sha512"
+// hash-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
+//
+bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, DigestValue& hash, ContentSecurityPolicyHashAlgorithm& hashAlgorithm)
+{
+    // Any additions or subtractions from this struct should also modify the
+    // respective entries in the kAlgorithmMap array in checkDigest().
+    static const struct {
+        const char* prefix;
+        ContentSecurityPolicyHashAlgorithm algorithm;
+    } kSupportedPrefixes[] = {
+        { "'sha1-", ContentSecurityPolicyHashAlgorithmSha1 },
+        { "'sha256-", ContentSecurityPolicyHashAlgorithmSha256 },
+        { "'sha384-", ContentSecurityPolicyHashAlgorithmSha384 },
+        { "'sha512-", ContentSecurityPolicyHashAlgorithmSha512 }
+    };
+
+    String prefix;
+    hashAlgorithm = ContentSecurityPolicyHashAlgorithmNone;
+
+    // Instead of this sizeof() calculation to get the length of this array,
+    // it would be preferable to use WTF_ARRAY_LENGTH for simplicity and to
+    // guarantee a compile time calculation. Unfortunately, on some
+    // compliers, the call to WTF_ARRAY_LENGTH fails on arrays of anonymous
+    // stucts, so, for now, it is necessary to resort to this sizeof
+    // calculation.
+    for (size_t i = 0; i < (sizeof(kSupportedPrefixes) / sizeof(kSupportedPrefixes[0])); i++) {
+        if (equalIgnoringCase(kSupportedPrefixes[i].prefix, begin, strlen(kSupportedPrefixes[i].prefix))) {
+            prefix = kSupportedPrefixes[i].prefix;
+            hashAlgorithm = kSupportedPrefixes[i].algorithm;
+            break;
+        }
+    }
+
+    if (hashAlgorithm == ContentSecurityPolicyHashAlgorithmNone)
+        return true;
+
+    const UChar* position = begin + prefix.length();
+    const UChar* hashBegin = position;
+
+    skipWhile<UChar, isBase64EncodedCharacter>(position, end);
+    ASSERT(hashBegin <= position);
+
+    // Base64 encodings may end with exactly one or two '=' characters
+    skipExactly<UChar>(position, position + 1, '=');
+    skipExactly<UChar>(position, position + 1, '=');
+
+    if ((position + 1) != end || *position != '\'' || !(position - hashBegin))
+        return false;
+
+    Vector<char> hashVector;
+    base64Decode(hashBegin, position - hashBegin, hashVector);
+    if (hashVector.size() > kMaxDigestSize)
+        return false;
+    hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size());
+    return true;
+}
+
+//                     ; <scheme> production from RFC 3986
+// scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+//
+bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
+{
+    ASSERT(begin <= end);
+    ASSERT(scheme.isEmpty());
+
+    if (begin == end)
+        return false;
+
+    const UChar* position = begin;
+
+    if (!skipExactly<UChar, isASCIIAlpha>(position, end))
+        return false;
+
+    skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
+
+    if (position != end)
+        return false;
+
+    scheme = String(begin, end - begin);
+    return true;
+}
+
+// host              = [ "*." ] 1*host-char *( "." 1*host-char )
+//                   / "*"
+// host-char         = ALPHA / DIGIT / "-"
+//
+bool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard)
+{
+    ASSERT(begin <= end);
+    ASSERT(host.isEmpty());
+    ASSERT(!hostHasWildcard);
+
+    if (begin == end)
+        return false;
+
+    const UChar* position = begin;
+
+    if (skipExactly<UChar>(position, end, '*')) {
+        hostHasWildcard = true;
+
+        if (position == end)
+            return true;
+
+        if (!skipExactly<UChar>(position, end, '.'))
+            return false;
+    }
+
+    const UChar* hostBegin = position;
+
+    while (position < end) {
+        if (!skipExactly<UChar, isHostCharacter>(position, end))
+            return false;
+
+        skipWhile<UChar, isHostCharacter>(position, end);
+
+        if (position < end && !skipExactly<UChar>(position, end, '.'))
+            return false;
+    }
+
+    ASSERT(position == end);
+    host = String(hostBegin, end - hostBegin);
+    return true;
+}
+
+bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path)
+{
+    ASSERT(begin <= end);
+    ASSERT(path.isEmpty());
+
+    const UChar* position = begin;
+    skipWhile<UChar, isPathComponentCharacter>(position, end);
+    // path/to/file.js?query=string || path/to/file.js#anchor
+    //                ^                               ^
+    if (position < end)
+        m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
+
+    path = decodeURLEscapeSequences(String(begin, position - begin));
+
+    ASSERT(position <= end);
+    ASSERT(position == end || (*position == '#' || *position == '?'));
+    return true;
+}
+
+// port              = ":" ( 1*DIGIT / "*" )
+//
+bool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard)
+{
+    ASSERT(begin <= end);
+    ASSERT(!port);
+    ASSERT(!portHasWildcard);
+
+    if (!skipExactly<UChar>(begin, end, ':'))
+        ASSERT_NOT_REACHED();
+
+    if (begin == end)
+        return false;
+
+    if (end - begin == 1 && *begin == '*') {
+        port = 0;
+        portHasWildcard = true;
+        return true;
+    }
+
+    const UChar* position = begin;
+    skipWhile<UChar, isASCIIDigit>(position, end);
+
+    if (position != end)
+        return false;
+
+    bool ok;
+    port = charactersToIntStrict(begin, end - begin, &ok);
+    return ok;
+}
+
+void CSPSourceList::addSourceSelf()
+{
+    m_list.append(CSPSource(m_policy, m_policy->securityOrigin()->protocol(), m_policy->securityOrigin()->host(), m_policy->securityOrigin()->port(), String(), false, false));
+}
+
+void CSPSourceList::addSourceStar()
+{
+    m_allowStar = true;
+}
+
+void CSPSourceList::addSourceUnsafeInline()
+{
+    m_allowInline = true;
+}
+
+void CSPSourceList::addSourceUnsafeEval()
+{
+    m_allowEval = true;
+}
+
+void CSPSourceList::addSourceNonce(const String& nonce)
+{
+    m_nonces.add(nonce);
+}
+
+void CSPSourceList::addSourceHash(const ContentSecurityPolicyHashAlgorithm& algorithm, const DigestValue& hash)
+{
+    m_hashes.add(CSPHashValue(algorithm, hash));
+    m_hashAlgorithmsUsed |= algorithm;
+}
+
+
+} // namespace WebCore
diff --git a/Source/core/frame/csp/CSPSourceList.h b/Source/core/frame/csp/CSPSourceList.h
new file mode 100644
index 0000000..5475eff
--- /dev/null
+++ b/Source/core/frame/csp/CSPSourceList.h
@@ -0,0 +1,64 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CSPSourceList_h
+#define CSPSourceList_h
+
+#include "core/frame/csp/CSPSource.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class CSPSourceList {
+    WTF_MAKE_NONCOPYABLE(CSPSourceList);
+public:
+    CSPSourceList(ContentSecurityPolicy*, const String& directiveName);
+
+    void parse(const UChar* begin, const UChar* end);
+
+    bool matches(const KURL&) const;
+    bool allowInline() const;
+    bool allowEval() const;
+    bool allowNonce(const String&) const;
+    bool allowHash(const CSPHashValue&) const;
+    uint8_t hashAlgorithmsUsed() const;
+
+    bool isHashOrNoncePresent() const;
+
+private:
+    bool parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard);
+    bool parseScheme(const UChar* begin, const UChar* end, String& scheme);
+    bool parseHost(const UChar* begin, const UChar* end, String& host, bool& hostHasWildcard);
+    bool parsePort(const UChar* begin, const UChar* end, int& port, bool& portHasWildcard);
+    bool parsePath(const UChar* begin, const UChar* end, String& path);
+    bool parseNonce(const UChar* begin, const UChar* end, String& nonce);
+    bool parseHash(const UChar* begin, const UChar* end, DigestValue& hash, ContentSecurityPolicyHashAlgorithm&);
+
+    void addSourceSelf();
+    void addSourceStar();
+    void addSourceUnsafeInline();
+    void addSourceUnsafeEval();
+    void addSourceNonce(const String& nonce);
+    void addSourceHash(const ContentSecurityPolicyHashAlgorithm&, const DigestValue& hash);
+
+    ContentSecurityPolicy* m_policy;
+    Vector<CSPSource> m_list;
+    String m_directiveName;
+    bool m_allowStar;
+    bool m_allowInline;
+    bool m_allowEval;
+    HashSet<String> m_nonces;
+    HashSet<CSPHashValue> m_hashes;
+    uint8_t m_hashAlgorithmsUsed;
+};
+
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/frame/csp/ContentSecurityPolicy.cpp b/Source/core/frame/csp/ContentSecurityPolicy.cpp
new file mode 100644
index 0000000..26cb7d0
--- /dev/null
+++ b/Source/core/frame/csp/ContentSecurityPolicy.cpp
@@ -0,0 +1,800 @@
+/*
+ * Copyright (C) 2011 Google, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+
+#include "RuntimeEnabledFeatures.h"
+#include "bindings/v8/ScriptCallStackFactory.h"
+#include "bindings/v8/ScriptController.h"
+#include "core/dom/DOMStringList.h"
+#include "core/dom/Document.h"
+#include "core/events/SecurityPolicyViolationEvent.h"
+#include "core/frame/DOMWindow.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
+#include "core/frame/csp/CSPDirectiveList.h"
+#include "core/frame/csp/CSPSource.h"
+#include "core/frame/csp/CSPSourceList.h"
+#include "core/frame/csp/MediaListDirective.h"
+#include "core/frame/csp/SourceListDirective.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/ScriptCallStack.h"
+#include "core/loader/DocumentLoader.h"
+#include "core/loader/PingLoader.h"
+#include "platform/JSONValues.h"
+#include "platform/NotImplemented.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
+#include "platform/network/FormData.h"
+#include "platform/network/ResourceResponse.h"
+#include "platform/weborigin/KURL.h"
+#include "platform/weborigin/KnownPorts.h"
+#include "platform/weborigin/SchemeRegistry.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/Platform.h"
+#include "public/platform/WebArrayBuffer.h"
+#include "public/platform/WebCrypto.h"
+#include "public/platform/WebCryptoAlgorithm.h"
+#include "wtf/HashMap.h"
+#include "wtf/StringHasher.h"
+#include "wtf/text/StringBuilder.h"
+#include "wtf/text/StringUTF8Adaptor.h"
+
+namespace WebCore {
+
+// CSP 1.0 Directives
+const char ContentSecurityPolicy::ConnectSrc[] = "connect-src";
+const char ContentSecurityPolicy::DefaultSrc[] = "default-src";
+const char ContentSecurityPolicy::FontSrc[] = "font-src";
+const char ContentSecurityPolicy::FrameSrc[] = "frame-src";
+const char ContentSecurityPolicy::ImgSrc[] = "img-src";
+const char ContentSecurityPolicy::MediaSrc[] = "media-src";
+const char ContentSecurityPolicy::ObjectSrc[] = "object-src";
+const char ContentSecurityPolicy::ReportURI[] = "report-uri";
+const char ContentSecurityPolicy::Sandbox[] = "sandbox";
+const char ContentSecurityPolicy::ScriptSrc[] = "script-src";
+const char ContentSecurityPolicy::StyleSrc[] = "style-src";
+
+// CSP 1.1 Directives
+const char ContentSecurityPolicy::BaseURI[] = "base-uri";
+const char ContentSecurityPolicy::ChildSrc[] = "child-src";
+const char ContentSecurityPolicy::FormAction[] = "form-action";
+const char ContentSecurityPolicy::FrameAncestors[] = "frame-ancestors";
+const char ContentSecurityPolicy::PluginTypes[] = "plugin-types";
+const char ContentSecurityPolicy::ReflectedXSS[] = "reflected-xss";
+const char ContentSecurityPolicy::Referrer[] = "referrer";
+
+bool ContentSecurityPolicy::isDirectiveName(const String& name)
+{
+    return (equalIgnoringCase(name, ConnectSrc)
+        || equalIgnoringCase(name, DefaultSrc)
+        || equalIgnoringCase(name, FontSrc)
+        || equalIgnoringCase(name, FrameSrc)
+        || equalIgnoringCase(name, ImgSrc)
+        || equalIgnoringCase(name, MediaSrc)
+        || equalIgnoringCase(name, ObjectSrc)
+        || equalIgnoringCase(name, ReportURI)
+        || equalIgnoringCase(name, Sandbox)
+        || equalIgnoringCase(name, ScriptSrc)
+        || equalIgnoringCase(name, StyleSrc)
+        || equalIgnoringCase(name, BaseURI)
+        || equalIgnoringCase(name, ChildSrc)
+        || equalIgnoringCase(name, FormAction)
+        || equalIgnoringCase(name, FrameAncestors)
+        || equalIgnoringCase(name, PluginTypes)
+        || equalIgnoringCase(name, ReflectedXSS)
+        || equalIgnoringCase(name, Referrer)
+    );
+}
+
+static UseCounter::Feature getUseCounterType(ContentSecurityPolicyHeaderType type)
+{
+    switch (type) {
+    case ContentSecurityPolicyHeaderTypeEnforce:
+        return UseCounter::ContentSecurityPolicy;
+    case ContentSecurityPolicyHeaderTypeReport:
+        return UseCounter::ContentSecurityPolicyReportOnly;
+    }
+    ASSERT_NOT_REACHED();
+    return UseCounter::NumberOfFeatures;
+}
+
+static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b)
+{
+    if (a != b)
+        return ReferrerPolicyNever;
+    return a;
+}
+
+ContentSecurityPolicy::ContentSecurityPolicy(ExecutionContextClient* client)
+    : m_client(client)
+    , m_overrideInlineStyleAllowed(false)
+    , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
+    , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone)
+{
+}
+
+ContentSecurityPolicy::~ContentSecurityPolicy()
+{
+}
+
+void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other)
+{
+    ASSERT(m_policies.isEmpty());
+    for (CSPDirectiveListVector::const_iterator iter = other->m_policies.begin(); iter != other->m_policies.end(); ++iter)
+        addPolicyFromHeaderValue((*iter)->header(), (*iter)->headerType(), (*iter)->headerSource());
+}
+
+void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyResponseHeaders& headers)
+{
+    if (!headers.contentSecurityPolicy().isEmpty())
+        didReceiveHeader(headers.contentSecurityPolicy(), ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceHTTP);
+    if (!headers.contentSecurityPolicyReportOnly().isEmpty())
+        didReceiveHeader(headers.contentSecurityPolicyReportOnly(), ContentSecurityPolicyHeaderTypeReport, ContentSecurityPolicyHeaderSourceHTTP);
+}
+
+void ContentSecurityPolicy::didReceiveHeader(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+{
+    addPolicyFromHeaderValue(header, type, source);
+}
+
+void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
+{
+    Document* document = this->document();
+    if (document) {
+        UseCounter::count(*document, getUseCounterType(type));
+
+        // CSP 1.1 defines report-only in a <meta> element as invalid. Measure for now, disable in experimental mode.
+        if (source == ContentSecurityPolicyHeaderSourceMeta && type == ContentSecurityPolicyHeaderTypeReport) {
+            UseCounter::count(*document, UseCounter::ContentSecurityPolicyReportOnlyInMeta);
+            if (experimentalFeaturesEnabled()) {
+                reportReportOnlyInMeta(header);
+                return;
+            }
+        }
+    }
+
+
+    Vector<UChar> characters;
+    header.appendTo(characters);
+
+    const UChar* begin = characters.data();
+    const UChar* end = begin + characters.size();
+
+    // RFC2616, section 4.2 specifies that headers appearing multiple times can
+    // be combined with a comma. Walk the header string, and parse each comma
+    // separated chunk as a separate header.
+    const UChar* position = begin;
+    while (position < end) {
+        skipUntil<UChar>(position, end, ',');
+
+        // header1,header2 OR header1
+        //        ^                  ^
+        OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type, source);
+
+        // We disable 'eval()' even in the case of report-only policies, and rely on the check in the V8Initializer::codeGenerationCheckCallbackInMainThread callback to determine whether the call should execute or not.
+        if (!policy->allowEval(0, SuppressReport))
+            m_client->disableEval(policy->evalDisabledErrorMessage());
+
+        m_policies.append(policy.release());
+
+        // Skip the comma, and begin the next header from the current position.
+        ASSERT(position == end || *position == ',');
+        skipExactly<UChar>(position, end, ',');
+        begin = position;
+    }
+
+    if (document && type != ContentSecurityPolicyHeaderTypeReport && didSetReferrerPolicy())
+        document->setReferrerPolicy(referrerPolicy());
+}
+
+void ContentSecurityPolicy::setOverrideAllowInlineStyle(bool value)
+{
+    m_overrideInlineStyleAllowed = value;
+}
+
+const String& ContentSecurityPolicy::deprecatedHeader() const
+{
+    return m_policies.isEmpty() ? emptyString() : m_policies[0]->header();
+}
+
+ContentSecurityPolicyHeaderType ContentSecurityPolicy::deprecatedHeaderType() const
+{
+    return m_policies.isEmpty() ? ContentSecurityPolicyHeaderTypeEnforce : m_policies[0]->headerType();
+}
+
+template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowed)(reportingStatus))
+            return false;
+    }
+    return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(ScriptState* state, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowed)(state, reportingStatus))
+            return false;
+    }
+    return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowed)(contextURL, contextLine, reportingStatus))
+            return false;
+    }
+    return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const String&) const>
+bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
+{
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowed)(nonce))
+            return false;
+    }
+    return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const>
+bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHashValue& hashValue)
+{
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowed)(hashValue))
+            return false;
+    }
+    return true;
+}
+
+template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowFromURL)(url, reportingStatus))
+            return false;
+    }
+    return true;
+}
+
+template<bool (CSPDirectiveList::*allowed)(LocalFrame*, ContentSecurityPolicy::ReportingStatus) const>
+bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus)
+{
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowed)(frame, reportingStatus))
+            return false;
+    }
+    return true;
+}
+
+void computeDigest(const char* source, size_t length, blink::WebCryptoAlgorithmId algorithmId, DigestValue& digest)
+{
+    blink::WebCrypto* crypto = blink::Platform::current()->crypto();
+    blink::WebArrayBuffer result;
+
+    ASSERT(crypto);
+
+    crypto->digestSynchronous(algorithmId, reinterpret_cast<const unsigned char*>(source), length, result);
+
+    ASSERT(!result.isNull());
+
+    digest.append(reinterpret_cast<uint8_t*>(result.data()), result.byteLength());
+}
+
+template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const>
+bool checkDigest(const String& source, uint8_t hashAlgorithmsUsed, const CSPDirectiveListVector& policies)
+{
+    // Any additions or subtractions from this struct should also modify the
+    // respective entries in the kSupportedPrefixes array in
+    // CSPSourceList::parseHash().
+    static const struct {
+        ContentSecurityPolicyHashAlgorithm cspHashAlgorithm;
+        blink::WebCryptoAlgorithmId webCryptoAlgorithmId;
+    } kAlgorithmMap[] = {
+        { ContentSecurityPolicyHashAlgorithmSha1, blink::WebCryptoAlgorithmIdSha1 },
+        { ContentSecurityPolicyHashAlgorithmSha256, blink::WebCryptoAlgorithmIdSha256 },
+        { ContentSecurityPolicyHashAlgorithmSha384, blink::WebCryptoAlgorithmIdSha384 },
+        { ContentSecurityPolicyHashAlgorithmSha512, blink::WebCryptoAlgorithmIdSha512 }
+    };
+
+    // Only bother normalizing the source/computing digests if there are any checks to be done.
+    if (hashAlgorithmsUsed == ContentSecurityPolicyHashAlgorithmNone)
+        return false;
+
+    StringUTF8Adaptor normalizedSource(source, StringUTF8Adaptor::Normalize, WTF::EntitiesForUnencodables);
+
+    // See comment in CSPSourceList::parseHash about why we are using this sizeof
+    // calculation instead of WTF_ARRAY_LENGTH.
+    for (size_t i = 0; i < (sizeof(kAlgorithmMap) / sizeof(kAlgorithmMap[0])); i++) {
+        DigestValue digest;
+        if (kAlgorithmMap[i].cspHashAlgorithm & hashAlgorithmsUsed) {
+            computeDigest(normalizedSource.data(), normalizedSource.length(), kAlgorithmMap[i].webCryptoAlgorithmId, digest);
+            if (isAllowedByAllWithHash<allowed>(policies, CSPHashValue(kAlgorithmMap[i].cspHashAlgorithm, digest)))
+                return true;
+        }
+    }
+
+    return false;
+}
+
+bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithContext<&CSPDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    if (m_overrideInlineStyleAllowed)
+        return true;
+    return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, state, reportingStatus);
+}
+
+String ContentSecurityPolicy::evalDisabledErrorMessage() const
+{
+    for (size_t i = 0; i < m_policies.size(); ++i) {
+        if (!m_policies[i]->allowEval(0, SuppressReport))
+            return m_policies[i]->evalDisabledErrorMessage();
+    }
+    return String();
+}
+
+bool ContentSecurityPolicy::allowPluginType(const String& type, const String& typeAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    for (size_t i = 0; i < m_policies.size(); ++i) {
+        if (!m_policies[i]->allowPluginType(type, typeAttribute, url, reportingStatus))
+            return false;
+    }
+    return true;
+}
+
+bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowScriptNonce(const String& nonce) const
+{
+    return isAllowedByAllWithNonce<&CSPDirectiveList::allowScriptNonce>(m_policies, nonce);
+}
+
+bool ContentSecurityPolicy::allowStyleNonce(const String& nonce) const
+{
+    return isAllowedByAllWithNonce<&CSPDirectiveList::allowStyleNonce>(m_policies, nonce);
+}
+
+bool ContentSecurityPolicy::allowScriptHash(const String& source) const
+{
+    return checkDigest<&CSPDirectiveList::allowScriptHash>(source, m_scriptHashAlgorithmsUsed, m_policies);
+}
+
+bool ContentSecurityPolicy::allowStyleHash(const String& source) const
+{
+    return checkDigest<&CSPDirectiveList::allowStyleHash>(source, m_styleHashAlgorithmsUsed, m_policies);
+}
+
+void ContentSecurityPolicy::usesScriptHashAlgorithms(uint8_t algorithms)
+{
+    m_scriptHashAlgorithmsUsed |= algorithms;
+}
+
+void ContentSecurityPolicy::usesStyleHashAlgorithms(uint8_t algorithms)
+{
+    m_styleHashAlgorithmsUsed |= algorithms;
+}
+
+bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowImageFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowFontFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowMediaFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowConnectToSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowFormAction(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowFormAction>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowBaseURI(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowBaseURI>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowAncestors(LocalFrame* frame, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithFrame<&CSPDirectiveList::allowAncestors>(m_policies, frame, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowChildContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::allowWorkerContextFromSource(const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) const
+{
+    // CSP 1.1 moves workers from 'script-src' to the new 'child-src'. Measure the impact of this backwards-incompatible change.
+    if (m_client->isDocument()) {
+        Document* document = static_cast<Document*>(m_client);
+        UseCounter::count(*document, UseCounter::WorkerSubjectToCSP);
+        if (isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, SuppressReport) && !isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, SuppressReport))
+            UseCounter::count(*document, UseCounter::WorkerAllowedByChildBlockedByScript);
+    }
+
+    return experimentalFeaturesEnabled() ?
+        isAllowedByAllWithURL<&CSPDirectiveList::allowChildContextFromSource>(m_policies, url, reportingStatus) :
+        isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url, reportingStatus);
+}
+
+bool ContentSecurityPolicy::isActive() const
+{
+    return !m_policies.isEmpty();
+}
+
+ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const
+{
+    ReflectedXSSDisposition disposition = ReflectedXSSUnset;
+    for (size_t i = 0; i < m_policies.size(); ++i) {
+        if (m_policies[i]->reflectedXSSDisposition() > disposition)
+            disposition = std::max(disposition, m_policies[i]->reflectedXSSDisposition());
+    }
+    return disposition;
+}
+
+ReferrerPolicy ContentSecurityPolicy::referrerPolicy() const
+{
+    ReferrerPolicy policy = ReferrerPolicyDefault;
+    bool first = true;
+    for (size_t i = 0; i < m_policies.size(); ++i) {
+        if (m_policies[i]->didSetReferrerPolicy()) {
+            if (first)
+                policy = m_policies[i]->referrerPolicy();
+            else
+                policy = mergeReferrerPolicies(policy, m_policies[i]->referrerPolicy());
+        }
+    }
+    return policy;
+}
+
+bool ContentSecurityPolicy::didSetReferrerPolicy() const
+{
+    for (size_t i = 0; i < m_policies.size(); ++i) {
+        if (m_policies[i]->didSetReferrerPolicy())
+            return true;
+    }
+    return false;
+}
+
+SecurityOrigin* ContentSecurityPolicy::securityOrigin() const
+{
+    return m_client->securityContext().securityOrigin();
+}
+
+const KURL ContentSecurityPolicy::url() const
+{
+    return m_client->contextURL();
+}
+
+KURL ContentSecurityPolicy::completeURL(const String& url) const
+{
+    return m_client->contextCompleteURL(url);
+}
+
+void ContentSecurityPolicy::enforceSandboxFlags(SandboxFlags mask) const
+{
+    if (Document* document = this->document())
+        document->enforceSandboxFlags(mask);
+}
+
+static String stripURLForUseInReport(Document* document, const KURL& url)
+{
+    if (!url.isValid())
+        return String();
+    if (!url.isHierarchical() || url.protocolIs("file"))
+        return url.protocol();
+    return document->securityOrigin()->canRequest(url) ? url.strippedForUseAsReferrer() : SecurityOrigin::create(url)->toString();
+}
+
+static void gatherSecurityPolicyViolationEventData(SecurityPolicyViolationEventInit& init, Document* document, const String& directiveText, const String& effectiveDirective, const KURL& blockedURL, const String& header)
+{
+    init.documentURI = document->url().string();
+    init.referrer = document->referrer();
+    init.blockedURI = stripURLForUseInReport(document, blockedURL);
+    init.violatedDirective = directiveText;
+    init.effectiveDirective = effectiveDirective;
+    init.originalPolicy = header;
+    init.sourceFile = String();
+    init.lineNumber = 0;
+    init.columnNumber = 0;
+    init.statusCode = 0;
+
+    if (!SecurityOrigin::isSecure(document->url()) && document->loader())
+        init.statusCode = document->loader()->response().httpStatusCode();
+
+    RefPtr<ScriptCallStack> stack = createScriptCallStack(1, false);
+    if (!stack)
+        return;
+
+    const ScriptCallFrame& callFrame = stack->at(0);
+
+    if (callFrame.lineNumber()) {
+        KURL source = KURL(ParsedURLString, callFrame.sourceURL());
+        init.sourceFile = stripURLForUseInReport(document, source);
+        init.lineNumber = callFrame.lineNumber();
+        init.columnNumber = callFrame.columnNumber();
+    }
+}
+
+void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& effectiveDirective, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header)
+{
+    // FIXME: Support sending reports from worker.
+    if (!m_client->isDocument())
+        return;
+
+    Document* document = this->document();
+    LocalFrame* frame = document->frame();
+    if (!frame)
+        return;
+
+    SecurityPolicyViolationEventInit violationData;
+    gatherSecurityPolicyViolationEventData(violationData, document, directiveText, effectiveDirective, blockedURL, header);
+
+    if (experimentalFeaturesEnabled())
+        frame->domWindow()->enqueueDocumentEvent(SecurityPolicyViolationEvent::create(EventTypeNames::securitypolicyviolation, violationData));
+
+    if (reportURIs.isEmpty())
+        return;
+
+    // We need to be careful here when deciding what information to send to the
+    // report-uri. Currently, we send only the current document's URL and the
+    // directive that was violated. The document's URL is safe to send because
+    // it's the document itself that's requesting that it be sent. You could
+    // make an argument that we shouldn't send HTTPS document URLs to HTTP
+    // report-uris (for the same reasons that we supress the Referer in that
+    // case), but the Referer is sent implicitly whereas this request is only
+    // sent explicitly. As for which directive was violated, that's pretty
+    // harmless information.
+
+    RefPtr<JSONObject> cspReport = JSONObject::create();
+    cspReport->setString("document-uri", violationData.documentURI);
+    cspReport->setString("referrer", violationData.referrer);
+    cspReport->setString("violated-directive", violationData.violatedDirective);
+    if (experimentalFeaturesEnabled())
+        cspReport->setString("effective-directive", violationData.effectiveDirective);
+    cspReport->setString("original-policy", violationData.originalPolicy);
+    cspReport->setString("blocked-uri", violationData.blockedURI);
+    if (!violationData.sourceFile.isEmpty() && violationData.lineNumber) {
+        cspReport->setString("source-file", violationData.sourceFile);
+        cspReport->setNumber("line-number", violationData.lineNumber);
+        cspReport->setNumber("column-number", violationData.columnNumber);
+    }
+    cspReport->setNumber("status-code", violationData.statusCode);
+
+    RefPtr<JSONObject> reportObject = JSONObject::create();
+    reportObject->setObject("csp-report", cspReport.release());
+    String stringifiedReport = reportObject->toJSONString();
+
+    if (!shouldSendViolationReport(stringifiedReport))
+        return;
+
+    RefPtr<FormData> report = FormData::create(stringifiedReport.utf8());
+
+    for (size_t i = 0; i < reportURIs.size(); ++i)
+        PingLoader::sendViolationReport(frame, reportURIs[i], report, PingLoader::ContentSecurityPolicyViolationReport);
+
+    didSendViolationReport(stringifiedReport);
+}
+
+void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) const
+{
+    logToConsole("The 'referrer' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"always\", \"default\", \"never\", and \"origin\".");
+}
+
+void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) const
+{
+    logToConsole("The report-only Content Security Policy '" + header + "' was delivered via a <meta> element, which is disallowed. The policy has been ignored.");
+}
+
+void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) const
+{
+    logToConsole("The Content Security Policy '" + header + "' was delivered via a <meta> element outside the document's <head>, which is disallowed. The policy has been ignored.");
+}
+
+void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) const
+{
+    logToConsole("The Content Security Policy directive '" + name + "' is ignored when delivered in a report-only policy.");
+}
+
+void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const
+{
+    DEFINE_STATIC_LOCAL(String, allow, ("allow"));
+    DEFINE_STATIC_LOCAL(String, options, ("options"));
+    DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri"));
+    DEFINE_STATIC_LOCAL(String, allowMessage, ("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect."));
+    DEFINE_STATIC_LOCAL(String, optionsMessage, ("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect."));
+    DEFINE_STATIC_LOCAL(String, policyURIMessage, ("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header."));
+
+    String message = "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
+    if (equalIgnoringCase(name, allow))
+        message = allowMessage;
+    else if (equalIgnoringCase(name, options))
+        message = optionsMessage;
+    else if (equalIgnoringCase(name, policyURI))
+        message = policyURIMessage;
+
+    logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const
+{
+    String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?";
+    logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const
+{
+    String message = "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
+    logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) const
+{
+    String message;
+    if (pluginType.isNull())
+        message = "'plugin-types' Content Security Policy directive is empty; all plugins will be blocked.\n";
+    else
+        message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n";
+    logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags) const
+{
+    logToConsole("Error while parsing the 'sandbox' Content Security Policy directive: " + invalidFlags);
+}
+
+void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue) const
+{
+    logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\".");
+}
+
+void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& directiveName, const String& value) const
+{
+    String message = "The value for Content Security Policy directive '" + directiveName + "' contains an invalid character: '" + value + "'. Non-whitespace characters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 3986, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.";
+    logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveName, const String& value, const char invalidChar) const
+{
+    ASSERT(invalidChar == '#' || invalidChar == '?');
+
+    String ignoring = "The fragment identifier, including the '#', will be ignored.";
+    if (invalidChar == '?')
+        ignoring = "The query component, including the '?', will be ignored.";
+    String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring;
+    logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const
+{
+    String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ignored.";
+    if (equalIgnoringCase(source, "'none'"))
+        message = message + " Note that 'none' has no effect unless it is the only expression in the source list.";
+    logToConsole(message);
+}
+
+void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const
+{
+    logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no effect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.");
+}
+
+void ContentSecurityPolicy::logToConsole(const String& message) const
+{
+    m_client->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, message);
+}
+
+void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String& directiveText) const
+{
+    m_client->reportBlockedScriptExecutionToInspector(directiveText);
+}
+
+bool ContentSecurityPolicy::experimentalFeaturesEnabled() const
+{
+    return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnabled();
+}
+
+bool ContentSecurityPolicy::shouldBypassMainWorld(ExecutionContext* context)
+{
+    if (context && context->isDocument()) {
+        Document* document = toDocument(context);
+        if (document->frame())
+            return document->frame()->script().shouldBypassMainWorldContentSecurityPolicy();
+    }
+    return false;
+}
+
+bool ContentSecurityPolicy::shouldSendViolationReport(const String& report) const
+{
+    // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
+    return !m_violationReportsSent.contains(report.impl()->hash());
+}
+
+void ContentSecurityPolicy::didSendViolationReport(const String& report)
+{
+    m_violationReportsSent.add(report.impl()->hash());
+}
+
+} // namespace WebCore
diff --git a/Source/core/frame/ContentSecurityPolicy.h b/Source/core/frame/csp/ContentSecurityPolicy.h
similarity index 81%
rename from Source/core/frame/ContentSecurityPolicy.h
rename to Source/core/frame/csp/ContentSecurityPolicy.h
index 6cf0205..5aee0ea 100644
--- a/Source/core/frame/ContentSecurityPolicy.h
+++ b/Source/core/frame/csp/ContentSecurityPolicy.h
@@ -28,10 +28,13 @@
 
 #include "bindings/v8/ScriptState.h"
 #include "core/dom/Document.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
 #include "platform/network/HTTPParsers.h"
 #include "platform/weborigin/ReferrerPolicy.h"
 #include "wtf/HashSet.h"
 #include "wtf/PassOwnPtr.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
 #include "wtf/Vector.h"
 #include "wtf/text/StringHash.h"
 #include "wtf/text/TextPosition.h"
@@ -54,52 +57,57 @@
 typedef int SandboxFlags;
 typedef Vector<OwnPtr<CSPDirectiveList> > CSPDirectiveListVector;
 
-class ContentSecurityPolicy {
+class ContentSecurityPolicy : public RefCounted<ContentSecurityPolicy> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<ContentSecurityPolicy> create(ExecutionContextClient* client)
+    // CSP 1.0 Directives
+    static const char ConnectSrc[];
+    static const char DefaultSrc[];
+    static const char FontSrc[];
+    static const char FrameSrc[];
+    static const char ImgSrc[];
+    static const char MediaSrc[];
+    static const char ObjectSrc[];
+    static const char ReportURI[];
+    static const char Sandbox[];
+    static const char ScriptSrc[];
+    static const char StyleSrc[];
+
+    // CSP 1.1 Directives
+    static const char BaseURI[];
+    static const char ChildSrc[];
+    static const char FormAction[];
+    static const char FrameAncestors[];
+    static const char PluginTypes[];
+    static const char ReflectedXSS[];
+    static const char Referrer[];
+
+    static PassRefPtr<ContentSecurityPolicy> create(ExecutionContextClient* client)
     {
-        return adoptPtr(new ContentSecurityPolicy(client));
+        return adoptRef(new ContentSecurityPolicy(client));
     }
     ~ContentSecurityPolicy();
 
     void copyStateFrom(const ContentSecurityPolicy*);
 
-    enum HeaderType {
-        Report,
-        Enforce,
-    };
-
-    enum HeaderSource {
-        HeaderSourceHTTP,
-        HeaderSourceMeta
-    };
-
     enum ReportingStatus {
         SendReport,
         SuppressReport
     };
 
-    enum HashAlgorithms {
-        HashAlgorithmsNone   = 0,
-        HashAlgorithmsSha1   = 1 << 1,
-        HashAlgorithmsSha256 = 1 << 2
-    };
-
     void didReceiveHeaders(const ContentSecurityPolicyResponseHeaders&);
-    void didReceiveHeader(const String&, HeaderType, HeaderSource);
+    void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
 
     // These functions are wrong because they assume that there is only one header.
     // FIXME: Replace them with functions that return vectors.
     const String& deprecatedHeader() const;
-    HeaderType deprecatedHeaderType() const;
+    ContentSecurityPolicyHeaderType deprecatedHeaderType() const;
 
     bool allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
     bool allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
     bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
     bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const;
-    bool allowScriptEval(ScriptState* = 0, ReportingStatus = SendReport) const;
-    bool allowStyleEval(ScriptState* = 0, ReportingStatus = SendReport) const;
+    bool allowEval(ScriptState* = 0, ReportingStatus = SendReport) const;
     bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ReportingStatus = SendReport) const;
 
     bool allowScriptFromSource(const KURL&, ReportingStatus = SendReport) const;
@@ -112,7 +120,7 @@
     bool allowConnectToSource(const KURL&, ReportingStatus = SendReport) const;
     bool allowFormAction(const KURL&, ReportingStatus = SendReport) const;
     bool allowBaseURI(const KURL&, ReportingStatus = SendReport) const;
-    bool allowAncestors(Frame*, ReportingStatus = SendReport) const;
+    bool allowAncestors(LocalFrame*, ReportingStatus = SendReport) const;
     bool allowChildContextFromSource(const KURL&, ReportingStatus = SendReport) const;
     bool allowWorkerContextFromSource(const KURL&, ReportingStatus = SendReport) const;
 
@@ -123,8 +131,8 @@
     bool allowScriptHash(const String& source) const;
     bool allowStyleHash(const String& source) const;
 
-    void usesScriptHashAlgorithms(uint8_t HashAlgorithms);
-    void usesStyleHashAlgorithms(uint8_t HashAlgorithms);
+    void usesScriptHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm);
+    void usesStyleHashAlgorithms(uint8_t ContentSecurityPolicyHashAlgorithm);
 
     ReflectedXSSDisposition reflectedXSSDisposition() const;
 
@@ -158,12 +166,13 @@
     SecurityOrigin* securityOrigin() const;
     void enforceSandboxFlags(SandboxFlags) const;
     String evalDisabledErrorMessage() const;
-    String styleEvalDisabledErrorMessage() const;
 
     bool experimentalFeaturesEnabled() const;
 
     static bool shouldBypassMainWorld(ExecutionContext*);
 
+    static bool isDirectiveName(const String&);
+
     ExecutionContextClient* client() const { return m_client; }
     Document* document() const { return client()->isDocument() ? toDocument(client()) : 0; }
 
@@ -171,7 +180,7 @@
     explicit ContentSecurityPolicy(ExecutionContextClient*);
 
     void logToConsole(const String& message) const;
-    void addPolicyFromHeaderValue(const String&, HeaderType, HeaderSource);
+    void addPolicyFromHeaderValue(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicyHeaderSource);
 
     bool shouldSendViolationReport(const String&) const;
     void didSendViolationReport(const String&);
diff --git a/Source/core/frame/csp/MediaListDirective.cpp b/Source/core/frame/csp/MediaListDirective.cpp
new file mode 100644
index 0000000..434c779
--- /dev/null
+++ b/Source/core/frame/csp/MediaListDirective.cpp
@@ -0,0 +1,86 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/MediaListDirective.h"
+
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/ParsingUtilities.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+MediaListDirective::MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+    : CSPDirective(name, value, policy)
+{
+    Vector<UChar> characters;
+    value.appendTo(characters);
+    parse(characters.data(), characters.data() + characters.size());
+}
+
+bool MediaListDirective::allows(const String& type)
+{
+    return m_pluginTypes.contains(type);
+}
+
+void MediaListDirective::parse(const UChar* begin, const UChar* end)
+{
+    const UChar* position = begin;
+
+    // 'plugin-types ____;' OR 'plugin-types;'
+    if (position == end) {
+        policy()->reportInvalidPluginTypes(String());
+        return;
+    }
+
+    while (position < end) {
+        // _____ OR _____mime1/mime1
+        // ^        ^
+        skipWhile<UChar, isASCIISpace>(position, end);
+        if (position == end)
+            return;
+
+        // mime1/mime1 mime2/mime2
+        // ^
+        begin = position;
+        if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
+            skipWhile<UChar, isNotASCIISpace>(position, end);
+            policy()->reportInvalidPluginTypes(String(begin, position - begin));
+            continue;
+        }
+        skipWhile<UChar, isMediaTypeCharacter>(position, end);
+
+        // mime1/mime1 mime2/mime2
+        //      ^
+        if (!skipExactly<UChar>(position, end, '/')) {
+            skipWhile<UChar, isNotASCIISpace>(position, end);
+            policy()->reportInvalidPluginTypes(String(begin, position - begin));
+            continue;
+        }
+
+        // mime1/mime1 mime2/mime2
+        //       ^
+        if (!skipExactly<UChar, isMediaTypeCharacter>(position, end)) {
+            skipWhile<UChar, isNotASCIISpace>(position, end);
+            policy()->reportInvalidPluginTypes(String(begin, position - begin));
+            continue;
+        }
+        skipWhile<UChar, isMediaTypeCharacter>(position, end);
+
+        // mime1/mime1 mime2/mime2 OR mime1/mime1  OR mime1/mime1/error
+        //            ^                          ^               ^
+        if (position < end && isNotASCIISpace(*position)) {
+            skipWhile<UChar, isNotASCIISpace>(position, end);
+            policy()->reportInvalidPluginTypes(String(begin, position - begin));
+            continue;
+        }
+        m_pluginTypes.add(String(begin, position - begin));
+
+        ASSERT(position == end || isASCIISpace(*position));
+    }
+}
+
+} // namespace WebCore
diff --git a/Source/core/frame/csp/MediaListDirective.h b/Source/core/frame/csp/MediaListDirective.h
new file mode 100644
index 0000000..9f230ce
--- /dev/null
+++ b/Source/core/frame/csp/MediaListDirective.h
@@ -0,0 +1,31 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef MediaListDirective_h
+#define MediaListDirective_h
+
+#include "core/frame/csp/CSPDirective.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+
+class MediaListDirective FINAL : public CSPDirective {
+    WTF_MAKE_NONCOPYABLE(MediaListDirective);
+public:
+    MediaListDirective(const String& name, const String& value, ContentSecurityPolicy*);
+    bool allows(const String& type);
+
+private:
+    void parse(const UChar* begin, const UChar* end);
+
+    HashSet<String> m_pluginTypes;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/frame/csp/SourceListDirective.cpp b/Source/core/frame/csp/SourceListDirective.cpp
new file mode 100644
index 0000000..ccf8c37
--- /dev/null
+++ b/Source/core/frame/csp/SourceListDirective.cpp
@@ -0,0 +1,62 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/frame/csp/SourceListDirective.h"
+
+#include "core/frame/csp/CSPSourceList.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "platform/weborigin/KURL.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+SourceListDirective::SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
+    : CSPDirective(name, value, policy)
+    , m_sourceList(policy, name)
+{
+    Vector<UChar> characters;
+    value.appendTo(characters);
+
+    m_sourceList.parse(characters.data(), characters.data() + characters.size());
+}
+
+bool SourceListDirective::allows(const KURL& url) const
+{
+    return m_sourceList.matches(url.isEmpty() ? policy()->url() : url);
+}
+
+bool SourceListDirective::allowInline() const
+{
+    return m_sourceList.allowInline();
+}
+
+bool SourceListDirective::allowEval() const
+{
+    return m_sourceList.allowEval();
+}
+
+bool SourceListDirective::allowNonce(const String& nonce) const
+{
+    return m_sourceList.allowNonce(nonce.stripWhiteSpace());
+}
+
+bool SourceListDirective::allowHash(const CSPHashValue& hashValue) const
+{
+    return m_sourceList.allowHash(hashValue);
+}
+
+bool SourceListDirective::isHashOrNoncePresent() const
+{
+    return m_sourceList.isHashOrNoncePresent();
+}
+
+uint8_t SourceListDirective::hashAlgorithmsUsed() const
+{
+    return m_sourceList.hashAlgorithmsUsed();
+}
+
+} // namespace WebCore
+
diff --git a/Source/core/frame/csp/SourceListDirective.h b/Source/core/frame/csp/SourceListDirective.h
new file mode 100644
index 0000000..38005d1
--- /dev/null
+++ b/Source/core/frame/csp/SourceListDirective.h
@@ -0,0 +1,38 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SourceListDirective_h
+#define SourceListDirective_h
+
+#include "core/frame/csp/CSPDirective.h"
+#include "core/frame/csp/CSPSourceList.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
+#include "wtf/HashSet.h"
+#include "wtf/text/WTFString.h"
+
+namespace WebCore {
+
+class ContentSecurityPolicy;
+class KURL;
+
+class SourceListDirective FINAL : public CSPDirective {
+    WTF_MAKE_NONCOPYABLE(SourceListDirective);
+public:
+    SourceListDirective(const String& name, const String& value, ContentSecurityPolicy*);
+
+    bool allows(const KURL&) const;
+    bool allowInline() const;
+    bool allowEval() const;
+    bool allowNonce(const String& nonce) const;
+    bool allowHash(const CSPHashValue&) const;
+    bool isHashOrNoncePresent() const;
+    uint8_t hashAlgorithmsUsed() const;
+
+private:
+    CSPSourceList m_sourceList;
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/html/DOMFormData.h b/Source/core/html/DOMFormData.h
index c522b72..0d2dce3 100644
--- a/Source/core/html/DOMFormData.h
+++ b/Source/core/html/DOMFormData.h
@@ -32,6 +32,7 @@
 #define DOMFormData_h
 
 #include "core/html/FormDataList.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -45,10 +46,17 @@
 class Blob;
 class HTMLFormElement;
 
-class DOMFormData : public FormDataList, public ScriptWrappable, public RefCounted<DOMFormData> {
+class DOMFormData : public RefCountedWillBeGarbageCollectedFinalized<DOMFormData>, public FormDataList, public ScriptWrappable {
 public:
-    static PassRefPtr<DOMFormData> create(HTMLFormElement* form) { return adoptRef(new DOMFormData(form)); }
-    static PassRefPtr<DOMFormData> create(const WTF::TextEncoding& encoding) { return adoptRef(new DOMFormData(encoding)); }
+    static PassRefPtrWillBeRawPtr<DOMFormData> create(HTMLFormElement* form)
+    {
+        return adoptRefWillBeNoop(new DOMFormData(form));
+    }
+
+    static PassRefPtrWillBeRawPtr<DOMFormData> create(const WTF::TextEncoding& encoding)
+    {
+        return adoptRefWillBeNoop(new DOMFormData(encoding));
+    }
 
     void append(const String& name, const String& value);
     void append(const String& name, Blob*, const String& filename = String());
diff --git a/Source/core/html/FormAssociatedElement.cpp b/Source/core/html/FormAssociatedElement.cpp
index c9e911c..c8d69c3 100644
--- a/Source/core/html/FormAssociatedElement.cpp
+++ b/Source/core/html/FormAssociatedElement.cpp
@@ -108,11 +108,8 @@
         // value is a form element, then associate the form-associated element
         // with that form element.
         // 3.2. Abort the "reset the form owner" steps.
-        HTMLFormElement* newForm = 0;
         Element* newFormCandidate = element->treeScope().getElementById(formId);
-        if (newFormCandidate && newFormCandidate->hasTagName(formTag))
-            newForm = toHTMLFormElement(newFormCandidate);
-        return newForm;
+        return isHTMLFormElement(newFormCandidate) ? toHTMLFormElement(newFormCandidate) : 0;
     }
     // 4. Otherwise, if the form-associated element in question has an ancestor
     // form element, then associate the form-associated element with the nearest
@@ -120,7 +117,7 @@
     return element->findFormAncestor();
 }
 
-void FormAssociatedElement::formRemovedFromTree(const Node* formRoot)
+void FormAssociatedElement::formRemovedFromTree(const Node& formRoot)
 {
     ASSERT(m_form);
     if (toHTMLElement(this)->highestAncestor() == formRoot)
diff --git a/Source/core/html/FormAssociatedElement.h b/Source/core/html/FormAssociatedElement.h
index 70101f5..f0f1851 100644
--- a/Source/core/html/FormAssociatedElement.h
+++ b/Source/core/html/FormAssociatedElement.h
@@ -66,7 +66,7 @@
 
     void resetFormOwner();
 
-    void formRemovedFromTree(const Node* formRoot);
+    void formRemovedFromTree(const Node& formRoot);
 
     // ValidityState attribute implementations
     bool customError() const;
diff --git a/Source/core/html/FormData.idl b/Source/core/html/FormData.idl
index 73dcbfb..560abfc 100644
--- a/Source/core/html/FormData.idl
+++ b/Source/core/html/FormData.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     Constructor([Default=Undefined] optional HTMLFormElement form),
     ImplementedAs=DOMFormData
 ] interface FormData {
diff --git a/Source/core/html/FormDataList.cpp b/Source/core/html/FormDataList.cpp
index b564d2c..61127d3 100644
--- a/Source/core/html/FormDataList.cpp
+++ b/Source/core/html/FormDataList.cpp
@@ -43,7 +43,7 @@
     m_items.append(string);
 }
 
-void FormDataList::appendBlob(PassRefPtr<Blob> blob, const String& filename)
+void FormDataList::appendBlob(PassRefPtrWillBeRawPtr<Blob> blob, const String& filename)
 {
     m_items.append(Item(blob, filename));
 }
@@ -69,7 +69,7 @@
 
     Vector<char> encodedData;
 
-    const Vector<FormDataList::Item>& items = this->items();
+    const WillBeHeapVector<Item>& items = this->items();
     size_t formDataListSize = items.size();
     ASSERT(!(formDataListSize % 2));
     for (size_t i = 0; i < formDataListSize; i += 2) {
@@ -130,12 +130,7 @@
             }
             formData->appendData("\r\n", 2);
         } else {
-            // Omit the name "isindex" if it's the first form data element.
-            // FIXME: Why is this a good rule? Is this obsolete now?
-            if (encodedData.isEmpty() && key.data() == "isindex")
-                FormDataBuilder::encodeStringAsFormData(encodedData, value.data());
-            else
-                FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
+            FormDataBuilder::addKeyValuePairAsFormData(encodedData, key.data(), value.data(), encodingType);
         }
     }
 
@@ -145,4 +140,14 @@
     formData->appendData(encodedData.data(), encodedData.size());
 }
 
+void FormDataList::trace(Visitor* visitor)
+{
+    visitor->trace(m_items);
+}
+
+void FormDataList::Item::trace(Visitor* visitor)
+{
+    visitor->trace(m_blob);
+}
+
 } // namespace
diff --git a/Source/core/html/FormDataList.h b/Source/core/html/FormDataList.h
index 123e566..2204689 100644
--- a/Source/core/html/FormDataList.h
+++ b/Source/core/html/FormDataList.h
@@ -22,6 +22,7 @@
 #define FormDataList_h
 
 #include "core/fileapi/Blob.h"
+#include "heap/Handle.h"
 #include "platform/network/FormData.h"
 #include "wtf/Forward.h"
 #include "wtf/text/CString.h"
@@ -32,18 +33,21 @@
 class FormDataList {
 public:
     class Item {
+        ALLOW_ONLY_INLINE_ALLOCATION();
     public:
         Item() { }
         Item(const WTF::CString& data) : m_data(data) { }
-        Item(PassRefPtr<Blob> blob, const String& filename) : m_blob(blob), m_filename(filename) { }
+        Item(PassRefPtrWillBeRawPtr<Blob> blob, const String& filename) : m_blob(blob), m_filename(filename) { }
 
         const WTF::CString& data() const { return m_data; }
         Blob* blob() const { return m_blob.get(); }
         const String& filename() const { return m_filename; }
 
+        void trace(Visitor*);
+
     private:
         WTF::CString m_data;
-        RefPtr<Blob> m_blob;
+        RefPtrWillBeMember<Blob> m_blob;
         String m_filename;
     };
 
@@ -64,29 +68,39 @@
         appendString(key);
         appendString(String::number(value));
     }
-    void appendBlob(const String& key, PassRefPtr<Blob> blob, const String& filename = String())
+    void appendBlob(const String& key, PassRefPtrWillBeRawPtr<Blob> blob, const String& filename = String())
     {
         appendString(key);
         appendBlob(blob, filename);
     }
 
-    const Vector<Item>& items() const { return m_items; }
+    const WillBeHeapVector<Item>& items() const { return m_items; }
     const WTF::TextEncoding& encoding() const { return m_encoding; }
 
     PassRefPtr<FormData> createFormData(const WTF::TextEncoding&, FormData::EncodingType = FormData::FormURLEncoded);
     PassRefPtr<FormData> createMultiPartFormData(const WTF::TextEncoding&);
 
+    void trace(Visitor*);
+
 private:
     void appendKeyValuePairItemsTo(FormData*, const WTF::TextEncoding&, bool isMultiPartForm, FormData::EncodingType = FormData::FormURLEncoded);
 
     void appendString(const CString&);
     void appendString(const String&);
-    void appendBlob(PassRefPtr<Blob>, const String& filename);
+    void appendBlob(PassRefPtrWillBeRawPtr<Blob>, const String& filename);
 
     WTF::TextEncoding m_encoding;
-    Vector<Item> m_items;
+    WillBeHeapVector<Item> m_items;
 };
 
 } // namespace WebCore
 
+// FIXME: oilpan: remove once traceability can be derived/inferred.
+namespace WTF {
+template<>
+struct NeedsTracing<WebCore::FormDataList::Item> {
+    static const bool value = true;
+};
+}
+
 #endif // FormDataList_h
diff --git a/Source/core/html/HTMLAllCollection.cpp b/Source/core/html/HTMLAllCollection.cpp
index 5e38017..f9bbdf6 100644
--- a/Source/core/html/HTMLAllCollection.cpp
+++ b/Source/core/html/HTMLAllCollection.cpp
@@ -31,12 +31,12 @@
 
 namespace WebCore {
 
-PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(ContainerNode* node, CollectionType type)
+PassRefPtr<HTMLAllCollection> HTMLAllCollection::create(ContainerNode& node, CollectionType type)
 {
     return adoptRef(new HTMLAllCollection(node, type));
 }
 
-HTMLAllCollection::HTMLAllCollection(ContainerNode* node, CollectionType type)
+HTMLAllCollection::HTMLAllCollection(ContainerNode& node, CollectionType type)
     : HTMLCollection(node, type, DoesNotOverrideItemAfter)
 {
     ScriptWrappable::init(this);
diff --git a/Source/core/html/HTMLAllCollection.h b/Source/core/html/HTMLAllCollection.h
index 010a44b..64aec84 100644
--- a/Source/core/html/HTMLAllCollection.h
+++ b/Source/core/html/HTMLAllCollection.h
@@ -32,14 +32,14 @@
 
 class HTMLAllCollection FINAL : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLAllCollection> create(ContainerNode*, CollectionType);
+    static PassRefPtr<HTMLAllCollection> create(ContainerNode&, CollectionType);
     virtual ~HTMLAllCollection();
 
     Element* namedItemWithIndex(const AtomicString& name, unsigned index) const;
     void namedGetter(const AtomicString& name, bool&, RefPtr<NodeList>&, bool&, RefPtr<Element>&);
 
 private:
-    HTMLAllCollection(ContainerNode*, CollectionType);
+    HTMLAllCollection(ContainerNode&, CollectionType);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/HTMLAnchorElement.cpp b/Source/core/html/HTMLAnchorElement.cpp
index 47990fa..33e6a31 100644
--- a/Source/core/html/HTMLAnchorElement.cpp
+++ b/Source/core/html/HTMLAnchorElement.cpp
@@ -29,9 +29,10 @@
 #include "core/events/KeyboardEvent.h"
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
@@ -170,16 +171,16 @@
     ASSERT(event->target());
     Node* target = event->target()->toNode();
     ASSERT(target);
-    if (!target->hasTagName(imgTag))
+    if (!isHTMLImageElement(*target))
         return;
 
-    HTMLImageElement* imageElement = toHTMLImageElement(event->target()->toNode());
-    if (!imageElement || !imageElement->isServerMap())
+    HTMLImageElement& imageElement = toHTMLImageElement(*target);
+    if (!imageElement.isServerMap())
         return;
 
-    if (!imageElement->renderer() || !imageElement->renderer()->isRenderImage())
+    if (!imageElement.renderer() || !imageElement.renderer()->isRenderImage())
         return;
-    RenderImage* renderer = toRenderImage(imageElement->renderer());
+    RenderImage* renderer = toRenderImage(imageElement.renderer());
 
     // FIXME: This should probably pass true for useTransforms.
     FloatPoint absolutePosition = renderer->absoluteToLocal(FloatPoint(toMouseEvent(event)->pageX(), toMouseEvent(event)->pageY()));
@@ -392,10 +393,13 @@
 
 void HTMLAnchorElement::sendPings(const KURL& destinationURL)
 {
-    if (!hasAttribute(pingAttr) || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
+    const AtomicString& pingValue = getAttribute(pingAttr);
+    if (pingValue.isNull() || !document().settings() || !document().settings()->hyperlinkAuditingEnabled())
         return;
 
-    SpaceSplitString pingURLs(getAttribute(pingAttr), false);
+    UseCounter::count(document(), UseCounter::HTMLAnchorElementPingAttribute);
+
+    SpaceSplitString pingURLs(pingValue, false);
     for (unsigned i = 0; i < pingURLs.size(); i++)
         PingLoader::sendPing(document().frame(), document().completeURL(pingURLs[i]), destinationURL);
 }
@@ -404,7 +408,7 @@
 {
     event->setDefaultHandled();
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
@@ -664,7 +668,7 @@
     if (url.hasFragmentIdentifier() && equalIgnoringFragmentIdentifier(document.url(), url))
         return false;
 
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     if (!frame)
         return false;
 
diff --git a/Source/core/html/HTMLAnchorElement.h b/Source/core/html/HTMLAnchorElement.h
index 9907b8e..821fa34 100644
--- a/Source/core/html/HTMLAnchorElement.h
+++ b/Source/core/html/HTMLAnchorElement.h
@@ -140,8 +140,6 @@
 bool isEnterKeyKeydownEvent(Event*);
 bool isLinkClick(Event*);
 
-DEFINE_NODE_TYPE_CASTS(HTMLAnchorElement, hasTagName(HTMLNames::aTag));
-
 } // namespace WebCore
 
 #endif // HTMLAnchorElement_h
diff --git a/Source/core/html/HTMLAppletElement.cpp b/Source/core/html/HTMLAppletElement.cpp
index 242e2ea..7620bea 100644
--- a/Source/core/html/HTMLAppletElement.cpp
+++ b/Source/core/html/HTMLAppletElement.cpp
@@ -29,9 +29,9 @@
 #include "core/html/HTMLParamElement.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/rendering/RenderApplet.h"
 #include "platform/Widget.h"
 #include "platform/weborigin/KURL.h"
@@ -114,14 +114,9 @@
 
     RenderEmbeddedObject* renderer = renderEmbeddedObject();
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     ASSERT(frame);
 
-    LayoutUnit contentWidth = renderer->style()->width().isFixed() ? LayoutUnit(renderer->style()->width().value()) :
-        renderer->width() - renderer->borderAndPaddingWidth();
-    LayoutUnit contentHeight = renderer->style()->height().isFixed() ? LayoutUnit(renderer->style()->height().value()) :
-        renderer->height() - renderer->borderAndPaddingHeight();
-
     Vector<String> paramNames;
     Vector<String> paramValues;
 
@@ -172,11 +167,7 @@
         paramValues.append(mayScript.string());
     }
 
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (!child->hasTagName(paramTag))
-            continue;
-
-        HTMLParamElement* param = toHTMLParamElement(child);
+    for (HTMLParamElement* param = Traversal<HTMLParamElement>::firstChild(*this); param; param = Traversal<HTMLParamElement>::nextSibling(*param)) {
         if (param->name().isEmpty())
             continue;
 
@@ -186,7 +177,7 @@
 
     RefPtr<Widget> widget;
     if (frame->loader().allowPlugins(AboutToInstantiatePlugin))
-        widget = frame->loader().client()->createJavaAppletWidget(roundedIntSize(LayoutSize(contentWidth, contentHeight)), this, baseURL, paramNames, paramValues);
+        widget = frame->loader().client()->createJavaAppletWidget(this, baseURL, paramNames, paramValues);
 
     if (!widget) {
         if (!renderer->showsUnavailablePluginIndicator())
diff --git a/Source/core/html/HTMLAreaElement.cpp b/Source/core/html/HTMLAreaElement.cpp
index 4c1ce23..350ff0e 100644
--- a/Source/core/html/HTMLAreaElement.cpp
+++ b/Source/core/html/HTMLAreaElement.cpp
@@ -146,30 +146,30 @@
         case Poly:
             if (m_coords.size() >= 6) {
                 int numPoints = m_coords.size() / 2;
-                path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width), minimumValueForLength(m_coords[1], height)));
+                path.moveTo(FloatPoint(minimumValueForLength(m_coords[0], width).toFloat(), minimumValueForLength(m_coords[1], height).toFloat()));
                 for (int i = 1; i < numPoints; ++i)
-                    path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width), minimumValueForLength(m_coords[i * 2 + 1], height)));
+                    path.addLineTo(FloatPoint(minimumValueForLength(m_coords[i * 2], width).toFloat(), minimumValueForLength(m_coords[i * 2 + 1], height).toFloat()));
                 path.closeSubpath();
             }
             break;
         case Circle:
             if (m_coords.size() >= 3) {
                 Length radius = m_coords[2];
-                int r = min(minimumValueForLength(radius, width), minimumValueForLength(radius, height));
-                path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width) - r, minimumValueForLength(m_coords[1], height) - r, 2 * r, 2 * r));
+                float r = min(minimumValueForLength(radius, width).toFloat(), minimumValueForLength(radius, height).toFloat());
+                path.addEllipse(FloatRect(minimumValueForLength(m_coords[0], width).toFloat() - r, minimumValueForLength(m_coords[1], height).toFloat() - r, 2 * r, 2 * r));
             }
             break;
         case Rect:
             if (m_coords.size() >= 4) {
-                int x0 = minimumValueForLength(m_coords[0], width);
-                int y0 = minimumValueForLength(m_coords[1], height);
-                int x1 = minimumValueForLength(m_coords[2], width);
-                int y1 = minimumValueForLength(m_coords[3], height);
+                float x0 = minimumValueForLength(m_coords[0], width).toFloat();
+                float y0 = minimumValueForLength(m_coords[1], height).toFloat();
+                float x1 = minimumValueForLength(m_coords[2], width).toFloat();
+                float y1 = minimumValueForLength(m_coords[3], height).toFloat();
                 path.addRect(FloatRect(x0, y0, x1 - x0, y1 - y0));
             }
             break;
         case Default:
-            path.addRect(FloatRect(0, 0, width, height));
+            path.addRect(FloatRect(0, 0, width.toFloat(), height.toFloat()));
             break;
         case Unknown:
             break;
@@ -181,13 +181,13 @@
 HTMLImageElement* HTMLAreaElement::imageElement() const
 {
     Element* mapElement = parentElement();
-    while (mapElement && !mapElement->hasTagName(mapTag))
+    while (mapElement && !isHTMLMapElement(*mapElement))
         mapElement = mapElement->parentElement();
 
     if (!mapElement)
         return 0;
 
-    return toHTMLMapElement(mapElement)->imageElement();
+    return toHTMLMapElement(*mapElement).imageElement();
 }
 
 bool HTMLAreaElement::isKeyboardFocusable() const
diff --git a/Source/core/html/HTMLAreaElement.h b/Source/core/html/HTMLAreaElement.h
index 0029fb9..f664130 100644
--- a/Source/core/html/HTMLAreaElement.h
+++ b/Source/core/html/HTMLAreaElement.h
@@ -67,8 +67,6 @@
     Shape m_shape;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLAreaElement, hasTagName(HTMLNames::areaTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLBodyElement.cpp b/Source/core/html/HTMLBodyElement.cpp
index a0024d2..10882ea 100644
--- a/Source/core/html/HTMLBodyElement.cpp
+++ b/Source/core/html/HTMLBodyElement.cpp
@@ -32,10 +32,10 @@
 #include "core/css/StylePropertySet.h"
 #include "core/dom/Attribute.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/rendering/RenderBox.h"
 
 namespace WebCore {
@@ -69,7 +69,7 @@
     if (name == backgroundAttr) {
         String url = stripLeadingAndTrailingHTMLSpaces(value);
         if (!url.isEmpty()) {
-            RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(document().completeURL(url));
+            RefPtrWillBeRawPtr<CSSImageValue> imageValue = CSSImageValue::create(url, document().completeURL(url));
             imageValue->setInitiator(localName());
             style->setProperty(CSSProperty(CSSPropertyBackgroundImage, imageValue.release()));
         }
@@ -188,7 +188,7 @@
 
 static int adjustForZoom(int value, Document* document)
 {
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
     float zoomFactor = frame->pageZoomFactor();
     if (zoomFactor == 1)
         return value;
@@ -246,7 +246,7 @@
             return;
     }
 
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     if (!frame)
         return;
     FrameView* view = frame->view();
@@ -292,7 +292,7 @@
             return;
     }
 
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     if (!frame)
         return;
     FrameView* view = frame->view();
diff --git a/Source/core/html/HTMLBodyElement.h b/Source/core/html/HTMLBodyElement.h
index fa247ff..b80c40f 100644
--- a/Source/core/html/HTMLBodyElement.h
+++ b/Source/core/html/HTMLBodyElement.h
@@ -66,8 +66,6 @@
     virtual int scrollWidth() OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLBodyElement, hasTagName(HTMLNames::bodyTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLCanvasElement.cpp b/Source/core/html/HTMLCanvasElement.cpp
index c07e0d3..4ea2212 100644
--- a/Source/core/html/HTMLCanvasElement.cpp
+++ b/Source/core/html/HTMLCanvasElement.cpp
@@ -36,13 +36,13 @@
 #include "bindings/v8/ScriptController.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
 #include "core/html/ImageData.h"
 #include "core/html/canvas/Canvas2DContextAttributes.h"
 #include "core/html/canvas/CanvasRenderingContext2D.h"
 #include "core/html/canvas/WebGLContextAttributes.h"
 #include "core/html/canvas/WebGLRenderingContext.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
 #include "core/rendering/RenderHTMLCanvas.h"
 #include "platform/MIMETypeRegistry.h"
 #include "platform/graphics/Canvas2DImageBufferSurface.h"
@@ -91,7 +91,7 @@
 
 HTMLCanvasElement::~HTMLCanvasElement()
 {
-    setExternallyAllocatedMemory(0);
+    v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(-m_externallyAllocatedMemory);
     HashSet<CanvasObserver*>::iterator end = m_observers.end();
     for (HashSet<CanvasObserver*>::iterator it = m_observers.begin(); it != end; ++it)
         (*it)->canvasDestroyed(this);
@@ -108,7 +108,7 @@
 
 RenderObject* HTMLCanvasElement::createRenderer(RenderStyle* style)
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (frame && frame->script().canExecuteScripts(NotAboutToExecuteScript)) {
         m_rendererIsCanvas = true;
         return new RenderHTMLCanvas(this);
@@ -195,8 +195,10 @@
             if (!m_context) {
                 blink::Platform::current()->histogramEnumeration("Canvas.ContextType", contextType, ContextTypeCount);
                 m_context = WebGLRenderingContext::create(this, static_cast<WebGLContextAttributes*>(attrs));
-                if (m_context)
+                if (m_context) {
                     scheduleLayerUpdate();
+                    updateExternallyAllocatedMemory();
+                }
             }
             return m_context.get();
         }
@@ -340,12 +342,14 @@
     if (!m_presentedImage) {
         // The buffer contains the last presented data, so save a copy of it.
         m_presentedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
+        updateExternallyAllocatedMemory();
     }
 }
 
 void HTMLCanvasElement::clearPresentationCopy()
 {
     m_presentedImage.clear();
+    updateExternallyAllocatedMemory();
 }
 
 void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
@@ -353,7 +357,6 @@
     m_size = size;
     m_didFailToCreateImageBuffer = false;
     discardImageBuffer();
-    setExternallyAllocatedMemory(0);
     clearCopiedImage();
 }
 
@@ -395,7 +398,7 @@
 PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
 {
     if (!m_context || !m_context->is3d())
-       return 0;
+        return nullptr;
     return toWebGLRenderingContext(m_context.get())->paintRenderingResultsToImageData();
 }
 
@@ -471,7 +474,7 @@
 
     m_didFailToCreateImageBuffer = false;
 
-    setExternallyAllocatedMemory(4 * width() * height());
+    updateExternallyAllocatedMemory();
 
     if (is3D()) {
         // Early out for WebGL canvases
@@ -496,8 +499,26 @@
         scheduleLayerUpdate();
 }
 
-void HTMLCanvasElement::setExternallyAllocatedMemory(intptr_t externallyAllocatedMemory)
+void HTMLCanvasElement::updateExternallyAllocatedMemory() const
 {
+    int bufferCount = 0;
+    if (m_imageBuffer)
+        bufferCount++;
+    if (is3D())
+        bufferCount += 2;
+    if (m_copiedImage)
+        bufferCount++;
+    if (m_presentedImage)
+        bufferCount++;
+
+    Checked<intptr_t, RecordOverflow> checkedExternallyAllocatedMemory = 4 * bufferCount;
+    checkedExternallyAllocatedMemory *= width();
+    checkedExternallyAllocatedMemory *= height();
+    intptr_t externallyAllocatedMemory;
+    if (checkedExternallyAllocatedMemory.safeGet(externallyAllocatedMemory) == CheckedState::DidOverflow)
+        externallyAllocatedMemory = std::numeric_limits<intptr_t>::max();
+
+    // Subtracting two intptr_t that are known to be positive will never underflow.
     v8::Isolate::GetCurrent()->AdjustAmountOfExternalAllocatedMemory(externallyAllocatedMemory - m_externallyAllocatedMemory);
     m_externallyAllocatedMemory = externallyAllocatedMemory;
 }
@@ -540,6 +561,7 @@
         if (m_context)
             m_context->paintRenderingResultsToCanvas();
         m_copiedImage = buffer()->copyImage(CopyBackingStore, Unscaled);
+        updateExternallyAllocatedMemory();
     }
     return m_copiedImage.get();
 }
@@ -563,12 +585,14 @@
 {
     m_contextStateSaver.clear(); // uses context owned by m_imageBuffer
     m_imageBuffer.clear();
+    updateExternallyAllocatedMemory();
 }
 
 void HTMLCanvasElement::clearCopiedImage()
 {
     m_copiedImage.clear();
     m_didClearImageBuffer = false;
+    updateExternallyAllocatedMemory();
 }
 
 AffineTransform HTMLCanvasElement::baseTransform() const
@@ -599,4 +623,40 @@
     HTMLElement::didMoveToNewDocument(oldDocument);
 }
 
+PassRefPtr<Image> HTMLCanvasElement::getSourceImageForCanvas(SourceImageMode mode, SourceImageStatus* status) const
+{
+    if (!width() || !height()) {
+        *status = ZeroSizeCanvasSourceImageStatus;
+        return nullptr;
+    }
+
+    if (!buffer()) {
+        *status = InvalidSourceImageStatus;
+        return nullptr;
+    }
+
+    if (mode == CopySourceImageIfVolatile) {
+        *status = NormalSourceImageStatus;
+        return copiedImage();
+    }
+
+    if (m_context && m_context->is3d()) {
+        m_context->paintRenderingResultsToCanvas();
+        *status = ExternalSourceImageStatus;
+    } else {
+        *status = NormalSourceImageStatus;
+    }
+    return m_imageBuffer->copyImage(DontCopyBackingStore, Unscaled);
+}
+
+bool HTMLCanvasElement::wouldTaintOrigin(SecurityOrigin*) const
+{
+    return !originClean();
+}
+
+FloatSize HTMLCanvasElement::sourceSize() const
+{
+    return FloatSize(width(), height());
+}
+
 }
diff --git a/Source/core/html/HTMLCanvasElement.h b/Source/core/html/HTMLCanvasElement.h
index e5e6723..99a1d1c 100644
--- a/Source/core/html/HTMLCanvasElement.h
+++ b/Source/core/html/HTMLCanvasElement.h
@@ -29,6 +29,7 @@
 #define HTMLCanvasElement_h
 
 #include "core/html/HTMLElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/geometry/IntSize.h"
 #include "platform/graphics/Canvas2DLayerBridge.h"
@@ -59,7 +60,7 @@
     virtual void canvasDestroyed(HTMLCanvasElement*) = 0;
 };
 
-class HTMLCanvasElement FINAL : public HTMLElement, public DocumentVisibilityObserver {
+class HTMLCanvasElement FINAL : public HTMLElement, public DocumentVisibilityObserver, public CanvasImageSource {
 public:
     static PassRefPtr<HTMLCanvasElement> create(Document&);
     virtual ~HTMLCanvasElement();
@@ -115,8 +116,8 @@
     void clearPresentationCopy();
 
     SecurityOrigin* securityOrigin() const;
-    void setOriginTainted() { m_originClean = false; }
     bool originClean() const { return m_originClean; }
+    void setOriginTainted() { m_originClean = false; }
 
     AffineTransform baseTransform() const;
 
@@ -131,6 +132,11 @@
     // DocumentVisibilityObserver implementation
     virtual void didChangeVisibilityState(PageVisibilityState) OVERRIDE;
 
+    // CanvasImageSource implementation
+    virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+    virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+    virtual FloatSize sourceSize() const OVERRIDE;
+
 protected:
     virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
 
@@ -152,7 +158,7 @@
 
     bool paintsIntoCanvasBuffer() const;
 
-    void setExternallyAllocatedMemory(intptr_t);
+    void updateExternallyAllocatedMemory() const;
 
     HashSet<CanvasObserver*> m_observers;
 
@@ -166,7 +172,7 @@
     bool m_accelerationDisabled;
     FloatRect m_dirtyRect;
 
-    intptr_t m_externallyAllocatedMemory;
+    mutable intptr_t m_externallyAllocatedMemory;
 
     bool m_originClean;
 
@@ -181,8 +187,6 @@
     mutable RefPtr<Image> m_copiedImage; // FIXME: This is temporary for platforms that have to copy the image buffer to render (and for CSSCanvasValue).
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLCanvasElement, hasTagName(HTMLNames::canvasTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLCanvasElement.idl b/Source/core/html/HTMLCanvasElement.idl
index 0bee59f..d4afad8 100644
--- a/Source/core/html/HTMLCanvasElement.idl
+++ b/Source/core/html/HTMLCanvasElement.idl
@@ -34,4 +34,3 @@
     // The custom binding is needed to handle context creation attributes.
     [Custom, PerWorldBindings, ActivityLogging=ForIsolatedWorlds] any getContext([Default=Undefined] optional DOMString contextId);
 };
-
diff --git a/Source/core/html/HTMLCollection.cpp b/Source/core/html/HTMLCollection.cpp
index e332fb7..0ab210b 100644
--- a/Source/core/html/HTMLCollection.cpp
+++ b/Source/core/html/HTMLCollection.cpp
@@ -27,9 +27,7 @@
 #include "HTMLNames.h"
 #include "core/dom/ClassCollection.h"
 #include "core/dom/ElementTraversal.h"
-#include "core/dom/NodeList.h"
 #include "core/dom/NodeRareData.h"
-#include "core/dom/NodeTraversal.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLObjectElement.h"
 #include "core/html/HTMLOptionElement.h"
@@ -160,7 +158,7 @@
     return DoNotInvalidateOnAttributeChanges;
 }
 
-HTMLCollection::HTMLCollection(ContainerNode* ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType)
+HTMLCollection::HTMLCollection(ContainerNode& ownerNode, CollectionType type, ItemAfterOverrideType itemAfterOverrideType)
     : LiveNodeListBase(ownerNode, rootTypeFromCollectionType(type), invalidationTypeExcludingIdAndNameAttributes(type), type)
     , m_overridesItemAfter(itemAfterOverrideType == OverridesItemAfter)
     , m_shouldOnlyIncludeDirectChildren(shouldTypeOnlyIncludeDirectChildren(type))
@@ -169,7 +167,7 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode* base, CollectionType type)
+PassRefPtr<HTMLCollection> HTMLCollection::create(ContainerNode& base, CollectionType type)
 {
     return adoptRef(new HTMLCollection(base, type, DoesNotOverrideItemAfter));
 }
@@ -181,7 +179,7 @@
     // HTMLNameCollection, ClassCollection and TagCollection remove cache by themselves.
     if (type() != WindowNamedItems && type() != DocumentNamedItems && type() != ClassCollectionType
         && type() != HTMLTagCollectionType && type() != TagCollectionType) {
-        ownerNode()->nodeLists()->removeCache(this, type());
+        ownerNode().nodeLists()->removeCache(this, type());
     }
 }
 
@@ -279,108 +277,11 @@
     return collection.elementMatches(element);
 }
 
-template <> inline bool isMatchingElement(const LiveNodeList& nodeList, const Element& element)
-{
-    return nodeList.nodeMatches(element);
-}
-
-static Node* previousNode(const ContainerNode& base, const Node& previous, bool onlyIncludeDirectChildren)
-{
-    return onlyIncludeDirectChildren ? previous.previousSibling() : NodeTraversal::previous(previous, &base);
-}
-
-static inline Node* lastDescendant(const ContainerNode& node)
-{
-    Node* descendant = node.lastChild();
-    for (Node* current = descendant; current; current = current->lastChild())
-        descendant = current;
-    return descendant;
-}
-
-static Node* lastNode(const ContainerNode& rootNode, bool onlyIncludeDirectChildren)
-{
-    return onlyIncludeDirectChildren ? rootNode.lastChild() : lastDescendant(rootNode);
-}
-
-template <typename Collection>
-ALWAYS_INLINE Element* LiveNodeListBase::iterateForPreviousNode(const Collection& collection, Node* current)
-{
-    bool onlyIncludeDirectChildren = collection.shouldOnlyIncludeDirectChildren();
-    ContainerNode& rootNode = collection.rootNode();
-    for (; current; current = previousNode(rootNode, *current, onlyIncludeDirectChildren)) {
-        if (current->isElementNode() && isMatchingElement(collection, toElement(*current)))
-            return toElement(current);
-    }
-    return 0;
-}
-
-template <typename Collection>
-Element* LiveNodeListBase::itemBefore(const Collection& collection, const Element* previous)
-{
-    Node* current;
-    if (LIKELY(!!previous)) // Without this LIKELY, length() and item() can be 10% slower.
-        current = previousNode(collection.rootNode(), *previous, collection.shouldOnlyIncludeDirectChildren());
-    else
-        current = lastNode(collection.rootNode(), collection.shouldOnlyIncludeDirectChildren());
-
-    return iterateForPreviousNode(collection, current);
-}
-
-Element* LiveNodeList::itemBefore(const Element* previous) const
-{
-    return LiveNodeListBase::itemBefore(*this, previous);
-}
-
 Element* HTMLCollection::itemBefore(const Element* previous) const
 {
     return LiveNodeListBase::itemBefore(*this, previous);
 }
 
-template <class NodeListType>
-inline Element* firstMatchingElement(const NodeListType& nodeList, const ContainerNode& root)
-{
-    Element* element = ElementTraversal::firstWithin(root);
-    while (element && !isMatchingElement(nodeList, *element))
-        element = ElementTraversal::next(*element, &root);
-    return element;
-}
-
-template <class NodeListType>
-inline Element* nextMatchingElement(const NodeListType& nodeList, Element& current, const ContainerNode& root)
-{
-    Element* next = &current;
-    do {
-        next = ElementTraversal::next(*next, &root);
-    } while (next && !isMatchingElement(nodeList, *next));
-    return next;
-}
-
-template <class NodeListType>
-inline Element* traverseMatchingElementsForwardToOffset(const NodeListType& nodeList, unsigned offset, Element& currentElement, unsigned& currentOffset, const ContainerNode& root)
-{
-    ASSERT(currentOffset < offset);
-    Element* next = &currentElement;
-    while ((next = nextMatchingElement(nodeList, *next, root))) {
-        if (++currentOffset == offset)
-            return next;
-    }
-    return 0;
-}
-
-// FIXME: This should be in LiveNodeList.cpp but it needs to stay here until firstMatchingElement()
-// and others are moved to a separate header.
-Element* LiveNodeList::traverseToFirstElement(const ContainerNode& root) const
-{
-    return firstMatchingElement(*this, root);
-}
-
-// FIXME: This should be in LiveNodeList.cpp but it needs to stay here until traverseMatchingElementsForwardToOffset()
-// and others are moved to a separate header.
-Element* LiveNodeList::traverseForwardToOffset(unsigned offset, Element& currentNode, unsigned& currentOffset, const ContainerNode& root) const
-{
-    return traverseMatchingElementsForwardToOffset(*this, offset, currentNode, currentOffset, root);
-}
-
 Element* HTMLCollection::virtualItemAfter(Element*) const
 {
     ASSERT_NOT_REACHED();
diff --git a/Source/core/html/HTMLCollection.h b/Source/core/html/HTMLCollection.h
index 29f039e..0c91644 100644
--- a/Source/core/html/HTMLCollection.h
+++ b/Source/core/html/HTMLCollection.h
@@ -24,7 +24,8 @@
 #ifndef HTMLCollection_h
 #define HTMLCollection_h
 
-#include "core/dom/LiveNodeList.h"
+#include "core/dom/LiveNodeListBase.h"
+#include "core/html/CollectionIndexCache.h"
 #include "core/html/CollectionType.h"
 #include "wtf/Forward.h"
 #include "wtf/HashMap.h"
@@ -39,7 +40,7 @@
         DoesNotOverrideItemAfter,
     };
 
-    static PassRefPtr<HTMLCollection> create(ContainerNode* base, CollectionType);
+    static PassRefPtr<HTMLCollection> create(ContainerNode& base, CollectionType);
     virtual ~HTMLCollection();
     virtual void invalidateCache(Document* oldDocument = 0) const OVERRIDE;
 
@@ -62,7 +63,7 @@
     Element* traverseForwardToOffset(unsigned offset, Element& currentElement, unsigned& currentOffset, const ContainerNode& root) const;
 
 protected:
-    HTMLCollection(ContainerNode* base, CollectionType, ItemAfterOverrideType);
+    HTMLCollection(ContainerNode& base, CollectionType, ItemAfterOverrideType);
 
     bool overridesItemAfter() const { return m_overridesItemAfter; }
     virtual Element* virtualItemAfter(Element*) const;
diff --git a/Source/core/html/shadow/HTMLContentElement.cpp b/Source/core/html/HTMLContentElement.cpp
similarity index 98%
rename from Source/core/html/shadow/HTMLContentElement.cpp
rename to Source/core/html/HTMLContentElement.cpp
index 69faf7f..c6495ab 100644
--- a/Source/core/html/shadow/HTMLContentElement.cpp
+++ b/Source/core/html/HTMLContentElement.cpp
@@ -25,12 +25,12 @@
  */
 
 #include "config.h"
-#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/HTMLContentElement.h"
 
 #include "HTMLNames.h"
-#include "core/css/parser/BisonCSSParser.h"
 #include "core/css/SelectorChecker.h"
 #include "core/css/SiblingTraversalStrategies.h"
+#include "core/css/parser/BisonCSSParser.h"
 #include "core/dom/QualifiedName.h"
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/dom/shadow/ShadowRoot.h"
@@ -77,8 +77,9 @@
             root->owner()->willAffectSelector();
         m_shouldParseSelect = true;
         m_select = value;
-    } else
+    } else {
         InsertionPoint::parseAttribute(name, value);
+    }
 }
 
 bool HTMLContentElement::validateSelect() const
diff --git a/Source/core/html/HTMLContentElement.h b/Source/core/html/HTMLContentElement.h
index 9d14a27..5518122 100644
--- a/Source/core/html/HTMLContentElement.h
+++ b/Source/core/html/HTMLContentElement.h
@@ -1,2 +1,95 @@
-// FIXME: Move HTMLContentElement.h here.
-#include "core/html/shadow/HTMLContentElement.h"
+/*
+ * Copyright (C) 2011 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLContentElement_h
+#define HTMLContentElement_h
+
+#include "core/css/CSSSelectorList.h"
+#include "core/dom/shadow/InsertionPoint.h"
+
+namespace WebCore {
+
+class HTMLContentElement FINAL : public InsertionPoint {
+public:
+    static PassRefPtr<HTMLContentElement> create(Document&);
+
+    virtual ~HTMLContentElement();
+
+    virtual bool canAffectSelector() const OVERRIDE { return true; }
+
+    bool canSelectNode(const Vector<Node*, 32>& siblings, int nth) const;
+
+    const CSSSelectorList& selectorList() const;
+    bool isSelectValid() const;
+
+private:
+    explicit HTMLContentElement(Document&);
+
+    virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
+
+    bool validateSelect() const;
+    void parseSelect();
+
+    bool matchSelector(const Vector<Node*, 32>& siblings, int nth) const;
+
+    bool m_shouldParseSelect;
+    bool m_isValidSelector;
+    AtomicString m_select;
+    CSSSelectorList m_selectorList;
+};
+
+inline const CSSSelectorList& HTMLContentElement::selectorList() const
+{
+    if (m_shouldParseSelect)
+        const_cast<HTMLContentElement*>(this)->parseSelect();
+    return m_selectorList;
+}
+
+inline bool HTMLContentElement::isSelectValid() const
+{
+    if (m_shouldParseSelect)
+        const_cast<HTMLContentElement*>(this)->parseSelect();
+    return m_isValidSelector;
+}
+
+inline bool HTMLContentElement::canSelectNode(const Vector<Node*, 32>& siblings, int nth) const
+{
+    if (m_select.isNull() || m_select.isEmpty())
+        return true;
+    if (!isSelectValid())
+        return false;
+    if (!siblings[nth]->isElementNode())
+        return false;
+    return matchSelector(siblings, nth);
+}
+
+}
+
+#endif
diff --git a/Source/core/html/shadow/HTMLContentElement.idl b/Source/core/html/HTMLContentElement.idl
similarity index 100%
rename from Source/core/html/shadow/HTMLContentElement.idl
rename to Source/core/html/HTMLContentElement.idl
diff --git a/Source/core/html/HTMLDataListElement.h b/Source/core/html/HTMLDataListElement.h
index e19686b..f46756a 100644
--- a/Source/core/html/HTMLDataListElement.h
+++ b/Source/core/html/HTMLDataListElement.h
@@ -51,8 +51,6 @@
     virtual void finishParsingChildren() OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLDataListElement, hasTagName(HTMLNames::datalistTag));
-
 } // namespace WebCore
 
 #endif // HTMLDataListElement_h
diff --git a/Source/core/html/HTMLDetailsElement.cpp b/Source/core/html/HTMLDetailsElement.cpp
index 9546f30..e88582f 100644
--- a/Source/core/html/HTMLDetailsElement.cpp
+++ b/Source/core/html/HTMLDetailsElement.cpp
@@ -27,9 +27,9 @@
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/Text.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLContentElement.h"
 #include "core/html/HTMLDivElement.h"
 #include "core/html/HTMLSummaryElement.h"
-#include "core/html/shadow/HTMLContentElement.h"
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/rendering/RenderBlockFlow.h"
 #include "platform/text/PlatformLocale.h"
@@ -79,13 +79,11 @@
 
 Element* HTMLDetailsElement::findMainSummary() const
 {
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(summaryTag))
-            return toElement(child);
-    }
+    if (HTMLSummaryElement* summary = Traversal<HTMLSummaryElement>::firstChild(*this))
+        return summary;
 
     HTMLContentElement* content = toHTMLContentElement(userAgentShadowRoot()->firstChild());
-    ASSERT(content->firstChild() && content->firstChild()->hasTagName(summaryTag));
+    ASSERT(content->firstChild() && isHTMLSummaryElement(*content->firstChild()));
     return toElement(content->firstChild());
 }
 
diff --git a/Source/core/html/HTMLDetailsElement.h b/Source/core/html/HTMLDetailsElement.h
index 1bcf1d2..63e4475 100644
--- a/Source/core/html/HTMLDetailsElement.h
+++ b/Source/core/html/HTMLDetailsElement.h
@@ -43,8 +43,6 @@
     bool m_isOpen;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLDetailsElement, hasTagName(HTMLNames::detailsTag));
-
 } // namespace WebCore
 
 #endif // HTMLDetailsElement_h
diff --git a/Source/core/html/HTMLDialogElement.cpp b/Source/core/html/HTMLDialogElement.cpp
index 6ba713b..b868465 100644
--- a/Source/core/html/HTMLDialogElement.cpp
+++ b/Source/core/html/HTMLDialogElement.cpp
@@ -45,7 +45,7 @@
     Element* focusableDescendant = 0;
     Node* next = 0;
     for (Node* node = dialog->firstChild(); node; node = next) {
-        if (node->hasTagName(dialogTag))
+        if (isHTMLDialogElement(*node))
             next = NodeTraversal::nextSkippingChildren(*node, dialog);
         else
             next = NodeTraversal::next(*node, dialog);
@@ -74,7 +74,7 @@
         return;
     }
 
-    dialog->document().setFocusedElement(0);
+    dialog->document().setFocusedElement(nullptr);
 }
 
 static void inertSubtreesChanged(Document& document)
@@ -83,10 +83,10 @@
     // tree can change inertness which means they must be added or removed from
     // the tree. The most foolproof way is to clear the entire tree and rebuild
     // it, though a more clever way is probably possible.
-    Document* topDocument = document.topDocument();
-    topDocument->clearAXObjectCache();
-    if (AXObjectCache* cache = topDocument->axObjectCache())
-        cache->childrenChanged(cache->getOrCreate(topDocument));
+    Document& topDocument = document.topDocument();
+    topDocument.clearAXObjectCache();
+    if (AXObjectCache* cache = topDocument.axObjectCache())
+        cache->childrenChanged(cache->getOrCreate(&topDocument));
 }
 
 HTMLDialogElement::HTMLDialogElement(Document& document)
diff --git a/Source/core/html/HTMLDialogElement.h b/Source/core/html/HTMLDialogElement.h
index 26d88cd..f837bfd 100644
--- a/Source/core/html/HTMLDialogElement.h
+++ b/Source/core/html/HTMLDialogElement.h
@@ -74,14 +74,6 @@
     String m_returnValue;
 };
 
-inline bool isHTMLDialogElement(const Node& node)
-{
-    ASSERT_WITH_SECURITY_IMPLICATION(RuntimeEnabledFeatures::dialogElementEnabled());
-    return node.hasTagName(HTMLNames::dialogTag);
-}
-
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLDialogElement);
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/html/HTMLDivElement.h b/Source/core/html/HTMLDivElement.h
index f810ce4..69338d2 100644
--- a/Source/core/html/HTMLDivElement.h
+++ b/Source/core/html/HTMLDivElement.h
@@ -38,8 +38,6 @@
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLDivElement, hasTagName(HTMLNames::divTag));
-
 } // namespace WebCore
 
 #endif // HTMLDivElement_h
diff --git a/Source/core/html/HTMLDocument.cpp b/Source/core/html/HTMLDocument.cpp
index eee2118..61e37d5 100644
--- a/Source/core/html/HTMLDocument.cpp
+++ b/Source/core/html/HTMLDocument.cpp
@@ -56,8 +56,8 @@
 #include "HTMLNames.h"
 #include "bindings/v8/ScriptController.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLBodyElement.h"
 #include "core/page/FocusController.h"
 #include "core/page/FrameTree.h"
@@ -114,7 +114,7 @@
 HTMLBodyElement* HTMLDocument::htmlBodyElement() const
 {
     HTMLElement* body = this->body();
-    return (body && body->hasTagName(bodyTag)) ? toHTMLBodyElement(body) : 0;
+    return isHTMLBodyElement(body) ? toHTMLBodyElement(body) : 0;
 }
 
 const AtomicString& HTMLDocument::bodyAttributeValue(const QualifiedName& name) const
@@ -200,7 +200,7 @@
     if (name.isEmpty())
         return;
     map.add(name);
-    if (Frame* f = frame())
+    if (LocalFrame* f = frame())
         f->script().namedItemAdded(this, name);
 }
 
@@ -209,7 +209,7 @@
     if (name.isEmpty())
         return;
     map.remove(name);
-    if (Frame* f = frame())
+    if (LocalFrame* f = frame())
         f->script().namedItemRemoved(this, name);
 }
 
@@ -300,29 +300,22 @@
     return !isPossibleHTMLAttr || !htmlCaseInsensitiveAttributesSet->contains(attributeName.localName().impl());
 }
 
-void HTMLDocument::clear()
+void HTMLDocument::write(DOMWindow* callingWindow, const Vector<String>& text)
 {
-    // FIXME: This does nothing, and that seems unlikely to be correct.
-    // We've long had a comment saying that IE doesn't support this.
-    // But I do see it in the documentation for Mozilla.
-}
-
-void HTMLDocument::write(DOMWindow* activeWindow, const Vector<String>& text)
-{
-    ASSERT(activeWindow);
+    ASSERT(callingWindow);
     StringBuilder builder;
     for (size_t i = 0; i < text.size(); ++i)
         builder.append(text[i]);
-    write(builder.toString(), activeWindow->document());
+    write(builder.toString(), callingWindow->document());
 }
 
-void HTMLDocument::writeln(DOMWindow* activeWindow, const Vector<String>& text)
+void HTMLDocument::writeln(DOMWindow* callingWindow, const Vector<String>& text)
 {
-    ASSERT(activeWindow);
+    ASSERT(callingWindow);
     StringBuilder builder;
     for (size_t i = 0; i < text.size(); ++i)
         builder.append(text[i]);
-    writeln(builder.toString(), activeWindow->document());
+    writeln(builder.toString(), callingWindow->document());
 }
 
 }
diff --git a/Source/core/html/HTMLDocument.h b/Source/core/html/HTMLDocument.h
index a0c6220..b30eae5 100644
--- a/Source/core/html/HTMLDocument.h
+++ b/Source/core/html/HTMLDocument.h
@@ -58,7 +58,7 @@
     const AtomicString& vlinkColor() const;
     void setVlinkColor(const AtomicString&);
 
-    void clear();
+    void clear() { }
 
     void captureEvents() { }
     void releaseEvents() { }
diff --git a/Source/core/html/HTMLDocument.idl b/Source/core/html/HTMLDocument.idl
index 2b2eb03..9066ca2 100644
--- a/Source/core/html/HTMLDocument.idl
+++ b/Source/core/html/HTMLDocument.idl
@@ -36,10 +36,10 @@
 
     [Replaceable, ImplementedAs=allForBinding] readonly attribute HTMLAllCollection all;
 
-    [DeprecateAs=DocumentClear] void clear();
+    [MeasureAs=DocumentClear] void clear();
 
-    [DeprecateAs=CaptureEvents] void captureEvents();
-    [DeprecateAs=ReleaseEvents] void releaseEvents();
+    [MeasureAs=DocumentCaptureEvents] void captureEvents();
+    [MeasureAs=DocumentReleaseEvents] void releaseEvents();
 
     [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString dir;
     [TreatNullAs=NullString, CustomElementCallbacks] attribute DOMString designMode;
diff --git a/Source/core/html/HTMLElement.cpp b/Source/core/html/HTMLElement.cpp
index 79c7fa1..1a98cf0 100644
--- a/Source/core/html/HTMLElement.cpp
+++ b/Source/core/html/HTMLElement.cpp
@@ -99,7 +99,6 @@
         || hasLocalName(imageTag)
         || hasLocalName(imgTag)
         || hasLocalName(inputTag)
-        || hasLocalName(isindexTag)
         || hasLocalName(linkTag)
         || hasLocalName(metaTag)
         || hasLocalName(paramTag)
@@ -340,12 +339,12 @@
 
         fragment->appendChild(Text::create(document(), text.substring(start, i - start)), exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return nullptr;
 
         if (c == '\r' || c == '\n') {
             fragment->appendChild(HTMLBRElement::create(document()), exceptionState);
             if (exceptionState.hadException())
-                return 0;
+                return nullptr;
             // Make sure \r\n doesn't result in two line breaks.
             if (c == '\r' && i + 1 < length && text[i + 1] == '\n')
                 i++;
@@ -634,7 +633,7 @@
 HTMLFormElement* HTMLElement::findFormAncestor() const
 {
     for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-        if (ancestor->hasTagName(formTag))
+        if (isHTMLFormElement(*ancestor))
             return toHTMLFormElement(ancestor);
     }
     return 0;
@@ -642,7 +641,7 @@
 
 static inline bool elementAffectsDirectionality(const Node* node)
 {
-    return node->isHTMLElement() && (node->hasTagName(bdiTag) || toHTMLElement(node)->hasAttribute(dirAttr));
+    return node->isHTMLElement() && (isHTMLBDIElement(*node) || toHTMLElement(node)->hasAttribute(dirAttr));
 }
 
 static void setHasDirAutoFlagRecursively(Node* firstNode, bool flag, Node* lastNode = 0)
@@ -677,7 +676,7 @@
 bool HTMLElement::hasDirectionAuto() const
 {
     const AtomicString& direction = fastGetAttribute(dirAttr);
-    return (hasTagName(bdiTag) && direction == nullAtom) || equalIgnoringCase(direction, "auto");
+    return (isHTMLBDIElement(*this) && direction == nullAtom) || equalIgnoringCase(direction, "auto");
 }
 
 TextDirection HTMLElement::directionalityIfhasDirAutoAttribute(bool& isAuto) const
@@ -693,7 +692,7 @@
 
 TextDirection HTMLElement::directionality(Node** strongDirectionalityTextNode) const
 {
-    if (hasTagName(inputTag)) {
+    if (isHTMLInputElement(*this)) {
         HTMLInputElement* inputElement = toHTMLInputElement(const_cast<HTMLElement*>(this));
         bool hasStrongDirectionality;
         TextDirection textDirection = determineDirectionality(inputElement->value(), hasStrongDirectionality);
@@ -705,7 +704,7 @@
     Node* node = firstChild();
     while (node) {
         // Skip bdi, script, style and text form controls.
-        if (equalIgnoringCase(node->nodeName(), "bdi") || node->hasTagName(scriptTag) || node->hasTagName(styleTag)
+        if (equalIgnoringCase(node->nodeName(), "bdi") || isHTMLScriptElement(*node) || isHTMLStyleElement(*node)
             || (node->isElementNode() && toElement(node)->isTextFormControl())) {
             node = NodeTraversal::nextSkippingChildren(*node, this);
             continue;
@@ -929,6 +928,25 @@
     Element::defaultEventHandler(event);
 }
 
+bool HTMLElement::matchesReadOnlyPseudoClass() const
+{
+    return !matchesReadWritePseudoClass();
+}
+
+bool HTMLElement::matchesReadWritePseudoClass() const
+{
+    const AtomicString& value = fastGetAttribute(contenteditableAttr);
+    if (!value.isNull()) {
+        if (value.isEmpty() || equalIgnoringCase(value, "true") || equalIgnoringCase(value, "plaintext-only"))
+            return true;
+        if (equalIgnoringCase(value, "false"))
+            return false;
+        // All other values should be treated as "inherit".
+    }
+
+    return parentElement() && parentElement()->rendererIsEditable();
+}
+
 void HTMLElement::handleKeypressEvent(KeyboardEvent* event)
 {
     if (!document().settings() || !document().settings()->spatialNavigationEnabled() || !supportsFocus())
diff --git a/Source/core/html/HTMLElement.h b/Source/core/html/HTMLElement.h
index 9d94c24..90c3963 100644
--- a/Source/core/html/HTMLElement.h
+++ b/Source/core/html/HTMLElement.h
@@ -87,6 +87,9 @@
 
     static const AtomicString& eventNameForAttributeName(const QualifiedName& attrName);
 
+    virtual bool matchesReadOnlyPseudoClass() const OVERRIDE;
+    virtual bool matchesReadWritePseudoClass() const OVERRIDE;
+
 protected:
     HTMLElement(const QualifiedName& tagName, Document&, ConstructionType);
 
@@ -122,7 +125,10 @@
     bool supportsSpatialNavigationFocus() const;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLElement, isHTMLElement());
+DEFINE_ELEMENT_TYPE_CASTS(HTMLElement, isHTMLElement());
+
+template <typename T> bool isElementOfType(const HTMLElement&);
+template <> inline bool isElementOfType<HTMLElement>(const HTMLElement&) { return true; }
 
 inline HTMLElement::HTMLElement(const QualifiedName& tagName, Document& document, ConstructionType type = CreateHTMLElement)
     : Element(tagName, &document, type)
@@ -133,4 +139,6 @@
 
 } // namespace WebCore
 
+#include "HTMLElementTypeHelpers.h"
+
 #endif // HTMLElement_h
diff --git a/Source/core/html/HTMLEmbedElement.cpp b/Source/core/html/HTMLEmbedElement.cpp
index 10dcf7a..3d366ee 100644
--- a/Source/core/html/HTMLEmbedElement.cpp
+++ b/Source/core/html/HTMLEmbedElement.cpp
@@ -54,10 +54,11 @@
 
 static inline RenderWidget* findWidgetRenderer(const Node* n)
 {
-    if (!n->renderer())
-        do
+    if (!n->renderer()) {
+        do {
             n = n->parentNode();
-        while (n && !n->hasTagName(objectTag));
+        } while (n && !isHTMLObjectElement(*n));
+    }
 
     if (n && n->renderer() && n->renderer()->isWidget())
         return toRenderWidget(n->renderer());
@@ -115,10 +116,11 @@
     if (!hasAttributes())
         return;
 
-    for (unsigned i = 0; i < attributeCount(); ++i) {
-        const Attribute* attribute = attributeItem(i);
-        paramNames.append(attribute->localName().string());
-        paramValues.append(attribute->value().string());
+    unsigned attributeCount = this->attributeCount();
+    for (unsigned i = 0; i < attributeCount; ++i) {
+        const Attribute& attribute = attributeItem(i);
+        paramNames.append(attribute.localName().string());
+        paramValues.append(attribute.value().string());
     }
 }
 
@@ -166,14 +168,14 @@
     if (isImageType())
         return HTMLPlugInElement::rendererIsNeeded(style);
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return false;
 
     // If my parent is an <object> and is not set to use fallback content, I
     // should be ignored and not get a renderer.
     ContainerNode* p = parentNode();
-    if (p && p->hasTagName(objectTag)) {
+    if (isHTMLObjectElement(p)) {
         ASSERT(p->renderer());
         if (!toHTMLObjectElement(p)->useFallbackContent()) {
             ASSERT(!p->renderer()->isEmbeddedObject());
@@ -202,7 +204,7 @@
 {
     // http://www.whatwg.org/specs/web-apps/current-work/#exposed
     for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-        if (ancestor->hasTagName(objectTag) && toHTMLObjectElement(ancestor)->isExposed())
+        if (isHTMLObjectElement(*ancestor) && toHTMLObjectElement(*ancestor).isExposed())
             return false;
     }
     return true;
diff --git a/Source/core/html/HTMLEmbedElement.h b/Source/core/html/HTMLEmbedElement.h
index b5a8956..9e3c0af 100644
--- a/Source/core/html/HTMLEmbedElement.h
+++ b/Source/core/html/HTMLEmbedElement.h
@@ -55,8 +55,6 @@
     virtual bool isInteractiveContent() const OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLEmbedElement, hasTagName(HTMLNames::embedTag));
-
 }
 
 #endif
diff --git a/Source/core/html/HTMLFieldSetElement.cpp b/Source/core/html/HTMLFieldSetElement.cpp
index 65640c6..578fc59 100644
--- a/Source/core/html/HTMLFieldSetElement.cpp
+++ b/Source/core/html/HTMLFieldSetElement.cpp
@@ -67,10 +67,8 @@
 void HTMLFieldSetElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
 {
     HTMLFormControlElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
-    for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::nextSkippingChildren(*element, this)) {
-        if (element->hasTagName(legendTag))
-            invalidateDisabledStateUnder(*element);
-    }
+    for (HTMLLegendElement* legend = Traversal<HTMLLegendElement>::firstChild(*this); legend; legend = Traversal<HTMLLegendElement>::nextSibling(*legend))
+        invalidateDisabledStateUnder(*legend);
 }
 
 bool HTMLFieldSetElement::supportsFocus() const
@@ -91,11 +89,7 @@
 
 HTMLLegendElement* HTMLFieldSetElement::legend() const
 {
-    for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSkippingChildren(*child, this)) {
-        if (child->hasTagName(legendTag))
-            return toHTMLLegendElement(child);
-    }
-    return 0;
+    return Traversal<HTMLLegendElement>::firstChild(*this);
 }
 
 PassRefPtr<HTMLCollection> HTMLFieldSetElement::elements()
@@ -113,8 +107,8 @@
 
     m_associatedElements.clear();
 
-    for (Element* element = ElementTraversal::firstWithin(*this); element; element = ElementTraversal::next(*element, this)) {
-        if (element->hasTagName(objectTag)) {
+    for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(*this); element; element = Traversal<HTMLElement>::next(*element, this)) {
+        if (isHTMLObjectElement(*element)) {
             m_associatedElements.append(toHTMLObjectElement(element));
             continue;
         }
diff --git a/Source/core/html/HTMLFieldSetElement.h b/Source/core/html/HTMLFieldSetElement.h
index b8c3a8d..3a7afb7 100644
--- a/Source/core/html/HTMLFieldSetElement.h
+++ b/Source/core/html/HTMLFieldSetElement.h
@@ -62,8 +62,6 @@
     mutable uint64_t m_documentVersion;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLFieldSetElement, hasTagName(HTMLNames::fieldsetTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLFormControlElement.cpp b/Source/core/html/HTMLFormControlElement.cpp
index 5efd66f..6d32513 100644
--- a/Source/core/html/HTMLFormControlElement.cpp
+++ b/Source/core/html/HTMLFormControlElement.cpp
@@ -104,9 +104,9 @@
     HTMLFieldSetElement* fieldSetAncestor = 0;
     ContainerNode* legendAncestor = 0;
     for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-        if (!legendAncestor && ancestor->hasTagName(legendTag))
+        if (!legendAncestor && isHTMLLegendElement(*ancestor))
             legendAncestor = ancestor;
-        if (ancestor->hasTagName(fieldsetTag)) {
+        if (isHTMLFieldSetElement(*ancestor)) {
             fieldSetAncestor = toHTMLFieldSetElement(ancestor);
             break;
         }
@@ -358,7 +358,7 @@
 {
     if (m_dataListAncestorState == Unknown) {
         for (ContainerNode* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-            if (ancestor->hasTagName(datalistTag)) {
+            if (isHTMLDataListElement(*ancestor)) {
                 m_dataListAncestorState = InsideDataList;
                 break;
             }
diff --git a/Source/core/html/HTMLFormControlElement.h b/Source/core/html/HTMLFormControlElement.h
index 44d3315..8a89ebc 100644
--- a/Source/core/html/HTMLFormControlElement.h
+++ b/Source/core/html/HTMLFormControlElement.h
@@ -186,7 +186,7 @@
     return node.isElementNode() && toElement(node).isFormControlElement();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLFormControlElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFormControlElement);
 DEFINE_TYPE_CASTS(HTMLFormControlElement, FormAssociatedElement, control, control->isFormControlElement(), control.isFormControlElement());
 
 } // namespace
diff --git a/Source/core/html/HTMLFormControlElementWithState.cpp b/Source/core/html/HTMLFormControlElementWithState.cpp
index 3c9b9c5..4ecb0e9 100644
--- a/Source/core/html/HTMLFormControlElementWithState.cpp
+++ b/Source/core/html/HTMLFormControlElementWithState.cpp
@@ -25,8 +25,8 @@
 #include "config.h"
 #include "core/html/HTMLFormControlElementWithState.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/forms/FormController.h"
 #include "core/page/Chrome.h"
@@ -46,14 +46,14 @@
 Node::InsertionNotificationRequest HTMLFormControlElementWithState::insertedInto(ContainerNode* insertionPoint)
 {
     if (insertionPoint->inDocument() && !containingShadowRoot())
-        document().formController()->registerStatefulFormControl(*this);
+        document().formController().registerStatefulFormControl(*this);
     return HTMLFormControlElement::insertedInto(insertionPoint);
 }
 
 void HTMLFormControlElementWithState::removedFrom(ContainerNode* insertionPoint)
 {
     if (insertionPoint->inDocument() && !containingShadowRoot() && !insertionPoint->containingShadowRoot())
-        document().formController()->unregisterStatefulFormControl(*this);
+        document().formController().unregisterStatefulFormControl(*this);
     HTMLFormControlElement::removedFrom(insertionPoint);
 }
 
@@ -70,7 +70,7 @@
     // selection before the document is active (or even in a frame).
     if (!document().isActive())
         return;
-    document().frame()->host()->chrome().client().formStateDidChange(this);
+    document().frame()->loader().markDocumentStateDirty();
 }
 
 bool HTMLFormControlElementWithState::shouldSaveAndRestoreFormControlState() const
@@ -87,7 +87,7 @@
 void HTMLFormControlElementWithState::finishParsingChildren()
 {
     HTMLFormControlElement::finishParsingChildren();
-    document().formController()->restoreControlStateFor(*this);
+    document().formController().restoreControlStateFor(*this);
 }
 
 bool HTMLFormControlElementWithState::isFormControlElementWithState() const
diff --git a/Source/core/html/HTMLFormControlElementWithState.h b/Source/core/html/HTMLFormControlElementWithState.h
index f6f7867..d81fd20 100644
--- a/Source/core/html/HTMLFormControlElementWithState.h
+++ b/Source/core/html/HTMLFormControlElementWithState.h
@@ -36,6 +36,7 @@
 
     virtual bool canContainRangeEndPoint() const OVERRIDE FINAL { return false; }
 
+    virtual bool shouldAutocomplete() const;
     virtual bool shouldSaveAndRestoreFormControlState() const;
     virtual FormControlState saveFormControlState() const;
     // The specified FormControlState must have at least one string value.
@@ -45,7 +46,6 @@
 protected:
     HTMLFormControlElementWithState(const QualifiedName& tagName, Document&, HTMLFormElement*);
 
-    virtual bool shouldAutocomplete() const;
     virtual void finishParsingChildren() OVERRIDE;
     virtual InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
     virtual void removedFrom(ContainerNode*) OVERRIDE;
diff --git a/Source/core/html/HTMLFormControlsCollection.cpp b/Source/core/html/HTMLFormControlsCollection.cpp
index 6b2a290..2d23716 100644
--- a/Source/core/html/HTMLFormControlsCollection.cpp
+++ b/Source/core/html/HTMLFormControlsCollection.cpp
@@ -38,16 +38,16 @@
 // Since the collections are to be "live", we have to do the
 // calculation every time if anything has changed.
 
-HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode* ownerNode)
+HTMLFormControlsCollection::HTMLFormControlsCollection(ContainerNode& ownerNode)
     : HTMLCollection(ownerNode, FormControls, OverridesItemAfter)
     , m_cachedElement(0)
     , m_cachedElementOffsetInArray(0)
 {
-    ASSERT(ownerNode->hasTagName(formTag) || ownerNode->hasTagName(fieldsetTag));
+    ASSERT(isHTMLFormElement(ownerNode) || isHTMLFieldSetElement(ownerNode));
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ContainerNode* ownerNode, CollectionType)
+PassRefPtr<HTMLFormControlsCollection> HTMLFormControlsCollection::create(ContainerNode& ownerNode, CollectionType)
 {
     return adoptRef(new HTMLFormControlsCollection(ownerNode));
 }
@@ -58,17 +58,15 @@
 
 const Vector<FormAssociatedElement*>& HTMLFormControlsCollection::formControlElements() const
 {
-    ASSERT(ownerNode());
-    ASSERT(ownerNode()->hasTagName(formTag) || ownerNode()->hasTagName(fieldsetTag));
-    if (ownerNode()->hasTagName(formTag))
-        return toHTMLFormElement(ownerNode())->associatedElements();
-    return toHTMLFieldSetElement(ownerNode())->associatedElements();
+    ASSERT(isHTMLFormElement(ownerNode()) || isHTMLFieldSetElement(ownerNode()));
+    if (isHTMLFormElement(ownerNode()))
+        return toHTMLFormElement(ownerNode()).associatedElements();
+    return toHTMLFieldSetElement(ownerNode()).associatedElements();
 }
 
 const Vector<HTMLImageElement*>& HTMLFormControlsCollection::formImageElements() const
 {
-    ASSERT(ownerNode());
-    return toHTMLFormElement(ownerNode())->imageElements();
+    return toHTMLFormElement(ownerNode()).imageElements();
 }
 
 static unsigned findFormAssociatedElement(const Vector<FormAssociatedElement*>& associatedElements, Element* element)
@@ -143,7 +141,7 @@
     // attribute. If a match is not found, the method then searches for an
     // object with a matching name attribute, but only on those elements
     // that are allowed a name attribute.
-    const Vector<HTMLImageElement*>* imagesElements = ownerNode()->hasTagName(fieldsetTag) ? 0 : &formImageElements();
+    const Vector<HTMLImageElement*>* imagesElements = isHTMLFieldSetElement(ownerNode()) ? 0 : &formImageElements();
     if (HTMLElement* item = firstNamedItem(formControlElements(), imagesElements, idAttr, name))
         return item;
 
@@ -176,7 +174,7 @@
         }
     }
 
-    if (ownerNode()->hasTagName(formTag)) {
+    if (isHTMLFormElement(ownerNode())) {
         const Vector<HTMLImageElement*>& imageElementsArray = formImageElements();
         for (unsigned i = 0; i < imageElementsArray.size(); ++i) {
             HTMLImageElement* element = imageElementsArray[i];
@@ -207,7 +205,7 @@
     }
 
     radioNodeListEnabled = true;
-    radioNodeList = ownerNode()->radioNodeList(name);
+    radioNodeList = ownerNode().radioNodeList(name);
 }
 
 void HTMLFormControlsCollection::supportedPropertyNames(Vector<String>& names)
diff --git a/Source/core/html/HTMLFormControlsCollection.h b/Source/core/html/HTMLFormControlsCollection.h
index d5d7029..fcec719 100644
--- a/Source/core/html/HTMLFormControlsCollection.h
+++ b/Source/core/html/HTMLFormControlsCollection.h
@@ -39,7 +39,7 @@
 
 class HTMLFormControlsCollection FINAL : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLFormControlsCollection> create(ContainerNode*, CollectionType);
+    static PassRefPtr<HTMLFormControlsCollection> create(ContainerNode&, CollectionType);
 
     virtual ~HTMLFormControlsCollection();
 
@@ -47,7 +47,7 @@
     void namedGetter(const AtomicString& name, bool& radioNodeListEnabled, RefPtr<RadioNodeList>&, bool& elementEnabled, RefPtr<Element>&);
 
 private:
-    explicit HTMLFormControlsCollection(ContainerNode*);
+    explicit HTMLFormControlsCollection(ContainerNode&);
 
     virtual void updateIdNameCache() const OVERRIDE;
     virtual void supportedPropertyNames(Vector<String>& names) OVERRIDE;
diff --git a/Source/core/html/HTMLFormElement.cpp b/Source/core/html/HTMLFormElement.cpp
index 7e5a785..0c96bf0 100644
--- a/Source/core/html/HTMLFormElement.cpp
+++ b/Source/core/html/HTMLFormElement.cpp
@@ -46,10 +46,10 @@
 #include "core/html/forms/FormController.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/rendering/RenderTextControl.h"
 #include "platform/UserGestureIndicator.h"
 
@@ -84,7 +84,7 @@
 
 HTMLFormElement::~HTMLFormElement()
 {
-    document().formController()->willDeleteForm(this);
+    document().formController().willDeleteForm(this);
 }
 
 bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style)
@@ -96,11 +96,11 @@
     RenderObject* parentRenderer = node->renderer();
     // FIXME: Shouldn't we also check for table caption (see |formIsTablePart| below).
     // FIXME: This check is not correct for Shadow DOM.
-    bool parentIsTableElementPart = (parentRenderer->isTable() && node->hasTagName(tableTag))
-        || (parentRenderer->isTableRow() && node->hasTagName(trTag))
+    bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(*node))
+        || (parentRenderer->isTableRow() && isHTMLTableRowElement(*node))
         || (parentRenderer->isTableSection() && node->hasTagName(tbodyTag))
         || (parentRenderer->isRenderTableCol() && node->hasTagName(colTag))
-        || (parentRenderer->isTableCell() && node->hasTagName(trTag));
+        || (parentRenderer->isTableCell() && isHTMLTableRowElement(*node));
 
     if (!parentIsTableElementPart)
         return true;
@@ -123,7 +123,7 @@
 }
 
 template<class T>
-void notifyFormRemovedFromTree(const Vector<T*>& elements, Node* root)
+void notifyFormRemovedFromTree(const Vector<T*>& elements, Node& root)
 {
     size_t size = elements.size();
     for (size_t i = 0; i < size; ++i)
@@ -136,7 +136,7 @@
     // We don't need to take care of form association by 'form' content
     // attribute becuse IdTargetObserver handles it.
     if (m_hasElementsAssociatedByParser) {
-        Node* root = highestAncestor();
+        Node& root = highestAncestor();
         if (!m_associatedElementsAreDirty) {
             Vector<FormAssociatedElement*> elements(associatedElements());
             notifyFormRemovedFromTree(elements, root);
@@ -202,10 +202,8 @@
             if (fromImplicitSubmissionTrigger)
                 seenDefaultButton = true;
             if (control->isSuccessfulSubmitButton()) {
-                if (control->renderer()) {
-                    control->dispatchSimulatedClick(event);
-                    return;
-                }
+                control->dispatchSimulatedClick(event);
+                return;
             } else if (fromImplicitSubmissionTrigger) {
                 // Default (submit) button is not activated; no implicit submission.
                 return;
@@ -285,7 +283,7 @@
 bool HTMLFormElement::prepareForSubmission(Event* event)
 {
     RefPtr<HTMLFormElement> protector(this);
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (m_isSubmittingOrPreparingForSubmission || !frame)
         return m_isSubmittingOrPreparingForSubmission;
 
@@ -298,16 +296,14 @@
         return false;
     }
 
-    StringPairVector controlNamesAndValues;
-    getTextFieldValues(controlNamesAndValues);
-    RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, &document(), NotSubmittedByJavaScript);
-    frame->loader().client()->dispatchWillSendSubmitEvent(formState.release());
+    frame->loader().client()->dispatchWillSendSubmitEvent(this);
+
+    // Set flag before submission as dispatchEvent could trigger another event
+    m_isSubmittingOrPreparingForSubmission = false;
 
     if (dispatchEvent(Event::createCancelableBubble(EventTypeNames::submit)))
         m_shouldSubmit = true;
 
-    m_isSubmittingOrPreparingForSubmission = false;
-
     if (m_shouldSubmit)
         submit(event, true, true, NotSubmittedByJavaScript);
 
@@ -324,31 +320,11 @@
     submit(0, false, UserGestureIndicator::processingUserGesture(), SubmittedByJavaScript);
 }
 
-void HTMLFormElement::getTextFieldValues(StringPairVector& fieldNamesAndValues) const
-{
-    ASSERT_ARG(fieldNamesAndValues, fieldNamesAndValues.isEmpty());
-
-    const Vector<FormAssociatedElement*>& elements = associatedElements();
-    fieldNamesAndValues.reserveCapacity(elements.size());
-    for (unsigned i = 0; i < elements.size(); ++i) {
-        FormAssociatedElement* control = elements[i];
-        HTMLElement* element = toHTMLElement(control);
-        if (!element->hasTagName(inputTag))
-            continue;
-
-        HTMLInputElement* input = toHTMLInputElement(element);
-        if (!input->isTextField())
-            continue;
-
-        fieldNamesAndValues.append(make_pair(input->name().string(), input->value()));
-    }
-}
-
 void HTMLFormElement::submitDialog(PassRefPtr<FormSubmission> formSubmission)
 {
     for (Node* node = this; node; node = node->parentOrShadowHostNode()) {
-        if (node->hasTagName(dialogTag)) {
-            toHTMLDialogElement(node)->closeDialog(formSubmission->result());
+        if (isHTMLDialogElement(*node)) {
+            toHTMLDialogElement(*node).closeDialog(formSubmission->result());
             return;
         }
     }
@@ -357,7 +333,7 @@
 void HTMLFormElement::submit(Event* event, bool activateSubmitButton, bool processingUserGesture, FormSubmissionTrigger formSubmissionTrigger)
 {
     FrameView* view = document().view();
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!view || !frame || !frame->page())
         return;
 
@@ -423,9 +399,9 @@
         return;
     }
 
-    Frame* targetFrame = document().frame()->loader().findFrameForNavigation(submission->target(), submission->state()->sourceDocument());
+    LocalFrame* targetFrame = document().frame()->loader().findFrameForNavigation(submission->target(), submission->state()->sourceDocument());
     if (!targetFrame) {
-        if (!DOMWindow::allowPopUp(document().frame()) && !UserGestureIndicator::processingUserGesture())
+        if (!DOMWindow::allowPopUp(*document().frame()) && !UserGestureIndicator::processingUserGesture())
             return;
         targetFrame = document().frame();
     } else {
@@ -442,7 +418,7 @@
 
 void HTMLFormElement::reset()
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (m_isInResetFunction || !frame)
         return;
 
@@ -464,19 +440,10 @@
 
 void HTMLFormElement::requestAutocomplete()
 {
-    Frame* frame = document().frame();
-    if (!frame)
-        return;
-
-    if (!shouldAutocomplete() || !UserGestureIndicator::processingUserGesture()) {
+    if (!document().frame() || !shouldAutocomplete() || !UserGestureIndicator::processingUserGesture())
         finishRequestAutocomplete(AutocompleteResultErrorDisabled);
-        return;
-    }
-
-    StringPairVector controlNamesAndValues;
-    getTextFieldValues(controlNamesAndValues);
-    RefPtr<FormState> formState = FormState::create(this, controlNamesAndValues, &document(), SubmittedByJavaScript);
-    frame->loader().client()->didRequestAutocomplete(formState.release());
+    else
+        document().frame()->loader().client()->didRequestAutocomplete(this);
 }
 
 void HTMLFormElement::finishRequestAutocomplete(AutocompleteResult result)
@@ -496,7 +463,7 @@
 
     // Dispatch events later as this API is meant to work asynchronously in all situations and implementations.
     if (!m_requestAutocompleteTimer.isActive())
-        m_requestAutocompleteTimer.startOneShot(0);
+        m_requestAutocompleteTimer.startOneShot(0, FROM_HERE);
 }
 
 void HTMLFormElement::requestAutocompleteTimerFired(Timer<HTMLFormElement>*)
@@ -576,21 +543,19 @@
     return ensureCachedHTMLCollection(FormControls);
 }
 
-void HTMLFormElement::collectAssociatedElements(Node* root, Vector<FormAssociatedElement*>& elements) const
+void HTMLFormElement::collectAssociatedElements(Node& root, Vector<FormAssociatedElement*>& elements) const
 {
     elements.clear();
-    for (Node* node = root; node; node = NodeTraversal::next(*node)) {
-        if (!node->isHTMLElement())
-            continue;
-        FormAssociatedElement* element = 0;
-        if (toElement(node)->isFormControlElement())
-            element = toHTMLFormControlElement(node);
-        else if (node->hasTagName(objectTag))
-            element = toHTMLObjectElement(node);
+    for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(root); element; element = Traversal<HTMLElement>::next(*element)) {
+        FormAssociatedElement* associatedElement = 0;
+        if (element->isFormControlElement())
+            associatedElement = toHTMLFormControlElement(element);
+        else if (isHTMLObjectElement(*element))
+            associatedElement = toHTMLObjectElement(element);
         else
             continue;
-        if (element->form()== this)
-            elements.append(element);
+        if (associatedElement->form()== this)
+            elements.append(associatedElement);
     }
 }
 
@@ -603,20 +568,21 @@
     HTMLFormElement* mutableThis = const_cast<HTMLFormElement*>(this);
     Node* scope = mutableThis;
     if (m_hasElementsAssociatedByParser)
-        scope = highestAncestor();
+        scope = &highestAncestor();
     if (inDocument() && treeScope().idTargetObserverRegistry().hasObservers(fastGetAttribute(idAttr)))
         scope = &treeScope().rootNode();
-    collectAssociatedElements(scope, mutableThis->m_associatedElements);
+    ASSERT(scope);
+    collectAssociatedElements(*scope, mutableThis->m_associatedElements);
     mutableThis->m_associatedElementsAreDirty = false;
     return m_associatedElements;
 }
 
-void HTMLFormElement::collectImageElements(Node* root, Vector<HTMLImageElement*>& elements)
+void HTMLFormElement::collectImageElements(Node& root, Vector<HTMLImageElement*>& elements)
 {
     elements.clear();
-    for (Node* node = root; node; node = NodeTraversal::next(*node)) {
-        if (node->isHTMLElement() && node->hasTagName(imgTag) && toHTMLElement(node)->formOwner() == this)
-            elements.append(toHTMLImageElement(node));
+    for (HTMLImageElement* image = Traversal<HTMLImageElement>::firstWithin(root); image; image = Traversal<HTMLImageElement>::next(*image)) {
+        if (image->formOwner() == this)
+            elements.append(image);
     }
 }
 
@@ -624,7 +590,7 @@
 {
     if (!m_imageElementsAreDirty)
         return m_imageElements;
-    collectImageElements(m_hasElementsAssociatedByParser ? highestAncestor() : this, m_imageElements);
+    collectImageElements(m_hasElementsAssociatedByParser ? highestAncestor() : *this, m_imageElements);
     m_imageElementsAreDirty = false;
     return m_imageElements;
 }
@@ -722,9 +688,9 @@
     if (!element)
         return 0;
     ASSERT_WITH_SECURITY_IMPLICATION(toHTMLElement(element)->formOwner() == this);
-    if (element->hasTagName(imgTag)) {
+    if (isHTMLImageElement(*element)) {
         ASSERT_WITH_SECURITY_IMPLICATION(imageElements().find(element) != kNotFound);
-    } else if (element->hasTagName(objectTag)) {
+    } else if (isHTMLObjectElement(*element)) {
         ASSERT_WITH_SECURITY_IMPLICATION(associatedElements().find(toHTMLObjectElement(element)) != kNotFound);
     } else {
         ASSERT_WITH_SECURITY_IMPLICATION(associatedElements().find(toHTMLFormControlElement(element)) != kNotFound);
@@ -777,7 +743,7 @@
 void HTMLFormElement::finishParsingChildren()
 {
     HTMLElement::finishParsingChildren();
-    document().formController()->restoreControlStateIn(*this);
+    document().formController().restoreControlStateIn(*this);
     m_didFinishParsingChildren = true;
 }
 
@@ -811,7 +777,7 @@
         return;
     }
 
-    bool onlyMatchImg = elements.size() && elements.at(0)->hasTagName(imgTag);
+    bool onlyMatchImg = !elements.isEmpty() && isHTMLImageElement(*elements.first());
     returnValue0Enabled = true;
     returnValue0 = radioNodeList(name, onlyMatchImg);
 }
diff --git a/Source/core/html/HTMLFormElement.h b/Source/core/html/HTMLFormElement.h
index 0c3c890..758f5fe 100644
--- a/Source/core/html/HTMLFormElement.h
+++ b/Source/core/html/HTMLFormElement.h
@@ -27,7 +27,6 @@
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLFormControlElement.h"
 #include "core/html/forms/RadioButtonGroupScope.h"
-#include "core/loader/FormState.h"
 #include "core/loader/FormSubmission.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/WeakPtr.h"
@@ -114,7 +113,6 @@
     const Vector<FormAssociatedElement*>& associatedElements() const;
     const Vector<HTMLImageElement*>& imageElements();
 
-    void getTextFieldValues(StringPairVector& fieldNamesAndValues) const;
     void anonymousNamedGetter(const AtomicString& name, bool&, RefPtr<RadioNodeList>&, bool&, RefPtr<Element>&);
 
 private:
@@ -139,8 +137,8 @@
 
     void scheduleFormSubmission(PassRefPtr<FormSubmission>);
 
-    void collectAssociatedElements(Node* root, Vector<FormAssociatedElement*>&) const;
-    void collectImageElements(Node* root, Vector<HTMLImageElement*>&);
+    void collectAssociatedElements(Node& root, Vector<FormAssociatedElement*>&) const;
+    void collectImageElements(Node& root, Vector<HTMLImageElement*>&);
 
     // Returns true if the submission should proceed.
     bool validateInteractively(Event*);
@@ -185,8 +183,6 @@
     Timer<HTMLFormElement> m_requestAutocompleteTimer;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLFormElement, hasTagName(HTMLNames::formTag));
-
 } // namespace WebCore
 
 #endif // HTMLFormElement_h
diff --git a/Source/core/html/HTMLFrameElement.cpp b/Source/core/html/HTMLFrameElement.cpp
index 218a221..b5bb366 100644
--- a/Source/core/html/HTMLFrameElement.cpp
+++ b/Source/core/html/HTMLFrameElement.cpp
@@ -59,7 +59,7 @@
 static inline HTMLFrameSetElement* containingFrameSetElement(Node* node)
 {
     while ((node = node->parentNode())) {
-        if (node->hasTagName(framesetTag))
+        if (isHTMLFrameSetElement(*node))
             return toHTMLFrameSetElement(node);
     }
     return 0;
diff --git a/Source/core/html/HTMLFrameElement.h b/Source/core/html/HTMLFrameElement.h
index 1605626..f1c2621 100644
--- a/Source/core/html/HTMLFrameElement.h
+++ b/Source/core/html/HTMLFrameElement.h
@@ -50,8 +50,6 @@
     bool m_frameBorderSet;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLFrameElement, hasTagName(HTMLNames::frameTag));
-
 } // namespace WebCore
 
 #endif // HTMLFrameElement_h
diff --git a/Source/core/html/HTMLFrameElementBase.cpp b/Source/core/html/HTMLFrameElementBase.cpp
index afc9ec5..23eb76f 100644
--- a/Source/core/html/HTMLFrameElementBase.cpp
+++ b/Source/core/html/HTMLFrameElementBase.cpp
@@ -30,11 +30,11 @@
 #include "core/dom/Attribute.h"
 #include "core/dom/Document.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/loader/FrameLoader.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/rendering/RenderPart.h"
 
@@ -63,7 +63,7 @@
             return false;
     }
 
-    Frame* parentFrame = document().frame();
+    LocalFrame* parentFrame = document().frame();
     if (parentFrame)
         return parentFrame->isURLAllowed(completeURL);
 
@@ -78,7 +78,7 @@
     if (m_URL.isEmpty())
         m_URL = AtomicString(blankURL().string());
 
-    Frame* parentFrame = document().frame();
+    LocalFrame* parentFrame = document().frame();
     if (!parentFrame)
         return;
 
@@ -164,7 +164,7 @@
     HTMLFrameOwnerElement::attach(context);
 
     if (RenderPart* part = renderPart()) {
-        if (Frame* frame = contentFrame())
+        if (LocalFrame* frame = contentFrame())
             part->setWidget(frame->view());
     }
 }
@@ -196,7 +196,7 @@
         if (received)
             page->focusController().setFocusedFrame(contentFrame());
         else if (page->focusController().focusedFrame() == contentFrame()) // Focus may have already been given to another frame, don't take it away.
-            page->focusController().setFocusedFrame(0);
+            page->focusController().setFocusedFrame(nullptr);
     }
 }
 
diff --git a/Source/core/html/HTMLFrameElementBase.h b/Source/core/html/HTMLFrameElementBase.h
index 300cdf4..82c5013 100644
--- a/Source/core/html/HTMLFrameElementBase.h
+++ b/Source/core/html/HTMLFrameElementBase.h
@@ -82,7 +82,7 @@
     return node.isElementNode() && toElement(node).isFrameElementBase();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLFrameElementBase);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLFrameElementBase);
 
 } // namespace WebCore
 
diff --git a/Source/core/html/HTMLFrameOwnerElement.cpp b/Source/core/html/HTMLFrameOwnerElement.cpp
index 53868b0..5ebb4b8 100644
--- a/Source/core/html/HTMLFrameOwnerElement.cpp
+++ b/Source/core/html/HTMLFrameOwnerElement.cpp
@@ -24,10 +24,10 @@
 #include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "core/dom/ExceptionCode.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/rendering/RenderPart.h"
 #include "core/svg/SVGDocument.h"
 #include "platform/weborigin/SecurityOrigin.h"
@@ -51,7 +51,7 @@
     return toRenderPart(renderer());
 }
 
-void HTMLFrameOwnerElement::setContentFrame(Frame& frame)
+void HTMLFrameOwnerElement::setContentFrame(LocalFrame& frame)
 {
     // Make sure we will not end up with two frames referencing the same owner element.
     ASSERT(!m_contentFrame || m_contentFrame->ownerElement() != this);
@@ -80,8 +80,8 @@
     // unload event in the subframe which could execute script that could then
     // reach up into this document and then attempt to look back down. We should
     // see if this behavior is really needed as Gecko does not allow this.
-    if (Frame* frame = contentFrame()) {
-        RefPtr<Frame> protect(frame);
+    if (LocalFrame* frame = contentFrame()) {
+        RefPtr<LocalFrame> protect(frame);
         frame->loader().frameDetached();
         frame->disconnectOwnerElement();
     }
@@ -123,7 +123,7 @@
 
 bool HTMLFrameOwnerElement::loadOrRedirectSubframe(const KURL& url, const AtomicString& frameName, bool lockBackForwardList)
 {
-    RefPtr<Frame> parentFrame = document().frame();
+    RefPtr<LocalFrame> parentFrame = document().frame();
     if (contentFrame()) {
         contentFrame()->navigationScheduler().scheduleLocationChange(&document(), url.string(), Referrer(document().outgoingReferrer(), document().referrerPolicy()), lockBackForwardList);
         return true;
@@ -138,7 +138,7 @@
         return false;
 
     String referrer = SecurityPolicy::generateReferrerHeader(document().referrerPolicy(), url, document().outgoingReferrer());
-    RefPtr<Frame> childFrame = parentFrame->loader().client()->createFrame(url, frameName, Referrer(referrer, document().referrerPolicy()), this);
+    RefPtr<LocalFrame> childFrame = parentFrame->loader().client()->createFrame(url, frameName, Referrer(referrer, document().referrerPolicy()), this);
 
     if (!childFrame)  {
         parentFrame->loader().checkCompleted();
@@ -164,7 +164,7 @@
     // before we could connect the signals, so make sure to send the
     // completed() signal for the child by hand and mark the load as being
     // complete.
-    // FIXME: In this case the Frame will have finished loading before
+    // FIXME: In this case the LocalFrame will have finished loading before
     // it's being added to the child list. It would be a good idea to
     // create the child first, then invoke the loader separately.
     if (childFrame->loader().state() == FrameStateComplete && !childFrame->loader().policyDocumentLoader())
diff --git a/Source/core/html/HTMLFrameOwnerElement.h b/Source/core/html/HTMLFrameOwnerElement.h
index 572788c..1ba4474 100644
--- a/Source/core/html/HTMLFrameOwnerElement.h
+++ b/Source/core/html/HTMLFrameOwnerElement.h
@@ -29,18 +29,18 @@
 
 class DOMWindow;
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class RenderPart;
 
 class HTMLFrameOwnerElement : public HTMLElement {
 public:
     virtual ~HTMLFrameOwnerElement();
 
-    Frame* contentFrame() const { return m_contentFrame; }
+    LocalFrame* contentFrame() const { return m_contentFrame; }
     DOMWindow* contentWindow() const;
     Document* contentDocument() const;
 
-    void setContentFrame(Frame&);
+    void setContentFrame(LocalFrame&);
     void clearContentFrame();
 
     void disconnectContentFrame();
@@ -73,11 +73,11 @@
     virtual bool isKeyboardFocusable() const OVERRIDE;
     virtual bool isFrameOwnerElement() const OVERRIDE FINAL { return true; }
 
-    Frame* m_contentFrame;
+    LocalFrame* m_contentFrame;
     SandboxFlags m_sandboxFlags;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLFrameOwnerElement, isFrameOwnerElement());
+DEFINE_ELEMENT_TYPE_CASTS(HTMLFrameOwnerElement, isFrameOwnerElement());
 
 class SubframeLoadingDisabler {
 public:
diff --git a/Source/core/html/HTMLFrameSetElement.cpp b/Source/core/html/HTMLFrameSetElement.cpp
index 6bad8f9..37b4cd1 100644
--- a/Source/core/html/HTMLFrameSetElement.cpp
+++ b/Source/core/html/HTMLFrameSetElement.cpp
@@ -31,10 +31,10 @@
 #include "core/events/Event.h"
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLCollection.h"
 #include "core/html/HTMLFrameElement.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderFrameSet.h"
 
 namespace WebCore {
@@ -170,18 +170,18 @@
     // Inherit default settings from parent frameset
     // FIXME: This is not dynamic.
     for (ContainerNode* node = parentNode(); node; node = node->parentNode()) {
-        if (node->hasTagName(framesetTag)) {
-            HTMLFrameSetElement* frameset = toHTMLFrameSetElement(node);
+        if (isHTMLFrameSetElement(*node)) {
+            HTMLFrameSetElement& frameset = toHTMLFrameSetElement(*node);
             if (!m_frameborderSet)
-                m_frameborder = frameset->hasFrameBorder();
+                m_frameborder = frameset.hasFrameBorder();
             if (m_frameborder) {
                 if (!m_borderSet)
-                    m_border = frameset->border();
+                    m_border = frameset.border();
                 if (!m_borderColorSet)
-                    m_borderColorSet = frameset->hasBorderColor();
+                    m_borderColorSet = frameset.hasBorderColor();
             }
             if (!m_noresize)
-                m_noresize = frameset->noResize();
+                m_noresize = frameset.noResize();
             break;
         }
     }
@@ -220,7 +220,7 @@
 DOMWindow* HTMLFrameSetElement::anonymousNamedGetter(const AtomicString& name)
 {
     Element* frameElement = children()->namedItem(name);
-    if (!frameElement || !frameElement->hasTagName(HTMLNames::frameTag))
+    if (!isHTMLFrameElement(frameElement))
         return 0;
     Document* document = toHTMLFrameElement(frameElement)->contentDocument();
     if (!document || !document->frame())
diff --git a/Source/core/html/HTMLFrameSetElement.h b/Source/core/html/HTMLFrameSetElement.h
index 09648e7..cf64096 100644
--- a/Source/core/html/HTMLFrameSetElement.h
+++ b/Source/core/html/HTMLFrameSetElement.h
@@ -84,8 +84,6 @@
     bool m_noresize;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLFrameSetElement, hasTagName(HTMLNames::framesetTag));
-
 } // namespace WebCore
 
 #endif // HTMLFrameSetElement_h
diff --git a/Source/core/html/HTMLHRElement.cpp b/Source/core/html/HTMLHRElement.cpp
index e8a35a1..912c589 100644
--- a/Source/core/html/HTMLHRElement.cpp
+++ b/Source/core/html/HTMLHRElement.cpp
@@ -76,11 +76,13 @@
         addHTMLColorToStyle(style, CSSPropertyBorderColor, value);
         addHTMLColorToStyle(style, CSSPropertyBackgroundColor, value);
     } else if (name == noshadeAttr) {
-        addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid);
+        if (!hasAttribute(colorAttr)) {
+            addPropertyToPresentationAttributeStyle(style, CSSPropertyBorderStyle, CSSValueSolid);
 
-        RefPtrWillBeRawPtr<CSSPrimitiveValue> darkGrayValue = cssValuePool().createColorValue(Color::darkGray);
-        style->setProperty(CSSPropertyBorderColor, darkGrayValue);
-        style->setProperty(CSSPropertyBackgroundColor, darkGrayValue);
+            RefPtrWillBeRawPtr<CSSPrimitiveValue> darkGrayValue = cssValuePool().createColorValue(Color::darkGray);
+            style->setProperty(CSSPropertyBorderColor, darkGrayValue);
+            style->setProperty(CSSPropertyBackgroundColor, darkGrayValue);
+        }
     } else if (name == sizeAttr) {
         StringImpl* si = value.impl();
         int size = si->toInt();
diff --git a/Source/core/html/HTMLHRElement.h b/Source/core/html/HTMLHRElement.h
index 0b06bbe..6d67e7d 100644
--- a/Source/core/html/HTMLHRElement.h
+++ b/Source/core/html/HTMLHRElement.h
@@ -31,7 +31,7 @@
 public:
     static PassRefPtr<HTMLHRElement> create(Document&);
 
-    virtual bool canContainRangeEndPoint() const OVERRIDE { return hasChildNodes(); }
+    virtual bool canContainRangeEndPoint() const OVERRIDE { return hasChildren(); }
 
 private:
     explicit HTMLHRElement(Document&);
diff --git a/Source/core/html/HTMLHeadElement.h b/Source/core/html/HTMLHeadElement.h
index 7abcac7..68d66c1 100644
--- a/Source/core/html/HTMLHeadElement.h
+++ b/Source/core/html/HTMLHeadElement.h
@@ -36,8 +36,6 @@
     explicit HTMLHeadElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLHeadElement, hasTagName(HTMLNames::headTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLHtmlElement.cpp b/Source/core/html/HTMLHtmlElement.cpp
index c089bba..fb55c51 100644
--- a/Source/core/html/HTMLHtmlElement.cpp
+++ b/Source/core/html/HTMLHtmlElement.cpp
@@ -27,10 +27,10 @@
 #include "HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/dom/DocumentParser.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/frame/Frame.h"
 
 namespace WebCore {
 
diff --git a/Source/core/html/HTMLHtmlElement.h b/Source/core/html/HTMLHtmlElement.h
index cad8d8d..5207cf6 100644
--- a/Source/core/html/HTMLHtmlElement.h
+++ b/Source/core/html/HTMLHtmlElement.h
@@ -40,8 +40,6 @@
     virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLHtmlElement, hasTagName(HTMLNames::htmlTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLIFrameElement.cpp b/Source/core/html/HTMLIFrameElement.cpp
index a4bc0ff..55bd1ac 100644
--- a/Source/core/html/HTMLIFrameElement.cpp
+++ b/Source/core/html/HTMLIFrameElement.cpp
@@ -62,7 +62,7 @@
     else if (name == alignAttr)
         applyAlignmentAttributeToStyle(value, style);
     else if (name == frameborderAttr) {
-        // Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
+        // LocalFrame border doesn't really match the HTML4 spec definition for iframes. It simply adds
         // a presentational hint that the border should be off if set to zero.
         if (!value.toInt()) {
             // Add a rule that nulls out our border width.
diff --git a/Source/core/html/HTMLIFrameElement.h b/Source/core/html/HTMLIFrameElement.h
index e2c2f77..14589b9 100644
--- a/Source/core/html/HTMLIFrameElement.h
+++ b/Source/core/html/HTMLIFrameElement.h
@@ -53,8 +53,6 @@
     bool m_didLoadNonEmptyDocument;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLIFrameElement, hasTagName(HTMLNames::iframeTag));
-
 } // namespace WebCore
 
 #endif // HTMLIFrameElement_h
diff --git a/Source/core/html/HTMLImageElement.cpp b/Source/core/html/HTMLImageElement.cpp
index bed556d..df1902a 100644
--- a/Source/core/html/HTMLImageElement.cpp
+++ b/Source/core/html/HTMLImageElement.cpp
@@ -31,7 +31,9 @@
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/fetch/ImageResource.h"
 #include "core/html/HTMLAnchorElement.h"
+#include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLFormElement.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/html/parser/HTMLSrcsetParser.h"
 #include "core/rendering/RenderImage.h"
@@ -123,7 +125,7 @@
     return m_form.get();
 }
 
-void HTMLImageElement::formRemovedFromTree(const Node* formRoot)
+void HTMLImageElement::formRemovedFromTree(const Node& formRoot)
 {
     ASSERT(m_form);
     if (highestAncestor() != formRoot)
@@ -163,8 +165,9 @@
                 toRenderImage(renderer())->setImageDevicePixelRatio(m_imageDevicePixelRatio);
         }
         m_imageLoader.updateFromElementIgnoringPreviousError();
-    }
-    else if (name == usemapAttr)
+    } else if (name == crossoriginAttr) {
+        m_imageLoader.updateFromElementIgnoringPreviousError();
+    } else if (name == usemapAttr)
         setIsLink(!value.isNull());
     else if (name == onbeforeloadAttr)
         setAttributeEventListener(EventTypeNames::beforeload, createAttributeEventListener(this, name, value));
@@ -410,4 +413,57 @@
     return fastHasAttribute(usemapAttr);
 }
 
+PassRefPtr<Image> HTMLImageElement::getSourceImageForCanvas(SourceImageMode, SourceImageStatus* status) const
+{
+    if (!complete() || !cachedImage()) {
+        *status = IncompleteSourceImageStatus;
+        return nullptr;
+    }
+
+    if (cachedImage()->errorOccurred()) {
+        *status = UndecodableSourceImageStatus;
+        return nullptr;
+    }
+
+    RefPtr<Image> sourceImage = cachedImage()->imageForRenderer(renderer());
+
+    // We need to synthesize a container size if a renderer is not available to provide one.
+    if (!renderer() && sourceImage->usesContainerSize())
+        sourceImage->setContainerSize(sourceImage->size());
+
+    *status = NormalSourceImageStatus;
+    return sourceImage.release();
+}
+
+bool HTMLImageElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
+{
+    ImageResource* image = cachedImage();
+    if (!image)
+        return false;
+    return !image->isAccessAllowed(destinationSecurityOrigin);
+}
+
+FloatSize HTMLImageElement::sourceSize() const
+{
+    ImageResource* image = cachedImage();
+    if (!image)
+        return FloatSize();
+    LayoutSize size;
+    size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure about this.
+
+    return size;
+}
+
+FloatSize HTMLImageElement::defaultDestinationSize() const
+{
+    ImageResource* image = cachedImage();
+    if (!image)
+        return FloatSize();
+    LayoutSize size;
+    size = image->imageSizeForRenderer(renderer(), 1.0f); // FIXME: Not sure about this.
+    if (renderer() && renderer()->isRenderImage() && image->image() && !image->image()->hasRelativeWidth())
+        size.scale(toRenderImage(renderer())->imageDevicePixelRatio());
+    return size;
+}
+
 }
diff --git a/Source/core/html/HTMLImageElement.h b/Source/core/html/HTMLImageElement.h
index 54ea125..9a819a7 100644
--- a/Source/core/html/HTMLImageElement.h
+++ b/Source/core/html/HTMLImageElement.h
@@ -26,6 +26,7 @@
 
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLImageLoader.h"
+#include "core/html/canvas/CanvasImageSource.h"
 #include "platform/graphics/GraphicsTypes.h"
 #include "wtf/WeakPtr.h"
 
@@ -33,7 +34,7 @@
 
 class HTMLFormElement;
 
-class HTMLImageElement FINAL : public HTMLElement {
+class HTMLImageElement FINAL : public HTMLElement, public CanvasImageSource {
 public:
     static PassRefPtr<HTMLImageElement> create(Document&);
     static PassRefPtr<HTMLImageElement> create(Document&, HTMLFormElement*);
@@ -82,7 +83,13 @@
     virtual const AtomicString imageSourceURL() const OVERRIDE;
 
     virtual HTMLFormElement* formOwner() const OVERRIDE;
-    void formRemovedFromTree(const Node* formRoot);
+    void formRemovedFromTree(const Node& formRoot);
+
+    // CanvasImageSourceImplementations
+    virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const;
+    virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+    virtual FloatSize sourceSize() const OVERRIDE;
+    virtual FloatSize defaultDestinationSize() const OVERRIDE;
 
 protected:
     explicit HTMLImageElement(Document&, HTMLFormElement* = 0);
@@ -123,8 +130,6 @@
     bool m_formWasSetByParser;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLImageElement, hasTagName(HTMLNames::imgTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLImageLoader.cpp b/Source/core/html/HTMLImageLoader.cpp
index c884f3c..0669640 100644
--- a/Source/core/html/HTMLImageLoader.cpp
+++ b/Source/core/html/HTMLImageLoader.cpp
@@ -44,12 +44,12 @@
 void HTMLImageLoader::dispatchLoadEvent()
 {
     // HTMLVideoElement uses this class to load the poster image, but it should not fire events for loading or failure.
-    if (element()->hasTagName(HTMLNames::videoTag))
+    if (isHTMLVideoElement(*element()))
         return;
 
     bool errorOccurred = image()->errorOccurred();
     if (!errorOccurred && image()->response().httpStatusCode() >= 400)
-        errorOccurred = element()->hasTagName(HTMLNames::objectTag); // An <object> considers a 404 to be an error and should fire onerror.
+        errorOccurred = isHTMLObjectElement(*element()); // An <object> considers a 404 to be an error and should fire onerror.
     element()->dispatchEvent(Event::create(errorOccurred ? EventTypeNames::error : EventTypeNames::load));
 }
 
@@ -67,7 +67,7 @@
 
     bool loadError = cachedImage->errorOccurred() || cachedImage->response().httpStatusCode() >= 400;
 
-    if (loadError && element->hasTagName(HTMLNames::objectTag))
+    if (loadError && isHTMLObjectElement(*element))
         toHTMLObjectElement(element)->renderFallbackContent();
 }
 
diff --git a/Source/core/html/HTMLInputElement.cpp b/Source/core/html/HTMLInputElement.cpp
index 32ca5d5..fade032 100644
--- a/Source/core/html/HTMLInputElement.cpp
+++ b/Source/core/html/HTMLInputElement.cpp
@@ -51,9 +51,9 @@
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/events/TouchEvent.h"
 #include "core/fileapi/FileList.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
 #include "core/html/HTMLCollection.h"
 #include "core/html/HTMLDataListElement.h"
@@ -166,7 +166,7 @@
     // setForm(0) may register this to a document-level radio button group.
     // We should unregister it to avoid accessing a deleted object.
     if (isRadioButton())
-        document().formController()->radioButtonGroupScope().removeButton(this);
+        document().formController().radioButtonGroupScope().removeButton(this);
     if (m_hasTouchEventHandler)
         document().didRemoveTouchEventHandler(this);
 }
@@ -371,7 +371,7 @@
     if (!isTextField())
         return;
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     frame->spellChecker().didEndEditingOnTextField(this);
     frame->host()->chrome().client().didEndEditingOnTextField(*this);
 }
@@ -1031,6 +1031,11 @@
     setNeedsValidityCheck();
 }
 
+void HTMLInputElement::updateView()
+{
+    m_inputTypeView->updateView();
+}
+
 double HTMLInputElement::valueAsDate() const
 {
     return m_inputType->valueAsDate();
@@ -1311,7 +1316,7 @@
     return m_inputType->files();
 }
 
-void HTMLInputElement::setFiles(PassRefPtr<FileList> files)
+void HTMLInputElement::setFiles(PassRefPtrWillBeRawPtr<FileList> files)
 {
     m_inputType->setFiles(files);
 }
@@ -1428,7 +1433,7 @@
         imageLoader()->elementDidMoveToNewDocument();
 
     if (isRadioButton())
-        oldDocument.formController()->radioButtonGroupScope().removeButton(this);
+        oldDocument.formController().radioButtonGroupScope().removeButton(this);
     if (m_hasTouchEventHandler)
         oldDocument.didRemoveTouchEventHandler(this);
 
@@ -1480,7 +1485,7 @@
     Element* element = treeScope().getElementById(fastGetAttribute(listAttr));
     if (!element)
         return 0;
-    if (!element->hasTagName(datalistTag))
+    if (!isHTMLDataListElement(*element))
         return 0;
 
     return toHTMLDataListElement(element);
@@ -1644,7 +1649,7 @@
 
 void HTMLInputElement::updatePlaceholderText()
 {
-    return m_inputType->updatePlaceholderText();
+    return m_inputTypeView->updatePlaceholderText();
 }
 
 void HTMLInputElement::parseMaxLengthAttribute(const AtomicString& value)
@@ -1721,7 +1726,7 @@
     if (HTMLFormElement* formElement = form())
         return &formElement->radioButtonGroupScope();
     if (inDocument())
-        return &document().formController()->radioButtonGroupScope();
+        return &document().formController().radioButtonGroupScope();
     return 0;
 }
 
diff --git a/Source/core/html/HTMLInputElement.h b/Source/core/html/HTMLInputElement.h
index 0181231..e6dd216 100644
--- a/Source/core/html/HTMLInputElement.h
+++ b/Source/core/html/HTMLInputElement.h
@@ -173,6 +173,7 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE FINAL;
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
     virtual void detach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
+    virtual void updateFocusAppearance(bool restorePreviousSelection) OVERRIDE FINAL;
 
     // FIXME: For isActivatedSubmit and setActivatedSubmit, we should use the NVI-idiom here by making
     // it private virtual in all classes and expose a public method in HTMLFormControlElement to call
@@ -202,7 +203,7 @@
     bool multiple() const;
 
     FileList* files();
-    void setFiles(PassRefPtr<FileList>);
+    void setFiles(PassRefPtrWillBeRawPtr<FileList>);
 
     // Returns true if the given DragData has more than one dropped files.
     bool receiveDroppedFiles(const DragData*);
@@ -231,6 +232,7 @@
     // Functions for InputType classes.
     void setValueInternal(const String&, TextFieldEventBehavior);
     bool valueAttributeWasUpdatedAfterParsing() const { return m_valueAttributeWasUpdatedAfterParsing; }
+    void updateView();
 
     void cacheSelectionInResponseToSetValue(int caretOffset) { cacheSelection(caretOffset, caretOffset, SelectionHasNoDirection); }
 
@@ -299,7 +301,6 @@
     virtual bool isEnumeratable() const OVERRIDE FINAL;
     virtual bool isInteractiveContent() const OVERRIDE FINAL;
     virtual bool supportLabels() const OVERRIDE FINAL;
-    virtual void updateFocusAppearance(bool restorePreviousSelection) OVERRIDE FINAL;
     virtual bool shouldUseInputMethod() OVERRIDE FINAL;
 
     virtual bool isTextFormControl() const OVERRIDE FINAL { return isTextField(); }
@@ -399,7 +400,5 @@
     OwnPtr<ListAttributeTargetObserver> m_listAttributeTargetObserver;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLInputElement, hasTagName(HTMLNames::inputTag));
-
 } //namespace
 #endif
diff --git a/Source/core/html/HTMLLIElement.cpp b/Source/core/html/HTMLLIElement.cpp
index aba2007..7f3f899 100644
--- a/Source/core/html/HTMLLIElement.cpp
+++ b/Source/core/html/HTMLLIElement.cpp
@@ -26,6 +26,7 @@
 #include "CSSPropertyNames.h"
 #include "CSSValueKeywords.h"
 #include "HTMLNames.h"
+#include "core/dom/NodeRenderingTraversal.h"
 #include "core/rendering/RenderListItem.h"
 
 namespace WebCore {
@@ -85,14 +86,16 @@
     if (renderer() && renderer()->isListItem()) {
         RenderListItem* listItemRenderer = toRenderListItem(renderer());
 
+        ASSERT(!document().childNeedsDistributionRecalc());
+
         // Find the enclosing list node.
         Element* listNode = 0;
         Element* current = this;
         while (!listNode) {
-            current = current->parentElement();
+            current = NodeRenderingTraversal::parentElement(current);
             if (!current)
                 break;
-            if (current->hasTagName(ulTag) || current->hasTagName(olTag))
+            if (isHTMLUListElement(*current) || isHTMLOListElement(*current))
                 listNode = current;
         }
 
diff --git a/Source/core/html/HTMLLabelElement.h b/Source/core/html/HTMLLabelElement.h
index a735ce2..fe1ebd5 100644
--- a/Source/core/html/HTMLLabelElement.h
+++ b/Source/core/html/HTMLLabelElement.h
@@ -57,8 +57,6 @@
     virtual void focus(bool restorePreviousSelection, FocusType) OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLLabelElement, hasTagName(HTMLNames::labelTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLLegendElement.cpp b/Source/core/html/HTMLLegendElement.cpp
index 20a6e8f..858578d 100644
--- a/Source/core/html/HTMLLegendElement.cpp
+++ b/Source/core/html/HTMLLegendElement.cpp
@@ -50,20 +50,14 @@
 {
     // Check if there's a fieldset belonging to this legend.
     Element* fieldset = parentElement();
-    while (fieldset && !fieldset->hasTagName(fieldsetTag))
+    while (fieldset && !isHTMLFieldSetElement(*fieldset))
         fieldset = fieldset->parentElement();
     if (!fieldset)
         return 0;
 
     // Find first form element inside the fieldset that is not a legend element.
     // FIXME: Should we consider tabindex?
-    Element* element = fieldset;
-    while ((element = ElementTraversal::next(*element, fieldset))) {
-        if (element->isFormControlElement())
-            return toHTMLFormControlElement(element);
-    }
-
-    return 0;
+    return Traversal<HTMLFormControlElement>::next(*fieldset, fieldset);
 }
 
 void HTMLLegendElement::focus(bool, FocusType type)
@@ -88,7 +82,7 @@
     // its parent, then the form attribute must return the same value as the
     // form attribute on that fieldset element. Otherwise, it must return null.
     ContainerNode* fieldset = parentNode();
-    if (!fieldset || !fieldset->hasTagName(fieldsetTag))
+    if (!isHTMLFieldSetElement(fieldset))
         return 0;
 
     return toHTMLFieldSetElement(fieldset)->formOwner();
diff --git a/Source/core/html/HTMLLegendElement.h b/Source/core/html/HTMLLegendElement.h
index a2e8849..6d390f2 100644
--- a/Source/core/html/HTMLLegendElement.h
+++ b/Source/core/html/HTMLLegendElement.h
@@ -46,8 +46,6 @@
     virtual void focus(bool restorePreviousSelection, FocusType) OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLLegendElement, hasTagName(HTMLNames::legendTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLLinkElement.cpp b/Source/core/html/HTMLLinkElement.cpp
index c34f02e..b2a8f5b 100644
--- a/Source/core/html/HTMLLinkElement.cpp
+++ b/Source/core/html/HTMLLinkElement.cpp
@@ -40,12 +40,12 @@
 #include "core/fetch/CSSStyleSheetResource.h"
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/html/LinkImport.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/imports/LinkImport.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "wtf/StdLibExtras.h"
 
 namespace WebCore {
@@ -342,6 +342,11 @@
     return getAttribute(typeAttr);
 }
 
+bool HTMLLinkElement::async() const
+{
+    return fastHasAttribute(HTMLNames::asyncAttr);
+}
+
 IconType HTMLLinkElement::iconType() const
 {
     return m_relAttribute.iconType();
@@ -395,7 +400,7 @@
 
     CSSParserContext parserContext(m_owner->document(), 0, baseURL, charset);
 
-    if (RefPtr<StyleSheetContents> restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
+    if (RefPtrWillBeRawPtr<StyleSheetContents> restoredSheet = const_cast<CSSStyleSheetResource*>(cachedStyleSheet)->restoreParsedStyleSheet(parserContext)) {
         ASSERT(restoredSheet->isCacheable());
         ASSERT(!restoredSheet->isLoading());
 
@@ -410,7 +415,7 @@
         return;
     }
 
-    RefPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
+    RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(href, parserContext);
 
     if (m_sheet)
         clearSheet();
@@ -458,7 +463,7 @@
     ASSERT(m_sheet);
     ASSERT(m_sheet->ownerNode() == m_owner);
     m_sheet->clearOwnerNode();
-    m_sheet = 0;
+    m_sheet = nullptr;
 }
 
 bool LinkStyle::styleSheetIsLoading() const
@@ -581,10 +586,10 @@
 
         bool mediaQueryMatches = true;
         if (!m_owner->media().isEmpty()) {
-            Frame* frame = loadingFrame();
+            LocalFrame* frame = loadingFrame();
             if (Document* document = loadingFrame()->document()) {
                 RefPtr<RenderStyle> documentStyle = StyleResolver::styleForDocument(*document);
-                RefPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
+                RefPtrWillBeRawPtr<MediaQuerySet> media = MediaQuerySet::create(m_owner->media());
                 MediaQueryEvaluator evaluator(frame->view()->mediaType(), frame, documentStyle.get());
                 mediaQueryMatches = evaluator.eval(media.get());
             }
diff --git a/Source/core/html/HTMLLinkElement.h b/Source/core/html/HTMLLinkElement.h
index f2285f8..8508abd 100644
--- a/Source/core/html/HTMLLinkElement.h
+++ b/Source/core/html/HTMLLinkElement.h
@@ -136,6 +136,8 @@
     // the icon size string as parsed from the HTML attribute
     const AtomicString& iconSizes() const;
 
+    bool async() const;
+
     CSSStyleSheet* sheet() const { return linkStyle() ? linkStyle()->sheet() : 0; }
     Document* import() const;
 
@@ -204,8 +206,6 @@
     int m_beforeLoadRecurseCount;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLLinkElement, hasTagName(HTMLNames::linkTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLMapElement.cpp b/Source/core/html/HTMLMapElement.cpp
index 00f7032..88938ef 100644
--- a/Source/core/html/HTMLMapElement.cpp
+++ b/Source/core/html/HTMLMapElement.cpp
@@ -54,15 +54,12 @@
 bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size, HitTestResult& result)
 {
     HTMLAreaElement* defaultArea = 0;
-    Element* element = this;
-    while ((element = ElementTraversal::next(*element, this))) {
-        if (element->hasTagName(areaTag)) {
-            HTMLAreaElement* areaElt = toHTMLAreaElement(element);
-            if (areaElt->isDefault()) {
-                if (!defaultArea)
-                    defaultArea = areaElt;
-            } else if (areaElt->mapMouseEvent(location, size, result))
-                return true;
+    for (HTMLAreaElement* area = Traversal<HTMLAreaElement>::firstWithin(*this); area; area = Traversal<HTMLAreaElement>::next(*area, this)) {
+        if (area->isDefault()) {
+            if (!defaultArea)
+                defaultArea = area;
+        } else if (area->mapMouseEvent(location, size, result)) {
+            return true;
         }
     }
 
@@ -77,15 +74,14 @@
 {
     RefPtr<HTMLCollection> images = document().images();
     for (unsigned i = 0; Element* curr = images->item(i); i++) {
-        if (!curr->hasTagName(imgTag))
-            continue;
+        ASSERT(isHTMLImageElement(curr));
 
         // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning,
         // which has to be stripped off.
-        HTMLImageElement* imageElement = toHTMLImageElement(curr);
-        String useMapName = imageElement->getAttribute(usemapAttr).string().substring(1);
+        HTMLImageElement& imageElement = toHTMLImageElement(*curr);
+        String useMapName = imageElement.getAttribute(usemapAttr).string().substring(1);
         if (equalIgnoringCase(useMapName, m_name))
-            return imageElement;
+            return &imageElement;
     }
 
     return 0;
diff --git a/Source/core/html/HTMLMapElement.h b/Source/core/html/HTMLMapElement.h
index cdd5c76..5535717 100644
--- a/Source/core/html/HTMLMapElement.h
+++ b/Source/core/html/HTMLMapElement.h
@@ -53,8 +53,6 @@
     AtomicString m_name;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLMapElement, hasTagName(HTMLNames::mapTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLMarqueeElement.cpp b/Source/core/html/HTMLMarqueeElement.cpp
index 882cb06..200d570 100644
--- a/Source/core/html/HTMLMarqueeElement.cpp
+++ b/Source/core/html/HTMLMarqueeElement.cpp
@@ -57,6 +57,12 @@
     return 0;
 }
 
+void HTMLMarqueeElement::didMoveToNewDocument(Document& oldDocument)
+{
+    ActiveDOMObject::didMoveToNewExecutionContext(&document());
+    HTMLElement::didMoveToNewDocument(oldDocument);
+}
+
 bool HTMLMarqueeElement::isPresentationAttribute(const QualifiedName& name) const
 {
     if (name == widthAttr || name == heightAttr || name == bgcolorAttr || name == vspaceAttr || name == hspaceAttr || name == scrollamountAttr || name == scrolldelayAttr || name == loopAttr || name == behaviorAttr || name == directionAttr)
diff --git a/Source/core/html/HTMLMarqueeElement.h b/Source/core/html/HTMLMarqueeElement.h
index 4c7b14a..6b11a18 100644
--- a/Source/core/html/HTMLMarqueeElement.h
+++ b/Source/core/html/HTMLMarqueeElement.h
@@ -56,6 +56,8 @@
 private:
     explicit HTMLMarqueeElement(Document&);
 
+    virtual void didMoveToNewDocument(Document& oldDocument) OVERRIDE;
+
     virtual bool isPresentationAttribute(const QualifiedName&) const OVERRIDE;
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
 
@@ -68,8 +70,6 @@
     RenderMarquee* renderMarquee() const;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLMarqueeElement, hasTagName(HTMLNames::marqueeTag));
-
 } // namespace WebCore
 
 #endif // HTMLMarqueeElement_h
diff --git a/Source/core/html/HTMLMediaElement.cpp b/Source/core/html/HTMLMediaElement.cpp
index c1c66cc..fe5779b 100644
--- a/Source/core/html/HTMLMediaElement.cpp
+++ b/Source/core/html/HTMLMediaElement.cpp
@@ -40,30 +40,25 @@
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/events/Event.h"
 #include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/frame/UseCounter.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/HTMLMediaSource.h"
 #include "core/html/HTMLSourceElement.h"
 #include "core/html/HTMLTrackElement.h"
 #include "core/html/MediaController.h"
 #include "core/html/MediaError.h"
 #include "core/html/MediaFragmentURIParser.h"
-#include "core/html/MediaKeyError.h"
-#include "core/html/MediaKeyEvent.h"
 #include "core/html/TimeRanges.h"
 #include "core/html/shadow/MediaControls.h"
 #include "core/html/track/InbandTextTrack.h"
 #include "core/html/track/TextTrackCueList.h"
 #include "core/html/track/TextTrackList.h"
 #include "core/loader/FrameLoader.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderVideo.h"
 #include "core/rendering/RenderView.h"
-// FIXME: Remove dependency on modules/encryptedmedia (http://crbug.com/242754).
-#include "modules/encryptedmedia/MediaKeyNeededEvent.h"
-#include "modules/encryptedmedia/MediaKeys.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "platform/ContentType.h"
 #include "platform/Language.h"
 #include "platform/Logging.h"
@@ -151,26 +146,6 @@
         map.add(document, set);
 }
 
-static void throwExceptionForMediaKeyException(MediaPlayer::MediaKeyException exception, ExceptionState& exceptionState)
-{
-    switch (exception) {
-    case MediaPlayer::NoError:
-        return;
-    case MediaPlayer::InvalidPlayerState:
-        exceptionState.throwUninformativeAndGenericDOMException(InvalidStateError);
-        return;
-    case MediaPlayer::KeySystemNotSupported:
-        exceptionState.throwUninformativeAndGenericDOMException(NotSupportedError);
-        return;
-    case MediaPlayer::InvalidAccess:
-        exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
-        return;
-    }
-
-    ASSERT_NOT_REACHED();
-    return;
-}
-
 class TrackDisplayUpdateScope {
 public:
     TrackDisplayUpdateScope(HTMLMediaElement* mediaElement)
@@ -275,7 +250,6 @@
     , m_loadState(WaitingForSource)
     , m_webLayer(0)
     , m_opaque(false)
-    , m_restrictions(NoRestrictions)
     , m_preload(MediaPlayer::Auto)
     , m_displayMode(Unknown)
     , m_cachedTime(MediaPlayer::invalidTime())
@@ -284,6 +258,7 @@
     , m_fragmentStartTime(MediaPlayer::invalidTime())
     , m_fragmentEndTime(MediaPlayer::invalidTime())
     , m_pendingActionFlags(0)
+    , m_userGestureRequiredForPlay(false)
     , m_playing(false)
     , m_shouldDelayLoadEvent(false)
     , m_haveFiredLoadedData(false)
@@ -302,24 +277,19 @@
     , m_haveVisibleTextTrack(false)
     , m_processingPreferenceChange(false)
     , m_lastTextTrackUpdateTime(-1)
-    , m_textTracks(0)
+    , m_textTracks(nullptr)
     , m_ignoreTrackDisplayUpdate(0)
 #if ENABLE(WEB_AUDIO)
     , m_audioSourceNode(0)
 #endif
-    , m_emeMode(EmeModeNotSelected)
 {
     ASSERT(RuntimeEnabledFeatures::mediaEnabled());
 
     WTF_LOG(Media, "HTMLMediaElement::HTMLMediaElement");
     ScriptWrappable::init(this);
 
-    if (document.settings()) {
-        if (document.settings()->mediaPlaybackRequiresUserGesture())
-            addBehaviorRestriction(RequireUserGestureForPlayRestriction);
-        if (document.settings()->mediaFullscreenRequiresUserGesture())
-            addBehaviorRestriction(RequireUserGestureForFullscreenRestriction);
-    }
+    if (document.settings() && document.settings()->mediaPlaybackRequiresUserGesture())
+        m_userGestureRequiredForPlay = true;
 
     // We must always have a ShadowRoot so children like <source> will not render
     // as they never have an insertion point.
@@ -335,22 +305,17 @@
     m_asyncEventQueue->close();
 
     setShouldDelayLoadEvent(false);
+
     if (m_textTracks)
         m_textTracks->clearOwner();
-    if (m_textTracks) {
-        for (unsigned i = 0; i < m_textTracks->length(); ++i)
-            m_textTracks->item(i)->clearClient();
-    }
 
     if (m_mediaController) {
         m_mediaController->removeMediaElement(this);
-        m_mediaController = 0;
+        m_mediaController = nullptr;
     }
 
     closeMediaSource();
 
-    setMediaKeysInternal(0);
-
     removeElementFromDocumentMap(this, &document());
 
     // Destroying the player may cause a resource load to be canceled,
@@ -392,9 +357,9 @@
     addElementToDocumentMap(this, &document());
 
     // FIXME: This is a temporary fix to prevent this object from causing the
-    // MediaPlayer to dereference Frame and FrameLoader pointers from the
+    // MediaPlayer to dereference LocalFrame and FrameLoader pointers from the
     // previous document. A proper fix would provide a mechanism to allow this
-    // object to refresh the MediaPlayer's Frame and FrameLoader references on
+    // object to refresh the MediaPlayer's LocalFrame and FrameLoader references on
     // document changes so that playback can be resumed properly.
     userCancelledLoad();
 
@@ -402,6 +367,7 @@
     // and there is no risk of dispatching a load event from within the destructor.
     oldDocument.decrementLoadEventDelayCount();
 
+    ActiveDOMObject::didMoveToNewExecutionContext(&document());
     HTMLElement::didMoveToNewDocument(oldDocument);
 }
 
@@ -464,12 +430,8 @@
     if (!RuntimeEnabledFeatures::videoTrackEnabled())
         return;
 
-    for (Node* node = firstChild(); node; node = node->nextSibling()) {
-        if (node->hasTagName(trackTag)) {
-            scheduleDelayedAction(LoadTextTrackResource);
-            break;
-        }
-    }
+    if (Traversal<HTMLTrackElement>::firstChild(*this))
+        scheduleDelayedAction(LoadTextTrackResource);
 }
 
 bool HTMLMediaElement::rendererIsNeeded(const RenderStyle& style)
@@ -503,7 +465,7 @@
     WTF_LOG(Media, "HTMLMediaElement::removedFrom");
 
     m_active = false;
-    if (insertionPoint->inDocument()) {
+    if (insertionPoint->inDocument() && insertionPoint->document().isActive()) {
         configureMediaControls();
         if (m_networkState > NETWORK_EMPTY)
             pause();
@@ -539,22 +501,27 @@
         m_pendingActionFlags |= LoadTextTrackResource;
 
     if (!m_loadTimer.isActive())
-        m_loadTimer.startOneShot(0);
+        m_loadTimer.startOneShot(0, FROM_HERE);
 }
 
 void HTMLMediaElement::scheduleNextSourceChild()
 {
     // Schedule the timer to try the next <source> element WITHOUT resetting state ala prepareForLoad.
     m_pendingActionFlags |= LoadMediaResource;
-    m_loadTimer.startOneShot(0);
+    m_loadTimer.startOneShot(0, FROM_HERE);
 }
 
 void HTMLMediaElement::scheduleEvent(const AtomicString& eventName)
 {
+    scheduleEvent(Event::createCancelable(eventName));
+}
+
+void HTMLMediaElement::scheduleEvent(PassRefPtr<Event> event)
+{
 #if LOG_MEDIA_EVENTS
-    WTF_LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", eventName.ascii().data());
+    WTF_LOG(Media, "HTMLMediaElement::scheduleEvent - scheduling '%s'", event->type().ascii().data());
 #endif
-    m_asyncEventQueue->enqueueEvent(Event::createCancelable(eventName));
+    m_asyncEventQueue->enqueueEvent(event);
 }
 
 void HTMLMediaElement::loadTimerFired(Timer<HTMLMediaElement>*)
@@ -622,11 +589,8 @@
 
     WTF_LOG(Media, "HTMLMediaElement::load()");
 
-    if (document().settings() && !document().settings()->mediaEnabled())
-        return;
-
     if (UserGestureIndicator::processingUserGesture())
-        removeBehaviorsRestrictionsAfterFirstUserGesture();
+        m_userGestureRequiredForPlay = false;
 
     prepareForLoad();
     loadInternal();
@@ -649,7 +613,7 @@
 
     // 1 - Abort any already-running instance of the resource selection algorithm for this element.
     m_loadState = WaitingForSource;
-    m_currentSourceNode = 0;
+    m_currentSourceNode = nullptr;
 
     // 2 - If there are any tasks from the media element's media element event task source in
     // one of the task queues, then remove those tasks.
@@ -666,14 +630,40 @@
 
     // 4 - If the media element's networkState is not set to NETWORK_EMPTY, then run these substeps
     if (m_networkState != NETWORK_EMPTY) {
+        // 4.1 - Queue a task to fire a simple event named emptied at the media element.
+        scheduleEvent(EventTypeNames::emptied);
+
+        // 4.2 - If a fetching process is in progress for the media element, the user agent should stop it.
         m_networkState = NETWORK_EMPTY;
+
+        // 4.3 - Forget the media element's media-resource-specific tracks.
+        forgetResourceSpecificTracks();
+
+        // 4.4 - If readyState is not set to HAVE_NOTHING, then set it to that state.
         m_readyState = HAVE_NOTHING;
         m_readyStateMaximum = HAVE_NOTHING;
-        refreshCachedTime();
+
+        // 4.5 - If the paused attribute is false, then set it to true.
         m_paused = true;
+
+        // 4.6 - If seeking is true, set it to false.
         m_seeking = false;
+
+        // 4.7 - Set the current playback position to 0.
+        //       Set the official playback position to 0.
+        //       If this changed the official playback position, then queue a task to fire a simple event named timeupdate at the media element.
+        // FIXME: Add support for firing this event.
+
+        // 4.8 - Set the initial playback position to 0.
+        // FIXME: Make this less subtle. The position only becomes 0 because of the createMediaPlayer() call
+        // above.
+        refreshCachedTime();
         invalidateCachedTime();
-        scheduleEvent(EventTypeNames::emptied);
+
+        // 4.9 - Set the timeline offset to Not-a-Number (NaN).
+        // 4.10 - Update the duration attribute to Not-a-Number (NaN).
+
+
         updateMediaController();
         if (RuntimeEnabledFeatures::videoTrackEnabled())
             updateActiveTextTrackCues(0);
@@ -683,7 +673,7 @@
     setPlaybackRate(defaultPlaybackRate());
 
     // 6 - Set the error attribute to null and the autoplaying flag to true.
-    m_error = 0;
+    m_error = nullptr;
     m_autoplaying = true;
 
     // 7 - Invoke the media element's resource selection algorithm.
@@ -697,6 +687,9 @@
     // 2 - Asynchronously await a stable state.
 
     m_playedTimeRanges = TimeRanges::create();
+
+    // FIXME: Investigate whether these can be moved into m_networkState != NETWORK_EMPTY block above
+    // so they are closer to the relevant spec steps.
     m_lastSeekTime = 0;
     m_duration = numeric_limits<double>::quiet_NaN();
 
@@ -740,19 +733,13 @@
     // 3 - If the media element has a src attribute, then let mode be attribute.
     Mode mode = attribute;
     if (!fastHasAttribute(srcAttr)) {
-        Node* node;
-        for (node = firstChild(); node; node = node->nextSibling()) {
-            if (node->hasTagName(sourceTag))
-                break;
-        }
-
         // Otherwise, if the media element does not have a src attribute but has a source
         // element child, then let mode be children and let candidate be the first such
         // source element child in tree order.
-        if (node) {
+        if (HTMLSourceElement* element = Traversal<HTMLSourceElement>::firstChild(*this)) {
             mode = children;
-            m_nextChildNodeToConsider = node;
-            m_currentSourceNode = 0;
+            m_nextChildNodeToConsider = element;
+            m_currentSourceNode = nullptr;
         } else {
             // Otherwise the media element has neither a src attribute nor a source element
             // child: set the networkState to NETWORK_EMPTY, and abort these steps; the
@@ -827,7 +814,7 @@
 
     WTF_LOG(Media, "HTMLMediaElement::loadResource(%s, %s, %s)", urlForLoggingMedia(url).utf8().data(), contentType.raw().utf8().data(), keySystem.utf8().data());
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame) {
         mediaLoadingFailed(MediaPlayer::FormatError);
         return;
@@ -863,7 +850,7 @@
     if (url.protocolIs(mediaSourceBlobProtocol)) {
         if (isMediaStreamURL(url.string())) {
             loadType = blink::WebMediaPlayer::LoadTypeMediaStream;
-            removeBehaviorRestriction(RequireUserGestureForPlayRestriction);
+            m_userGestureRequiredForPlay = false;
         } else {
             m_mediaSource = HTMLMediaSource::lookup(url.string());
 
@@ -873,7 +860,7 @@
                 if (!m_mediaSource->attachToElement(this)) {
                     // Forget our reference to the MediaSource, so we leave it alone
                     // while processing remainder of load failure.
-                    m_mediaSource = 0;
+                    m_mediaSource = nullptr;
                     attemptLoad = false;
                 }
             }
@@ -1190,10 +1177,7 @@
         // or showing by default for the first time, the user agent must immediately and synchronously
         // run the following algorithm ...
 
-        for (Node* node = firstChild(); node; node = node->nextSibling()) {
-            if (!node->hasTagName(trackTag))
-                continue;
-            HTMLTrackElement* trackElement = toHTMLTrackElement(node);
+        for (HTMLTrackElement* trackElement = Traversal<HTMLTrackElement>::firstChild(*this); trackElement; trackElement = Traversal<HTMLTrackElement>::nextSibling(*trackElement)) {
             if (trackElement->track() != track)
                 continue;
 
@@ -1209,8 +1193,9 @@
             }
             break;
         }
-    } else if (track->trackType() == TextTrack::AddTrack && track->mode() != TextTrack::disabledKeyword())
+    } else if (track->trackType() == TextTrack::AddTrack && track->mode() != TextTrack::disabledKeyword()) {
         textTrackAddCues(track, track->cues());
+    }
 
     configureTextTrackDisplay(AssumeVisibleChange);
 
@@ -1305,7 +1290,7 @@
         return false;
     }
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame || !document().securityOrigin()->canDisplay(url)) {
         if (actionIfInvalid == Complain)
             FrameLoader::reportLocalLoadFailed(frame, url.elidedString());
@@ -1328,7 +1313,7 @@
 
     m_previousProgressTime = WTF::currentTime();
     // 350ms is not magic, it is in the spec!
-    m_progressEventTimer.startRepeating(0.350);
+    m_progressEventTimer.startRepeating(0.350, FROM_HERE);
 }
 
 void HTMLMediaElement::waitForSourceChange()
@@ -1356,7 +1341,7 @@
 
     stopPeriodicTimers();
     m_loadState = WaitingForSource;
-    m_currentSourceNode = 0;
+    m_currentSourceNode = nullptr;
 
     // 4.8.10.5
     // 6 - Reaching this step indicates that the media resource failed to load or that the given
@@ -1367,6 +1352,7 @@
     m_error = MediaError::create(MediaError::MEDIA_ERR_SRC_NOT_SUPPORTED);
 
     // 6.2 - Forget the media element's media-resource-specific text tracks.
+    forgetResourceSpecificTracks();
 
     // 6.3 - Set the element's networkState attribute to the NETWORK_NO_SOURCE value.
     m_networkState = NETWORK_NO_SOURCE;
@@ -1414,7 +1400,7 @@
     setShouldDelayLoadEvent(false);
 
     // 6 - Abort the overall resource selection algorithm.
-    m_currentSourceNode = 0;
+    m_currentSourceNode = nullptr;
 }
 
 void HTMLMediaElement::cancelPendingEventsAndCallbacks()
@@ -1422,10 +1408,8 @@
     WTF_LOG(Media, "HTMLMediaElement::cancelPendingEventsAndCallbacks");
     m_asyncEventQueue->cancelAllEvents();
 
-    for (Node* node = firstChild(); node; node = node->nextSibling()) {
-        if (node->hasTagName(sourceTag))
-            toHTMLSourceElement(node)->cancelPendingErrorEvent();
-    }
+    for (HTMLSourceElement* source = Traversal<HTMLSourceElement>::firstChild(*this); source; source = Traversal<HTMLSourceElement>::nextSibling(*source))
+        source->cancelPendingErrorEvent();
 }
 
 void HTMLMediaElement::mediaPlayerNetworkStateChanged()
@@ -1441,11 +1425,18 @@
     // <source> children, schedule the next one
     if (m_readyState < HAVE_METADATA && m_loadState == LoadingFromSourceElement) {
 
+        // resource selection algorithm
+        // Step 9.Otherwise.9 - Failed with elements: Queue a task, using the DOM manipulation task source, to fire a simple event named error at the candidate element.
         if (m_currentSourceNode)
             m_currentSourceNode->scheduleErrorEvent();
         else
             WTF_LOG(Media, "HTMLMediaElement::setNetworkState - error event not sent, <source> was removed");
 
+        // 9.Otherwise.10 - Asynchronously await a stable state. The synchronous section consists of all the remaining steps of this algorithm until the algorithm says the synchronous section has ended.
+
+        // 9.Otherwise.11 - Forget the media element's media-resource-specific tracks.
+        forgetResourceSpecificTracks();
+
         if (havePotentialSourceChild()) {
             WTF_LOG(Media, "HTMLMediaElement::setNetworkState - scheduling next <source>");
             scheduleNextSourceChild();
@@ -1509,8 +1500,6 @@
 void HTMLMediaElement::changeNetworkStateFromLoadingToIdle()
 {
     m_progressEventTimer.stop();
-    if (hasMediaControls() && m_player->didLoadingProgress())
-        mediaControls()->bufferingProgressed();
 
     // Schedule one last progress event so we guarantee that at least one is fired
     // for files that load very quickly.
@@ -1607,21 +1596,21 @@
     }
 
     if (m_readyState == HAVE_ENOUGH_DATA && oldState < HAVE_ENOUGH_DATA && tracksAreReady) {
-        if (oldState <= HAVE_CURRENT_DATA)
+        if (oldState <= HAVE_CURRENT_DATA) {
             scheduleEvent(EventTypeNames::canplay);
+            if (isPotentiallyPlaying)
+                scheduleEvent(EventTypeNames::playing);
+        }
 
-        scheduleEvent(EventTypeNames::canplaythrough);
-
-        if (isPotentiallyPlaying && oldState <= HAVE_CURRENT_DATA)
-            scheduleEvent(EventTypeNames::playing);
-
-        if (m_autoplaying && m_paused && autoplay() && !document().isSandboxed(SandboxAutomaticFeatures) && !userGestureRequiredForPlay()) {
+        if (m_autoplaying && m_paused && autoplay() && !document().isSandboxed(SandboxAutomaticFeatures) && !m_userGestureRequiredForPlay) {
             m_paused = false;
             invalidateCachedTime();
             scheduleEvent(EventTypeNames::play);
             scheduleEvent(EventTypeNames::playing);
         }
 
+        scheduleEvent(EventTypeNames::canplaythrough);
+
         shouldUpdateDisplayState = true;
     }
 
@@ -1637,165 +1626,6 @@
         updateActiveTextTrackCues(currentTime());
 }
 
-void HTMLMediaElement::mediaPlayerKeyAdded(const String& keySystem, const String& sessionId)
-{
-    WTF_LOG(Media, "HTMLMediaElement::mediaPlayerKeyAdded");
-
-    MediaKeyEventInit initializer;
-    initializer.keySystem = keySystem;
-    initializer.sessionId = sessionId;
-    initializer.bubbles = false;
-    initializer.cancelable = false;
-
-    RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyadded, initializer);
-    event->setTarget(this);
-    m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-void HTMLMediaElement::mediaPlayerKeyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode errorCode, unsigned short systemCode)
-{
-    WTF_LOG(Media, "HTMLMediaElement::mediaPlayerKeyError: sessionID=%s, errorCode=%d, systemCode=%d", sessionId.utf8().data(), errorCode, systemCode);
-
-    MediaKeyError::Code mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
-    switch (errorCode) {
-    case MediaPlayerClient::UnknownError:
-        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_UNKNOWN;
-        break;
-    case MediaPlayerClient::ClientError:
-        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_CLIENT;
-        break;
-    case MediaPlayerClient::ServiceError:
-        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_SERVICE;
-        break;
-    case MediaPlayerClient::OutputError:
-        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_OUTPUT;
-        break;
-    case MediaPlayerClient::HardwareChangeError:
-        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_HARDWARECHANGE;
-        break;
-    case MediaPlayerClient::DomainError:
-        mediaKeyErrorCode = MediaKeyError::MEDIA_KEYERR_DOMAIN;
-        break;
-    }
-
-    MediaKeyEventInit initializer;
-    initializer.keySystem = keySystem;
-    initializer.sessionId = sessionId;
-    initializer.errorCode = MediaKeyError::create(mediaKeyErrorCode);
-    initializer.systemCode = systemCode;
-    initializer.bubbles = false;
-    initializer.cancelable = false;
-
-    RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeyerror, initializer);
-    event->setTarget(this);
-    m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-void HTMLMediaElement::mediaPlayerKeyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL)
-{
-    WTF_LOG(Media, "HTMLMediaElement::mediaPlayerKeyMessage: sessionID=%s", sessionId.utf8().data());
-
-    MediaKeyEventInit initializer;
-    initializer.keySystem = keySystem;
-    initializer.sessionId = sessionId;
-    initializer.message = Uint8Array::create(message, messageLength);
-    initializer.defaultURL = defaultURL;
-    initializer.bubbles = false;
-    initializer.cancelable = false;
-
-    RefPtr<Event> event = MediaKeyEvent::create(EventTypeNames::webkitkeymessage, initializer);
-    event->setTarget(this);
-    m_asyncEventQueue->enqueueEvent(event.release());
-}
-
-// Create a MediaKeyNeededEvent for WD EME.
-static PassRefPtr<Event> createNeedKeyEvent(const String& contentType, const unsigned char* initData, unsigned initDataLength)
-{
-    MediaKeyNeededEventInit initializer;
-    initializer.contentType = contentType;
-    initializer.initData = Uint8Array::create(initData, initDataLength);
-    initializer.bubbles = false;
-    initializer.cancelable = false;
-
-    return MediaKeyNeededEvent::create(EventTypeNames::needkey, initializer);
-}
-
-// Create a 'needkey' MediaKeyEvent for v0.1b EME.
-static PassRefPtr<Event> createWebkitNeedKeyEvent(const String& contentType, const unsigned char* initData, unsigned initDataLength)
-{
-    MediaKeyEventInit webkitInitializer;
-    webkitInitializer.keySystem = String();
-    webkitInitializer.sessionId = String();
-    webkitInitializer.initData = Uint8Array::create(initData, initDataLength);
-    webkitInitializer.bubbles = false;
-    webkitInitializer.cancelable = false;
-
-    return MediaKeyEvent::create(EventTypeNames::webkitneedkey, webkitInitializer);
-}
-
-bool HTMLMediaElement::mediaPlayerKeyNeeded(const String& contentType, const unsigned char* initData, unsigned initDataLength)
-{
-    WTF_LOG(Media, "HTMLMediaElement::mediaPlayerKeyNeeded: contentType=%s", contentType.utf8().data());
-
-    if (RuntimeEnabledFeatures::encryptedMediaEnabled()) {
-        // Send event for WD EME.
-        RefPtr<Event> event = createNeedKeyEvent(contentType, initData, initDataLength);
-        event->setTarget(this);
-        m_asyncEventQueue->enqueueEvent(event.release());
-    }
-
-    if (RuntimeEnabledFeatures::prefixedEncryptedMediaEnabled()) {
-        // Send event for v0.1b EME.
-        RefPtr<Event> event = createWebkitNeedKeyEvent(contentType, initData, initDataLength);
-        event->setTarget(this);
-        m_asyncEventQueue->enqueueEvent(event.release());
-    }
-
-    return true;
-}
-
-bool HTMLMediaElement::setEmeMode(EmeMode emeMode, ExceptionState& exceptionState)
-{
-    if (m_emeMode != EmeModeNotSelected && m_emeMode != emeMode) {
-        exceptionState.throwDOMException(InvalidStateError, "Mixed use of EME prefixed and unprefixed API not allowed.");
-        return false;
-    }
-    m_emeMode = emeMode;
-    return true;
-}
-
-blink::WebContentDecryptionModule* HTMLMediaElement::contentDecryptionModule()
-{
-    return m_mediaKeys ? m_mediaKeys->contentDecryptionModule() : 0;
-}
-
-void HTMLMediaElement::setMediaKeysInternal(MediaKeys* mediaKeys)
-{
-    WTF_LOG(Media, "HTMLMediaElement::setMediaKeys");
-    if (m_mediaKeys == mediaKeys)
-        return;
-
-    ASSERT(m_emeMode = EmeModeUnprefixed);
-
-    if (m_mediaKeys)
-        m_mediaKeys->setMediaElement(0);
-    m_mediaKeys = mediaKeys;
-    if (m_mediaKeys)
-        m_mediaKeys->setMediaElement(this);
-
-    // If a player is connected, tell it that the CDM has changed.
-    if (m_player)
-        m_player->setContentDecryptionModule(contentDecryptionModule());
-}
-
-void HTMLMediaElement::setMediaKeys(MediaKeys* mediaKeys, ExceptionState& exceptionState)
-{
-    if (!setEmeMode(EmeModeUnprefixed, exceptionState))
-        return;
-
-    setMediaKeysInternal(mediaKeys);
-}
-
 void HTMLMediaElement::progressEventTimerFired(Timer<HTMLMediaElement>*)
 {
     ASSERT(m_player);
@@ -1811,8 +1641,6 @@
         m_sentStalledEvent = false;
         if (renderer())
             renderer()->updateFromElement();
-        if (hasMediaControls())
-            mediaControls()->bufferingProgressed();
     } else if (timedelta > 3.0 && !m_sentStalledEvent) {
         scheduleEvent(EventTypeNames::stalled);
         m_sentStalledEvent = true;
@@ -2019,7 +1847,7 @@
 void HTMLMediaElement::setCurrentTime(double time, ExceptionState& exceptionState)
 {
     if (m_mediaController) {
-        exceptionState.throwDOMException(InvalidStateError, "No media controller is available.");
+        exceptionState.throwDOMException(InvalidStateError, "The element is slaved to a MediaController.");
         return;
     }
     seek(time, exceptionState);
@@ -2131,10 +1959,10 @@
 {
     WTF_LOG(Media, "HTMLMediaElement::play()");
 
-    if (userGestureRequiredForPlay() && !UserGestureIndicator::processingUserGesture())
+    if (m_userGestureRequiredForPlay && !UserGestureIndicator::processingUserGesture())
         return;
     if (UserGestureIndicator::processingUserGesture())
-        removeBehaviorsRestrictionsAfterFirstUserGesture();
+        m_userGestureRequiredForPlay = false;
 
     playInternal();
 }
@@ -2193,104 +2021,7 @@
         return;
 
     m_mediaSource->close();
-    m_mediaSource = 0;
-}
-
-void HTMLMediaElement::webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState& exceptionState)
-{
-    WTF_LOG(Media, "HTMLMediaElement::webkitGenerateKeyRequest");
-
-    if (!setEmeMode(EmeModePrefixed, exceptionState))
-        return;
-
-    if (keySystem.isEmpty()) {
-        exceptionState.throwDOMException(SyntaxError, "The key system provided is empty.");
-        return;
-    }
-
-    if (!m_player) {
-        exceptionState.throwDOMException(InvalidStateError, "No player is available.");
-        return;
-    }
-
-    const unsigned char* initDataPointer = 0;
-    unsigned initDataLength = 0;
-    if (initData) {
-        initDataPointer = initData->data();
-        initDataLength = initData->length();
-    }
-
-    MediaPlayer::MediaKeyException result = m_player->generateKeyRequest(keySystem, initDataPointer, initDataLength);
-    throwExceptionForMediaKeyException(result, exceptionState);
-}
-
-void HTMLMediaElement::webkitGenerateKeyRequest(const String& keySystem, ExceptionState& exceptionState)
-{
-    webkitGenerateKeyRequest(keySystem, Uint8Array::create(0), exceptionState);
-}
-
-void HTMLMediaElement::webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState& exceptionState)
-{
-    WTF_LOG(Media, "HTMLMediaElement::webkitAddKey");
-
-    if (!setEmeMode(EmeModePrefixed, exceptionState))
-        return;
-
-    if (keySystem.isEmpty()) {
-        exceptionState.throwDOMException(SyntaxError, "The key system provided is empty.");
-        return;
-    }
-
-    if (!key) {
-        exceptionState.throwDOMException(SyntaxError, "The key provided is invalid.");
-        return;
-    }
-
-    if (!key->length()) {
-        exceptionState.throwDOMException(TypeMismatchError, "The key provided is invalid.");
-        return;
-    }
-
-    if (!m_player) {
-        exceptionState.throwDOMException(InvalidStateError, "No player is available.");
-        return;
-    }
-
-    const unsigned char* initDataPointer = 0;
-    unsigned initDataLength = 0;
-    if (initData) {
-        initDataPointer = initData->data();
-        initDataLength = initData->length();
-    }
-
-    MediaPlayer::MediaKeyException result = m_player->addKey(keySystem, key->data(), key->length(), initDataPointer, initDataLength, sessionId);
-    throwExceptionForMediaKeyException(result, exceptionState);
-}
-
-void HTMLMediaElement::webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState& exceptionState)
-{
-    webkitAddKey(keySystem, key, Uint8Array::create(0), String(), exceptionState);
-}
-
-void HTMLMediaElement::webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionState& exceptionState)
-{
-    WTF_LOG(Media, "HTMLMediaElement::webkitCancelKeyRequest");
-
-    if (!setEmeMode(EmeModePrefixed, exceptionState))
-        return;
-
-    if (keySystem.isEmpty()) {
-        exceptionState.throwDOMException(SyntaxError, "The key system provided is empty.");
-        return;
-    }
-
-    if (!m_player) {
-        exceptionState.throwDOMException(InvalidStateError, "No player is available.");
-        return;
-    }
-
-    MediaPlayer::MediaKeyException result = m_player->cancelKeyRequest(keySystem, sessionId);
-    throwExceptionForMediaKeyException(result, exceptionState);
+    m_mediaSource = nullptr;
 }
 
 bool HTMLMediaElement::loop() const
@@ -2306,7 +2037,7 @@
 
 bool HTMLMediaElement::controls() const
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
 
     // always show controls when scripting is disabled
     if (frame && !frame->script().canExecuteScripts(NotAboutToExecuteScript))
@@ -2335,7 +2066,7 @@
     WTF_LOG(Media, "HTMLMediaElement::setVolume(%f)", vol);
 
     if (vol < 0.0f || vol > 1.0f) {
-        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("volume", vol, 0.0f, ExceptionMessages::ExclusiveBound, 1.0f, ExceptionMessages::ExclusiveBound));
+        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("volume", vol, 0.0, ExceptionMessages::InclusiveBound, 1.0, ExceptionMessages::InclusiveBound));
         return;
     }
 
@@ -2355,15 +2086,17 @@
 {
     WTF_LOG(Media, "HTMLMediaElement::setMuted(%s)", boolString(muted));
 
-    if (m_muted != muted) {
-        m_muted = muted;
-        if (m_player) {
-            m_player->setMuted(m_muted);
-            if (hasMediaControls())
-                mediaControls()->changedMute();
-        }
-        scheduleEvent(EventTypeNames::volumechange);
-    }
+    if (m_muted == muted)
+        return;
+
+    m_muted = muted;
+
+    updateVolume();
+
+    if (hasMediaControls())
+        mediaControls()->changedMute();
+
+    scheduleEvent(EventTypeNames::volumechange);
 }
 
 void HTMLMediaElement::beginScrubbing()
@@ -2403,7 +2136,7 @@
         return;
 
     m_previousProgressTime = WTF::currentTime();
-    m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency);
+    m_playbackProgressTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HERE);
 }
 
 void HTMLMediaElement::playbackProgressTimerFired(Timer<HTMLMediaElement>*)
@@ -2413,6 +2146,7 @@
     if (m_fragmentEndTime != MediaPlayer::invalidTime() && currentTime() >= m_fragmentEndTime && m_playbackRate > 0) {
         m_fragmentEndTime = MediaPlayer::invalidTime();
         if (!m_mediaController && !m_paused) {
+            UseCounter::count(document(), UseCounter::HTMLMediaElementPauseAtFragmentEnd);
             // changes paused to true and fires a simple event named pause at the media element.
             pause();
         }
@@ -2455,14 +2189,14 @@
     return paused() || ended() || m_readyState < HAVE_METADATA;
 }
 
-void HTMLMediaElement::mediaPlayerDidAddTrack(WebInbandTextTrack* webTrack)
+void HTMLMediaElement::mediaPlayerDidAddTextTrack(WebInbandTextTrack* webTrack)
 {
     if (!RuntimeEnabledFeatures::videoTrackEnabled())
         return;
 
     // 4.8.10.12.2 Sourcing in-band text tracks
     // 1. Associate the relevant data with a new text track and its corresponding new TextTrack object.
-    RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), this, webTrack);
+    RefPtr<InbandTextTrack> textTrack = InbandTextTrack::create(document(), webTrack);
 
     // 2. Set the new text track's kind, label, and language based on the semantics of the relevant data,
     // as defined by the relevant specification. If there is no label in that data, then the label must
@@ -2487,10 +2221,10 @@
     // 9. Fire an event with the name addtrack, that does not bubble and is not cancelable, and that uses the TrackEvent
     // interface, with the track attribute initialized to the text track's TextTrack object, at the media element's
     // textTracks attribute's TextTrackList object.
-    addTrack(textTrack.get());
+    addTextTrack(textTrack.get());
 }
 
-void HTMLMediaElement::mediaPlayerDidRemoveTrack(WebInbandTextTrack* webTrack)
+void HTMLMediaElement::mediaPlayerDidRemoveTextTrack(WebInbandTextTrack* webTrack)
 {
     if (!RuntimeEnabledFeatures::videoTrackEnabled())
         return;
@@ -2499,12 +2233,12 @@
         return;
 
     // This cast is safe because we created the InbandTextTrack with the WebInbandTextTrack
-    // passed to mediaPlayerDidAddTrack.
+    // passed to mediaPlayerDidAddTextTrack.
     RefPtr<InbandTextTrack> textTrack = static_cast<InbandTextTrack*>(webTrack->client());
     if (!textTrack)
         return;
 
-    removeTrack(textTrack.get());
+    removeTextTrack(textTrack.get());
 }
 
 void HTMLMediaElement::closeCaptionTracksChanged()
@@ -2513,35 +2247,27 @@
         mediaControls()->closedCaptionTracksChanged();
 }
 
-void HTMLMediaElement::addTrack(TextTrack* track)
+void HTMLMediaElement::addTextTrack(TextTrack* track)
 {
     textTracks()->append(track);
 
     closeCaptionTracksChanged();
 }
 
-void HTMLMediaElement::removeTrack(TextTrack* track)
+void HTMLMediaElement::removeTextTrack(TextTrack* track)
 {
     TrackDisplayUpdateScope scope(this);
-    TextTrackCueList* cues = track->cues();
-    if (cues)
-        textTrackRemoveCues(track, cues);
     m_textTracks->remove(track);
 
     closeCaptionTracksChanged();
 }
 
-void HTMLMediaElement::removeAllInbandTracks()
+void HTMLMediaElement::forgetResourceSpecificTracks()
 {
-    if (!m_textTracks)
-        return;
-
-    TrackDisplayUpdateScope scope(this);
-    for (int i = m_textTracks->length() - 1; i >= 0; --i) {
-        TextTrack* track = m_textTracks->item(i);
-
-        if (track->trackType() == TextTrack::InBand)
-            removeTrack(track);
+    if (m_textTracks) {
+        TrackDisplayUpdateScope scope(this);
+        m_textTracks->removeAllInbandTracks();
+        closeCaptionTracksChanged();
     }
 }
 
@@ -2555,7 +2281,7 @@
     // 1. If kind is not one of the following strings, then throw a SyntaxError exception and abort these steps
     if (!TextTrack::isValidKindKeyword(kind)) {
         exceptionState.throwDOMException(SyntaxError, "The 'kind' provided ('" + kind + "') is invalid.");
-        return 0;
+        return nullptr;
     }
 
     // 2. If the label argument was omitted, let label be the empty string.
@@ -2564,13 +2290,13 @@
 
     // 5. Create a new text track corresponding to the new object, and set its text track kind to kind, its text
     // track label to label, its text track language to language...
-    RefPtr<TextTrack> textTrack = TextTrack::create(document(), this, kind, label, language);
+    RefPtr<TextTrack> textTrack = TextTrack::create(document(), kind, label, language);
 
     // Note, due to side effects when changing track parameters, we have to
     // first append the track to the text track list.
 
     // 6. Add the new text track to the media element's list of text tracks.
-    addTrack(textTrack.get());
+    addTextTrack(textTrack.get());
 
     // ... its text track readiness state to the text track loaded state ...
     textTrack->setReadinessState(TextTrack::Loaded);
@@ -2591,10 +2317,8 @@
     return m_textTracks.get();
 }
 
-void HTMLMediaElement::didAddTrack(HTMLTrackElement* trackElement)
+void HTMLMediaElement::didAddTrackElement(HTMLTrackElement* trackElement)
 {
-    ASSERT(trackElement->hasTagName(trackTag));
-
     if (!RuntimeEnabledFeatures::videoTrackEnabled())
         return;
 
@@ -2606,7 +2330,7 @@
     if (!textTrack)
         return;
 
-    addTrack(textTrack.get());
+    addTextTrack(textTrack.get());
 
     // Do not schedule the track loading until parsing finishes so we don't start before all tracks
     // in the markup have been added.
@@ -2617,18 +2341,14 @@
         mediaControls()->closedCaptionTracksChanged();
 }
 
-void HTMLMediaElement::didRemoveTrack(HTMLTrackElement* trackElement)
+void HTMLMediaElement::didRemoveTrackElement(HTMLTrackElement* trackElement)
 {
-    ASSERT(trackElement->hasTagName(trackTag));
-
     if (!RuntimeEnabledFeatures::videoTrackEnabled())
         return;
 
 #if !LOG_DISABLED
-    if (trackElement->hasTagName(trackTag)) {
-        KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
-        WTF_LOG(Media, "HTMLMediaElement::didRemoveTrack - 'src' is %s", urlForLoggingMedia(url).utf8().data());
-    }
+    KURL url = trackElement->getNonEmptyURLAttribute(srcAttr);
+    WTF_LOG(Media, "HTMLMediaElement::didRemoveTrackElement - 'src' is %s", urlForLoggingMedia(url).utf8().data());
 #endif
 
     RefPtr<TextTrack> textTrack = trackElement->track();
@@ -2644,7 +2364,7 @@
     // When a track element's parent element changes and the old parent was a media element,
     // then the user agent must remove the track element's corresponding text track from the
     // media element's list of text tracks.
-    removeTrack(textTrack.get());
+    removeTextTrack(textTrack.get());
 
     size_t index = m_textTracksWhenResourceSelectionBegan.find(textTrack.get());
     if (index != kNotFound)
@@ -2868,7 +2588,7 @@
             continue;
         lookingForStartNode = false;
 
-        if (!node->hasTagName(sourceTag))
+        if (!isHTMLSourceElement(*node))
             continue;
         if (node->parentNode() != this)
             continue;
@@ -2926,8 +2646,8 @@
         m_currentSourceNode = source;
         m_nextChildNodeToConsider = source->nextSibling();
     } else {
-        m_currentSourceNode = 0;
-        m_nextChildNodeToConsider = 0;
+        m_currentSourceNode = nullptr;
+        m_nextChildNodeToConsider = nullptr;
     }
 
 #if !LOG_DISABLED
@@ -2942,10 +2662,8 @@
     WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded(%p)", source);
 
 #if !LOG_DISABLED
-    if (source->hasTagName(sourceTag)) {
-        KURL url = source->getNonEmptyURLAttribute(srcAttr);
-        WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLoggingMedia(url).utf8().data());
-    }
+    KURL url = source->getNonEmptyURLAttribute(srcAttr);
+    WTF_LOG(Media, "HTMLMediaElement::sourceWasAdded - 'src' is %s", urlForLoggingMedia(url).utf8().data());
 #endif
 
     // We should only consider a <source> element when there is not src attribute at all.
@@ -2990,10 +2708,8 @@
     WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved(%p)", source);
 
 #if !LOG_DISABLED
-    if (source->hasTagName(sourceTag)) {
-        KURL url = source->getNonEmptyURLAttribute(srcAttr);
-        WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved - 'src' is %s", urlForLoggingMedia(url).utf8().data());
-    }
+    KURL url = source->getNonEmptyURLAttribute(srcAttr);
+    WTF_LOG(Media, "HTMLMediaElement::sourceWasRemoved - 'src' is %s", urlForLoggingMedia(url).utf8().data());
 #endif
 
     if (source != m_currentSourceNode && source != m_nextChildNodeToConsider)
@@ -3007,7 +2723,7 @@
         // Clear the current source node pointer, but don't change the movie as the spec says:
         // 4.8.8 - Dynamically modifying a source element and its attribute when the element is already
         // inserted in a video or audio element will have no effect.
-        m_currentSourceNode = 0;
+        m_currentSourceNode = nullptr;
         WTF_LOG(Media, "HTMLMediaElement::sourceRemoved - m_currentSourceNode set to 0");
     }
 }
@@ -3240,9 +2956,15 @@
 
 void HTMLMediaElement::updateVolume()
 {
-    if (!m_player)
-        return;
+    if (webMediaPlayer())
+        webMediaPlayer()->setVolume(playerVolume());
 
+    if (hasMediaControls())
+        mediaControls()->changedVolume();
+}
+
+double HTMLMediaElement::playerVolume() const
+{
     double volumeMultiplier = 1;
     bool shouldMute = m_muted;
 
@@ -3251,11 +2973,7 @@
         shouldMute = m_mediaController->muted();
     }
 
-    m_player->setMuted(shouldMute);
-    m_player->setVolume(m_volume * volumeMultiplier);
-
-    if (hasMediaControls())
-        mediaControls()->changedVolume();
+    return shouldMute ? 0 : m_volume * volumeMultiplier;
 }
 
 void HTMLMediaElement::updatePlayState()
@@ -3287,7 +3005,7 @@
             // Set rate, muted before calling play in case they were set before the media engine was setup.
             // The media engine should just stash the rate and muted values since it isn't already playing.
             m_player->setRate(m_playbackRate);
-            m_player->setMuted(m_muted);
+            updateVolume();
 
             m_player->play();
         }
@@ -3368,7 +3086,7 @@
     setShouldDelayLoadEvent(false);
 
     // 6 - Abort the overall resource selection algorithm.
-    m_currentSourceNode = 0;
+    m_currentSourceNode = nullptr;
 
     // Reset m_readyState since m_player is gone.
     m_readyState = HAVE_NOTHING;
@@ -3397,12 +3115,10 @@
 
 void HTMLMediaElement::clearMediaPlayer(int flags)
 {
-    removeAllInbandTracks();
+    forgetResourceSpecificTracks();
 
     closeMediaSource();
 
-    setMediaKeysInternal(0);
-
     clearMediaPlayerAndAudioSourceProviderClient();
 
     stopPeriodicTimers();
@@ -3457,15 +3173,7 @@
     WTF_LOG(Media, "HTMLMediaElement::enterFullscreen");
 
     if (document().settings() && document().settings()->fullScreenEnabled())
-        FullscreenElementStack::from(&document())->requestFullScreenForElement(this, 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
-}
-
-void HTMLMediaElement::exitFullscreen()
-{
-    WTF_LOG(Media, "HTMLMediaElement::exitFullscreen");
-
-    if (document().settings() && document().settings()->fullScreenEnabled() && isFullscreen())
-        FullscreenElementStack::from(&document())->webkitCancelFullScreen();
+        FullscreenElementStack::from(document()).requestFullScreenForElement(this, 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
 }
 
 void HTMLMediaElement::didBecomeFullscreenElement()
@@ -3473,7 +3181,7 @@
     if (hasMediaControls())
         mediaControls()->enteredFullscreen();
     if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isVideo())
-        document().renderView()->compositor()->setCompositingLayersNeedRebuild(true);
+        document().renderView()->compositor()->setCompositingLayersNeedRebuild();
 }
 
 void HTMLMediaElement::willStopBeingFullscreenElement()
@@ -3481,7 +3189,7 @@
     if (hasMediaControls())
         mediaControls()->exitedFullscreen();
     if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isVideo())
-        document().renderView()->compositor()->setCompositingLayersNeedRebuild(true);
+        document().renderView()->compositor()->setCompositingLayersNeedRebuild();
 }
 
 blink::WebLayer* HTMLMediaElement::platformLayer() const
@@ -3592,11 +3300,10 @@
     if (hasMediaControls())
         return true;
 
-    RefPtr<MediaControls> mediaControls = MediaControls::create(document());
+    RefPtr<MediaControls> mediaControls = MediaControls::create(*this);
     if (!mediaControls)
         return false;
 
-    mediaControls->setMediaController(m_mediaController ? m_mediaController.get() : static_cast<MediaControllerInterface*>(this));
     mediaControls->reset();
     if (isFullscreen())
         mediaControls->enteredFullscreen();
@@ -3620,6 +3327,7 @@
     if (!hasMediaControls() && !createMediaControls())
         return;
 
+    mediaControls()->reset();
     mediaControls()->show();
 }
 
@@ -3701,9 +3409,6 @@
 
     m_player = MediaPlayer::create(this);
 
-    if (m_emeMode == EmeModeUnprefixed && m_player)
-        m_player->setContentDecryptionModule(contentDecryptionModule());
-
 #if ENABLE(WEB_AUDIO)
     if (m_audioSourceNode) {
         // When creating the player, make sure its AudioSourceProvider knows about the MediaElementAudioSourceNode.
@@ -3750,7 +3455,7 @@
     // attribute is set, changed, or removed, the user agent must run the following steps:
     // 1. Let m [this] be the media element in question.
     // 2. Let m have no current media controller, if it currently has one.
-    setControllerInternal(0);
+    setControllerInternal(nullptr);
 
     // 3. If m's mediagroup attribute is being removed, then abort these steps.
     if (group.isNull() || group.isEmpty())
@@ -3801,9 +3506,6 @@
         UseCounter::count(document(), UseCounter::HTMLMediaElementControllerNotNull);
         m_mediaController->addMediaElement(this);
     }
-
-    if (hasMediaControls())
-        mediaControls()->setMediaController(m_mediaController ? m_mediaController.get() : static_cast<MediaControllerInterface*>(this));
 }
 
 void HTMLMediaElement::updateMediaController()
@@ -3872,6 +3574,7 @@
 {
     if (m_fragmentStartTime != MediaPlayer::invalidTime()) {
         m_sentEndEvent = false;
+        UseCounter::count(document(), UseCounter::HTMLMediaElementSeekToFragmentStart);
         seek(m_fragmentStartTime, IGNORE_EXCEPTION);
     }
 }
@@ -3886,11 +3589,6 @@
     return Anonymous;
 }
 
-void HTMLMediaElement::removeBehaviorsRestrictionsAfterFirstUserGesture()
-{
-    m_restrictions = NoRestrictions;
-}
-
 void HTMLMediaElement::mediaPlayerSetWebLayer(blink::WebLayer* webLayer)
 {
     if (webLayer == m_webLayer)
diff --git a/Source/core/html/HTMLMediaElement.h b/Source/core/html/HTMLMediaElement.h
index 05df584..695bf5f 100644
--- a/Source/core/html/HTMLMediaElement.h
+++ b/Source/core/html/HTMLMediaElement.h
@@ -58,7 +58,6 @@
 class MediaController;
 class MediaControls;
 class MediaError;
-class MediaKeys;
 class HTMLMediaSource;
 class TextTrackList;
 class TimeRanges;
@@ -72,8 +71,7 @@
 // But it can't be until the Chromium WebMediaPlayerClientImpl class is fixed so it
 // no longer depends on typecasting a MediaPlayerClient to an HTMLMediaElement.
 
-class HTMLMediaElement : public HTMLElement, public MediaPlayerClient, public ActiveDOMObject, public MediaControllerInterface
-    , private TextTrackClient
+class HTMLMediaElement : public Supplementable<HTMLMediaElement>, public HTMLElement, public MediaPlayerClient, public ActiveDOMObject, public MediaControllerInterface
 {
 public:
     static blink::WebMimeRegistry::SupportsType supportsType(const ContentType&, const String& keySystem = String());
@@ -81,7 +79,10 @@
     static void setMediaStreamRegistry(URLRegistry*);
     static bool isMediaStreamURL(const String& url);
 
+    // Do not use player().
+    // FIXME: Replace all uses with webMediaPlayer() and remove this API.
     MediaPlayer* player() const { return m_player.get(); }
+    blink::WebMediaPlayer* webMediaPlayer() const { return m_player ? m_player->webMediaPlayer() : 0; }
 
     virtual bool isVideo() const = 0;
     virtual bool hasVideo() const OVERRIDE { return false; }
@@ -149,23 +150,6 @@
     void closeMediaSource();
     void durationChanged(double duration);
 
-    // encrypted media extensions (v0.1b)
-    void webkitGenerateKeyRequest(const String& keySystem, PassRefPtr<Uint8Array> initData, ExceptionState&);
-    void webkitGenerateKeyRequest(const String& keySystem, ExceptionState&);
-    void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, PassRefPtr<Uint8Array> initData, const String& sessionId, ExceptionState&);
-    void webkitAddKey(const String& keySystem, PassRefPtr<Uint8Array> key, ExceptionState&);
-    void webkitCancelKeyRequest(const String& keySystem, const String& sessionId, ExceptionState&);
-
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyadded);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeyerror);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitkeymessage);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(webkitneedkey);
-
-    // encrypted media extensions (WD)
-    MediaKeys* mediaKeys() const { return m_mediaKeys.get(); }
-    void setMediaKeys(MediaKeys*, ExceptionState&);
-    DEFINE_ATTRIBUTE_EVENT_LISTENER(needkey);
-
     // controls
     bool controls() const;
     void setControls(bool);
@@ -186,17 +170,19 @@
     TextTrackList* textTracks();
     CueList currentlyActiveCues() const { return m_currentlyActiveCues; }
 
-    void addTrack(TextTrack*);
-    void removeTrack(TextTrack*);
-    void removeAllInbandTracks();
+    void addTextTrack(TextTrack*);
+    void removeTextTrack(TextTrack*);
     void closeCaptionTracksChanged();
     void notifyMediaPlayerOfTextTrackChanges();
 
-    void didAddTrack(HTMLTrackElement*);
-    void didRemoveTrack(HTMLTrackElement*);
+    // Implements the "forget the media element's media-resource-specific tracks" algorithm in the HTML5 spec.
+    void forgetResourceSpecificTracks();
 
-    virtual void mediaPlayerDidAddTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
-    virtual void mediaPlayerDidRemoveTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
+    void didAddTrackElement(HTMLTrackElement*);
+    void didRemoveTrackElement(HTMLTrackElement*);
+
+    virtual void mediaPlayerDidAddTextTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
+    virtual void mediaPlayerDidRemoveTextTrack(blink::WebInbandTextTrack*) OVERRIDE FINAL;
     // FIXME: Remove this when WebMediaPlayerClientImpl::loadInternal does not depend on it.
     virtual KURL mediaPlayerPosterURL() OVERRIDE { return KURL(); }
 
@@ -204,8 +190,8 @@
         enum GroupKind { CaptionsAndSubtitles, Description, Chapter, Metadata, Other };
 
         TrackGroup(GroupKind kind)
-            : visibleTrack(0)
-            , defaultTrack(0)
+            : visibleTrack(nullptr)
+            , defaultTrack(nullptr)
             , kind(kind)
             , hasSrcLang(false)
         {
@@ -231,13 +217,12 @@
     void updateTextTrackDisplay();
     void textTrackReadyStateChanged(TextTrack*);
 
-    // TextTrackClient
-    virtual void textTrackKindChanged(TextTrack*) OVERRIDE FINAL;
-    virtual void textTrackModeChanged(TextTrack*) OVERRIDE FINAL;
-    virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) OVERRIDE FINAL;
-    virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) OVERRIDE FINAL;
-    virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE FINAL;
-    virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE FINAL;
+    void textTrackKindChanged(TextTrack*);
+    void textTrackModeChanged(TextTrack*);
+    void textTrackAddCues(TextTrack*, const TextTrackCueList*);
+    void textTrackRemoveCues(TextTrack*, const TextTrackCueList*);
+    void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>);
+    void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>);
 
     // EventTarget function.
     // Both Node (via HTMLElement) and ActiveDOMObject define this method, which
@@ -250,7 +235,6 @@
 
     bool isFullscreen() const;
     virtual void enterFullscreen() OVERRIDE FINAL;
-    void exitFullscreen();
 
     virtual bool hasClosedCaptions() const OVERRIDE FINAL;
     virtual bool closedCaptionsVisible() const OVERRIDE FINAL;
@@ -280,6 +264,12 @@
     MediaController* controller() const;
     void setController(PassRefPtr<MediaController>); // Resets the MediaGroup and sets the MediaController.
 
+    void scheduleEvent(PassRefPtr<Event>);
+
+    // Current volume that should be used by the webMediaPlayer(). This method takes muted state
+    // and m_mediaController multipliers into account.
+    double playerVolume() const;
+
 protected:
     HTMLMediaElement(const QualifiedName&, Document&);
     virtual ~HTMLMediaElement();
@@ -295,24 +285,8 @@
     DisplayMode displayMode() const { return m_displayMode; }
     virtual void setDisplayMode(DisplayMode mode) { m_displayMode = mode; }
 
-    virtual bool isMediaElement() const OVERRIDE FINAL { return true; }
-
     void setControllerInternal(PassRefPtr<MediaController>);
 
-    // Restrictions to change default behaviors.
-    enum BehaviorRestrictionFlags {
-        NoRestrictions = 0,
-        RequireUserGestureForPlayRestriction = 1 << 0,
-        RequireUserGestureForFullscreenRestriction = 1 << 1,
-    };
-    typedef unsigned BehaviorRestrictions;
-
-    bool userGestureRequiredForPlay() const { return m_restrictions & RequireUserGestureForPlayRestriction; }
-    bool userGestureRequiredForFullscreen() const { return m_restrictions & RequireUserGestureForFullscreenRestriction; }
-
-    void addBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions |= restriction; }
-    void removeBehaviorRestriction(BehaviorRestrictions restriction) { m_restrictions &= ~restriction; }
-
     bool ignoreTrackDisplayUpdateRequests() const { return m_ignoreTrackDisplayUpdate > 0; }
     void beginIgnoringTrackDisplayUpdateRequests();
     void endIgnoringTrackDisplayUpdateRequests();
@@ -354,11 +328,6 @@
     virtual void mediaPlayerRepaint() OVERRIDE FINAL;
     virtual void mediaPlayerSizeChanged() OVERRIDE FINAL;
 
-    virtual void mediaPlayerKeyAdded(const String& keySystem, const String& sessionId) OVERRIDE FINAL;
-    virtual void mediaPlayerKeyError(const String& keySystem, const String& sessionId, MediaPlayerClient::MediaKeyErrorCode, unsigned short systemCode) OVERRIDE FINAL;
-    virtual void mediaPlayerKeyMessage(const String& keySystem, const String& sessionId, const unsigned char* message, unsigned messageLength, const KURL& defaultURL) OVERRIDE FINAL;
-    virtual bool mediaPlayerKeyNeeded(const String& contentType, const unsigned char* initData, unsigned initDataLength) OVERRIDE FINAL;
-
     virtual CORSMode mediaPlayerCORSMode() const OVERRIDE FINAL;
 
     virtual void mediaPlayerSetWebLayer(blink::WebLayer*) OVERRIDE FINAL;
@@ -378,7 +347,7 @@
     void addPlayedRange(double start, double end);
 
     void scheduleTimeupdateEvent(bool periodicEvent);
-    void scheduleEvent(const AtomicString& eventName);
+    void scheduleEvent(const AtomicString& eventName); // FIXME: Rename to scheduleNamedEvent for clarity.
 
     // loading
     void prepareForLoad();
@@ -439,8 +408,6 @@
 
     void changeNetworkStateFromLoadingToIdle();
 
-    void removeBehaviorsRestrictionsAfterFirstUserGesture();
-
     const AtomicString& mediaGroup() const;
     void setMediaGroup(const AtomicString&);
     void updateMediaController();
@@ -448,19 +415,6 @@
     bool isBlockedOnMediaController() const;
     bool isAutoplaying() const { return m_autoplaying; }
 
-    // Currently we have both EME v0.1b and EME WD implemented in media element.
-    // But we do not want to support both at the same time. The one used first
-    // will be supported. Use |m_emeMode| to track this selection.
-    // FIXME: Remove EmeMode once EME v0.1b support is removed. See crbug.com/249976.
-    enum EmeMode { EmeModeNotSelected, EmeModePrefixed, EmeModeUnprefixed };
-
-    // check (and set if necessary) the encrypted media extensions (EME) mode
-    // (v0.1b or WD). Returns whether the mode is allowed and successfully set.
-    bool setEmeMode(EmeMode, ExceptionState&);
-
-    blink::WebContentDecryptionModule* contentDecryptionModule();
-    void setMediaKeysInternal(MediaKeys*);
-
     Timer<HTMLMediaElement> m_loadTimer;
     Timer<HTMLMediaElement> m_progressEventTimer;
     Timer<HTMLMediaElement> m_playbackProgressTimer;
@@ -500,8 +454,6 @@
     blink::WebLayer* m_webLayer;
     bool m_opaque;
 
-    BehaviorRestrictions m_restrictions;
-
     MediaPlayer::Preload m_preload;
 
     DisplayMode m_displayMode;
@@ -519,6 +471,7 @@
     PendingActionFlags m_pendingActionFlags;
 
     // FIXME: MediaElement has way too many state bits.
+    bool m_userGestureRequiredForPlay : 1;
     bool m_playing : 1;
     bool m_shouldDelayLoadEvent : 1;
     bool m_haveFiredLoadedData : 1;
@@ -566,10 +519,6 @@
 
     friend class TrackDisplayUpdateScope;
 
-    EmeMode m_emeMode;
-
-    RefPtrWillBePersistent<MediaKeys> m_mediaKeys;
-
     static URLRegistry* s_mediaStreamRegistry;
 };
 
@@ -594,10 +543,15 @@
 
 inline bool isHTMLMediaElement(const Node& node)
 {
-    return node.isElementNode() && toElement(node).isMediaElement();
+    return isHTMLAudioElement(node) || isHTMLVideoElement(node);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
+inline bool isHTMLMediaElement(const Node* node)
+{
+    return node && isHTMLMediaElement(*node);
+}
+
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLMediaElement);
 
 } //namespace
 
diff --git a/Source/core/html/HTMLMediaElement.idl b/Source/core/html/HTMLMediaElement.idl
index 977066a..98b899f 100644
--- a/Source/core/html/HTMLMediaElement.idl
+++ b/Source/core/html/HTMLMediaElement.idl
@@ -89,17 +89,4 @@
     // The number of bytes consumed by the media decoder.
     [MeasureAs=PrefixedAudioDecodedByteCount] readonly attribute unsigned long webkitAudioDecodedByteCount;
     [MeasureAs=PrefixedVideoDecodedByteCount] readonly attribute unsigned long webkitVideoDecodedByteCount;
-
-    [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException, MeasureAs=PrefixedMediaGenerateKeyRequest] void webkitGenerateKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, optional Uint8Array initData);
-    [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException, MeasureAs=PrefixedMediaAddKey] void webkitAddKey([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, Uint8Array key, optional Uint8Array initData, [Default=NullString] optional DOMString sessionId);
-    [RuntimeEnabled=PrefixedEncryptedMedia, RaisesException, MeasureAs=PrefixedMediaCancelKeyRequest] void webkitCancelKeyRequest([TreatNullAs=NullString, TreatUndefinedAs=NullString] DOMString keySystem, [Default=NullString] optional DOMString sessionId);
-
-    [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeyadded;
-    [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeyerror;
-    [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitkeymessage;
-    [RuntimeEnabled=PrefixedEncryptedMedia] attribute EventHandler onwebkitneedkey;
-
-    [RuntimeEnabled=EncryptedMedia] readonly attribute MediaKeys mediaKeys;
-    [RuntimeEnabled=EncryptedMedia, RaisesException] void setMediaKeys(MediaKeys mediaKeys);
-    [RuntimeEnabled=EncryptedMedia] attribute EventHandler onneedkey;
 };
diff --git a/Source/core/html/HTMLMetaElement-in.cpp b/Source/core/html/HTMLMetaElement-in.cpp
index f63a6f8..d63713d 100644
--- a/Source/core/html/HTMLMetaElement-in.cpp
+++ b/Source/core/html/HTMLMetaElement-in.cpp
@@ -449,7 +449,7 @@
         return false;
 
     for (Element* current = element; current; current = current->parentElement()) {
-        if (current->hasTagName(HTMLNames::headTag))
+        if (isHTMLHeadElement(*current))
             return true;
     }
     return false;
diff --git a/Source/core/html/HTMLMetaElement.h b/Source/core/html/HTMLMetaElement.h
index c859a33..a80814f 100644
--- a/Source/core/html/HTMLMetaElement.h
+++ b/Source/core/html/HTMLMetaElement.h
@@ -66,8 +66,6 @@
     void processViewportContentAttribute(const String& content, ViewportDescription::Type origin);
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLMetaElement, hasTagName(HTMLNames::metaTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/html/HTMLMeterElement.h b/Source/core/html/HTMLMeterElement.h
index 670ec81..b92860a 100644
--- a/Source/core/html/HTMLMeterElement.h
+++ b/Source/core/html/HTMLMeterElement.h
@@ -80,8 +80,6 @@
     RefPtr<MeterValueElement> m_value;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLMeterElement, hasTagName(HTMLNames::meterTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLNameCollection.cpp b/Source/core/html/HTMLNameCollection.cpp
index 47f681d..48def4b 100644
--- a/Source/core/html/HTMLNameCollection.cpp
+++ b/Source/core/html/HTMLNameCollection.cpp
@@ -34,7 +34,7 @@
 
 using namespace HTMLNames;
 
-HTMLNameCollection::HTMLNameCollection(ContainerNode* document, CollectionType type, const AtomicString& name)
+HTMLNameCollection::HTMLNameCollection(ContainerNode& document, CollectionType type, const AtomicString& name)
     : HTMLCollection(document, type, OverridesItemAfter)
     , m_name(name)
 {
@@ -42,11 +42,10 @@
 
 HTMLNameCollection::~HTMLNameCollection()
 {
-    ASSERT(ownerNode());
-    ASSERT(ownerNode()->isDocumentNode());
+    ASSERT(ownerNode().isDocumentNode());
     ASSERT(type() == WindowNamedItems || type() == DocumentNamedItems);
 
-    ownerNode()->nodeLists()->removeCache(this, type(), m_name);
+    ownerNode().nodeLists()->removeCache(this, type(), m_name);
 }
 
 Element* HTMLNameCollection::virtualItemAfter(Element* previous) const
@@ -55,20 +54,20 @@
 
     Element* current;
     if (!previous)
-        current = ElementTraversal::firstWithin(*ownerNode());
+        current = ElementTraversal::firstWithin(ownerNode());
     else
-        current = ElementTraversal::next(*previous, ownerNode());
+        current = ElementTraversal::next(*previous, &ownerNode());
 
-    for (; current; current = ElementTraversal::next(*current, ownerNode())) {
+    for (; current; current = ElementTraversal::next(*current, &ownerNode())) {
         switch (type()) {
         case WindowNamedItems:
             // find only images, forms, applets, embeds and objects by name,
             // but anything by id
-            if (current->hasTagName(imgTag)
-                || current->hasTagName(formTag)
-                || current->hasTagName(appletTag)
-                || current->hasTagName(embedTag)
-                || current->hasTagName(objectTag)) {
+            if (isHTMLImageElement(*current)
+                || isHTMLFormElement(*current)
+                || isHTMLAppletElement(*current)
+                || isHTMLEmbedElement(*current)
+                || isHTMLObjectElement(*current)) {
                 if (current->getNameAttribute() == m_name)
                     return current;
             }
@@ -79,16 +78,16 @@
             // find images, forms, applets, embeds, objects and iframes by name,
             // applets and object by id, and images by id but only if they have
             // a name attribute (this very strange rule matches IE)
-            if (current->hasTagName(formTag)
-                || current->hasTagName(iframeTag)
-                || (current->hasTagName(embedTag) && toHTMLEmbedElement(current)->isExposed())) {
+            if (isHTMLFormElement(*current)
+                || isHTMLIFrameElement(*current)
+                || (isHTMLEmbedElement(*current) && toHTMLEmbedElement(*current).isExposed())) {
                 if (current->getNameAttribute() == m_name)
                     return current;
-            } else if (current->hasTagName(appletTag)
-                || (current->hasTagName(objectTag) && toHTMLObjectElement(current)->isExposed())) {
+            } else if (isHTMLAppletElement(*current)
+                || (isHTMLObjectElement(*current) && toHTMLObjectElement(*current).isExposed())) {
                 if (current->getNameAttribute() == m_name || current->getIdAttribute() == m_name)
                     return current;
-            } else if (current->hasTagName(imgTag)) {
+            } else if (isHTMLImageElement(*current)) {
                 if (current->getNameAttribute() == m_name || (current->getIdAttribute() == m_name && current->hasName()))
                     return current;
             }
diff --git a/Source/core/html/HTMLNameCollection.h b/Source/core/html/HTMLNameCollection.h
index afb3019..978e770 100644
--- a/Source/core/html/HTMLNameCollection.h
+++ b/Source/core/html/HTMLNameCollection.h
@@ -33,7 +33,7 @@
 
 class HTMLNameCollection FINAL : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLNameCollection> create(ContainerNode* document, CollectionType type, const AtomicString& name)
+    static PassRefPtr<HTMLNameCollection> create(ContainerNode& document, CollectionType type, const AtomicString& name)
     {
         return adoptRef(new HTMLNameCollection(document, type, name));
     }
@@ -41,7 +41,7 @@
     ~HTMLNameCollection();
 
 private:
-    HTMLNameCollection(ContainerNode*, CollectionType, const AtomicString& name);
+    HTMLNameCollection(ContainerNode&, CollectionType, const AtomicString& name);
 
     virtual Element* virtualItemAfter(Element*) const OVERRIDE;
 
diff --git a/Source/core/html/HTMLNoEmbedElement.cpp b/Source/core/html/HTMLNoEmbedElement.cpp
index d9e268c..417c416 100644
--- a/Source/core/html/HTMLNoEmbedElement.cpp
+++ b/Source/core/html/HTMLNoEmbedElement.cpp
@@ -32,7 +32,7 @@
 #include "core/html/HTMLNoEmbedElement.h"
 
 #include "HTMLNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoader.h"
 
 namespace WebCore {
diff --git a/Source/core/html/HTMLNoScriptElement.cpp b/Source/core/html/HTMLNoScriptElement.cpp
index 65f1c1b..f8982db 100644
--- a/Source/core/html/HTMLNoScriptElement.cpp
+++ b/Source/core/html/HTMLNoScriptElement.cpp
@@ -33,7 +33,7 @@
 
 #include "HTMLNames.h"
 #include "bindings/v8/ScriptController.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
diff --git a/Source/core/html/HTMLOListElement.h b/Source/core/html/HTMLOListElement.h
index 0da2e2c..dfd7953 100644
--- a/Source/core/html/HTMLOListElement.h
+++ b/Source/core/html/HTMLOListElement.h
@@ -64,8 +64,6 @@
     bool m_shouldRecalculateItemCount : 1;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLOListElement, hasTagName(HTMLNames::olTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLObjectElement.cpp b/Source/core/html/HTMLObjectElement.cpp
index 2879919..5e0fb91 100644
--- a/Source/core/html/HTMLObjectElement.cpp
+++ b/Source/core/html/HTMLObjectElement.cpp
@@ -145,11 +145,7 @@
 
     // Scan the PARAM children and store their name/value pairs.
     // Get the URL and type from the params if we don't already have them.
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (!child->hasTagName(paramTag))
-            continue;
-
-        HTMLParamElement* p = toHTMLParamElement(child);
+    for (HTMLParamElement* p = Traversal<HTMLParamElement>::firstChild(*this); p; p = Traversal<HTMLParamElement>::nextSibling(*p)) {
         String name = p->name();
         if (name.isEmpty())
             continue;
@@ -183,12 +179,13 @@
 
     // Turn the attributes of the <object> element into arrays, but don't override <param> values.
     if (hasAttributes()) {
-        for (unsigned i = 0; i < attributeCount(); ++i) {
-            const Attribute* attribute = attributeItem(i);
-            const AtomicString& name = attribute->name().localName();
+        unsigned attributeCount = this->attributeCount();
+        for (unsigned i = 0; i < attributeCount; ++i) {
+            const Attribute& attribute = attributeItem(i);
+            const AtomicString& name = attribute.name().localName();
             if (!uniqueParamNames.contains(name.impl())) {
                 paramNames.append(name.string());
-                paramValues.append(attribute->value().string());
+                paramValues.append(attribute.value().string());
             }
         }
     }
@@ -215,8 +212,9 @@
         if (child->isTextNode()) {
             if (!toText(child)->containsOnlyWhitespace())
                 return true;
-        } else if (!child->hasTagName(paramTag))
+        } else if (!isHTMLParamElement(*child)) {
             return true;
+        }
     }
     return false;
 }
@@ -417,11 +415,11 @@
 {
     // http://www.whatwg.org/specs/web-apps/current-work/#exposed
     for (Node* ancestor = parentNode(); ancestor; ancestor = ancestor->parentNode()) {
-        if (ancestor->hasTagName(objectTag) && toHTMLObjectElement(ancestor)->isExposed())
+        if (isHTMLObjectElement(*ancestor) && toHTMLObjectElement(ancestor)->isExposed())
             return false;
     }
-    for (Node* node = firstChild(); node; node = NodeTraversal::next(*node, this)) {
-        if (node->hasTagName(objectTag) || node->hasTagName(embedTag))
+    for (HTMLElement* element = Traversal<HTMLElement>::firstWithin(*this); element; element = Traversal<HTMLElement>::next(*element, this)) {
+        if (isHTMLObjectElement(*element) || isHTMLEmbedElement(*element))
             return false;
     }
     return true;
@@ -432,14 +430,14 @@
     if (MIMETypeRegistry::isJavaAppletMIMEType(getAttribute(typeAttr)))
         return true;
 
-    for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSkippingChildren(*child, this)) {
-        if (child->hasTagName(paramTag)
+    for (HTMLElement* child = Traversal<HTMLElement>::firstWithin(*this); child; child = Traversal<HTMLElement>::nextSkippingChildren(*child, this)) {
+        if (isHTMLParamElement(*child)
                 && equalIgnoringCase(child->getNameAttribute(), "type")
                 && MIMETypeRegistry::isJavaAppletMIMEType(child->getAttribute(valueAttr).string()))
             return true;
-        if (child->hasTagName(objectTag) && toHTMLObjectElement(child)->containsJavaApplet())
+        if (isHTMLObjectElement(*child) && toHTMLObjectElement(*child).containsJavaApplet())
             return true;
-        if (child->hasTagName(appletTag))
+        if (isHTMLAppletElement(*child))
             return true;
     }
 
diff --git a/Source/core/html/HTMLObjectElement.h b/Source/core/html/HTMLObjectElement.h
index 347ed79..1ca9fd8 100644
--- a/Source/core/html/HTMLObjectElement.h
+++ b/Source/core/html/HTMLObjectElement.h
@@ -111,9 +111,13 @@
     bool m_useFallbackContent : 1;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLObjectElement, hasTagName(HTMLNames::objectTag));
+// Intentionally left unimplemented, template specialization needs to be provided for specific
+// return types.
+template<typename T> inline const T& toElement(const FormAssociatedElement&);
+template<typename T> inline const T* toElement(const FormAssociatedElement*);
 
-inline const HTMLObjectElement* toHTMLObjectElement(const FormAssociatedElement* element)
+// Make toHTMLObjectElement() accept a FormAssociatedElement as input instead of a Node.
+template<> inline const HTMLObjectElement* toElement<HTMLObjectElement>(const FormAssociatedElement* element)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!element || !element->isFormControlElement());
     const HTMLObjectElement* objectElement = static_cast<const HTMLObjectElement*>(element);
@@ -123,7 +127,7 @@
     return objectElement;
 }
 
-inline const HTMLObjectElement& toHTMLObjectElement(const FormAssociatedElement& element)
+template<> inline const HTMLObjectElement& toElement<HTMLObjectElement>(const FormAssociatedElement& element)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!element.isFormControlElement());
     const HTMLObjectElement& objectElement = static_cast<const HTMLObjectElement&>(element);
diff --git a/Source/core/html/HTMLOptGroupElement.cpp b/Source/core/html/HTMLOptGroupElement.cpp
index 1f1a413..314e220 100644
--- a/Source/core/html/HTMLOptGroupElement.cpp
+++ b/Source/core/html/HTMLOptGroupElement.cpp
@@ -76,7 +76,7 @@
 void HTMLOptGroupElement::recalcSelectOptions()
 {
     ContainerNode* select = parentNode();
-    while (select && !select->hasTagName(selectTag))
+    while (select && !isHTMLSelectElement(*select))
         select = select->parentNode();
     if (select)
         toHTMLSelectElement(select)->setRecalcListItems();
@@ -84,7 +84,10 @@
 
 void HTMLOptGroupElement::attach(const AttachContext& context)
 {
-    updateNonRenderStyle();
+    if (context.resolvedStyle) {
+        ASSERT(!m_style || m_style == context.resolvedStyle);
+        m_style = context.resolvedStyle;
+    }
     HTMLElement::attach(context);
 }
 
@@ -106,15 +109,10 @@
 
 PassRefPtr<RenderStyle> HTMLOptGroupElement::customStyleForRenderer()
 {
+    updateNonRenderStyle();
     return m_style;
 }
 
-void HTMLOptGroupElement::willRecalcStyle(StyleRecalcChange change)
-{
-    if (!needsAttach() && (needsStyleRecalc() || change >= Inherit))
-        updateNonRenderStyle();
-}
-
 String HTMLOptGroupElement::groupLabelText() const
 {
     String itemText = getAttribute(labelAttr);
@@ -130,7 +128,7 @@
 HTMLSelectElement* HTMLOptGroupElement::ownerSelectElement() const
 {
     ContainerNode* select = parentNode();
-    while (select && !select->hasTagName(selectTag))
+    while (select && !isHTMLSelectElement(*select))
         select = select->parentNode();
 
     if (!select)
diff --git a/Source/core/html/HTMLOptGroupElement.h b/Source/core/html/HTMLOptGroupElement.h
index 841fb5f..749868c 100644
--- a/Source/core/html/HTMLOptGroupElement.h
+++ b/Source/core/html/HTMLOptGroupElement.h
@@ -47,7 +47,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
     virtual void attach(const AttachContext& = AttachContext()) OVERRIDE;
     virtual void detach(const AttachContext& = AttachContext()) OVERRIDE;
-    virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
 
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
 
@@ -63,8 +62,6 @@
     RefPtr<RenderStyle> m_style;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLOptGroupElement, hasTagName(HTMLNames::optgroupTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLOptionElement.cpp b/Source/core/html/HTMLOptionElement.cpp
index 7b5bc1f..c0b02f1 100644
--- a/Source/core/html/HTMLOptionElement.cpp
+++ b/Source/core/html/HTMLOptionElement.cpp
@@ -68,7 +68,7 @@
 
     element->appendChild(text.release(), exceptionState);
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     if (!value.isNull())
         element->setValue(value);
@@ -81,8 +81,15 @@
 
 void HTMLOptionElement::attach(const AttachContext& context)
 {
-    updateNonRenderStyle();
-    HTMLElement::attach(context);
+    AttachContext optionContext(context);
+    if (context.resolvedStyle) {
+        ASSERT(!m_style || m_style == context.resolvedStyle);
+        m_style = context.resolvedStyle;
+    } else {
+        updateNonRenderStyle();
+        optionContext.resolvedStyle = m_style.get();
+    }
+    HTMLElement::attach(optionContext);
 }
 
 void HTMLOptionElement::detach(const AttachContext& context)
@@ -158,7 +165,7 @@
     const Vector<HTMLElement*>& items = selectElement->listItems();
     size_t length = items.size();
     for (size_t i = 0; i < length; ++i) {
-        if (!items[i]->hasTagName(optionTag))
+        if (!isHTMLOptionElement(*items[i]))
             continue;
         if (items[i] == this)
             return optionIndex;
@@ -253,7 +260,7 @@
 HTMLDataListElement* HTMLOptionElement::ownerDataListElement() const
 {
     for (ContainerNode* parent = parentNode(); parent ; parent = parent->parentNode()) {
-        if (parent->hasTagName(datalistTag))
+        if (isHTMLDataListElement(*parent))
             return toHTMLDataListElement(parent);
     }
     return 0;
@@ -262,7 +269,7 @@
 HTMLSelectElement* HTMLOptionElement::ownerSelectElement() const
 {
     ContainerNode* select = parentNode();
-    while (select && !select->hasTagName(selectTag))
+    while (select && !isHTMLSelectElement(*select))
         select = select->parentNode();
 
     if (!select)
@@ -296,19 +303,16 @@
 
 PassRefPtr<RenderStyle> HTMLOptionElement::customStyleForRenderer()
 {
+    updateNonRenderStyle();
     return m_style;
 }
 
-void HTMLOptionElement::willRecalcStyle(StyleRecalcChange change)
+void HTMLOptionElement::didRecalcStyle(StyleRecalcChange change)
 {
-    if (!needsAttach() && (needsStyleRecalc() || change >= Inherit))
-        updateNonRenderStyle();
-}
+    if (change == NoChange)
+        return;
 
-void HTMLOptionElement::didRecalcStyle(StyleRecalcChange)
-{
-    // FIXME: This is nasty, we ask our owner select to repaint even if the new
-    // style is exactly the same.
+    // FIXME: We ask our owner select to repaint regardless of which property changed.
     if (HTMLSelectElement* select = ownerSelectElement()) {
         if (RenderObject* renderer = select->renderer())
             renderer->repaint();
@@ -318,7 +322,7 @@
 String HTMLOptionElement::textIndentedToRespectGroupLabel() const
 {
     ContainerNode* parent = parentNode();
-    if (parent && parent->hasTagName(optgroupTag))
+    if (parent && isHTMLOptGroupElement(*parent))
         return "    " + text();
     return text();
 }
@@ -328,7 +332,7 @@
     if (ownElementDisabled())
         return true;
     if (Element* parent = parentElement())
-        return parent->hasTagName(optgroupTag) && parent->isDisabledFormControl();
+        return isHTMLOptGroupElement(*parent) && parent->isDisabledFormControl();
     return false;
 }
 
diff --git a/Source/core/html/HTMLOptionElement.h b/Source/core/html/HTMLOptionElement.h
index 6dc4c9d..ba2c323 100644
--- a/Source/core/html/HTMLOptionElement.h
+++ b/Source/core/html/HTMLOptionElement.h
@@ -85,9 +85,7 @@
     void updateNonRenderStyle();
     virtual RenderStyle* nonRendererStyle() const OVERRIDE;
     virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE;
-
     virtual void didRecalcStyle(StyleRecalcChange) OVERRIDE;
-    virtual void willRecalcStyle(StyleRecalcChange) OVERRIDE;
 
     String collectOptionInnerText() const;
 
@@ -96,8 +94,6 @@
     RefPtr<RenderStyle> m_style;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLOptionElement, hasTagName(HTMLNames::optionTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/html/HTMLOptionsCollection.cpp b/Source/core/html/HTMLOptionsCollection.cpp
index f99e5f4..d1abb1d 100644
--- a/Source/core/html/HTMLOptionsCollection.cpp
+++ b/Source/core/html/HTMLOptionsCollection.cpp
@@ -31,10 +31,10 @@
 
 namespace WebCore {
 
-HTMLOptionsCollection::HTMLOptionsCollection(ContainerNode* select)
+HTMLOptionsCollection::HTMLOptionsCollection(ContainerNode& select)
     : HTMLCollection(select, SelectOptions, DoesNotOverrideItemAfter)
 {
-    ASSERT(select->hasTagName(HTMLNames::selectTag));
+    ASSERT(isHTMLSelectElement(select));
     ScriptWrappable::init(this);
 }
 
@@ -64,7 +64,7 @@
     }
 }
 
-PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(ContainerNode* select, CollectionType)
+PassRefPtr<HTMLOptionsCollection> HTMLOptionsCollection::create(ContainerNode& select, CollectionType)
 {
     return adoptRef(new HTMLOptionsCollection(select));
 }
@@ -88,19 +88,19 @@
         return;
     }
 
-    HTMLSelectElement* select = toHTMLSelectElement(ownerNode());
+    HTMLSelectElement& select = toHTMLSelectElement(ownerNode());
 
     if (index == -1 || unsigned(index) >= length())
-        select->add(newOption, 0, exceptionState);
+        select.add(newOption, 0, exceptionState);
     else
-        select->add(newOption, toHTMLOptionElement(item(index)), exceptionState);
+        select.add(newOption, toHTMLOptionElement(item(index)), exceptionState);
 
     ASSERT(!exceptionState.hadException());
 }
 
 void HTMLOptionsCollection::remove(int index)
 {
-    toHTMLSelectElement(ownerNode())->remove(index);
+    toHTMLSelectElement(ownerNode()).remove(index);
 }
 
 void HTMLOptionsCollection::remove(HTMLOptionElement* option)
@@ -110,17 +110,17 @@
 
 int HTMLOptionsCollection::selectedIndex() const
 {
-    return toHTMLSelectElement(ownerNode())->selectedIndex();
+    return toHTMLSelectElement(ownerNode()).selectedIndex();
 }
 
 void HTMLOptionsCollection::setSelectedIndex(int index)
 {
-    toHTMLSelectElement(ownerNode())->setSelectedIndex(index);
+    toHTMLSelectElement(ownerNode()).setSelectedIndex(index);
 }
 
 void HTMLOptionsCollection::setLength(unsigned length, ExceptionState& exceptionState)
 {
-    toHTMLSelectElement(ownerNode())->setLength(length, exceptionState);
+    toHTMLSelectElement(ownerNode()).setLength(length, exceptionState);
 }
 
 void HTMLOptionsCollection::namedGetter(const AtomicString& name, bool& returnValue0Enabled, RefPtr<NodeList>& returnValue0, bool& returnValue1Enabled, RefPtr<Element>& returnValue1)
@@ -144,12 +144,12 @@
 
 bool HTMLOptionsCollection::anonymousIndexedSetter(unsigned index, PassRefPtr<HTMLOptionElement> value, ExceptionState& exceptionState)
 {
-    HTMLSelectElement* base = toHTMLSelectElement(ownerNode());
+    HTMLSelectElement& base = toHTMLSelectElement(ownerNode());
     if (!value) { // undefined or null
-        base->remove(index);
+        base.remove(index);
         return true;
     }
-    base->setOption(index, value.get(), exceptionState);
+    base.setOption(index, value.get(), exceptionState);
     return true;
 }
 
diff --git a/Source/core/html/HTMLOptionsCollection.h b/Source/core/html/HTMLOptionsCollection.h
index 55a591c..6927922 100644
--- a/Source/core/html/HTMLOptionsCollection.h
+++ b/Source/core/html/HTMLOptionsCollection.h
@@ -34,7 +34,7 @@
 
 class HTMLOptionsCollection FINAL : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLOptionsCollection> create(ContainerNode*, CollectionType);
+    static PassRefPtr<HTMLOptionsCollection> create(ContainerNode&, CollectionType);
 
     void add(PassRefPtr<HTMLOptionElement>, ExceptionState&);
     void add(PassRefPtr<HTMLOptionElement>, int index, ExceptionState&);
@@ -49,7 +49,7 @@
     bool anonymousIndexedSetter(unsigned, PassRefPtr<HTMLOptionElement>, ExceptionState&);
 
 private:
-    explicit HTMLOptionsCollection(ContainerNode*);
+    explicit HTMLOptionsCollection(ContainerNode&);
 
     virtual void supportedPropertyNames(Vector<String>& names) OVERRIDE;
 };
diff --git a/Source/core/html/HTMLOutputElement.cpp b/Source/core/html/HTMLOutputElement.cpp
index 6751780..4223ba4 100644
--- a/Source/core/html/HTMLOutputElement.cpp
+++ b/Source/core/html/HTMLOutputElement.cpp
@@ -39,7 +39,6 @@
 inline HTMLOutputElement::HTMLOutputElement(Document& document, HTMLFormElement* form)
     : HTMLFormControlElement(HTMLNames::outputTag, document, form)
     , m_isDefaultValueMode(true)
-    , m_isSetTextContentInProgress(false)
     , m_defaultValue("")
     , m_tokens(DOMSettableTokenList::create())
 {
@@ -84,11 +83,6 @@
 {
     HTMLFormControlElement::childrenChanged(createdByParser, beforeChange, afterChange, childCountDelta);
 
-    if (createdByParser || m_isSetTextContentInProgress) {
-        m_isSetTextContentInProgress = false;
-        return;
-    }
-
     if (m_isDefaultValueMode)
         m_defaultValue = textContent();
 }
@@ -98,10 +92,10 @@
     // The reset algorithm for output elements is to set the element's
     // value mode flag to "default" and then to set the element's textContent
     // attribute to the default value.
-    m_isDefaultValueMode = true;
     if (m_defaultValue == value())
         return;
-    setTextContentInternal(m_defaultValue);
+    setTextContent(m_defaultValue);
+    m_isDefaultValueMode = true;
 }
 
 String HTMLOutputElement::value() const
@@ -115,7 +109,7 @@
     m_isDefaultValueMode = false;
     if (value == this->value())
         return;
-    setTextContentInternal(value);
+    setTextContent(value);
 }
 
 String HTMLOutputElement::defaultValue() const
@@ -131,14 +125,7 @@
     // The spec requires the value attribute set to the default value
     // when the element's value mode flag to "default".
     if (m_isDefaultValueMode)
-        setTextContentInternal(value);
-}
-
-void HTMLOutputElement::setTextContentInternal(const String& value)
-{
-    ASSERT(!m_isSetTextContentInProgress);
-    m_isSetTextContentInProgress = true;
-    setTextContent(value);
+        setTextContent(value);
 }
 
 } // namespace
diff --git a/Source/core/html/HTMLOutputElement.h b/Source/core/html/HTMLOutputElement.h
index 92ad652..ba77d11 100644
--- a/Source/core/html/HTMLOutputElement.h
+++ b/Source/core/html/HTMLOutputElement.h
@@ -62,10 +62,7 @@
     virtual void childrenChanged(bool createdByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE;
     virtual void resetImpl() OVERRIDE;
 
-    void setTextContentInternal(const String&);
-
     bool m_isDefaultValueMode;
-    bool m_isSetTextContentInProgress;
     String m_defaultValue;
     RefPtr<DOMSettableTokenList> m_tokens;
 };
diff --git a/Source/core/html/HTMLParamElement.h b/Source/core/html/HTMLParamElement.h
index e7a709c..b34e4ed 100644
--- a/Source/core/html/HTMLParamElement.h
+++ b/Source/core/html/HTMLParamElement.h
@@ -42,8 +42,6 @@
     virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLParamElement, hasTagName(HTMLNames::paramTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/html/HTMLPlugInElement.cpp b/Source/core/html/HTMLPlugInElement.cpp
index b3eb176..f2d84b3 100644
--- a/Source/core/html/HTMLPlugInElement.cpp
+++ b/Source/core/html/HTMLPlugInElement.cpp
@@ -32,11 +32,11 @@
 #include "core/dom/PostAttachCallbacks.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/events/Event.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
+#include "core/html/HTMLContentElement.h"
 #include "core/html/HTMLImageLoader.h"
 #include "core/html/PluginDocument.h"
-#include "core/html/shadow/HTMLContentElement.h"
 #include "core/loader/FrameLoaderClient.h"
 #include "core/page/EventHandler.h"
 #include "core/page/Page.h"
@@ -157,8 +157,8 @@
     resetInstance();
 
     if (m_isCapturingMouseEvents) {
-        if (Frame* frame = document().frame())
-            frame->eventHandler().setCapturingMouseEventsNode(0);
+        if (LocalFrame* frame = document().frame())
+            frame->eventHandler().setCapturingMouseEventsNode(nullptr);
         m_isCapturingMouseEvents = false;
     }
 
@@ -212,7 +212,7 @@
 
 SharedPersistent<v8::Object>* HTMLPlugInElement::pluginWrapper()
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return 0;
 
@@ -279,18 +279,16 @@
     }
 }
 
-void HTMLPlugInElement::defaultEventHandler(Event* event)
+void HTMLPlugInElement::handleLocalEvents(Event* event)
 {
+    HTMLFrameOwnerElement::handleLocalEvents(event);
+
     // Firefox seems to use a fake event listener to dispatch events to plug-in
     // (tested with mouse events only). This is observable via different order
     // of events - in Firefox, event listeners specified in HTML attributes
     // fires first, then an event gets dispatched to plug-in, and only then
     // other event listeners fire. Hopefully, this difference does not matter in
     // practice.
-
-    // FIXME: Mouse down and scroll events are passed down to plug-in via custom
-    // code in EventHandler; these code paths should be united.
-
     RenderObject* r = renderer();
     if (!r || !r->isWidget())
         return;
@@ -304,9 +302,6 @@
     if (!widget)
         return;
     widget->handleEvent(event);
-    if (event->defaultHandled())
-        return;
-    HTMLFrameOwnerElement::defaultEventHandler(event);
 }
 
 RenderWidget* HTMLPlugInElement::renderWidgetForJSBindings() const
@@ -358,7 +353,7 @@
     if (m_serviceType.isEmpty() && protocolIs(m_url, "data"))
         m_serviceType = mimeTypeFromDataURL(m_url);
 
-    if (Frame* frame = document().frame()) {
+    if (LocalFrame* frame = document().frame()) {
         KURL completedURL = document().completeURL(m_url);
         return frame->loader().client()->objectContentType(completedURL, m_serviceType, shouldPreferPlugInsForImages()) == ObjectContentImage;
     }
@@ -433,7 +428,7 @@
 
 bool HTMLPlugInElement::loadPlugin(const KURL& url, const String& mimeType, const Vector<String>& paramNames, const Vector<String>& paramValues, bool useFallback)
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
 
     if (!frame->loader().allowPlugins(AboutToInstantiatePlugin))
         return false;
@@ -447,9 +442,8 @@
     WTF_LOG(Plugins, "   Loaded URL: %s", url.string().utf8().data());
     m_loadedUrl = url;
 
-    IntSize contentSize = roundedIntSize(LayoutSize(renderer->contentWidth(), renderer->contentHeight()));
     bool loadManually = document().isPluginDocument() && !document().containsPlugins() && toPluginDocument(document()).shouldLoadPluginManually();
-    RefPtr<Widget> widget = frame->loader().client()->createPlugin(contentSize, this, url, paramNames, paramValues, mimeType, loadManually);
+    RefPtr<Widget> widget = frame->loader().client()->createPlugin(this, url, paramNames, paramValues, mimeType, loadManually, FrameLoaderClient::FailOnDetachedPlugin);
 
     if (!widget) {
         if (!renderer->showsUnavailablePluginIndicator())
@@ -493,7 +487,7 @@
 
 bool HTMLPlugInElement::pluginIsLoadable(const KURL& url, const String& mimeType)
 {
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     Settings* settings = frame->settings();
     if (!settings)
         return false;
diff --git a/Source/core/html/HTMLPlugInElement.h b/Source/core/html/HTMLPlugInElement.h
index c9b8fc9..74e7a0c 100644
--- a/Source/core/html/HTMLPlugInElement.h
+++ b/Source/core/html/HTMLPlugInElement.h
@@ -94,7 +94,7 @@
     // Node functions:
     virtual bool canContainRangeEndPoint() const OVERRIDE { return false; }
     virtual bool willRespondToMouseClickEvents() OVERRIDE FINAL;
-    virtual void defaultEventHandler(Event*) OVERRIDE FINAL;
+    virtual void handleLocalEvents(Event*) OVERRIDE FINAL;
     virtual void attach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
     virtual void detach(const AttachContext& = AttachContext()) OVERRIDE FINAL;
     virtual void finishParsingChildren() OVERRIDE FINAL;
@@ -138,7 +138,7 @@
     DisplayState m_displayState;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLPlugInElement, isPluginElement());
+DEFINE_ELEMENT_TYPE_CASTS(HTMLPlugInElement, isPluginElement());
 
 } // namespace WebCore
 
diff --git a/Source/core/html/HTMLProgressElement.h b/Source/core/html/HTMLProgressElement.h
index 4f33d24..b70f26e 100644
--- a/Source/core/html/HTMLProgressElement.h
+++ b/Source/core/html/HTMLProgressElement.h
@@ -68,8 +68,6 @@
     ProgressValueElement* m_value;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLProgressElement, hasTagName(HTMLNames::progressTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLScriptElement.h b/Source/core/html/HTMLScriptElement.h
index f02d51f..adc0362 100644
--- a/Source/core/html/HTMLScriptElement.h
+++ b/Source/core/html/HTMLScriptElement.h
@@ -72,8 +72,6 @@
     OwnPtr<ScriptLoader> m_loader;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLScriptElement, hasTagName(HTMLNames::scriptTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLSelectElement.cpp b/Source/core/html/HTMLSelectElement.cpp
index 1f74f02..535b803 100644
--- a/Source/core/html/HTMLSelectElement.cpp
+++ b/Source/core/html/HTMLSelectElement.cpp
@@ -39,12 +39,12 @@
 #include "core/events/KeyboardEvent.h"
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/FormDataList.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLOptionElement.h"
 #include "core/html/forms/FormController.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/page/SpatialNavigation.h"
 #include "core/rendering/RenderListBox.h"
 #include "core/rendering/RenderMenuList.h"
@@ -113,7 +113,7 @@
     if (optionIndex == selectedIndex())
         return;
 
-    selectOption(optionIndex, DeselectOtherOptions | (fireOnChangeNow ? DispatchChangeEvent : 0) | UserDriven);
+    selectOption(optionIndex, DeselectOtherOptions | (fireOnChangeNow ? DispatchInputAndChangeEvent : 0) | UserDriven);
 }
 
 bool HTMLSelectElement::hasPlaceholderLabelOption() const
@@ -219,14 +219,6 @@
     listItems()[listIndex]->remove(IGNORE_EXCEPTION);
 }
 
-void HTMLSelectElement::remove(HTMLOptionElement* option)
-{
-    if (option->ownerSelectElement() != this)
-        return;
-
-    option->remove(IGNORE_EXCEPTION);
-}
-
 String HTMLSelectElement::value() const
 {
     const Vector<HTMLElement*>& items = listItems();
@@ -282,7 +274,7 @@
         AtomicString attrSize = AtomicString::number(size);
         if (attrSize != value) {
             // FIXME: This is horribly factored.
-            if (Attribute* sizeAttribute = ensureUniqueElementData()->getAttributeItem(sizeAttr))
+            if (Attribute* sizeAttribute = ensureUniqueElementData().getAttributeItem(sizeAttr))
                 sizeAttribute->setValue(attrSize);
         }
         size = max(size, 1);
@@ -302,6 +294,15 @@
     else if (name == accesskeyAttr) {
         // FIXME: ignore for the moment.
         //
+    } else if (name == disabledAttr) {
+        HTMLFormControlElementWithState::parseAttribute(name, value);
+        if (renderer() && renderer()->isMenuList()) {
+            if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
+                if (menuList->popupIsVisible())
+                    menuList->hidePopup();
+            }
+        }
+
     } else
         HTMLFormControlElementWithState::parseAttribute(name, value);
 }
@@ -400,7 +401,7 @@
     if (index > maxSelectItems - 1)
         index = maxSelectItems - 1;
     int diff = index - length();
-    RefPtr<HTMLElement> before = 0;
+    RefPtr<HTMLElement> before = nullptr;
     // Out of array bounds? First insert empty dummies.
     if (diff > 0) {
         setLength(index, exceptionState);
@@ -472,7 +473,7 @@
     int size = listItems.size();
     for (listIndex += direction; listIndex >= 0 && listIndex < size; listIndex += direction) {
         --skip;
-        if (!listItems[listIndex]->isDisabledFormControl() && listItems[listIndex]->hasTagName(optionTag)) {
+        if (!listItems[listIndex]->isDisabledFormControl() && isHTMLOptionElement(*listItems[listIndex])) {
             lastGoodIndex = listIndex;
             if (skip <= 0)
                 break;
@@ -554,7 +555,7 @@
     const Vector<HTMLElement*>& items = listItems();
     for (unsigned i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        m_lastOnChangeSelection.append(element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected());
+        m_lastOnChangeSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected());
     }
 }
 
@@ -569,7 +570,7 @@
     const Vector<HTMLElement*>& items = listItems();
     for (unsigned i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        m_cachedStateForActiveSelection.append(element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected());
+        m_cachedStateForActiveSelection.append(isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected());
     }
 }
 
@@ -589,7 +590,7 @@
     const Vector<HTMLElement*>& items = listItems();
     for (unsigned i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisabledFormControl())
+        if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl())
             continue;
 
         if (i >= start && i <= end)
@@ -623,17 +624,20 @@
     bool fireOnChange = false;
     for (unsigned i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        bool selected = element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected();
+        bool selected = isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected();
         if (selected != m_lastOnChangeSelection[i])
             fireOnChange = true;
         m_lastOnChangeSelection[i] = selected;
     }
 
-    if (fireOnChange)
+    if (fireOnChange) {
+        RefPtr<HTMLSelectElement> protector(this);
+        dispatchInputEvent();
         dispatchFormControlChangeEvent();
+    }
 }
 
-void HTMLSelectElement::dispatchChangeEventForMenuList()
+void HTMLSelectElement::dispatchInputAndChangeEventForMenuList()
 {
     ASSERT(usesMenuList());
 
@@ -641,6 +645,8 @@
     if (m_lastOnChangeIndex != selected && m_isProcessingUserDrivenChange) {
         m_lastOnChangeIndex = selected;
         m_isProcessingUserDrivenChange = false;
+        RefPtr<HTMLSelectElement> protector(this);
+        dispatchInputEvent();
         dispatchFormControlChangeEvent();
     }
 }
@@ -726,7 +732,7 @@
         // optgroup tags may not nest. However, both FireFox and IE will
         // flatten the tree automatically, so we follow suit.
         // (http://www.w3.org/TR/html401/interact/forms.html#h-17.6)
-        if (current.hasTagName(optgroupTag)) {
+        if (isHTMLOptGroupElement(current)) {
             m_listItems.append(&current);
             if (Element* nextElement = ElementTraversal::firstWithin(current)) {
                 currentElement = nextElement;
@@ -734,7 +740,7 @@
             }
         }
 
-        if (current.hasTagName(optionTag)) {
+        if (isHTMLOptionElement(current)) {
             m_listItems.append(&current);
 
             if (updateSelectedStates && !m_multiple) {
@@ -752,7 +758,7 @@
             }
         }
 
-        if (current.hasTagName(hrTag))
+        if (isHTMLHRElement(current))
             m_listItems.append(&current);
 
         // In conforming HTML code, only <optgroup> and <option> will be found
@@ -776,8 +782,8 @@
     const Vector<HTMLElement*>& items = listItems();
     for (size_t i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        if (element->hasTagName(optionTag)) {
-            if (toHTMLOptionElement(element)->selected())
+        if (isHTMLOptionElement(*element)) {
+            if (toHTMLOptionElement(*element).selected())
                 return index;
             ++index;
         }
@@ -812,12 +818,12 @@
     HTMLElement* element = 0;
     if (listIndex >= 0) {
         element = items[listIndex];
-        if (element->hasTagName(optionTag)) {
+        if (isHTMLOptionElement(*element)) {
             if (m_activeSelectionAnchorIndex < 0 || shouldDeselect)
                 setActiveSelectionAnchorIndex(listIndex);
             if (m_activeSelectionEndIndex < 0 || shouldDeselect)
                 setActiveSelectionEndIndex(listIndex);
-            toHTMLOptionElement(element)->setSelectedState(true);
+            toHTMLOptionElement(*element).setSelectedState(true);
         }
     }
 
@@ -832,8 +838,8 @@
 
     if (usesMenuList()) {
         m_isProcessingUserDrivenChange = flags & UserDriven;
-        if (flags & DispatchChangeEvent)
-            dispatchChangeEventForMenuList();
+        if (flags & DispatchInputAndChangeEvent)
+            dispatchInputAndChangeEventForMenuList();
         if (RenderObject* renderer = this->renderer()) {
             if (usesMenuList())
                 toRenderMenuList(renderer)->didSetSelectedIndex(listIndex);
@@ -855,7 +861,7 @@
 
     int optionIndex2 = -1;
     for (int listIndex = 0; listIndex < listSize; ++listIndex) {
-        if (items[listIndex]->hasTagName(optionTag)) {
+        if (isHTMLOptionElement(*items[listIndex])) {
             ++optionIndex2;
             if (optionIndex2 == optionIndex)
                 return listIndex;
@@ -868,13 +874,13 @@
 int HTMLSelectElement::listToOptionIndex(int listIndex) const
 {
     const Vector<HTMLElement*>& items = listItems();
-    if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !items[listIndex]->hasTagName(optionTag))
+    if (listIndex < 0 || listIndex >= static_cast<int>(items.size()) || !isHTMLOptionElement(*items[listIndex]))
         return -1;
 
     // Actual index of option not counting OPTGROUP entries that may be in list.
     int optionIndex = 0;
     for (int i = 0; i < listIndex; ++i) {
-        if (items[i]->hasTagName(optionTag))
+        if (isHTMLOptionElement(*items[i]))
             ++optionIndex;
     }
 
@@ -896,7 +902,7 @@
     // change events for list boxes whenever the selection change is actually made.
     // This matches other browsers' behavior.
     if (usesMenuList())
-        dispatchChangeEventForMenuList();
+        dispatchInputAndChangeEventForMenuList();
     HTMLFormControlElementWithState::dispatchBlurEvent(newFocusedElement);
 }
 
@@ -905,7 +911,7 @@
     const Vector<HTMLElement*>& items = listItems();
     for (unsigned i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        if (element != excludeElement && element->hasTagName(optionTag))
+        if (element != excludeElement && isHTMLOptionElement(*element))
             toHTMLOptionElement(element)->setSelectedState(false);
     }
 }
@@ -916,7 +922,7 @@
     size_t length = items.size();
     FormControlState state;
     for (unsigned i = 0; i < length; ++i) {
-        if (!items[i]->hasTagName(optionTag))
+        if (!isHTMLOptionElement(*items[i]))
             continue;
         HTMLOptionElement* option = toHTMLOptionElement(items[i]);
         if (!option->selected())
@@ -998,8 +1004,8 @@
 
     for (unsigned i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected() && !toHTMLOptionElement(element)->isDisabledFormControl()) {
-            list.appendData(name, toHTMLOptionElement(element)->value());
+        if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selected() && !toHTMLOptionElement(*element).isDisabledFormControl()) {
+            list.appendData(name, toHTMLOptionElement(*element).value());
             successful = true;
         }
     }
@@ -1018,7 +1024,7 @@
     const Vector<HTMLElement*>& items = listItems();
     for (unsigned i = 0; i < items.size(); ++i) {
         HTMLElement* element = items[i];
-        if (!element->hasTagName(optionTag))
+        if (!isHTMLOptionElement(*element))
             continue;
 
         if (items[i]->fastHasAttribute(selectedAttr)) {
@@ -1053,7 +1059,7 @@
             // Calling focus() may cause us to lose our renderer. Return true so
             // that our caller doesn't process the event further, but don't set
             // the event as handled.
-            if (!renderer())
+            if (!renderer() || isDisabledFormControl())
                 return true;
 
             // Save the selection so it can be compared to the new selection
@@ -1112,7 +1118,7 @@
             handled = false;
 
         if (handled && static_cast<size_t>(listIndex) < listItems.size())
-            selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
+            selectOption(listToOptionIndex(listIndex), DeselectOtherOptions | DispatchInputAndChangeEvent | UserDriven);
 
         if (handled)
             event->setDefaultHandled();
@@ -1140,7 +1146,7 @@
 
                 // Calling focus() may remove the renderer or change the
                 // renderer type.
-                if (!renderer() || !renderer()->isMenuList())
+                if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
                     return;
 
                 // Save the selection so it can be compared to the new selection
@@ -1158,7 +1164,7 @@
 
                 // Calling focus() may remove the renderer or change the
                 // renderer type.
-                if (!renderer() || !renderer()->isMenuList())
+                if (!renderer() || !renderer()->isMenuList() || isDisabledFormControl())
                     return;
 
                 // Save the selection so it can be compared to the new selection
@@ -1172,7 +1178,7 @@
             } else if (keyCode == '\r') {
                 if (form())
                     form()->submitImplicitly(event, false);
-                dispatchChangeEventForMenuList();
+                dispatchInputAndChangeEventForMenuList();
                 handled = true;
             }
         }
@@ -1183,7 +1189,7 @@
 
     if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
         focus();
-        if (renderer() && renderer()->isMenuList()) {
+        if (renderer() && renderer()->isMenuList() && !isDisabledFormControl()) {
             if (RenderMenuList* menuList = toRenderMenuList(renderer())) {
                 if (menuList->popupIsVisible())
                     menuList->hidePopup();
@@ -1223,13 +1229,14 @@
     bool multiSelect = m_multiple && multi && !shift;
 
     HTMLElement* clickedElement = listItems()[listIndex];
-    if (clickedElement->hasTagName(optionTag)) {
+    ASSERT(clickedElement);
+    if (isHTMLOptionElement(*clickedElement)) {
         // Keep track of whether an active selection (like during drag
         // selection), should select or deselect.
-        if (toHTMLOptionElement(clickedElement)->selected() && multiSelect)
+        if (toHTMLOptionElement(*clickedElement).selected() && multiSelect)
             m_activeSelectionState = false;
         if (!m_activeSelectionState)
-            toHTMLOptionElement(clickedElement)->setSelectedState(false);
+            toHTMLOptionElement(*clickedElement).setSelectedState(false);
     }
 
     // If we're not in any special multiple selection mode, then deselect all
@@ -1244,8 +1251,8 @@
         setActiveSelectionAnchorIndex(selectedIndex());
 
     // Set the selection state of the clicked option.
-    if (clickedElement->hasTagName(optionTag) && !toHTMLOptionElement(clickedElement)->isDisabledFormControl())
-        toHTMLOptionElement(clickedElement)->setSelectedState(true);
+    if (isHTMLOptionElement(*clickedElement) && !toHTMLOptionElement(*clickedElement).isDisabledFormControl())
+        toHTMLOptionElement(*clickedElement).setSelectedState(true);
 
     // If there was no selectedIndex() for the previous initialization, or If
     // we're doing a single selection, or a multiple selection (using cmd or
@@ -1280,7 +1287,7 @@
                 updateSelectedState(listIndex, mouseEvent->ctrlKey(), mouseEvent->shiftKey());
 #endif
             }
-            if (Frame* frame = document().frame())
+            if (LocalFrame* frame = document().frame())
                 frame->eventHandler().setMouseDownMayStartAutoscroll();
 
             event->setDefaultHandled();
@@ -1454,7 +1461,7 @@
     const Vector<HTMLElement*>& items = listItems();
     for (size_t i = items.size(); i;) {
         HTMLElement* element = items[--i];
-        if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected())
+        if (isHTMLOptionElement(*element) && toHTMLOptionElement(element)->selected())
             return i;
     }
     return -1;
@@ -1475,7 +1482,7 @@
     const Vector<HTMLElement*>& items = listItems();
 
     HTMLElement* element = items[index];
-    if (!element->hasTagName(optionTag) || toHTMLOptionElement(element)->isDisabledFormControl())
+    if (!isHTMLOptionElement(*element) || toHTMLOptionElement(element)->isDisabledFormControl())
         return String();
     return toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
 }
@@ -1485,7 +1492,7 @@
     int index = m_typeAhead.handleEvent(event, TypeAhead::MatchPrefix | TypeAhead::CycleFirstChar);
     if (index < 0)
         return;
-    selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchChangeEvent | UserDriven);
+    selectOption(listToOptionIndex(index), DeselectOtherOptions | DispatchInputAndChangeEvent | UserDriven);
     if (!usesMenuList())
         listBoxOnChange();
 }
@@ -1511,16 +1518,16 @@
     int listIndex = optionToListIndex(index);
     if (listIndex >= 0) {
         HTMLElement* element = items[listIndex];
-        if (element->hasTagName(optionTag)) {
-            if (toHTMLOptionElement(element)->selected())
-                toHTMLOptionElement(element)->setSelectedState(false);
+        if (isHTMLOptionElement(*element)) {
+            if (toHTMLOptionElement(*element).selected())
+                toHTMLOptionElement(*element).setSelectedState(false);
             else
-                selectOption(index, DispatchChangeEvent | UserDriven);
+                selectOption(index, DispatchInputAndChangeEvent | UserDriven);
         }
     }
 
     if (usesMenuList())
-        dispatchChangeEventForMenuList();
+        dispatchInputAndChangeEventForMenuList();
     else
         listBoxOnChange();
 
@@ -1533,7 +1540,7 @@
 
     const Vector<HTMLElement*>& items = listItems();
     for (unsigned i = 0; i < items.size(); ++i) {
-        if (items[i]->hasTagName(optionTag))
+        if (isHTMLOptionElement(*items[i]))
             ++options;
     }
 
diff --git a/Source/core/html/HTMLSelectElement.h b/Source/core/html/HTMLSelectElement.h
index f4c205e..2f1f0e2 100644
--- a/Source/core/html/HTMLSelectElement.h
+++ b/Source/core/html/HTMLSelectElement.h
@@ -64,7 +64,6 @@
 
     using Node::remove;
     void remove(int index);
-    void remove(HTMLOptionElement*);
 
     String value() const;
     void setValue(const String&);
@@ -141,7 +140,7 @@
 
     virtual void defaultEventHandler(Event*) OVERRIDE;
 
-    void dispatchChangeEventForMenuList();
+    void dispatchInputAndChangeEventForMenuList();
 
     void recalcListItems(bool updateSelectedStates = true) const;
 
@@ -157,7 +156,7 @@
 
     enum SelectOptionFlag {
         DeselectOtherOptions = 1 << 0,
-        DispatchChangeEvent = 1 << 1,
+        DispatchInputAndChangeEvent = 1 << 1,
         UserDriven = 1 << 2,
     };
     typedef unsigned SelectOptionFlags;
@@ -207,8 +206,6 @@
     mutable bool m_shouldRecalcListItems;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLSelectElement, hasTagName(HTMLNames::selectTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLSelectElement.idl b/Source/core/html/HTMLSelectElement.idl
index 3104a3f..658e991 100644
--- a/Source/core/html/HTMLSelectElement.idl
+++ b/Source/core/html/HTMLSelectElement.idl
@@ -39,7 +39,6 @@
     [RaisesException] void add([Default=Undefined] optional HTMLElement element,
                                [Default=Undefined] optional HTMLElement before);
     void remove(long index);
-    void remove(HTMLOptionElement option);  // non-standard
     [RaisesException] void remove();
     readonly attribute HTMLCollection selectedOptions;
     attribute long selectedIndex;
diff --git a/Source/core/html/shadow/HTMLShadowElement.cpp b/Source/core/html/HTMLShadowElement.cpp
similarity index 98%
rename from Source/core/html/shadow/HTMLShadowElement.cpp
rename to Source/core/html/HTMLShadowElement.cpp
index edfba07..00b7f8d 100644
--- a/Source/core/html/shadow/HTMLShadowElement.cpp
+++ b/Source/core/html/HTMLShadowElement.cpp
@@ -29,7 +29,7 @@
  */
 
 #include "config.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLShadowElement.h"
 
 #include "HTMLNames.h"
 #include "core/dom/shadow/ShadowRoot.h"
diff --git a/Source/core/html/HTMLShadowElement.h b/Source/core/html/HTMLShadowElement.h
index 7083339..e9aa02f 100644
--- a/Source/core/html/HTMLShadowElement.h
+++ b/Source/core/html/HTMLShadowElement.h
@@ -1,2 +1,54 @@
-// FIXME: Move HTMLShadowElement.h here.
-#include "core/html/shadow/HTMLShadowElement.h"
+/*
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HTMLShadowElement_h
+#define HTMLShadowElement_h
+
+#include "core/dom/shadow/InsertionPoint.h"
+#include "wtf/Forward.h"
+
+namespace WebCore {
+
+class HTMLShadowElement FINAL : public InsertionPoint {
+public:
+    static PassRefPtr<HTMLShadowElement> create(Document&);
+
+    virtual ~HTMLShadowElement();
+
+    ShadowRoot* olderShadowRoot();
+
+private:
+    explicit HTMLShadowElement(Document&);
+    virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint) OVERRIDE;
+};
+
+} // namespace WebCore
+
+#endif // HTMLShadowElement_h
diff --git a/Source/core/html/shadow/HTMLShadowElement.idl b/Source/core/html/HTMLShadowElement.idl
similarity index 100%
rename from Source/core/html/shadow/HTMLShadowElement.idl
rename to Source/core/html/HTMLShadowElement.idl
diff --git a/Source/core/html/HTMLSourceElement.cpp b/Source/core/html/HTMLSourceElement.cpp
index 75daceb..b161826 100644
--- a/Source/core/html/HTMLSourceElement.cpp
+++ b/Source/core/html/HTMLSourceElement.cpp
@@ -55,8 +55,8 @@
 {
     HTMLElement::insertedInto(insertionPoint);
     Element* parent = parentElement();
-    if (parent && parent->isMediaElement())
-        toHTMLMediaElement(parentNode())->sourceWasAdded(this);
+    if (isHTMLMediaElement(parent))
+        toHTMLMediaElement(parent)->sourceWasAdded(this);
     return InsertionDone;
 }
 
@@ -65,7 +65,7 @@
     Element* parent = parentElement();
     if (!parent && removalRoot->isElementNode())
         parent = toElement(removalRoot);
-    if (parent && parent->isMediaElement())
+    if (isHTMLMediaElement(parent))
         toHTMLMediaElement(parent)->sourceWasRemoved(this);
     HTMLElement::removedFrom(removalRoot);
 }
@@ -101,7 +101,7 @@
     if (m_errorEventTimer.isActive())
         return;
 
-    m_errorEventTimer.startOneShot(0);
+    m_errorEventTimer.startOneShot(0, FROM_HERE);
 }
 
 void HTMLSourceElement::cancelPendingErrorEvent()
diff --git a/Source/core/html/HTMLSourceElement.h b/Source/core/html/HTMLSourceElement.h
index 0002d21..581e19a 100644
--- a/Source/core/html/HTMLSourceElement.h
+++ b/Source/core/html/HTMLSourceElement.h
@@ -56,8 +56,6 @@
     Timer<HTMLSourceElement> m_errorEventTimer;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLSourceElement, hasTagName(HTMLNames::sourceTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/html/HTMLStyleElement.cpp b/Source/core/html/HTMLStyleElement.cpp
index ff66523..c7f9ec6 100644
--- a/Source/core/html/HTMLStyleElement.cpp
+++ b/Source/core/html/HTMLStyleElement.cpp
@@ -101,7 +101,7 @@
             scopingNode = containingShadowRoot();
             unregisterWithScopingNode(scopingNode);
         }
-        document().styleEngine()->removeStyleSheetCandidateNode(this, scopingNode);
+        document().styleEngine()->removeStyleSheetCandidateNode(this, scopingNode, treeScope());
         registerWithScopingNode(true);
 
         document().styleEngine()->addStyleSheetCandidateNode(this, false);
@@ -115,7 +115,7 @@
         return;
 
     unregisterWithScopingNode(parentNode());
-    document().styleEngine()->removeStyleSheetCandidateNode(this, parentNode());
+    document().styleEngine()->removeStyleSheetCandidateNode(this, parentNode(), treeScope());
 
     // As any <style> in a shadow tree is treated as "scoped",
     // need to add the <style> to its shadow root.
@@ -190,19 +190,23 @@
     // That is, because willRemove() is also called if an ancestor is removed from the document.
     // Now, if we want to register <style scoped> even if it's not inDocument,
     // we'd need to find a way to discern whether that is the case, or whether <style scoped> itself is about to be removed.
-    ContainerNode* scope = 0;
+    ContainerNode* scopingNode = 0;
     if (m_scopedStyleRegistrationState != NotRegistered) {
         if (m_scopedStyleRegistrationState == RegisteredInShadowRoot) {
-            scope = containingShadowRoot();
-            if (!scope)
-                scope = insertionPoint->containingShadowRoot();
-        } else
-            scope = parentNode() ? parentNode() : insertionPoint;
-        unregisterWithScopingNode(scope);
+            scopingNode = containingShadowRoot();
+            if (!scopingNode)
+                scopingNode = insertionPoint->containingShadowRoot();
+        } else {
+            scopingNode = parentNode() ? parentNode() : insertionPoint;
+        }
+
+        unregisterWithScopingNode(scopingNode);
     }
 
-    if (insertionPoint->inDocument())
-        StyleElement::removedFromDocument(document(), this, scope);
+    if (insertionPoint->inDocument()) {
+        TreeScope* containingScope = containingShadowRoot();
+        StyleElement::removedFromDocument(document(), this, scopingNode, containingScope ? *containingScope : insertionPoint->treeScope());
+    }
 }
 
 void HTMLStyleElement::didNotifySubtreeInsertionsToDocument()
diff --git a/Source/core/html/HTMLStyleElement.h b/Source/core/html/HTMLStyleElement.h
index 01a10e4..c058e8f 100644
--- a/Source/core/html/HTMLStyleElement.h
+++ b/Source/core/html/HTMLStyleElement.h
@@ -100,8 +100,6 @@
     ScopedStyleRegistrationState m_scopedStyleRegistrationState;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLStyleElement, hasTagName(HTMLNames::styleTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLSummaryElement.cpp b/Source/core/html/HTMLSummaryElement.cpp
index 7c19001..d213a27 100644
--- a/Source/core/html/HTMLSummaryElement.cpp
+++ b/Source/core/html/HTMLSummaryElement.cpp
@@ -26,9 +26,9 @@
 #include "core/events/KeyboardEvent.h"
 #include "core/dom/NodeRenderingTraversal.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/html/HTMLContentElement.h"
 #include "core/html/HTMLDetailsElement.h"
 #include "core/html/shadow/DetailsMarkerControl.h"
-#include "core/html/shadow/HTMLContentElement.h"
 #include "core/rendering/RenderBlockFlow.h"
 
 namespace WebCore {
@@ -61,7 +61,7 @@
 HTMLDetailsElement* HTMLSummaryElement::detailsElement() const
 {
     Node* parent = NodeRenderingTraversal::parent(this);
-    if (parent && parent->hasTagName(detailsTag))
+    if (isHTMLDetailsElement(parent))
         return toHTMLDetailsElement(parent);
     return 0;
 }
diff --git a/Source/core/html/HTMLSummaryElement.h b/Source/core/html/HTMLSummaryElement.h
index 1eebc5b..89c130c 100644
--- a/Source/core/html/HTMLSummaryElement.h
+++ b/Source/core/html/HTMLSummaryElement.h
@@ -44,8 +44,6 @@
     virtual bool supportsFocus() const OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLSummaryElement, hasTagName(HTMLNames::summaryTag));
-
 }
 
 #endif // HTMLSummaryElement_h
diff --git a/Source/core/html/HTMLTableCaptionElement.h b/Source/core/html/HTMLTableCaptionElement.h
index bd3bdf4..214950d 100644
--- a/Source/core/html/HTMLTableCaptionElement.h
+++ b/Source/core/html/HTMLTableCaptionElement.h
@@ -40,8 +40,6 @@
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLTableCaptionElement, hasTagName(HTMLNames::captionTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLTableCellElement.cpp b/Source/core/html/HTMLTableCellElement.cpp
index 8331963..9e0b4f1 100644
--- a/Source/core/html/HTMLTableCellElement.cpp
+++ b/Source/core/html/HTMLTableCellElement.cpp
@@ -67,14 +67,12 @@
 
 int HTMLTableCellElement::cellIndex() const
 {
-    int index = 0;
-    if (!parentElement() || !parentElement()->hasTagName(trTag))
+    if (!isHTMLTableRowElement(parentElement()))
         return -1;
 
-    for (const Node * node = previousSibling(); node; node = node->previousSibling()) {
-        if (node->hasTagName(tdTag) || node->hasTagName(thTag))
-            index++;
-    }
+    int index = 0;
+    for (const HTMLTableCellElement* element = Traversal<HTMLTableCellElement>::previousSibling(*this); element; element = Traversal<HTMLTableCellElement>::previousSibling(*element))
+        ++index;
 
     return index;
 }
diff --git a/Source/core/html/HTMLTableCellElement.h b/Source/core/html/HTMLTableCellElement.h
index 0ccc3ed..19ea012 100644
--- a/Source/core/html/HTMLTableCellElement.h
+++ b/Source/core/html/HTMLTableCellElement.h
@@ -66,7 +66,7 @@
     return node.hasTagName(HTMLNames::tdTag) || node.hasTagName(HTMLNames::thTag);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableCellElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableCellElement);
 
 } // namespace
 
diff --git a/Source/core/html/HTMLTableColElement.h b/Source/core/html/HTMLTableColElement.h
index ecd3f73..be4069e 100644
--- a/Source/core/html/HTMLTableColElement.h
+++ b/Source/core/html/HTMLTableColElement.h
@@ -55,7 +55,7 @@
     return node.hasTagName(HTMLNames::colTag) || node.hasTagName(HTMLNames::colgroupTag);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableColElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableColElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/html/HTMLTableElement.cpp b/Source/core/html/HTMLTableElement.cpp
index e1c9014..49c56e9 100644
--- a/Source/core/html/HTMLTableElement.cpp
+++ b/Source/core/html/HTMLTableElement.cpp
@@ -34,8 +34,10 @@
 #include "core/css/CSSValuePool.h"
 #include "core/css/StylePropertySet.h"
 #include "core/dom/Attribute.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/html/HTMLTableCaptionElement.h"
+#include "core/html/HTMLTableCellElement.h"
 #include "core/html/HTMLTableRowElement.h"
 #include "core/html/HTMLTableRowsCollection.h"
 #include "core/html/HTMLTableSectionElement.h"
@@ -65,11 +67,7 @@
 
 HTMLTableCaptionElement* HTMLTableElement::caption() const
 {
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(captionTag))
-            return toHTMLTableCaptionElement(child);
-    }
-    return 0;
+    return Traversal<HTMLTableCaptionElement>::firstChild(*this);
 }
 
 void HTMLTableElement::setCaption(PassRefPtr<HTMLTableCaptionElement> newCaption, ExceptionState& exceptionState)
@@ -80,7 +78,7 @@
 
 HTMLTableSectionElement* HTMLTableElement::tHead() const
 {
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
+    for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
         if (child->hasTagName(theadTag))
             return toHTMLTableSectionElement(child);
     }
@@ -91,17 +89,18 @@
 {
     deleteTHead();
 
-    Node* child;
-    for (child = firstChild(); child; child = child->nextSibling())
-        if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
+    Element* child;
+    for (child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
+        if (!child->hasTagName(captionTag) && !child->hasTagName(colgroupTag))
             break;
+    }
 
     insertBefore(newHead, child, exceptionState);
 }
 
 HTMLTableSectionElement* HTMLTableElement::tFoot() const
 {
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
+    for (Element* child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
         if (child->hasTagName(tfootTag))
             return toHTMLTableSectionElement(child);
     }
@@ -112,10 +111,11 @@
 {
     deleteTFoot();
 
-    Node* child;
-    for (child = firstChild(); child; child = child->nextSibling())
-        if (child->isElementNode() && !child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
+    Element* child;
+    for (child = ElementTraversal::firstWithin(*this); child; child = ElementTraversal::nextSibling(*child)) {
+        if (!child->hasTagName(captionTag) && !child->hasTagName(colgroupTag) && !child->hasTagName(theadTag))
             break;
+    }
 
     insertBefore(newFoot, child, exceptionState);
 }
@@ -184,22 +184,22 @@
 {
     if (index < -1) {
         exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is less than -1.");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<Node> protectFromMutationEvents(this);
 
-    RefPtr<HTMLTableRowElement> lastRow = 0;
-    RefPtr<HTMLTableRowElement> row = 0;
+    RefPtr<HTMLTableRowElement> lastRow = nullptr;
+    RefPtr<HTMLTableRowElement> row = nullptr;
     if (index == -1)
-        lastRow = HTMLTableRowsCollection::lastRow(this);
+        lastRow = HTMLTableRowsCollection::lastRow(*this);
     else {
         for (int i = 0; i <= index; ++i) {
-            row = HTMLTableRowsCollection::rowAfter(this, lastRow.get());
+            row = HTMLTableRowsCollection::rowAfter(*this, lastRow.get());
             if (!row) {
                 if (i != index) {
                     exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is greater than the number of rows in the table (" + String::number(i) + ").");
-                    return 0;
+                    return nullptr;
                 }
                 break;
             }
@@ -236,10 +236,10 @@
     HTMLTableRowElement* row = 0;
     int i = 0;
     if (index == -1)
-        row = HTMLTableRowsCollection::lastRow(this);
+        row = HTMLTableRowsCollection::lastRow(*this);
     else {
         for (i = 0; i <= index; ++i) {
-            row = HTMLTableRowsCollection::rowAfter(this, row);
+            row = HTMLTableRowsCollection::rowAfter(*this, row);
             if (!row)
                 break;
         }
@@ -251,29 +251,16 @@
     row->remove(exceptionState);
 }
 
-static inline bool isTableCellAncestor(Node* n)
+void HTMLTableElement::setNeedsTableStyleRecalc() const
 {
-    return n->hasTagName(theadTag) || n->hasTagName(tbodyTag) ||
-           n->hasTagName(tfootTag) || n->hasTagName(trTag) ||
-           n->hasTagName(thTag);
-}
-
-static bool setTableCellsChanged(Node* n)
-{
-    ASSERT(n);
-    bool cellChanged = false;
-
-    if (n->hasTagName(tdTag))
-        cellChanged = true;
-    else if (isTableCellAncestor(n)) {
-        for (Node* child = n->firstChild(); child; child = child->nextSibling())
-            cellChanged |= setTableCellsChanged(child);
+    Element* element = ElementTraversal::next(*this, this);
+    while (element) {
+        element->setNeedsStyleRecalc(LocalStyleChange);
+        if (isHTMLTableCellElement(*element))
+            element = ElementTraversal::nextSkippingChildren(*element, this);
+        else
+            element = ElementTraversal::next(*element, this);
     }
-
-    if (cellChanged)
-        n->setNeedsStyleRecalc(SubtreeStyleChange);
-
-    return cellChanged;
 }
 
 static bool getBordersFromFrameAttributeValue(const AtomicString& value, bool& borderTop, bool& borderRight, bool& borderBottom, bool& borderLeft)
@@ -318,7 +305,7 @@
     else if (name == backgroundAttr) {
         String url = stripLeadingAndTrailingHTMLSpaces(value);
         if (!url.isEmpty())
-            style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document().completeURL(url))));
+            style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(url, document().completeURL(url))));
     } else if (name == valignAttr) {
         if (!value.isEmpty())
             addPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign, value);
@@ -406,12 +393,8 @@
         HTMLElement::parseAttribute(name, value);
 
     if (bordersBefore != cellBorders() || oldPadding != m_padding) {
-        m_sharedCellStyle = 0;
-        bool cellChanged = false;
-        for (Node* child = firstChild(); child; child = child->nextSibling())
-            cellChanged |= setTableCellsChanged(child);
-        if (cellChanged)
-            setNeedsStyleRecalc(SubtreeStyleChange);
+        m_sharedCellStyle = nullptr;
+        setNeedsTableStyleRecalc();
     }
 }
 
diff --git a/Source/core/html/HTMLTableElement.h b/Source/core/html/HTMLTableElement.h
index 7b5dd49..71f8154 100644
--- a/Source/core/html/HTMLTableElement.h
+++ b/Source/core/html/HTMLTableElement.h
@@ -88,6 +88,8 @@
 
     HTMLTableSectionElement* lastBody() const;
 
+    void setNeedsTableStyleRecalc() const;
+
     bool m_borderAttr;          // Sets a precise border width and creates an outset border for the table and for its cells.
     bool m_borderColorAttr;     // Overrides the outset border and makes it solid for the table and cells instead.
     bool m_frameAttr;           // Implies a thin border width if no border is set and then a certain set of solid/hidden borders based off the value.
@@ -98,8 +100,6 @@
     RefPtr<StylePropertySet> m_sharedCellStyle;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLTableElement, hasTagName(HTMLNames::tableTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLTablePartElement.cpp b/Source/core/html/HTMLTablePartElement.cpp
index 06d86f7..8146ae4 100644
--- a/Source/core/html/HTMLTablePartElement.cpp
+++ b/Source/core/html/HTMLTablePartElement.cpp
@@ -53,7 +53,7 @@
     else if (name == backgroundAttr) {
         String url = stripLeadingAndTrailingHTMLSpaces(value);
         if (!url.isEmpty())
-            style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document().completeURL(url))));
+            style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(url, document().completeURL(url))));
     } else if (name == valignAttr) {
         if (equalIgnoringCase(value, "top"))
             addPropertyToPresentationAttributeStyle(style, CSSPropertyVerticalAlign, CSSValueTop);
@@ -86,7 +86,7 @@
 HTMLTableElement* HTMLTablePartElement::findParentTable() const
 {
     ContainerNode* parent = NodeRenderingTraversal::parent(this);
-    while (parent && !parent->hasTagName(tableTag))
+    while (parent && !isHTMLTableElement(*parent))
         parent = NodeRenderingTraversal::parent(parent);
     return toHTMLTableElement(parent);
 }
diff --git a/Source/core/html/HTMLTableRowElement.cpp b/Source/core/html/HTMLTableRowElement.cpp
index c54defc..2938abb 100644
--- a/Source/core/html/HTMLTableRowElement.cpp
+++ b/Source/core/html/HTMLTableRowElement.cpp
@@ -27,6 +27,7 @@
 
 #include "HTMLNames.h"
 #include "bindings/v8/ExceptionState.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/html/HTMLCollection.h"
 #include "core/html/HTMLTableCellElement.h"
@@ -54,7 +55,7 @@
     if (!table)
         return -1;
     table = table->parentNode();
-    if (!table || !table->hasTagName(tableTag))
+    if (!isHTMLTableElement(table))
         return -1;
 
     // To match Firefox, the row indices work like this:
@@ -65,32 +66,29 @@
     int rIndex = 0;
 
     if (HTMLTableSectionElement* head = toHTMLTableElement(table)->tHead()) {
-        for (Node *row = head->firstChild(); row; row = row->nextSibling()) {
+        for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*head); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
             if (row == this)
                 return rIndex;
-            if (row->hasTagName(trTag))
-                ++rIndex;
+            ++rIndex;
         }
     }
 
-    for (Node *node = table->firstChild(); node; node = node->nextSibling()) {
-        if (node->hasTagName(tbodyTag)) {
-            HTMLTableSectionElement* section = toHTMLTableSectionElement(node);
-            for (Node* row = section->firstChild(); row; row = row->nextSibling()) {
+    for (Element* child = ElementTraversal::firstWithin(*table); child; child = ElementTraversal::nextSibling(*child)) {
+        if (child->hasTagName(tbodyTag)) {
+            HTMLTableSectionElement* section = toHTMLTableSectionElement(child);
+            for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*section); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
                 if (row == this)
                     return rIndex;
-                if (row->hasTagName(trTag))
-                    ++rIndex;
+                ++rIndex;
             }
         }
     }
 
     if (HTMLTableSectionElement* foot = toHTMLTableElement(table)->tFoot()) {
-        for (Node *row = foot->firstChild(); row; row = row->nextSibling()) {
+        for (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*foot); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row)) {
             if (row == this)
                 return rIndex;
-            if (row->hasTagName(trTag))
-                ++rIndex;
+            ++rIndex;
         }
     }
 
@@ -101,13 +99,12 @@
 int HTMLTableRowElement::sectionRowIndex() const
 {
     int rIndex = 0;
-    const Node *n = this;
+    const Node* n = this;
     do {
         n = n->previousSibling();
-        if (n && n->hasTagName(trTag))
-            rIndex++;
-    }
-    while (n);
+        if (n && isHTMLTableRowElement(*n))
+            ++rIndex;
+    } while (n);
 
     return rIndex;
 }
@@ -118,7 +115,7 @@
     int numCells = children ? children->length() : 0;
     if (index < -1 || index > numCells) {
         exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(index) + ") is outside the range [-1, " + String::number(numCells) + "].");
-        return 0;
+        return nullptr;
     }
 
     RefPtr<HTMLTableCellElement> cell = HTMLTableCellElement::create(tdTag, document());
diff --git a/Source/core/html/HTMLTableRowElement.h b/Source/core/html/HTMLTableRowElement.h
index 9bd824c..3dac5e2 100644
--- a/Source/core/html/HTMLTableRowElement.h
+++ b/Source/core/html/HTMLTableRowElement.h
@@ -49,8 +49,6 @@
     explicit HTMLTableRowElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLTableRowElement, hasTagName(HTMLNames::trTag));
-
 } // namespace
 
 #endif
diff --git a/Source/core/html/HTMLTableRowsCollection.cpp b/Source/core/html/HTMLTableRowsCollection.cpp
index ae67c03..97214a6 100644
--- a/Source/core/html/HTMLTableRowsCollection.cpp
+++ b/Source/core/html/HTMLTableRowsCollection.cpp
@@ -55,29 +55,23 @@
 
 static inline HTMLTableRowElement* findTableRowElementInChildren(Element& current)
 {
-    for (Element* child = ElementTraversal::firstWithin(current); child; child = ElementTraversal::nextSibling(*child)) {
-        if (child->hasTagName(trTag))
-            return toHTMLTableRowElement(child);
-    }
-    return 0;
+    return Traversal<HTMLTableRowElement>::firstChild(current);
 }
 
-HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement* table, HTMLTableRowElement* previous)
+HTMLTableRowElement* HTMLTableRowsCollection::rowAfter(HTMLTableElement& table, HTMLTableRowElement* previous)
 {
     Element* child = 0;
 
     // Start by looking for the next row in this section.
     // Continue only if there is none.
     if (previous && previous->parentNode() != table) {
-        for (child = ElementTraversal::nextSibling(*previous); child; child = ElementTraversal::nextSibling(*child)) {
-            if (child->hasTagName(trTag))
-                return toHTMLTableRowElement(child);
-        }
+        if (HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::nextSibling(*previous))
+            return row;
     }
 
     // If still looking at head sections, find the first row in the next head section.
     if (!previous)
-        child = ElementTraversal::firstWithin(*table);
+        child = ElementTraversal::firstWithin(table);
     else if (isInHead(previous))
         child = ElementTraversal::nextSibling(*previous->parentNode());
     for (; child; child = ElementTraversal::nextSibling(*child)) {
@@ -89,13 +83,13 @@
 
     // If still looking at top level and bodies, find the next row in top level or the first in the next body section.
     if (!previous || isInHead(previous))
-        child = ElementTraversal::firstWithin(*table);
+        child = ElementTraversal::firstWithin(table);
     else if (previous->parentNode() == table)
         child = ElementTraversal::nextSibling(*previous);
     else if (isInBody(previous))
         child = ElementTraversal::nextSibling(*previous->parentNode());
     for (; child; child = ElementTraversal::nextSibling(*child)) {
-        if (child->hasTagName(trTag))
+        if (isHTMLTableRowElement(child))
             return toHTMLTableRowElement(child);
         if (child->hasTagName(tbodyTag)) {
             if (HTMLTableRowElement* row = findTableRowElementInChildren(*child))
@@ -105,7 +99,7 @@
 
     // Find the first row in the next foot section.
     if (!previous || !isInFoot(previous))
-        child = ElementTraversal::firstWithin(*table);
+        child = ElementTraversal::firstWithin(table);
     else
         child = ElementTraversal::nextSibling(*previous->parentNode());
     for (; child; child = ElementTraversal::nextSibling(*child)) {
@@ -118,34 +112,28 @@
     return 0;
 }
 
-HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement* table)
+HTMLTableRowElement* HTMLTableRowsCollection::lastRow(HTMLTableElement& table)
 {
-    for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+    for (Node* child = table.lastChild(); child; child = child->previousSibling()) {
         if (child->hasTagName(tfootTag)) {
-            for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
-                if (grandchild->hasTagName(trTag))
-                    return toHTMLTableRowElement(grandchild);
-            }
+            if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+                return lastRow;
         }
     }
 
-    for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
-        if (child->hasTagName(trTag))
+    for (Node* child = table.lastChild(); child; child = child->previousSibling()) {
+        if (isHTMLTableRowElement(child))
             return toHTMLTableRowElement(child);
         if (child->hasTagName(tbodyTag)) {
-            for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
-                if (grandchild->hasTagName(trTag))
-                    return toHTMLTableRowElement(grandchild);
-            }
+            if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+                return lastRow;
         }
     }
 
-    for (Node* child = table->lastChild(); child; child = child->previousSibling()) {
+    for (Node* child = table.lastChild(); child; child = child->previousSibling()) {
         if (child->hasTagName(theadTag)) {
-            for (Node* grandchild = child->lastChild(); grandchild; grandchild = grandchild->previousSibling()) {
-                if (grandchild->hasTagName(trTag))
-                    return toHTMLTableRowElement(grandchild);
-            }
+            if (HTMLTableRowElement* lastRow = Traversal<HTMLTableRowElement>::lastChild(*child))
+                return lastRow;
         }
     }
 
@@ -155,13 +143,13 @@
 // Must call get() on the table in case that argument is compiled before dereferencing the
 // table to get at the collection cache. Order of argument evaluation is undefined and can
 // differ between compilers.
-HTMLTableRowsCollection::HTMLTableRowsCollection(ContainerNode* table)
+HTMLTableRowsCollection::HTMLTableRowsCollection(ContainerNode& table)
     : HTMLCollection(table, TableRows, OverridesItemAfter)
 {
-    ASSERT(table->hasTagName(tableTag));
+    ASSERT(isHTMLTableElement(table));
 }
 
-PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(ContainerNode* table, CollectionType)
+PassRefPtr<HTMLTableRowsCollection> HTMLTableRowsCollection::create(ContainerNode& table, CollectionType)
 {
     return adoptRef(new HTMLTableRowsCollection(table));
 }
diff --git a/Source/core/html/HTMLTableRowsCollection.h b/Source/core/html/HTMLTableRowsCollection.h
index e7324b2..d731cb8 100644
--- a/Source/core/html/HTMLTableRowsCollection.h
+++ b/Source/core/html/HTMLTableRowsCollection.h
@@ -38,13 +38,13 @@
 
 class HTMLTableRowsCollection FINAL : public HTMLCollection {
 public:
-    static PassRefPtr<HTMLTableRowsCollection> create(ContainerNode*, CollectionType);
+    static PassRefPtr<HTMLTableRowsCollection> create(ContainerNode&, CollectionType);
 
-    static HTMLTableRowElement* rowAfter(HTMLTableElement*, HTMLTableRowElement*);
-    static HTMLTableRowElement* lastRow(HTMLTableElement*);
+    static HTMLTableRowElement* rowAfter(HTMLTableElement&, HTMLTableRowElement*);
+    static HTMLTableRowElement* lastRow(HTMLTableElement&);
 
 private:
-    explicit HTMLTableRowsCollection(ContainerNode*);
+    explicit HTMLTableRowsCollection(ContainerNode&);
 
     virtual Element* virtualItemAfter(Element*) const OVERRIDE;
 };
diff --git a/Source/core/html/HTMLTableSectionElement.cpp b/Source/core/html/HTMLTableSectionElement.cpp
index bf796d6..1820cab 100644
--- a/Source/core/html/HTMLTableSectionElement.cpp
+++ b/Source/core/html/HTMLTableSectionElement.cpp
@@ -27,6 +27,7 @@
 
 #include "HTMLNames.h"
 #include "bindings/v8/ExceptionState.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/html/HTMLCollection.h"
 #include "core/html/HTMLTableElement.h"
@@ -95,15 +96,10 @@
 
 int HTMLTableSectionElement::numRows() const
 {
-    int rows = 0;
-    const Node *n = firstChild();
-    while (n) {
-        if (n->hasTagName(trTag))
-            rows++;
-        n = n->nextSibling();
-    }
-
-    return rows;
+    int rowCount = 0;
+    for (const HTMLTableRowElement* row = Traversal<HTMLTableRowElement>::firstChild(*this); row; row = Traversal<HTMLTableRowElement>::nextSibling(*row))
+        ++rowCount;
+    return rowCount;
 }
 
 PassRefPtr<HTMLCollection> HTMLTableSectionElement::rows()
diff --git a/Source/core/html/HTMLTableSectionElement.h b/Source/core/html/HTMLTableSectionElement.h
index 2a72821..4ab3b0b 100644
--- a/Source/core/html/HTMLTableSectionElement.h
+++ b/Source/core/html/HTMLTableSectionElement.h
@@ -54,7 +54,7 @@
     return node.hasTagName(HTMLNames::tbodyTag) || node.hasTagName(HTMLNames::tfootTag) || node.hasTagName(HTMLNames::theadTag);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTableSectionElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTableSectionElement);
 
 } //namespace
 
diff --git a/Source/core/html/HTMLTagNames.in b/Source/core/html/HTMLTagNames.in
index 1014edd..c4ba7a9 100644
--- a/Source/core/html/HTMLTagNames.in
+++ b/Source/core/html/HTMLTagNames.in
@@ -69,7 +69,6 @@
 img interfaceName=HTMLImageElement, constructorNeedsFormElement
 input constructorNeedsFormElement, constructorNeedsCreatedByParser
 ins interfaceName=HTMLModElement
-isindex interfaceName=HTMLUnknownElement
 kbd interfaceName=HTMLElement
 keygen constructorNeedsFormElement
 label
diff --git a/Source/core/html/HTMLTemplateElement.h b/Source/core/html/HTMLTemplateElement.h
index b27958d..f44ac45 100644
--- a/Source/core/html/HTMLTemplateElement.h
+++ b/Source/core/html/HTMLTemplateElement.h
@@ -54,8 +54,6 @@
     mutable RefPtr<TemplateContentDocumentFragment> m_content;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLTemplateElement, hasTagName(HTMLNames::templateTag));
-
 } // namespace WebCore
 
 #endif // HTMLTemplateElement_h
diff --git a/Source/core/html/HTMLTextAreaElement.cpp b/Source/core/html/HTMLTextAreaElement.cpp
index 7ea7aa6..210fb8f 100644
--- a/Source/core/html/HTMLTextAreaElement.cpp
+++ b/Source/core/html/HTMLTextAreaElement.cpp
@@ -40,11 +40,14 @@
 #include "core/events/BeforeTextInsertedEvent.h"
 #include "core/events/Event.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/FormDataList.h"
 #include "core/html/forms/FormController.h"
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/html/shadow/TextControlInnerElements.h"
-#include "core/frame/Frame.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
 #include "core/rendering/RenderTextControlMultiLine.h"
 #include "platform/text/PlatformLocale.h"
 #include "wtf/StdLibExtras.h"
@@ -262,7 +265,7 @@
 
 void HTMLTextAreaElement::handleFocusEvent(Element*, FocusType)
 {
-    if (Frame* frame = document().frame())
+    if (LocalFrame* frame = document().frame())
         frame->spellChecker().didBeginEditing(this);
 }
 
@@ -277,6 +280,9 @@
 
     // When typing in a textarea, childrenChanged is not called, so we need to force the directionality check.
     calculateAndAdjustDirectionality();
+
+    ASSERT(document().isActive());
+    document().frameHost()->chrome().client().didChangeValueInTextField(*this);
 }
 
 void HTMLTextAreaElement::handleBeforeTextInsertedEvent(BeforeTextInsertedEvent* event) const
@@ -437,10 +443,13 @@
 void HTMLTextAreaElement::setSuggestedValue(const String& value)
 {
     m_suggestedValue = value;
-    setInnerTextValue(m_suggestedValue);
+
+    if (!value.isNull())
+        setInnerTextValue(m_suggestedValue);
+    else
+        setInnerTextValue(m_value);
     updatePlaceholderVisibility(false);
     setNeedsStyleRecalc(SubtreeStyleChange);
-    setFormControlValueMatchesRenderer(true);
 }
 
 String HTMLTextAreaElement::validationMessage() const
diff --git a/Source/core/html/HTMLTextAreaElement.h b/Source/core/html/HTMLTextAreaElement.h
index 00eb301..7d369ec 100644
--- a/Source/core/html/HTMLTextAreaElement.h
+++ b/Source/core/html/HTMLTextAreaElement.h
@@ -130,8 +130,6 @@
     String m_suggestedValue;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLTextAreaElement, hasTagName(HTMLNames::textareaTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLTextFormControlElement.cpp b/Source/core/html/HTMLTextFormControlElement.cpp
index a8ef2bf..4bcbac9 100644
--- a/Source/core/html/HTMLTextFormControlElement.cpp
+++ b/Source/core/html/HTMLTextFormControlElement.cpp
@@ -37,10 +37,10 @@
 #include "core/editing/TextIterator.h"
 #include "core/events/Event.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLBRElement.h"
 #include "core/html/shadow/ShadowElementNames.h"
-#include "core/frame/Frame.h"
-#include "core/frame/UseCounter.h"
 #include "core/rendering/RenderBlock.h"
 #include "core/rendering/RenderTheme.h"
 #include "wtf/text/StringBuilder.h"
@@ -209,6 +209,8 @@
         exceptionState.throwDOMException(IndexSizeError, "The provided start value (" + String::number(start) + ") is larger than the provided end value (" + String::number(end) + ").");
         return;
     }
+    if (hasAuthorShadowRoot())
+        return;
 
     String text = innerTextValue();
     unsigned textLength = text.length();
@@ -302,7 +304,7 @@
         newSelection = VisibleSelection(startPosition, endPosition);
     newSelection.setIsDirectional(direction != SelectionHasNoDirection);
 
-    if (Frame* frame = document().frame())
+    if (LocalFrame* frame = document().frame())
         frame->selection().setSelection(newSelection);
 }
 
@@ -342,11 +344,11 @@
 int HTMLTextFormControlElement::computeSelectionStart() const
 {
     ASSERT(isTextFormControl());
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return 0;
 
-    return indexForVisiblePosition(frame->selection().start());
+    return indexForVisiblePosition(VisiblePosition(frame->selection().start()));
 }
 
 int HTMLTextFormControlElement::selectionEnd() const
@@ -361,11 +363,11 @@
 int HTMLTextFormControlElement::computeSelectionEnd() const
 {
     ASSERT(isTextFormControl());
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return 0;
 
-    return indexForVisiblePosition(frame->selection().end());
+    return indexForVisiblePosition(VisiblePosition(frame->selection().end()));
 }
 
 static const AtomicString& directionString(TextFieldSelectionDirection direction)
@@ -400,7 +402,7 @@
 TextFieldSelectionDirection HTMLTextFormControlElement::computeSelectionDirection() const
 {
     ASSERT(isTextFormControl());
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return SelectionHasNoDirection;
 
@@ -422,7 +424,7 @@
 PassRefPtr<Range> HTMLTextFormControlElement::selection() const
 {
     if (!renderer() || !isTextFormControl() || !hasCachedSelection())
-        return 0;
+        return nullptr;
 
     int start = m_cachedSelectionStart;
     int end = m_cachedSelectionEnd;
@@ -430,7 +432,7 @@
     ASSERT(start <= end);
     HTMLElement* innerText = innerTextElement();
     if (!innerText)
-        return 0;
+        return nullptr;
 
     if (!innerText->firstChild())
         return Range::create(document(), innerText, 0, innerText, 0);
@@ -440,7 +442,7 @@
     Node* endNode = 0;
     for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
         ASSERT(!node->firstChild());
-        ASSERT(node->isTextNode() || node->hasTagName(brTag));
+        ASSERT(node->isTextNode() || isHTMLBRElement(*node));
         int length = node->isTextNode() ? lastOffsetInNode(node) : 1;
 
         if (offset <= start && start <= offset + length)
@@ -455,7 +457,7 @@
     }
 
     if (!startNode || !endNode)
-        return 0;
+        return nullptr;
 
     return Range::create(document(), startNode, start, endNode, end);
 }
@@ -473,7 +475,7 @@
     // selectionStart() or selectionEnd() will return cached selection when this node doesn't have focus
     cacheSelection(computeSelectionStart(), computeSelectionEnd(), computeSelectionDirection());
 
-    if (Frame* frame = document().frame()) {
+    if (LocalFrame* frame = document().frame()) {
         if (frame->selection().isRange() && userTriggered)
             dispatchEvent(Event::createBubble(EventTypeNames::select));
     }
@@ -497,11 +499,12 @@
 
 void HTMLTextFormControlElement::setInnerTextValue(const String& value)
 {
-    if (!isTextFormControl())
+    ASSERT(!hasAuthorShadowRoot());
+    if (!isTextFormControl() || hasAuthorShadowRoot())
         return;
 
     bool textIsChanged = value != innerTextValue();
-    if (textIsChanged || !innerTextElement()->hasChildNodes()) {
+    if (textIsChanged || !innerTextElement()->hasChildren()) {
         if (textIsChanged && renderer()) {
             if (AXObjectCache* cache = document().existingAXObjectCache())
                 cache->postNotification(this, AXObjectCache::AXValueChanged, false);
@@ -526,13 +529,14 @@
 
 String HTMLTextFormControlElement::innerTextValue() const
 {
+    ASSERT(!hasAuthorShadowRoot());
     HTMLElement* innerText = innerTextElement();
     if (!innerText || !isTextFormControl())
         return emptyString();
 
     StringBuilder result;
     for (Node* node = innerText; node; node = NodeTraversal::next(*node, innerText)) {
-        if (node->hasTagName(brTag))
+        if (isHTMLBRElement(*node))
             result.append(newlineCharacter);
         else if (node->isTextNode())
             result.append(toText(node)->data());
@@ -579,7 +583,7 @@
 
     StringBuilder result;
     for (Node* node = innerText->firstChild(); node; node = NodeTraversal::next(*node, innerText)) {
-        if (node->hasTagName(brTag))
+        if (isHTMLBRElement(*node))
             result.append(newlineCharacter);
         else if (node->isTextNode()) {
             String data = toText(node)->data();
@@ -611,7 +615,7 @@
     if (!container)
         return 0;
     Element* ancestor = container->shadowHost();
-    return ancestor && isHTMLTextFormControlElement(*ancestor) ? toHTMLTextFormControlElement(ancestor) : 0;
+    return ancestor && isHTMLTextFormControlElement(*ancestor) && container->containingShadowRoot()->type() == ShadowRoot::UserAgentShadowRoot ? toHTMLTextFormControlElement(ancestor) : 0;
 }
 
 static const HTMLElement* parentHTMLElement(const Element* element)
diff --git a/Source/core/html/HTMLTextFormControlElement.h b/Source/core/html/HTMLTextFormControlElement.h
index a8675d9..d64d1fc 100644
--- a/Source/core/html/HTMLTextFormControlElement.h
+++ b/Source/core/html/HTMLTextFormControlElement.h
@@ -140,7 +140,7 @@
     return node.isElementNode() && toElement(node).isTextFormControl();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLTextFormControlElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLTextFormControlElement);
 
 HTMLTextFormControlElement* enclosingTextFormControl(const Position&);
 
diff --git a/Source/core/html/HTMLTitleElement.h b/Source/core/html/HTMLTitleElement.h
index 129c03e..fda5df9 100644
--- a/Source/core/html/HTMLTitleElement.h
+++ b/Source/core/html/HTMLTitleElement.h
@@ -43,8 +43,6 @@
     bool m_ignoreTitleUpdatesWhenChildrenChange;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLTitleElement, hasTagName(HTMLNames::titleTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLTrackElement.cpp b/Source/core/html/HTMLTrackElement.cpp
index 1ca3479..280020b 100644
--- a/Source/core/html/HTMLTrackElement.cpp
+++ b/Source/core/html/HTMLTrackElement.cpp
@@ -29,8 +29,8 @@
 #include "HTMLNames.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/events/Event.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/HTMLMediaElement.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "platform/Logging.h"
 
 using namespace std;
@@ -61,7 +61,7 @@
 HTMLTrackElement::~HTMLTrackElement()
 {
     if (m_track)
-        m_track->clearClient();
+        m_track->clearTrackElement();
 }
 
 PassRefPtr<HTMLTrackElement> HTMLTrackElement::create(Document& document)
@@ -79,14 +79,14 @@
     HTMLElement::insertedInto(insertionPoint);
     HTMLMediaElement* parent = mediaElement();
     if (insertionPoint == parent)
-        parent->didAddTrack(this);
+        parent->didAddTrackElement(this);
     return InsertionDone;
 }
 
 void HTMLTrackElement::removedFrom(ContainerNode* insertionPoint)
 {
     if (!parentNode() && isHTMLMediaElement(*insertionPoint))
-        toHTMLMediaElement(insertionPoint)->didRemoveTrack(this);
+        toHTMLMediaElement(insertionPoint)->didRemoveTrackElement(this);
     HTMLElement::removedFrom(insertionPoint);
 }
 
@@ -162,7 +162,7 @@
         return;
 
     // 4. Run the remainder of these steps asynchronously, allowing whatever caused these steps to run to continue.
-    m_loadTimer.startOneShot(0);
+    m_loadTimer.startOneShot(0, FROM_HERE);
 }
 
 void HTMLTrackElement::loadTimerFired(Timer<HTMLTrackElement>*)
@@ -264,53 +264,12 @@
     return nullAtom;
 }
 
-void HTMLTrackElement::textTrackKindChanged(TextTrack* track)
-{
-    if (HTMLMediaElement* parent = mediaElement())
-        return parent->textTrackKindChanged(track);
-}
-
-void HTMLTrackElement::textTrackModeChanged(TextTrack* track)
-{
-    // Since we've moved to a new parent, we may now be able to load.
-    if (readyState() == HTMLTrackElement::NONE)
-        scheduleLoad();
-
-    if (HTMLMediaElement* parent = mediaElement())
-        return parent->textTrackModeChanged(track);
-}
-
-void HTMLTrackElement::textTrackAddCues(TextTrack* track, const TextTrackCueList* cues)
-{
-    if (HTMLMediaElement* parent = mediaElement())
-        return parent->textTrackAddCues(track, cues);
-}
-
-void HTMLTrackElement::textTrackRemoveCues(TextTrack* track, const TextTrackCueList* cues)
-{
-    if (HTMLMediaElement* parent = mediaElement())
-        return parent->textTrackRemoveCues(track, cues);
-}
-
-void HTMLTrackElement::textTrackAddCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
-{
-    if (HTMLMediaElement* parent = mediaElement())
-        return parent->textTrackAddCue(track, cue);
-}
-
-void HTMLTrackElement::textTrackRemoveCue(TextTrack* track, PassRefPtr<TextTrackCue> cue)
-{
-    if (HTMLMediaElement* parent = mediaElement())
-        return parent->textTrackRemoveCue(track, cue);
-}
-
 HTMLMediaElement* HTMLTrackElement::mediaElement() const
 {
     Element* parent = parentElement();
-    if (parent && parent->isMediaElement())
-        return toHTMLMediaElement(parentNode());
+    if (isHTMLMediaElement(parent))
+        return toHTMLMediaElement(parent);
     return 0;
 }
 
 }
-
diff --git a/Source/core/html/HTMLTrackElement.h b/Source/core/html/HTMLTrackElement.h
index 9e70146..11406a7 100644
--- a/Source/core/html/HTMLTrackElement.h
+++ b/Source/core/html/HTMLTrackElement.h
@@ -34,7 +34,7 @@
 
 class HTMLMediaElement;
 
-class HTMLTrackElement FINAL : public HTMLElement, public TextTrackClient {
+class HTMLTrackElement FINAL : public HTMLElement {
 public:
     static PassRefPtr<HTMLTrackElement> create(Document&);
 
@@ -69,14 +69,6 @@
 
     HTMLMediaElement* mediaElement() const;
 
-    // TextTrackClient
-    virtual void textTrackModeChanged(TextTrack*) OVERRIDE;
-    virtual void textTrackKindChanged(TextTrack*) OVERRIDE;
-    virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
-    virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) OVERRIDE;
-    virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
-    virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) OVERRIDE;
-
     LoadableTextTrack* ensureTrack();
     bool canLoadUrl(const KURL&);
 
@@ -84,8 +76,6 @@
     Timer<HTMLTrackElement> m_loadTimer;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLTrackElement, hasTagName(HTMLNames::trackTag));
-
 }
 
 #endif
diff --git a/Source/core/html/HTMLUnknownElement.h b/Source/core/html/HTMLUnknownElement.h
index 1c1794c..d35aa71 100644
--- a/Source/core/html/HTMLUnknownElement.h
+++ b/Source/core/html/HTMLUnknownElement.h
@@ -56,7 +56,7 @@
     return node.isElementNode() && toHTMLElement(node).isHTMLUnknownElement();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(HTMLUnknownElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(HTMLUnknownElement);
 
 } // namespace
 
diff --git a/Source/core/html/HTMLVideoElement.cpp b/Source/core/html/HTMLVideoElement.cpp
index 5dacbac..3cc8b3d 100644
--- a/Source/core/html/HTMLVideoElement.cpp
+++ b/Source/core/html/HTMLVideoElement.cpp
@@ -33,6 +33,7 @@
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/html/HTMLImageLoader.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/RenderImage.h"
@@ -120,17 +121,6 @@
         HTMLMediaElement::parseAttribute(name, value);
 }
 
-bool HTMLVideoElement::supportsFullscreen() const
-{
-    if (!document().page())
-        return false;
-
-    if (!player())
-        return false;
-
-    return true;
-}
-
 unsigned HTMLVideoElement::videoWidth() const
 {
     if (!player())
@@ -184,7 +174,7 @@
         setDisplayMode(Poster);
 }
 
-void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect)
+void HTMLVideoElement::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& destRect) const
 {
     MediaPlayer* player = HTMLMediaElement::player();
     if (!player)
@@ -207,41 +197,6 @@
     return player()->hasVideo() && player()->readyState() >= MediaPlayer::HaveCurrentData;
 }
 
-void HTMLVideoElement::webkitEnterFullscreen(ExceptionState& exceptionState)
-{
-    if (isFullscreen())
-        return;
-
-    // Generate an exception if this isn't called in response to a user gesture, or if the
-    // element does not support fullscreen.
-    if (userGestureRequiredForFullscreen() && !UserGestureIndicator::processingUserGesture()) {
-        exceptionState.throwDOMException(InvalidStateError, "This element may only enter fullscreen mode in response to a user gesture ('click', for example).");
-        return;
-    }
-    if (!supportsFullscreen()) {
-        exceptionState.throwDOMException(InvalidStateError, "This element does not support fullscreen mode.");
-        return;
-    }
-
-    enterFullscreen();
-}
-
-void HTMLVideoElement::webkitExitFullscreen()
-{
-    if (isFullscreen())
-        exitFullscreen();
-}
-
-bool HTMLVideoElement::webkitSupportsFullscreen()
-{
-    return supportsFullscreen();
-}
-
-bool HTMLVideoElement::webkitDisplayingFullscreen()
-{
-    return isFullscreen();
-}
-
 void HTMLVideoElement::didMoveToNewDocument(Document& oldDocument)
 {
     if (m_imageLoader)
@@ -278,4 +233,34 @@
     return posterImageURL();
 }
 
+PassRefPtr<Image> HTMLVideoElement::getSourceImageForCanvas(SourceImageMode mode, SourceImageStatus* status) const
+{
+    if (!hasAvailableVideoFrame()) {
+        *status = InvalidSourceImageStatus;
+        return nullptr;
+    }
+
+    IntSize intrinsicSize(videoWidth(), videoHeight());
+    OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(intrinsicSize);
+    if (!imageBuffer) {
+        *status = InvalidSourceImageStatus;
+        return nullptr;
+    }
+
+    paintCurrentFrameInContext(imageBuffer->context(), IntRect(IntPoint(0, 0), intrinsicSize));
+
+    *status = NormalSourceImageStatus;
+    return imageBuffer->copyImage(mode == CopySourceImageIfVolatile ? CopyBackingStore : DontCopyBackingStore, Unscaled);
+}
+
+bool HTMLVideoElement::wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const
+{
+    return !hasSingleSecurityOrigin() || (!(player() && player()->didPassCORSAccessCheck()) && destinationSecurityOrigin->taintsCanvas(currentSrc()));
+}
+
+FloatSize HTMLVideoElement::sourceSize() const
+{
+    return FloatSize(videoWidth(), videoHeight());
+}
+
 }
diff --git a/Source/core/html/HTMLVideoElement.h b/Source/core/html/HTMLVideoElement.h
index 13122fd..02e82e1 100644
--- a/Source/core/html/HTMLVideoElement.h
+++ b/Source/core/html/HTMLVideoElement.h
@@ -27,6 +27,7 @@
 #define HTMLVideoElement_h
 
 #include "core/html/HTMLMediaElement.h"
+#include "core/html/canvas/CanvasImageSource.h"
 
 namespace blink {
 class WebGraphicsContext3D;
@@ -37,25 +38,19 @@
 class ExceptionState;
 class HTMLImageLoader;
 
-class HTMLVideoElement FINAL : public HTMLMediaElement {
+class HTMLVideoElement FINAL : public HTMLMediaElement, public CanvasImageSource {
 public:
     static PassRefPtr<HTMLVideoElement> create(Document&);
 
     unsigned videoWidth() const;
     unsigned videoHeight() const;
 
-    // Fullscreen
-    void webkitEnterFullscreen(ExceptionState&);
-    void webkitExitFullscreen();
-    bool webkitSupportsFullscreen();
-    bool webkitDisplayingFullscreen();
-
     // Statistics
     unsigned webkitDecodedFrameCount() const;
     unsigned webkitDroppedFrameCount() const;
 
     // Used by canvas to gain raw pixel access
-    void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
+    void paintCurrentFrameInContext(GraphicsContext*, const IntRect&) const;
 
     // Used by WebGL to do GPU-GPU textures copy if possible.
     // See more details at MediaPlayer::copyVideoTextureToPlatformTexture() defined in Source/WebCore/platform/graphics/MediaPlayer.h.
@@ -68,6 +63,12 @@
     // FIXME: Remove this when WebMediaPlayerClientImpl::loadInternal does not depend on it.
     virtual KURL mediaPlayerPosterURL() OVERRIDE;
 
+    // CanvasImageSource implementation
+    virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus*) const OVERRIDE;
+    virtual bool isVideoElement() const OVERRIDE { return true; }
+    virtual bool wouldTaintOrigin(SecurityOrigin*) const OVERRIDE;
+    virtual FloatSize sourceSize() const OVERRIDE;
+
 private:
     HTMLVideoElement(Document&);
 
@@ -79,7 +80,6 @@
     virtual void collectStyleForPresentationAttribute(const QualifiedName&, const AtomicString&, MutableStylePropertySet*) OVERRIDE;
     virtual bool isVideo() const OVERRIDE { return true; }
     virtual bool hasVideo() const OVERRIDE { return player() && player()->hasVideo(); }
-    bool supportsFullscreen() const;
     virtual bool isURLAttribute(const Attribute&) const OVERRIDE;
     virtual const AtomicString imageSourceURL() const OVERRIDE;
 
@@ -93,8 +93,6 @@
     AtomicString m_defaultPosterURL;
 };
 
-DEFINE_NODE_TYPE_CASTS(HTMLVideoElement, hasTagName(HTMLNames::videoTag));
-
 } //namespace
 
 #endif
diff --git a/Source/core/html/HTMLVideoElement.idl b/Source/core/html/HTMLVideoElement.idl
index b68a7db..2d196d3 100644
--- a/Source/core/html/HTMLVideoElement.idl
+++ b/Source/core/html/HTMLVideoElement.idl
@@ -32,16 +32,6 @@
     readonly attribute unsigned long videoHeight;
     [Reflect, URL, PerWorldBindings, ActivityLogging=SetterForIsolatedWorlds] attribute DOMString poster;
 
-    [DeprecateAs=PrefixedVideoSupportsFullscreen] readonly attribute boolean webkitSupportsFullscreen;
-    [DeprecateAs=PrefixedVideoDisplayingFullscreen] readonly attribute boolean webkitDisplayingFullscreen;
-
-    [DeprecateAs=PrefixedVideoEnterFullscreen, RaisesException, PerWorldBindings, ActivityLogging=ForAllWorlds] void webkitEnterFullscreen();
-    [DeprecateAs=PrefixedVideoExitFullscreen] void webkitExitFullscreen();
-
-    // Note the different capitalization of the "S" in FullScreen.
-    [DeprecateAs=PrefixedVideoEnterFullScreen, ImplementedAs=webkitEnterFullscreen, RaisesException, PerWorldBindings, ActivityLogging=ForAllWorlds] void webkitEnterFullScreen();
-    [DeprecateAs=PrefixedVideoExitFullScreen, ImplementedAs=webkitExitFullscreen] void webkitExitFullScreen();
-
     // The number of frames that have been decoded and made available for
     // playback.
     [MeasureAs=PrefixedVideoDecodedFrameCount] readonly attribute unsigned long webkitDecodedFrameCount;
diff --git a/Source/core/html/HTMLViewSourceDocument.cpp b/Source/core/html/HTMLViewSourceDocument.cpp
index b47a8b8..395af05 100644
--- a/Source/core/html/HTMLViewSourceDocument.cpp
+++ b/Source/core/html/HTMLViewSourceDocument.cpp
@@ -216,7 +216,7 @@
 
 void HTMLViewSourceDocument::finishLine()
 {
-    if (!m_current->hasChildNodes()) {
+    if (!m_current->hasChildren()) {
         RefPtr<HTMLBRElement> br = HTMLBRElement::create(*this);
         m_current->parserAppendChild(br);
     }
diff --git a/Source/core/html/ImageData.cpp b/Source/core/html/ImageData.cpp
index 64c86c9..bcba908 100644
--- a/Source/core/html/ImageData.cpp
+++ b/Source/core/html/ImageData.cpp
@@ -37,7 +37,7 @@
     dataSize *= size.width();
     dataSize *= size.height();
     if (dataSize.hasOverflowed())
-        return 0;
+        return nullptr;
 
     return adoptRef(new ImageData(size));
 }
@@ -48,11 +48,11 @@
     dataSize *= size.width();
     dataSize *= size.height();
     if (dataSize.hasOverflowed())
-        return 0;
+        return nullptr;
 
     if (dataSize.unsafeGet() < 0
         || static_cast<unsigned>(dataSize.unsafeGet()) > byteArray->length())
-        return 0;
+        return nullptr;
 
     return adoptRef(new ImageData(size, byteArray));
 }
diff --git a/Source/core/html/ImageDocument.cpp b/Source/core/html/ImageDocument.cpp
index d5d8eb2..193cbab 100644
--- a/Source/core/html/ImageDocument.cpp
+++ b/Source/core/html/ImageDocument.cpp
@@ -32,6 +32,9 @@
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/fetch/ImageResource.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
 #include "core/html/HTMLBodyElement.h"
 #include "core/html/HTMLHeadElement.h"
 #include "core/html/HTMLHtmlElement.h"
@@ -40,9 +43,6 @@
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/Settings.h"
 #include "wtf/text/StringBuilder.h"
 
 using std::min;
@@ -101,7 +101,7 @@
 
 static float pageZoomFactor(const Document* document)
 {
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
     return frame ? frame->pageZoomFactor() : 1;
 }
 
@@ -124,12 +124,15 @@
     if (!length)
         return;
 
-    Frame* frame = document()->frame();
+    LocalFrame* frame = document()->frame();
     Settings* settings = frame->settings();
     if (!frame->loader().client()->allowImage(!settings || settings->imagesEnabled(), document()->url()))
         return;
 
     document()->cachedImage()->appendData(data, length);
+    // Make sure the image renderer gets created because we need the renderer
+    // to read the aspect ratio. See crbug.com/320244
+    document()->updateStyleIfNeeded();
     document()->imageUpdated();
 }
 
@@ -162,7 +165,7 @@
 
 ImageDocument::ImageDocument(const DocumentInit& initializer)
     : HTMLDocument(initializer, ImageDocumentClass)
-    , m_imageElement(0)
+    , m_imageElement(nullptr)
     , m_imageSizeIsKnown(false)
     , m_didShrinkImage(false)
     , m_shouldShrinkImage(shouldShrinkToFit())
@@ -365,7 +368,7 @@
 
 void ImageDocument::dispose()
 {
-    m_imageElement = 0;
+    m_imageElement = nullptr;
     HTMLDocument::dispose();
 }
 
diff --git a/Source/core/html/LabelableElement.cpp b/Source/core/html/LabelableElement.cpp
index 8e522cc..db86358 100644
--- a/Source/core/html/LabelableElement.cpp
+++ b/Source/core/html/LabelableElement.cpp
@@ -42,9 +42,9 @@
 PassRefPtr<NodeList> LabelableElement::labels()
 {
     if (!supportLabels())
-        return 0;
+        return nullptr;
 
-    return ensureRareData().ensureNodeLists().addCache<LabelsNodeList>(this, LabelsNodeListType);
+    return ensureRareData().ensureNodeLists().addCache<LabelsNodeList>(*this, LabelsNodeListType);
 }
 
 } // namespace Webcore
diff --git a/Source/core/html/LabelableElement.h b/Source/core/html/LabelableElement.h
index f3d2188..4497557 100644
--- a/Source/core/html/LabelableElement.h
+++ b/Source/core/html/LabelableElement.h
@@ -55,7 +55,7 @@
     return node.isHTMLElement() && toHTMLElement(node).isLabelable();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(LabelableElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(LabelableElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/html/LabelsNodeList.cpp b/Source/core/html/LabelsNodeList.cpp
index e4934cc..1f6068c 100644
--- a/Source/core/html/LabelsNodeList.cpp
+++ b/Source/core/html/LabelsNodeList.cpp
@@ -33,19 +33,19 @@
 
 using namespace HTMLNames;
 
-LabelsNodeList::LabelsNodeList(ContainerNode* ownerNode)
+LabelsNodeList::LabelsNodeList(ContainerNode& ownerNode)
     : LiveNodeList(ownerNode, LabelsNodeListType, InvalidateOnForAttrChange, NodeListIsRootedAtDocument)
 {
 }
 
 LabelsNodeList::~LabelsNodeList()
 {
-    ownerNode()->nodeLists()->removeCache(this, LabelsNodeListType);
+    ownerNode().nodeLists()->removeCache(this, LabelsNodeListType);
 }
 
-bool LabelsNodeList::nodeMatches(const Element& testNode) const
+bool LabelsNodeList::elementMatches(const Element& element) const
 {
-    return testNode.hasTagName(labelTag) && toHTMLLabelElement(testNode).control() == ownerNode();
+    return isHTMLLabelElement(element) && toHTMLLabelElement(element).control() == ownerNode();
 }
 
 } // namespace WebCore
diff --git a/Source/core/html/LabelsNodeList.h b/Source/core/html/LabelsNodeList.h
index 919edb1..fd0b055 100644
--- a/Source/core/html/LabelsNodeList.h
+++ b/Source/core/html/LabelsNodeList.h
@@ -32,7 +32,7 @@
 
 class LabelsNodeList FINAL : public LiveNodeList {
 public:
-    static PassRefPtr<LabelsNodeList> create(ContainerNode* ownerNode, CollectionType type)
+    static PassRefPtr<LabelsNodeList> create(ContainerNode& ownerNode, CollectionType type)
     {
         ASSERT_UNUSED(type, type == LabelsNodeListType);
         return adoptRef(new LabelsNodeList(ownerNode));
@@ -41,9 +41,9 @@
     virtual ~LabelsNodeList();
 
 protected:
-    explicit LabelsNodeList(ContainerNode*);
+    explicit LabelsNodeList(ContainerNode&);
 
-    virtual bool nodeMatches(const Element&) const OVERRIDE;
+    virtual bool elementMatches(const Element&) const OVERRIDE;
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/LinkResource.cpp b/Source/core/html/LinkResource.cpp
index d12d5de..f25f231 100644
--- a/Source/core/html/LinkResource.cpp
+++ b/Source/core/html/LinkResource.cpp
@@ -32,8 +32,8 @@
 #include "core/html/LinkResource.h"
 
 #include "HTMLNames.h"
-#include "core/html/HTMLImport.h"
 #include "core/html/HTMLLinkElement.h"
+#include "core/html/imports/HTMLImport.h"
 
 namespace WebCore {
 
@@ -53,7 +53,7 @@
     return m_owner->document().frame() || m_owner->document().import();
 }
 
-Frame* LinkResource::loadingFrame() const
+LocalFrame* LinkResource::loadingFrame() const
 {
     HTMLImport* import = m_owner->document().import();
     if (!import)
diff --git a/Source/core/html/LinkResource.h b/Source/core/html/LinkResource.h
index a922639..81e715a 100644
--- a/Source/core/html/LinkResource.h
+++ b/Source/core/html/LinkResource.h
@@ -51,11 +51,11 @@
     virtual ~LinkResource();
 
     bool shouldLoadResource() const;
-    Frame* loadingFrame() const;
+    LocalFrame* loadingFrame() const;
 
     virtual Type type() const = 0;
     virtual void process() = 0;
-    virtual void ownerRemoved() = 0;
+    virtual void ownerRemoved() { }
     virtual bool hasLoaded() const = 0;
 
 protected:
diff --git a/Source/core/html/MediaController.cpp b/Source/core/html/MediaController.cpp
index 4493fe5..c7fb6b5 100644
--- a/Source/core/html/MediaController.cpp
+++ b/Source/core/html/MediaController.cpp
@@ -153,7 +153,7 @@
     if (m_position == MediaPlayer::invalidTime()) {
         // Some clocks may return times outside the range of [0..duration].
         m_position = max(0.0, min(duration(), m_clock->currentTime()));
-        m_clearPositionTimer.startOneShot(0);
+        m_clearPositionTimer.startOneShot(0, FROM_HERE);
     }
 
     return m_position;
@@ -261,7 +261,7 @@
     // If the new value is outside the range 0.0 to 1.0 inclusive, then, on setting, an
     // IndexSizeError exception must be raised instead.
     if (level < 0 || level > 1) {
-        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::failedToSet("volume", "MediaController", "The value provided (" + String::number(level) + ") is not in the range [0.0, 1.0]."));
+        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("volume", level, 0.0, ExceptionMessages::InclusiveBound, 1.0, ExceptionMessages::InclusiveBound));
         return;
     }
 
@@ -539,7 +539,7 @@
 {
     m_pendingEvents.append(Event::createCancelable(eventName));
     if (!m_asyncEventTimer.isActive())
-        m_asyncEventTimer.startOneShot(0);
+        m_asyncEventTimer.startOneShot(0, FROM_HERE);
 }
 
 void MediaController::asyncEventTimerFired(Timer<MediaController>*)
@@ -633,7 +633,7 @@
     if (m_timeupdateTimer.isActive())
         return;
 
-    m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency);
+    m_timeupdateTimer.startRepeating(maxTimeupdateEventFrequency, FROM_HERE);
 }
 
 void MediaController::timeupdateTimerFired(Timer<MediaController>*)
diff --git a/Source/core/html/MediaDocument.cpp b/Source/core/html/MediaDocument.cpp
index b5c820b..b7b9024 100644
--- a/Source/core/html/MediaDocument.cpp
+++ b/Source/core/html/MediaDocument.cpp
@@ -29,10 +29,11 @@
 
 #include "HTMLNames.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/dom/RawDataDocumentParser.h"
 #include "core/events/KeyboardEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLBodyElement.h"
 #include "core/html/HTMLHeadElement.h"
 #include "core/html/HTMLHtmlElement.h"
@@ -41,7 +42,6 @@
 #include "core/html/HTMLVideoElement.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
 #include "platform/KeyboardCodes.h"
 
 namespace WebCore {
@@ -129,18 +129,6 @@
     return MediaDocumentParser::create(this);
 }
 
-static inline HTMLVideoElement* descendentVideoElement(Node* root)
-{
-    ASSERT(root);
-
-    for (Node* node = root; node; node = NodeTraversal::next(*node, root)) {
-        if (node->hasTagName(videoTag))
-            return toHTMLVideoElement(node);
-    }
-
-    return 0;
-}
-
 void MediaDocument::defaultEventHandler(Event* event)
 {
     Node* targetNode = event->target()->toNode();
@@ -148,7 +136,7 @@
         return;
 
     if (event->type() == EventTypeNames::keydown && event->isKeyboardEvent()) {
-        HTMLVideoElement* video = descendentVideoElement(targetNode);
+        HTMLVideoElement* video = Traversal<HTMLVideoElement>::firstWithin(*targetNode);
         if (!video)
             return;
 
diff --git a/Source/core/html/MediaKeyEvent.cpp b/Source/core/html/MediaKeyEvent.cpp
index 38f02b7..d628a3c 100644
--- a/Source/core/html/MediaKeyEvent.cpp
+++ b/Source/core/html/MediaKeyEvent.cpp
@@ -63,4 +63,9 @@
     return EventNames::MediaKeyEvent;
 }
 
+void MediaKeyEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/html/MediaKeyEvent.h b/Source/core/html/MediaKeyEvent.h
index f6726a2..fb71127 100644
--- a/Source/core/html/MediaKeyEvent.h
+++ b/Source/core/html/MediaKeyEvent.h
@@ -68,6 +68,8 @@
     MediaKeyError* errorCode(bool& isNull) const { isNull = !m_errorCode; return m_errorCode.get(); }
     unsigned short systemCode() const { return m_systemCode; }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     MediaKeyEvent();
     MediaKeyEvent(const AtomicString& type, const MediaKeyEventInit& initializer);
diff --git a/Source/core/html/PluginDocument.cpp b/Source/core/html/PluginDocument.cpp
index 59451bf..c30a687 100644
--- a/Source/core/html/PluginDocument.cpp
+++ b/Source/core/html/PluginDocument.cpp
@@ -28,14 +28,14 @@
 #include "HTMLNames.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/RawDataDocumentParser.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLBodyElement.h"
 #include "core/html/HTMLEmbedElement.h"
 #include "core/html/HTMLHtmlElement.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/plugins/PluginView.h"
 #include "core/rendering/RenderEmbeddedObject.h"
 
@@ -54,7 +54,7 @@
 private:
     PluginDocumentParser(Document* document)
         : RawDataDocumentParser(document)
-        , m_embedElement(0)
+        , m_embedElement(nullptr)
     {
     }
 
@@ -76,7 +76,7 @@
     ASSERT(document());
     RELEASE_ASSERT(document()->loader());
 
-    Frame* frame = document()->frame();
+    LocalFrame* frame = document()->frame();
     if (!frame)
         return;
 
@@ -134,7 +134,7 @@
             view->didFinishLoading();
         else
             view->didFailLoading(error);
-        m_embedElement = 0;
+        m_embedElement = nullptr;
     }
     RawDataDocumentParser::finish();
 }
@@ -178,7 +178,7 @@
 void PluginDocument::detach(const AttachContext& context)
 {
     // Release the plugin node so that we don't have a circular reference.
-    m_pluginNode = 0;
+    m_pluginNode = nullptr;
     HTMLDocument::detach(context);
 }
 
diff --git a/Source/core/html/PublicURLManager.cpp b/Source/core/html/PublicURLManager.cpp
index ce41a3f..f084b7c 100644
--- a/Source/core/html/PublicURLManager.cpp
+++ b/Source/core/html/PublicURLManager.cpp
@@ -27,8 +27,10 @@
 #include "config.h"
 #include "core/html/PublicURLManager.h"
 
+#include "core/fetch/MemoryCache.h"
 #include "core/html/URLRegistry.h"
 #include "platform/weborigin/KURL.h"
+#include "wtf/Vector.h"
 #include "wtf/text/StringHash.h"
 
 namespace WebCore {
@@ -46,14 +48,14 @@
 {
 }
 
-void PublicURLManager::registerURL(SecurityOrigin* origin, const KURL& url, URLRegistrable* registrable)
+void PublicURLManager::registerURL(SecurityOrigin* origin, const KURL& url, URLRegistrable* registrable, const String& uuid)
 {
     if (m_isStopped)
         return;
 
-    RegistryURLMap::ValueType* found = m_registryToURL.add(&registrable->registry(), URLSet()).storedValue;
+    RegistryURLMap::ValueType* found = m_registryToURL.add(&registrable->registry(), URLMap()).storedValue;
     found->key->registerURL(origin, url, registrable);
-    found->value.add(url.string());
+    found->value.add(url.string(), uuid);
 }
 
 void PublicURLManager::revoke(const KURL& url)
@@ -67,6 +69,27 @@
     }
 }
 
+void PublicURLManager::revoke(const String& uuid)
+{
+    // A linear scan; revoking by UUID is assumed rare.
+    Vector<String> urlsToRemove;
+    for (RegistryURLMap::iterator i = m_registryToURL.begin(); i != m_registryToURL.end(); ++i) {
+        URLRegistry* registry = i->key;
+        URLMap& registeredURLs = i->value;
+        for (URLMap::iterator j = registeredURLs.begin(); j != registeredURLs.end(); ++j) {
+            if (uuid == j->value) {
+                KURL url(ParsedURLString, j->key);
+                MemoryCache::removeURLFromCache(executionContext(), url);
+                registry->unregisterURL(url);
+                urlsToRemove.append(j->key);
+            }
+        }
+        for (unsigned j = 0; j < urlsToRemove.size(); j++)
+            registeredURLs.remove(urlsToRemove[j]);
+        urlsToRemove.clear();
+    }
+}
+
 void PublicURLManager::stop()
 {
     if (m_isStopped)
@@ -74,8 +97,8 @@
 
     m_isStopped = true;
     for (RegistryURLMap::iterator i = m_registryToURL.begin(); i != m_registryToURL.end(); ++i) {
-        for (URLSet::iterator j = i->value.begin(); j != i->value.end(); ++j)
-            i->key->unregisterURL(KURL(ParsedURLString, *j));
+        for (URLMap::iterator j = i->value.begin(); j != i->value.end(); ++j)
+            i->key->unregisterURL(KURL(ParsedURLString, j->key));
     }
 
     m_registryToURL.clear();
diff --git a/Source/core/html/PublicURLManager.h b/Source/core/html/PublicURLManager.h
index 02ae77d..094d42b 100644
--- a/Source/core/html/PublicURLManager.h
+++ b/Source/core/html/PublicURLManager.h
@@ -45,8 +45,9 @@
 public:
     static PassOwnPtr<PublicURLManager> create(ExecutionContext*);
 
-    void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*);
+    void registerURL(SecurityOrigin*, const KURL&, URLRegistrable*, const String& uuid = String());
     void revoke(const KURL&);
+    void revoke(const String& uuid);
 
     // ActiveDOMObject interface.
     virtual void stop() OVERRIDE;
@@ -54,12 +55,16 @@
 private:
     PublicURLManager(ExecutionContext*);
 
-    typedef HashSet<String> URLSet;
-    typedef HashMap<URLRegistry*, URLSet > RegistryURLMap;
+    // One or more URLs can be associated with the same unique ID.
+    // Objects need be revoked by unique ID in some cases.
+    typedef String URLString;
+    typedef HashMap<URLString, String> URLMap;
+    typedef HashMap<URLRegistry*, URLMap> RegistryURLMap;
+
     RegistryURLMap m_registryToURL;
     bool m_isStopped;
 };
 
 } // namespace WebCore
 
-#endif // PUBLICURLMANAGER_h
+#endif // PublicURLManager_h
diff --git a/Source/core/html/RadioNodeList.cpp b/Source/core/html/RadioNodeList.cpp
index d2c9f29..03a9034 100644
--- a/Source/core/html/RadioNodeList.cpp
+++ b/Source/core/html/RadioNodeList.cpp
@@ -37,8 +37,8 @@
 
 using namespace HTMLNames;
 
-RadioNodeList::RadioNodeList(ContainerNode* rootNode, const AtomicString& name, CollectionType type)
-    : LiveNodeList(rootNode, type, InvalidateForFormControls, rootNode->hasTagName(formTag) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
+RadioNodeList::RadioNodeList(ContainerNode& rootNode, const AtomicString& name, CollectionType type)
+    : LiveNodeList(rootNode, type, InvalidateForFormControls, isHTMLFormElement(rootNode) ? NodeListIsRootedAtDocument : NodeListIsRootedAtNode)
     , m_name(name)
     , m_onlyMatchImgElements(type == RadioImgNodeListType)
 {
@@ -47,18 +47,18 @@
 
 RadioNodeList::~RadioNodeList()
 {
-    ownerNode()->nodeLists()->removeCache(this, m_onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType, m_name);
+    ownerNode().nodeLists()->removeCache(this, m_onlyMatchImgElements ? RadioImgNodeListType : RadioNodeListType, m_name);
 }
 
-static inline HTMLInputElement* toRadioButtonInputElement(Node* node)
+static inline HTMLInputElement* toRadioButtonInputElement(Node& node)
 {
-    ASSERT(node->isElementNode());
-    if (!node->hasTagName(inputTag))
+    ASSERT(node.isElementNode());
+    if (!isHTMLInputElement(node))
         return 0;
-    HTMLInputElement* inputElement = toHTMLInputElement(node);
-    if (!inputElement->isRadioButton() || inputElement->value().isEmpty())
+    HTMLInputElement& inputElement = toHTMLInputElement(node);
+    if (!inputElement.isRadioButton() || inputElement.value().isEmpty())
         return 0;
-    return inputElement;
+    return &inputElement;
 }
 
 String RadioNodeList::value() const
@@ -67,7 +67,7 @@
         return String();
     for (unsigned i = 0; i < length(); ++i) {
         Node* node = item(i);
-        const HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+        const HTMLInputElement* inputElement = toRadioButtonInputElement(*node);
         if (!inputElement || !inputElement->checked())
             continue;
         return inputElement->value();
@@ -81,7 +81,7 @@
         return;
     for (unsigned i = 0; i < length(); ++i) {
         Node* node = item(i);
-        HTMLInputElement* inputElement = toRadioButtonInputElement(node);
+        HTMLInputElement* inputElement = toRadioButtonInputElement(*node);
         if (!inputElement || inputElement->value() != value)
             continue;
         inputElement->setChecked(true);
@@ -92,8 +92,8 @@
 bool RadioNodeList::checkElementMatchesRadioNodeListFilter(const Element& testElement) const
 {
     ASSERT(!m_onlyMatchImgElements);
-    ASSERT(testElement.hasTagName(objectTag) || testElement.isFormControlElement());
-    if (ownerNode()->hasTagName(formTag)) {
+    ASSERT(isHTMLObjectElement(testElement) || testElement.isFormControlElement());
+    if (isHTMLFormElement(ownerNode())) {
         HTMLFormElement* formElement = toHTMLElement(testElement).formOwner();
         if (!formElement || formElement != ownerNode())
             return false;
@@ -102,18 +102,18 @@
     return testElement.getIdAttribute() == m_name || testElement.getNameAttribute() == m_name;
 }
 
-bool RadioNodeList::nodeMatches(const Element& testElement) const
+bool RadioNodeList::elementMatches(const Element& element) const
 {
     if (m_onlyMatchImgElements)
-        return testElement.hasTagName(imgTag);
+        return isHTMLImageElement(element);
 
-    if (!testElement.hasTagName(objectTag) && !testElement.isFormControlElement())
+    if (!isHTMLObjectElement(element) && !element.isFormControlElement())
         return false;
 
-    if (testElement.hasTagName(inputTag) && toHTMLInputElement(testElement).isImageButton())
+    if (isHTMLInputElement(element) && toHTMLInputElement(element).isImageButton())
         return false;
 
-    return checkElementMatchesRadioNodeListFilter(testElement);
+    return checkElementMatchesRadioNodeListFilter(element);
 }
 
 } // namespace
diff --git a/Source/core/html/RadioNodeList.h b/Source/core/html/RadioNodeList.h
index df7d708..a0ae1b3 100644
--- a/Source/core/html/RadioNodeList.h
+++ b/Source/core/html/RadioNodeList.h
@@ -34,7 +34,7 @@
 
 class RadioNodeList FINAL : public LiveNodeList {
 public:
-    static PassRefPtr<RadioNodeList> create(ContainerNode* ownerNode, CollectionType type, const AtomicString& name)
+    static PassRefPtr<RadioNodeList> create(ContainerNode& ownerNode, CollectionType type, const AtomicString& name)
     {
         ASSERT_UNUSED(type, type == RadioNodeListType || type == RadioImgNodeListType);
         return adoptRef(new RadioNodeList(ownerNode, name, type));
@@ -46,11 +46,11 @@
     void setValue(const String&);
 
 private:
-    RadioNodeList(ContainerNode*, const AtomicString& name, CollectionType);
+    RadioNodeList(ContainerNode&, const AtomicString& name, CollectionType);
 
     bool checkElementMatchesRadioNodeListFilter(const Element&) const;
 
-    virtual bool nodeMatches(const Element&) const OVERRIDE;
+    virtual bool elementMatches(const Element&) const OVERRIDE;
 
     AtomicString m_name;
     const bool m_onlyMatchImgElements;
diff --git a/Source/core/html/TextMetrics.h b/Source/core/html/TextMetrics.h
index 9925831..f936067 100644
--- a/Source/core/html/TextMetrics.h
+++ b/Source/core/html/TextMetrics.h
@@ -39,14 +39,72 @@
     float width() const { return m_width; }
     void setWidth(float w) { m_width = w; }
 
+    float actualBoundingBoxLeft() const { return m_actualBoundingBoxLeft; }
+    void setActualBoundingBoxLeft(float actualBoundingBoxLeft) { m_actualBoundingBoxLeft = actualBoundingBoxLeft; }
+
+    float actualBoundingBoxRight() const { return m_actualBoundingBoxRight; }
+    void setActualBoundingBoxRight(float actualBoundingBoxRight) { m_actualBoundingBoxRight = actualBoundingBoxRight; }
+
+    float fontBoundingBoxAscent() const { return m_fontBoundingBoxAscent; }
+    void setFontBoundingBoxAscent(float fontBoundingBoxAscent) { m_fontBoundingBoxAscent = fontBoundingBoxAscent; }
+
+    float fontBoundingBoxDescent() const { return m_fontBoundingBoxDescent; }
+    void setFontBoundingBoxDescent(float fontBoundingBoxDescent) { m_fontBoundingBoxDescent = fontBoundingBoxDescent; }
+
+    float actualBoundingBoxAscent() const { return m_actualBoundingBoxAscent; }
+    void setActualBoundingBoxAscent(float actualBoundingBoxAscent) { m_actualBoundingBoxAscent = actualBoundingBoxAscent; }
+
+    float actualBoundingBoxDescent() const { return m_actualBoundingBoxDescent; }
+    void setActualBoundingBoxDescent(float actualBoundingBoxDescent) { m_actualBoundingBoxDescent = actualBoundingBoxDescent; }
+
+    float emHeightAscent() const { return m_emHeightAscent; }
+    void setEmHeightAscent(float emHeightAscent) { m_emHeightAscent = emHeightAscent; }
+
+    float emHeightDescent() const { return m_emHeightDescent; }
+    void setEmHeightDescent(float emHeightDescent) { m_emHeightDescent = emHeightDescent; }
+
+    float hangingBaseline() const { return m_hangingBaseline; }
+    void setHangingBaseline(float hangingBaseline) { m_hangingBaseline = hangingBaseline; }
+
+    float alphabeticBaseline() const { return m_alphabeticBaseline; }
+    void setAlphabeticBaseline(float alphabeticBaseline) { m_alphabeticBaseline = alphabeticBaseline; }
+
+    float ideographicBaseline() const { return m_ideographicBaseline; }
+    void setIdeographicBaseline(float ideographicBaseline) { m_ideographicBaseline = ideographicBaseline; }
+
 private:
     TextMetrics()
         : m_width(0)
+        , m_actualBoundingBoxLeft(0)
+        , m_actualBoundingBoxRight(0)
+        , m_fontBoundingBoxAscent(0)
+        , m_fontBoundingBoxDescent(0)
+        , m_actualBoundingBoxAscent(0)
+        , m_actualBoundingBoxDescent(0)
+        , m_emHeightAscent(0)
+        , m_emHeightDescent(0)
+        , m_hangingBaseline(0)
+        , m_alphabeticBaseline(0)
+        , m_ideographicBaseline(0)
     {
         ScriptWrappable::init(this);
     }
 
+    // x-direction
     float m_width;
+    float m_actualBoundingBoxLeft;
+    float m_actualBoundingBoxRight;
+
+    // y-direction
+    float m_fontBoundingBoxAscent;
+    float m_fontBoundingBoxDescent;
+    float m_actualBoundingBoxAscent;
+    float m_actualBoundingBoxDescent;
+    float m_emHeightAscent;
+    float m_emHeightDescent;
+    float m_hangingBaseline;
+    float m_alphabeticBaseline;
+    float m_ideographicBaseline;
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/TextMetrics.idl b/Source/core/html/TextMetrics.idl
index fc37998..14f1148 100644
--- a/Source/core/html/TextMetrics.idl
+++ b/Source/core/html/TextMetrics.idl
@@ -24,6 +24,20 @@
  */
 [
 ] interface TextMetrics {
+    // x-direction
     readonly attribute float width;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxLeft;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxRight;
+
+    // y-direction
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxAscent;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float fontBoundingBoxDescent;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxAscent;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float actualBoundingBoxDescent;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightAscent;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float emHeightDescent;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float hangingBaseline;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float alphabeticBaseline;
+    [RuntimeEnabled=ExperimentalCanvasFeatures] readonly attribute float ideographicBaseline;
 };
 
diff --git a/Source/core/html/TimeRanges.cpp b/Source/core/html/TimeRanges.cpp
index 407ff32..67c4cf9 100644
--- a/Source/core/html/TimeRanges.cpp
+++ b/Source/core/html/TimeRanges.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "core/html/TimeRanges.h"
 
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/ExceptionCode.h"
@@ -116,7 +117,7 @@
 double TimeRanges::start(unsigned index, ExceptionState& exceptionState) const
 {
     if (index >= length()) {
-        exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
+        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, length()));
         return 0;
     }
     return m_ranges[index].m_start;
@@ -125,7 +126,7 @@
 double TimeRanges::end(unsigned index, ExceptionState& exceptionState) const
 {
     if (index >= length()) {
-        exceptionState.throwDOMException(IndexSizeError, "The index provided (" + String::number(index) + ") is not less than the object's length (" + String::number(length()) + ").");
+        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, length()));
         return 0;
     }
     return m_ranges[index].m_end;
@@ -193,9 +194,9 @@
         if (time >= startTime && time <= endTime)
             return time;
         if (fabs(startTime - time) < closest)
-            closest = fabsf(startTime - time);
+            closest = fabs(startTime - time);
         else if (fabs(endTime - time) < closest)
-            closest = fabsf(endTime - time);
+            closest = fabs(endTime - time);
     }
     return closest;
 }
diff --git a/Source/core/html/canvas/ANGLEInstancedArrays.cpp b/Source/core/html/canvas/ANGLEInstancedArrays.cpp
index adaa8ef..08fac53 100644
--- a/Source/core/html/canvas/ANGLEInstancedArrays.cpp
+++ b/Source/core/html/canvas/ANGLEInstancedArrays.cpp
@@ -32,11 +32,11 @@
 
 #include "core/html/canvas/ANGLEInstancedArrays.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContext* context)
+ANGLEInstancedArrays::ANGLEInstancedArrays(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -47,17 +47,17 @@
 {
 }
 
-WebGLExtension::ExtensionName ANGLEInstancedArrays::name() const
+WebGLExtensionName ANGLEInstancedArrays::name() const
 {
     return ANGLEInstancedArraysName;
 }
 
-PassRefPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContext* context)
+PassRefPtr<ANGLEInstancedArrays> ANGLEInstancedArrays::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new ANGLEInstancedArrays(context));
 }
 
-bool ANGLEInstancedArrays::supported(WebGLRenderingContext* context)
+bool ANGLEInstancedArrays::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_ANGLE_instanced_arrays");
 }
diff --git a/Source/core/html/canvas/ANGLEInstancedArrays.h b/Source/core/html/canvas/ANGLEInstancedArrays.h
index 5004ec2..ac60478 100644
--- a/Source/core/html/canvas/ANGLEInstancedArrays.h
+++ b/Source/core/html/canvas/ANGLEInstancedArrays.h
@@ -36,23 +36,23 @@
 
 namespace WebCore {
 
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
 
 class ANGLEInstancedArrays FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<ANGLEInstancedArrays> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<ANGLEInstancedArrays> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~ANGLEInstancedArrays();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
     void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
     void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount);
     void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
 
 private:
-    ANGLEInstancedArrays(WebGLRenderingContext*);
+    ANGLEInstancedArrays(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/CanvasImageSource.h b/Source/core/html/canvas/CanvasImageSource.h
new file mode 100644
index 0000000..6c51714
--- /dev/null
+++ b/Source/core/html/canvas/CanvasImageSource.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2006, 2007, 2008 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2007 Alp Toker <alp@atoker.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef CanvasImageSource_h
+#define CanvasImageSource_h
+
+#include "wtf/PassRefPtr.h"
+
+namespace WebCore {
+
+class Image;
+class SecurityOrigin;
+
+enum SourceImageMode {
+    CopySourceImageIfVolatile,
+    DontCopySourceImage
+};
+
+enum SourceImageStatus {
+    NormalSourceImageStatus,
+    ExternalSourceImageStatus, // Shared with another GPU context
+    UndecodableSourceImageStatus, // Image element with a 'broken' image
+    ZeroSizeCanvasSourceImageStatus, // Source is a canvas with width or heigh of zero
+    IncompleteSourceImageStatus, // Image element with no source media
+    InvalidSourceImageStatus,
+};
+
+class CanvasImageSource {
+public:
+    virtual PassRefPtr<Image> getSourceImageForCanvas(SourceImageMode, SourceImageStatus* = 0) const = 0;
+
+    // IMPORTANT: Result must be independent of whether destinationContext is
+    // already tainted because this function may be used to determine whether
+    // a CanvasPattern is "origin clean", and that pattern may be used on
+    // another canvas, which may not be already tainted.
+    virtual bool wouldTaintOrigin(SecurityOrigin* destinationSecurityOrigin) const = 0;
+
+    virtual bool isVideoElement() const { return false; }
+
+    // Adjusts the source and destination rectangles for cases where the actual
+    // source image is a subregion of the image returned by getSourceImageForCanvas.
+    virtual void adjustDrawRects(FloatRect* srcRect, FloatRect* dstRect) const { }
+
+    virtual FloatSize sourceSize() const = 0;
+    virtual FloatSize defaultDestinationSize() const { return sourceSize(); }
+
+protected:
+    virtual ~CanvasImageSource() { }
+};
+
+} // namespace WebCore
+
+#endif
diff --git a/Source/core/html/canvas/CanvasPathMethods.cpp b/Source/core/html/canvas/CanvasPathMethods.cpp
index 4db53ac..879487b 100644
--- a/Source/core/html/canvas/CanvasPathMethods.cpp
+++ b/Source/core/html/canvas/CanvasPathMethods.cpp
@@ -135,7 +135,6 @@
 
 float adjustEndAngle(float startAngle, float endAngle, bool anticlockwise)
 {
-    float twoPi = 2 * piFloat;
     float newEndAngle = endAngle;
     /* http://www.whatwg.org/specs/web-apps/current-work/multipage/the-canvas-element.html#dom-context-2d-arc
      * If the anticlockwise argument is false and endAngle-startAngle is equal to or greater than 2pi, or,
@@ -143,10 +142,10 @@
      * then the arc is the whole circumference of this ellipse, and the point at startAngle along this circle's circumference,
      * measured in radians clockwise from the ellipse's semi-major axis, acts as both the start point and the end point.
      */
-    if (!anticlockwise && endAngle - startAngle >= twoPi)
-        newEndAngle = startAngle + twoPi;
-    else if (anticlockwise && startAngle - endAngle >= twoPi)
-        newEndAngle = startAngle - twoPi;
+    if (!anticlockwise && endAngle - startAngle >= twoPiFloat)
+        newEndAngle = startAngle + twoPiFloat;
+    else if (anticlockwise && startAngle - endAngle >= twoPiFloat)
+        newEndAngle = startAngle - twoPiFloat;
 
     /*
      * Otherwise, the arc is the path along the circumference of this ellipse from the start point to the end point,
@@ -159,9 +158,9 @@
      * We preserve backward-compatibility.
      */
     else if (!anticlockwise && startAngle > endAngle)
-        newEndAngle = startAngle + (twoPi - fmodf(startAngle - endAngle, twoPi));
+        newEndAngle = startAngle + (twoPiFloat - fmodf(startAngle - endAngle, twoPiFloat));
     else if (anticlockwise && startAngle < endAngle)
-        newEndAngle = startAngle - (twoPi - fmodf(endAngle - startAngle, twoPi));
+        newEndAngle = startAngle - (twoPiFloat - fmodf(endAngle - startAngle, twoPiFloat));
 
     ASSERT(ellipseIsRenderable(startAngle, newEndAngle));
     return newEndAngle;
@@ -180,17 +179,16 @@
 void canonicalizeAngle(float* startAngle, float* endAngle)
 {
     // Make 0 <= startAngle < 2*PI
-    float twoPi = 2 * piFloat;
     float newStartAngle = *startAngle;
     if (newStartAngle < 0)
-        newStartAngle = twoPi + fmodf(newStartAngle, -twoPi);
+        newStartAngle = twoPiFloat + fmodf(newStartAngle, -twoPiFloat);
     else
-        newStartAngle = fmodf(newStartAngle, twoPi);
+        newStartAngle = fmodf(newStartAngle, twoPiFloat);
 
     float delta = newStartAngle - *startAngle;
     *startAngle = newStartAngle;
     *endAngle = *endAngle + delta;
-    ASSERT(newStartAngle >= 0 && newStartAngle < twoPi);
+    ASSERT(newStartAngle >= 0 && newStartAngle < twoPiFloat);
 }
 
 /*
@@ -227,25 +225,24 @@
 void degenerateEllipse(CanvasPathMethods* path, float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise)
 {
     ASSERT(ellipseIsRenderable(startAngle, endAngle));
-    ASSERT(startAngle >= 0 && startAngle < 2 * piFloat);
+    ASSERT(startAngle >= 0 && startAngle < twoPiFloat);
     ASSERT((anticlockwise && (startAngle - endAngle) >= 0) || (!anticlockwise && (endAngle - startAngle) >= 0));
 
     FloatPoint center(x, y);
     AffineTransform rotationMatrix;
-    rotationMatrix.rotate(rad2deg(rotation));
+    rotationMatrix.rotateRadians(rotation);
     // First, if the object's path has any subpaths, then the method must add a straight line from the last point in the subpath to the start point of the arc.
     lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, startAngle)));
     if ((!radiusX && !radiusY) || startAngle == endAngle)
         return;
 
-    float halfPiFloat = piFloat * 0.5;
     if (!anticlockwise) {
-        // startAngle - fmodf(startAngle, halfPiFloat) + halfPiFloat is the one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi)
+        // startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat is the one of (0, 0.5Pi, Pi, 1.5Pi, 2Pi)
         // that is the closest to startAngle on the clockwise direction.
-        for (float angle = startAngle - fmodf(startAngle, halfPiFloat) + halfPiFloat; angle < endAngle; angle += halfPiFloat)
+        for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat) + piOverTwoFloat; angle < endAngle; angle += piOverTwoFloat)
             lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, angle)));
     } else {
-        for (float angle = startAngle - fmodf(startAngle, halfPiFloat); angle > endAngle; angle -= halfPiFloat)
+        for (float angle = startAngle - fmodf(startAngle, piOverTwoFloat); angle > endAngle; angle -= piOverTwoFloat)
             lineToFloatPoint(path, center + rotationMatrix.mapPoint(getPointOnEllipse(radiusX, radiusY, angle)));
     }
 
diff --git a/Source/core/html/canvas/CanvasPathMethods.h b/Source/core/html/canvas/CanvasPathMethods.h
index 100f95c..3de24b5 100644
--- a/Source/core/html/canvas/CanvasPathMethods.h
+++ b/Source/core/html/canvas/CanvasPathMethods.h
@@ -52,8 +52,29 @@
 
     virtual bool isTransformInvertible() const { return true; }
 
+    // CanvasPathMethods JS API.
+    static void closePath(CanvasPathMethods& object)
+        { object.closePath(); }
+    static void moveTo(CanvasPathMethods& object, float x, float y)
+        { object.moveTo(x, y); }
+    static void lineTo(CanvasPathMethods& object, float x, float y)
+        { object.lineTo(x, y); }
+    static void quadraticCurveTo(CanvasPathMethods& object, float cpx, float cpy, float x, float y)
+        { object.quadraticCurveTo(cpx, cpy, x, y); }
+    static void bezierCurveTo(CanvasPathMethods& object, float cp1x, float cp1y, float cp2x, float cp2y, float x, float y)
+        { object.bezierCurveTo(cp1x, cp1y, cp2x, cp2y, x, y); }
+    static void arcTo(CanvasPathMethods& object, float x0, float y0, float x1, float y1, float radius, ExceptionState& es)
+        { object.arcTo(x0, y0, x1, y1, radius, es); }
+    static void arc(CanvasPathMethods& object, float x, float y, float radius, float startAngle, float endAngle, bool anticlockwise, ExceptionState& es)
+        { object.arc(x, y, radius, startAngle, endAngle, anticlockwise, es); }
+    static void ellipse(CanvasPathMethods& object, float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, bool anticlockwise, ExceptionState& es)
+        { object.ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle, anticlockwise, es); }
+    static void rect(CanvasPathMethods& object, float x, float y, float width, float height)
+        { object.rect(x, y, width, height); }
+
 protected:
     CanvasPathMethods() { }
+    CanvasPathMethods(const Path& path) : m_path(path) { }
     Path m_path;
 };
 }
diff --git a/Source/core/html/canvas/CanvasPathMethods.idl b/Source/core/html/canvas/CanvasPathMethods.idl
new file mode 100644
index 0000000..d2e79d3
--- /dev/null
+++ b/Source/core/html/canvas/CanvasPathMethods.idl
@@ -0,0 +1,18 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+[
+    NoInterfaceObject
+] interface CanvasPathMethods {
+
+    void closePath();
+    void moveTo(float x, float y);
+    void lineTo(float x, float y);
+    void quadraticCurveTo(float cpx, float cpy, float x, float y);
+    void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
+    [RaisesException] void arcTo(float x1, float y1, float x2, float y2, float radius);
+    void rect(float x, float y, float width, float height);
+    [RaisesException] void arc(float x, float y, float radius, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
+    [RaisesException] void ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
+};
diff --git a/Source/core/html/canvas/CanvasRenderingContext.cpp b/Source/core/html/canvas/CanvasRenderingContext.cpp
index 47a0e61..b2cb6fa 100644
--- a/Source/core/html/canvas/CanvasRenderingContext.cpp
+++ b/Source/core/html/canvas/CanvasRenderingContext.cpp
@@ -26,10 +26,6 @@
 #include "config.h"
 #include "core/html/canvas/CanvasRenderingContext.h"
 
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/html/canvas/CanvasPattern.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace WebCore {
@@ -37,72 +33,7 @@
 CanvasRenderingContext::CanvasRenderingContext(HTMLCanvasElement* canvas)
     : m_canvas(canvas)
 {
-    ScriptWrappable::init(this);
-}
 
-bool CanvasRenderingContext::wouldTaintOrigin(const CanvasPattern* pattern)
-{
-    if (canvas()->originClean() && pattern && !pattern->originClean())
-        return true;
-    return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLCanvasElement* sourceCanvas)
-{
-    if (canvas()->originClean() && sourceCanvas && !sourceCanvas->originClean())
-        return true;
-    return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLImageElement* image)
-{
-    if (!image || !canvas()->originClean())
-        return false;
-
-    ImageResource* cachedImage = image->cachedImage();
-    if (!cachedImage->image()->currentFrameHasSingleSecurityOrigin())
-        return true;
-
-    return wouldTaintOrigin(cachedImage->response().url()) && !cachedImage->passesAccessControlCheck(canvas()->securityOrigin());
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const HTMLVideoElement* video)
-{
-    // FIXME: This check is likely wrong when a redirect is involved. We need
-    // to test the finalURL. Please be careful when fixing this issue not to
-    // make currentSrc be the final URL because then the
-    // HTMLMediaElement.currentSrc DOM API would leak redirect destinations!
-    if (!video || !canvas()->originClean())
-        return false;
-
-    if (!video->hasSingleSecurityOrigin())
-        return true;
-
-    if (!(video->player() && video->player()->didPassCORSAccessCheck()) && wouldTaintOrigin(video->currentSrc()))
-        return true;
-
-    return false;
-}
-
-bool CanvasRenderingContext::wouldTaintOrigin(const KURL& url)
-{
-    if (!canvas()->originClean() || m_cleanURLs.contains(url.string()))
-        return false;
-
-    if (canvas()->securityOrigin()->taintsCanvas(url))
-        return true;
-
-    if (url.protocolIsData())
-        return false;
-
-    m_cleanURLs.add(url.string());
-    return false;
-}
-
-void CanvasRenderingContext::checkOrigin(const KURL& url)
-{
-    if (wouldTaintOrigin(url))
-        canvas()->setOriginTainted();
 }
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/CanvasRenderingContext.h b/Source/core/html/canvas/CanvasRenderingContext.h
index 2f5cd63..f4140d9 100644
--- a/Source/core/html/canvas/CanvasRenderingContext.h
+++ b/Source/core/html/canvas/CanvasRenderingContext.h
@@ -26,7 +26,6 @@
 #ifndef CanvasRenderingContext_h
 #define CanvasRenderingContext_h
 
-#include "bindings/v8/ScriptWrappable.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "wtf/HashSet.h"
 #include "wtf/Noncopyable.h"
@@ -36,14 +35,11 @@
 
 namespace WebCore {
 
-class CanvasPattern;
 class HTMLCanvasElement;
-class HTMLImageElement;
-class HTMLVideoElement;
 class KURL;
 class WebGLObject;
 
-class CanvasRenderingContext : public ScriptWrappable {
+class CanvasRenderingContext {
     WTF_MAKE_NONCOPYABLE(CanvasRenderingContext); WTF_MAKE_FAST_ALLOCATED;
 public:
     virtual ~CanvasRenderingContext() { }
@@ -60,25 +56,11 @@
     virtual void paintRenderingResultsToCanvas() {}
 
     virtual blink::WebLayer* platformLayer() const { return 0; }
-
 protected:
     CanvasRenderingContext(HTMLCanvasElement*);
-    bool wouldTaintOrigin(const CanvasPattern*);
-    bool wouldTaintOrigin(const HTMLCanvasElement*);
-    bool wouldTaintOrigin(const HTMLImageElement*);
-    bool wouldTaintOrigin(const HTMLVideoElement*);
-    bool wouldTaintOrigin(const KURL&);
-
-    template<class T> void checkOrigin(const T* arg)
-    {
-        if (wouldTaintOrigin(arg))
-            canvas()->setOriginTainted();
-    }
-    void checkOrigin(const KURL&);
 
 private:
     HTMLCanvasElement* m_canvas;
-    HashSet<String> m_cleanURLs;
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/CanvasRenderingContext.idl b/Source/core/html/canvas/CanvasRenderingContext.idl
deleted file mode 100644
index ae89a5f..0000000
--- a/Source/core/html/canvas/CanvasRenderingContext.idl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2009 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-[
-    Custom=Wrap,
-    NoInterfaceObject,
-] interface CanvasRenderingContext {
-    readonly attribute HTMLCanvasElement canvas;
-};
-
diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.cpp b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
index eca1634..ef14b3f 100644
--- a/Source/core/html/canvas/CanvasRenderingContext2D.cpp
+++ b/Source/core/html/canvas/CanvasRenderingContext2D.cpp
@@ -44,6 +44,7 @@
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/fetch/ImageResource.h"
+#include "core/frame/ImageBitmap.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLMediaElement.h"
@@ -53,17 +54,15 @@
 #include "core/html/canvas/CanvasGradient.h"
 #include "core/html/canvas/CanvasPattern.h"
 #include "core/html/canvas/CanvasStyle.h"
-#include "core/html/canvas/DOMPath.h"
-#include "core/frame/ImageBitmap.h"
+#include "core/html/canvas/Path2D.h"
 #include "core/rendering/RenderImage.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderTheme.h"
 #include "platform/fonts/FontCache.h"
 #include "platform/geometry/FloatQuad.h"
+#include "platform/graphics/DrawLooperBuilder.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
-#include "platform/graphics/DrawLooper.h"
 #include "platform/text/TextRun.h"
-#include "platform/weborigin/SecurityOrigin.h"
 #include "wtf/CheckedArithmetic.h"
 #include "wtf/MathExtras.h"
 #include "wtf/OwnPtr.h"
@@ -290,8 +289,9 @@
             style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
         else
             style = CanvasStyle::createFromRGBA(currentColor(canvas()));
-    } else
-        checkOrigin(style->canvasPattern());
+    } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+        canvas()->setOriginTainted();
+    }
 
     realizeSaves();
     modifiableState().m_strokeStyle = style.release();
@@ -322,8 +322,9 @@
             style = CanvasStyle::createFromRGBA(colorWithOverrideAlpha(currentColor(canvas()), style->overrideAlpha()));
         else
             style = CanvasStyle::createFromRGBA(currentColor(canvas()));
-    } else
-        checkOrigin(style->canvasPattern());
+    } else if (canvas()->originClean() && style->canvasPattern() && !style->canvasPattern()->originClean()) {
+        canvas()->setOriginTainted();
+    }
 
     realizeSaves();
     modifiableState().m_fillStyle = style.release();
@@ -501,7 +502,7 @@
     // Spec requires the concatenation of two copies the dash list when the
     // number of elements is odd
     if (dash.size() % 2)
-        modifiableState().m_lineDash.append(dash);
+        modifiableState().m_lineDash.appendVector(dash);
 
     applyLineDash();
 }
@@ -548,7 +549,7 @@
     GraphicsContext* c = drawingContext();
     if (!c)
         return;
-    c->setAlpha(alpha);
+    c->setAlphaAsFloat(alpha);
 }
 
 String CanvasRenderingContext2D::globalCompositeOperation() const
@@ -573,9 +574,18 @@
     c->setCompositeOperation(op, blendMode);
 }
 
-void CanvasRenderingContext2D::setCurrentTransform(const SVGMatrix& matrix)
+void CanvasRenderingContext2D::setCurrentTransform(PassRefPtr<SVGMatrixTearOff> passMatrixTearOff, ExceptionState& exceptionState)
 {
-    setTransform(matrix.a(), matrix.b(), matrix.c(), matrix.d(), matrix.e(), matrix.f());
+    RefPtr<SVGMatrixTearOff> matrixTearOff = passMatrixTearOff;
+
+    // FIXME: bindings should do null checking and throw: http://crbug.com/321518
+    if (!matrixTearOff) {
+        exceptionState.throwTypeError("currentTransform only accepts a SVGMatrix.");
+        return;
+    }
+
+    const AffineTransform& transform = matrixTearOff->value();
+    setTransform(transform.a(), transform.b(), transform.c(), transform.d(), transform.e(), transform.f());
 }
 
 void CanvasRenderingContext2D::scale(float sx, float sy)
@@ -618,7 +628,7 @@
         return;
 
     AffineTransform newTransform = state().m_transform;
-    newTransform.rotate(angleInRadians / piDouble * 180.0);
+    newTransform.rotateRadians(angleInRadians);
     if (state().m_transform == newTransform)
         return;
 
@@ -631,7 +641,7 @@
 
     modifiableState().m_transform = newTransform;
     c->rotate(angleInRadians);
-    m_path.transform(AffineTransform().rotate(-angleInRadians / piDouble * 180.0));
+    m_path.transform(AffineTransform().rotateRadians(-angleInRadians));
 }
 
 void CanvasRenderingContext2D::translate(float tx, float ty)
@@ -733,7 +743,7 @@
     if (color == state().m_unparsedStrokeColor)
         return;
     realizeSaves();
-    setStrokeStyle(CanvasStyle::createFromString(color, &canvas()->document()));
+    setStrokeStyle(CanvasStyle::createFromString(color));
     modifiableState().m_unparsedStrokeColor = color;
 }
 
@@ -775,7 +785,7 @@
     if (color == state().m_unparsedFillColor)
         return;
     realizeSaves();
-    setFillStyle(CanvasStyle::createFromString(color, &canvas()->document()));
+    setFillStyle(CanvasStyle::createFromString(color));
     modifiableState().m_unparsedFillColor = color;
 }
 
@@ -817,12 +827,12 @@
     m_path.clear();
 }
 
-PassRefPtr<DOMPath> CanvasRenderingContext2D::currentPath()
+PassRefPtr<Path2D> CanvasRenderingContext2D::currentPath()
 {
-    return DOMPath::create(m_path);
+    return Path2D::create(m_path);
 }
 
-void CanvasRenderingContext2D::setCurrentPath(DOMPath* path)
+void CanvasRenderingContext2D::setCurrentPath(Path2D* path)
 {
     if (!path)
         return;
@@ -870,90 +880,178 @@
     return true;
 }
 
-void CanvasRenderingContext2D::fill(const String& windingRuleString)
+void CanvasRenderingContext2D::fillInternal(const Path& path, const String& windingRuleString)
 {
+    if (path.isEmpty()) {
+        return;
+    }
     GraphicsContext* c = drawingContext();
-    if (!c)
+    if (!c) {
         return;
-    if (!state().m_invertibleCTM)
+    }
+    if (!state().m_invertibleCTM) {
         return;
+    }
     FloatRect clipBounds;
-    if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+    if (!drawingContext()->getTransformedClipBounds(&clipBounds)) {
         return;
+    }
 
     // If gradient size is zero, then paint nothing.
     Gradient* gradient = c->fillGradient();
-    if (gradient && gradient->isZeroSize())
+    if (gradient && gradient->isZeroSize()) {
         return;
+    }
 
-    if (!m_path.isEmpty()) {
-        WindRule windRule = c->fillRule();
-        WindRule newWindRule = RULE_NONZERO;
-        if (!parseWinding(windingRuleString, newWindRule))
-            return;
-        c->setFillRule(newWindRule);
+    WindRule windRule = c->fillRule();
+    WindRule newWindRule = RULE_NONZERO;
+    if (!parseWinding(windingRuleString, newWindRule)) {
+        return;
+    }
+    c->setFillRule(newWindRule);
 
-        if (isFullCanvasCompositeMode(state().m_globalComposite)) {
-            fullCanvasCompositedFill(m_path);
-            didDraw(clipBounds);
-        } else if (state().m_globalComposite == CompositeCopy) {
-            clearCanvas();
-            c->fillPath(m_path);
-            didDraw(clipBounds);
-        } else {
-            FloatRect dirtyRect;
-            if (computeDirtyRect(m_path.boundingRect(), clipBounds, &dirtyRect)) {
-                c->fillPath(m_path);
-                didDraw(dirtyRect);
-            }
+    if (isFullCanvasCompositeMode(state().m_globalComposite)) {
+        fullCanvasCompositedFill(path);
+        didDraw(clipBounds);
+    } else if (state().m_globalComposite == CompositeCopy) {
+        clearCanvas();
+        c->fillPath(path);
+        didDraw(clipBounds);
+    } else {
+        FloatRect dirtyRect;
+        if (computeDirtyRect(path.boundingRect(), clipBounds, &dirtyRect)) {
+            c->fillPath(path);
+            didDraw(dirtyRect);
         }
+    }
 
-        c->setFillRule(windRule);
+    c->setFillRule(windRule);
+}
+
+void CanvasRenderingContext2D::fill(const String& windingRuleString)
+{
+    fillInternal(m_path, windingRuleString);
+}
+
+void CanvasRenderingContext2D::fill(Path2D* domPath, ExceptionState& exceptionState)
+{
+    fill(domPath, "nonzero", exceptionState);
+}
+
+void CanvasRenderingContext2D::fill(Path2D* domPath, const String& windingRuleString, ExceptionState& exceptionState)
+{
+    if (!domPath) {
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Path"));
+        return;
+    }
+
+    fillInternal(domPath->path(), windingRuleString);
+}
+
+void CanvasRenderingContext2D::strokeInternal(const Path& path)
+{
+    if (path.isEmpty()) {
+        return;
+    }
+    GraphicsContext* c = drawingContext();
+    if (!c) {
+        return;
+    }
+    if (!state().m_invertibleCTM) {
+        return;
+    }
+
+    // If gradient size is zero, then paint nothing.
+    Gradient* gradient = c->strokeGradient();
+    if (gradient && gradient->isZeroSize()) {
+        return;
+    }
+
+    FloatRect bounds = path.boundingRect();
+    inflateStrokeRect(bounds);
+    FloatRect dirtyRect;
+    if (computeDirtyRect(bounds, &dirtyRect)) {
+        c->strokePath(path);
+        didDraw(dirtyRect);
     }
 }
 
 void CanvasRenderingContext2D::stroke()
 {
-    GraphicsContext* c = drawingContext();
-    if (!c)
-        return;
-    if (!state().m_invertibleCTM)
-        return;
+    strokeInternal(m_path);
+}
 
-    // If gradient size is zero, then paint nothing.
-    Gradient* gradient = c->strokeGradient();
-    if (gradient && gradient->isZeroSize())
+void CanvasRenderingContext2D::stroke(Path2D* domPath, ExceptionState& exceptionState)
+{
+    if (!domPath) {
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Path"));
         return;
-
-    if (!m_path.isEmpty()) {
-        FloatRect bounds = m_path.boundingRect();
-        inflateStrokeRect(bounds);
-        FloatRect dirtyRect;
-        if (computeDirtyRect(bounds, &dirtyRect)) {
-            c->strokePath(m_path);
-            didDraw(dirtyRect);
-        }
     }
+
+    strokeInternal(domPath->path());
+}
+
+void CanvasRenderingContext2D::clipInternal(const Path& path, const String& windingRuleString)
+{
+    GraphicsContext* c = drawingContext();
+    if (!c) {
+        return;
+    }
+    if (!state().m_invertibleCTM) {
+        return;
+    }
+
+    WindRule newWindRule = RULE_NONZERO;
+    if (!parseWinding(windingRuleString, newWindRule)) {
+        return;
+    }
+
+    realizeSaves();
+    c->canvasClip(path, newWindRule);
 }
 
 void CanvasRenderingContext2D::clip(const String& windingRuleString)
 {
-    GraphicsContext* c = drawingContext();
-    if (!c)
-        return;
-    if (!state().m_invertibleCTM)
-        return;
+    clipInternal(m_path, windingRuleString);
+}
 
-    WindRule newWindRule = RULE_NONZERO;
-    if (!parseWinding(windingRuleString, newWindRule))
-        return;
+void CanvasRenderingContext2D::clip(Path2D* domPath, ExceptionState& exceptionState)
+{
+    clip(domPath, "nonzero", exceptionState);
+}
 
-    realizeSaves();
-    c->canvasClip(m_path, newWindRule);
+void CanvasRenderingContext2D::clip(Path2D* domPath, const String& windingRuleString, ExceptionState& exceptionState)
+{
+    if (!domPath) {
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Path"));
+        return;
+    }
+
+    clipInternal(domPath->path(), windingRuleString);
 }
 
 bool CanvasRenderingContext2D::isPointInPath(const float x, const float y, const String& windingRuleString)
 {
+    return isPointInPathInternal(m_path, x, y, windingRuleString);
+}
+
+bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, const float y, ExceptionState& exceptionState)
+{
+    return isPointInPath(domPath, x, y, "nonzero", exceptionState);
+}
+
+bool CanvasRenderingContext2D::isPointInPath(Path2D* domPath, const float x, const float y, const String& windingRuleString, ExceptionState& exceptionState)
+{
+    if (!domPath) {
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Path"));
+        return false;
+    }
+
+    return isPointInPathInternal(domPath->path(), x, y, windingRuleString);
+}
+
+bool CanvasRenderingContext2D::isPointInPathInternal(const Path& path, const float x, const float y, const String& windingRuleString)
+{
     GraphicsContext* c = drawingContext();
     if (!c)
         return false;
@@ -970,12 +1068,26 @@
     if (!parseWinding(windingRuleString, windRule))
         return false;
 
-    return m_path.contains(transformedPoint, windRule);
+    return path.contains(transformedPoint, windRule);
 }
 
-
 bool CanvasRenderingContext2D::isPointInStroke(const float x, const float y)
 {
+    return isPointInStrokeInternal(m_path, x, y);
+}
+
+bool CanvasRenderingContext2D::isPointInStroke(Path2D* domPath, const float x, const float y, ExceptionState& exceptionState)
+{
+    if (!domPath) {
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Path"));
+        return false;
+    }
+
+    return isPointInStrokeInternal(domPath->path(), x, y);
+}
+
+bool CanvasRenderingContext2D::isPointInStrokeInternal(const Path& path, const float x, const float y)
+{
     GraphicsContext* c = drawingContext();
     if (!c)
         return false;
@@ -994,7 +1106,7 @@
     strokeData.setLineJoin(getLineJoin());
     strokeData.setMiterLimit(miterLimit());
     strokeData.setLineDash(getLineDash(), lineDashOffset());
-    return m_path.strokeContains(transformedPoint, strokeData);
+    return path.strokeContains(transformedPoint, strokeData);
 }
 
 void CanvasRenderingContext2D::clearRect(float x, float y, float width, float height)
@@ -1023,7 +1135,7 @@
             context->save();
             saved = true;
         }
-        context->setAlpha(1);
+        context->setAlphaAsFloat(1);
     }
     if (state().m_globalComposite != CompositeSourceOver) {
         if (!saved) {
@@ -1178,7 +1290,7 @@
 
     if (shouldDrawShadows()) {
         c->setShadow(state().m_shadowOffset, state().m_shadowBlur, state().m_shadowColor,
-            DrawLooper::ShadowIgnoresTransforms);
+            DrawLooperBuilder::ShadowIgnoresTransforms);
     } else {
         c->clearShadow();
     }
@@ -1194,26 +1306,6 @@
     ImageSizeBeforeDevicePixelRatio
 };
 
-static LayoutSize sizeFor(HTMLImageElement* image, ImageSizeType sizeType)
-{
-    LayoutSize size;
-    ImageResource* cachedImage = image->cachedImage();
-    if (cachedImage) {
-        size = cachedImage->imageSizeForRenderer(image->renderer(), 1.0f); // FIXME: Not sure about this.
-
-        if (sizeType == ImageSizeAfterDevicePixelRatio && image->renderer() && image->renderer()->isRenderImage() && cachedImage->image() && !cachedImage->image()->hasRelativeWidth())
-            size.scale(toRenderImage(image->renderer())->imageDevicePixelRatio());
-    }
-    return size;
-}
-
-static IntSize sizeFor(HTMLVideoElement* video)
-{
-    if (MediaPlayer* player = video->player())
-        return player->naturalSize();
-    return IntSize();
-}
-
 static inline FloatRect normalizeRect(const FloatRect& rect)
 {
     return FloatRect(min(rect.x(), rect.maxX()),
@@ -1241,343 +1333,128 @@
     dstRect->move(offset);
 }
 
-void CanvasRenderingContext2D::drawImageInternal(Image* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode)
+static bool checkImageSource(CanvasImageSource* imageSource, ExceptionState& exceptionState)
 {
-    if (!image)
+    if (!imageSource) {
+        // FIXME: Message should mention ImageBitmap once that feature ships.
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, String("HTMLImageElement, HTMLCanvasElement or HTMLVideoElement")));
+        return false;
+    }
+    return true;
+}
+
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource, float x, float y, ExceptionState& exceptionState)
+{
+    if (!checkImageSource(imageSource, exceptionState))
         return;
+    FloatSize destRectSize = imageSource->defaultDestinationSize();
+    drawImage(imageSource, x, y, destRectSize.width(), destRectSize.height(), exceptionState);
+}
+
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
+    float x, float y, float width, float height, ExceptionState& exceptionState)
+{
+    if (!checkImageSource(imageSource, exceptionState))
+        return;
+    FloatSize sourceRectSize = imageSource->sourceSize();
+    drawImage(imageSource, 0, 0, sourceRectSize.width(), sourceRectSize.height(), x, y, width, height, exceptionState);
+}
+
+void CanvasRenderingContext2D::drawImage(CanvasImageSource* imageSource,
+    float sx, float sy, float sw, float sh,
+    float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
+{
+    GraphicsContext* c = drawingContext(); // Do not exit yet if !c because we may need to throw exceptions first
+    CompositeOperator op = c ? c->compositeOperation() : CompositeSourceOver;
+    blink::WebBlendMode blendMode = c ? c->blendModeOperation() : blink::WebBlendModeNormal;
+    drawImageInternal(imageSource, sx, sy, sw, sh, dx, dy, dw, dh, exceptionState, op, blendMode);
+}
+
+void CanvasRenderingContext2D::drawImageInternal(CanvasImageSource* imageSource,
+    float sx, float sy, float sw, float sh,
+    float dx, float dy, float dw, float dh, ExceptionState& exceptionState,
+    CompositeOperator op, blink::WebBlendMode blendMode)
+{
+    if (!checkImageSource(imageSource, exceptionState))
+        return;
+
+    RefPtr<Image> image;
+    SourceImageStatus sourceImageStatus;
+    if (!imageSource->isVideoElement()) {
+        SourceImageMode mode = canvas() == imageSource ? CopySourceImageIfVolatile : DontCopySourceImage; // Thunking for ==
+        image = imageSource->getSourceImageForCanvas(mode, &sourceImageStatus);
+        if (sourceImageStatus == UndecodableSourceImageStatus)
+            exceptionState.throwDOMException(InvalidStateError, "The HTMLImageElement provided is in the 'broken' state.");
+        if (!image || !image->width() || !image->height())
+            return;
+    }
 
     GraphicsContext* c = drawingContext();
     if (!c)
         return;
-    if (!state().m_invertibleCTM)
-        return;
-    FloatRect clipBounds;
-    if (!drawingContext()->getTransformedClipBounds(&clipBounds))
-        return;
 
-    if (rectContainsTransformedRect(dstRect, clipBounds)) {
-        c->drawImage(image, dstRect, srcRect, op, blendMode);
-        didDraw(clipBounds);
-    } else if (isFullCanvasCompositeMode(op)) {
-        fullCanvasCompositedDrawImage(image, dstRect, srcRect, op);
-        didDraw(clipBounds);
-    } else if (op == CompositeCopy) {
-        clearCanvas();
-        c->drawImage(image, dstRect, srcRect, op, blendMode);
-        didDraw(clipBounds);
-    } else {
-        FloatRect dirtyRect;
-        if (computeDirtyRect(dstRect, &dirtyRect)) {
-            c->drawImage(image, dstRect, srcRect, op, blendMode);
-            didDraw(dirtyRect);
-        }
-    }
-}
-
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap, float x, float y, ExceptionState& exceptionState)
-{
-    if (!bitmap) {
-        exceptionState.throwDOMException(TypeMismatchError, "The element provided is invalid.");
-        return;
-    }
-    drawImage(bitmap, x, y, bitmap->width(), bitmap->height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
-    float x, float y, float width, float height, ExceptionState& exceptionState)
-{
-    if (!bitmap) {
-        exceptionState.throwDOMException(TypeMismatchError, "The element provided is invalid.");
-        return;
-    }
-    if (!bitmap->bitmapRect().width() || !bitmap->bitmapRect().height())
-        return;
-
-    drawImage(bitmap, 0, 0, bitmap->width(), bitmap->height(), x, y, width, height, exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(ImageBitmap* bitmap,
-    float sx, float sy, float sw, float sh,
-    float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
-    if (!bitmap) {
-        exceptionState.throwDOMException(TypeMismatchError, "The element provided is invalid.");
-        return;
-    }
-
-    FloatRect srcRect(sx, sy, sw, sh);
-    FloatRect dstRect(dx, dy, dw, dh);
-    FloatRect bitmapRect = bitmap->bitmapRect();
-
-    if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
-        || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
-        return;
-
-    if (!dstRect.width() || !dstRect.height() || !srcRect.width() || !srcRect.height())
-        return;
-
-    ASSERT(bitmap->height() && bitmap->width());
-    FloatRect normalizedSrcRect = normalizeRect(srcRect);
-    FloatRect normalizedDstRect = normalizeRect(dstRect);
-
-    // Clip the rects to where the user thinks that the image is situated.
-    clipRectsToImageRect(IntRect(IntPoint(), bitmap->size()), &normalizedSrcRect, &normalizedDstRect);
-
-    FloatRect intersectRect = intersection(bitmapRect, normalizedSrcRect);
-    FloatRect actualSrcRect(intersectRect);
-
-    IntPoint bitmapOffset = bitmap->bitmapOffset();
-    actualSrcRect.move(bitmapOffset - bitmapRect.location());
-    FloatRect imageRect = FloatRect(bitmapOffset, bitmapRect.size());
-
-    FloatRect actualDstRect(FloatPoint(intersectRect.location() - normalizedSrcRect.location()), bitmapRect.size());
-    actualDstRect.scale(normalizedDstRect.width() / normalizedSrcRect.width() * intersectRect.width() / bitmapRect.width(),
-        normalizedDstRect.height() / normalizedSrcRect.height() * intersectRect.height() / bitmapRect.height());
-    actualDstRect.moveBy(normalizedDstRect.location());
-
-    if (!imageRect.intersects(actualSrcRect))
-        return;
-
-    RefPtr<Image> imageForRendering = bitmap->bitmapImage();
-    if (!imageForRendering)
-        return;
-
-    drawImageInternal(imageForRendering.get(), actualSrcRect, actualDstRect, state().m_globalComposite, state().m_globalBlend);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, float x, float y, ExceptionState& exceptionState)
-{
-    if (!image) {
-        exceptionState.throwDOMException(TypeMismatchError, "The image element provided is invalid.");
-        return;
-    }
-    LayoutSize destRectSize = sizeFor(image, ImageSizeAfterDevicePixelRatio);
-    drawImage(image, x, y, destRectSize.width(), destRectSize.height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
-    float x, float y, float width, float height, ExceptionState& exceptionState)
-{
-    if (!image) {
-        exceptionState.throwDOMException(TypeMismatchError, "The image element provided is invalid.");
-        return;
-    }
-    LayoutSize sourceRectSize = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
-    drawImage(image, FloatRect(0, 0, sourceRectSize.width(), sourceRectSize.height()), FloatRect(x, y, width, height), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image,
-    float sx, float sy, float sw, float sh,
-    float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
-    drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
-{
-    drawImage(image, srcRect, dstRect, state().m_globalComposite, state().m_globalBlend, exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLImageElement* image, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator& op, const blink::WebBlendMode& blendMode, ExceptionState& exceptionState)
-{
-    if (!image) {
-        exceptionState.throwDOMException(TypeMismatchError, "The image element provided is invalid.");
-        return;
-    }
-
-    if (!std::isfinite(dstRect.x()) || !std::isfinite(dstRect.y()) || !std::isfinite(dstRect.width()) || !std::isfinite(dstRect.height())
-        || !std::isfinite(srcRect.x()) || !std::isfinite(srcRect.y()) || !std::isfinite(srcRect.width()) || !std::isfinite(srcRect.height()))
-        return;
-
-    ImageResource* cachedImage = image->cachedImage();
-    if (!cachedImage || !image->complete())
-        return;
-
-    LayoutSize size = sizeFor(image, ImageSizeBeforeDevicePixelRatio);
-    if (!size.width() || !size.height() || !dstRect.width() || !dstRect.height() || !srcRect.width() || !srcRect.height())
-        return;
-
-    FloatRect normalizedSrcRect = normalizeRect(srcRect);
-    FloatRect normalizedDstRect = normalizeRect(dstRect);
-
-    FloatRect imageRect = FloatRect(FloatPoint(), size);
-    if (!imageRect.intersects(normalizedSrcRect))
-        return;
-
-    clipRectsToImageRect(imageRect, &normalizedSrcRect, &normalizedDstRect);
-
-    checkOrigin(image);
-
-    Image* imageForRendering = cachedImage->imageForRenderer(image->renderer());
-
-    // For images that depend on an unavailable container size, we need to fall back to the intrinsic
-    // object size. http://www.w3.org/TR/2dcontext2/#dom-context-2d-drawimage
-    // FIXME: Without a specified image size this should resolve against the canvas element's size, see: crbug.com/230163.
-    if (!image->renderer() && imageForRendering->usesContainerSize())
-        imageForRendering->setContainerSize(imageForRendering->size());
-
-    drawImageInternal(imageForRendering, normalizedSrcRect, normalizedDstRect, op, blendMode);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, float x, float y, ExceptionState& exceptionState)
-{
-    drawImage(sourceCanvas, 0, 0, sourceCanvas->width(), sourceCanvas->height(), x, y, sourceCanvas->width(), sourceCanvas->height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
-    float x, float y, float width, float height, ExceptionState& exceptionState)
-{
-    drawImage(sourceCanvas, FloatRect(0, 0, sourceCanvas->width(), sourceCanvas->height()), FloatRect(x, y, width, height), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas,
-    float sx, float sy, float sw, float sh,
-    float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
-    drawImage(sourceCanvas, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLCanvasElement* sourceCanvas, const FloatRect& srcRect,
-    const FloatRect& dstRect, ExceptionState& exceptionState)
-{
-    if (!sourceCanvas) {
-        exceptionState.throwDOMException(TypeMismatchError, "The canvas element provided is invalid.");
-        return;
-    }
-
-    FloatRect srcCanvasRect = FloatRect(FloatPoint(), sourceCanvas->size());
-
-    if (!srcCanvasRect.width() || !srcCanvasRect.height() || !srcRect.width() || !srcRect.height())
-        return;
-
-    FloatRect normalizedSrcRect = normalizeRect(srcRect);
-    FloatRect normalizedDstRect = normalizeRect(dstRect);
-
-    if (!srcCanvasRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
-        return;
-
-    clipRectsToImageRect(srcCanvasRect, &normalizedSrcRect, &normalizedDstRect);
-
-    GraphicsContext* c = drawingContext();
-    if (!c)
-        return;
     if (!state().m_invertibleCTM)
         return;
 
-    // FIXME: Do this through platform-independent GraphicsContext API.
-    ImageBuffer* buffer = sourceCanvas->buffer();
-    if (!buffer)
+    if (!std::isfinite(dx) || !std::isfinite(dy) || !std::isfinite(dw) || !std::isfinite(dh)
+        || !std::isfinite(sx) || !std::isfinite(sy) || !std::isfinite(sw) || !std::isfinite(sh)
+        || !dw || !dh || !sw || !sh)
         return;
 
     FloatRect clipBounds;
-    if (!drawingContext()->getTransformedClipBounds(&clipBounds))
+    if (!c->getTransformedClipBounds(&clipBounds))
         return;
 
-    checkOrigin(sourceCanvas);
+    FloatRect srcRect = normalizeRect(FloatRect(sx, sy, sw, sh));
+    FloatRect dstRect = normalizeRect(FloatRect(dx, dy, dw, dh));
 
-    // If we're drawing from one accelerated canvas 2d to another, avoid calling sourceCanvas->makeRenderingResultsAvailable()
-    // as that will do a readback to software.
-    CanvasRenderingContext* sourceContext = sourceCanvas->renderingContext();
-    // FIXME: Implement an accelerated path for drawing from a WebGL canvas to a 2d canvas when possible.
-    if (sourceContext && sourceContext->is3d())
-        sourceContext->paintRenderingResultsToCanvas();
+    clipRectsToImageRect(FloatRect(FloatPoint(), imageSource->sourceSize()), &srcRect, &dstRect);
 
-    if (rectContainsTransformedRect(normalizedDstRect, clipBounds)) {
-        c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
-        didDraw(clipBounds);
-    } else if (isFullCanvasCompositeMode(state().m_globalComposite)) {
-        fullCanvasCompositedDrawImage(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite);
-        didDraw(clipBounds);
-    } else if (state().m_globalComposite == CompositeCopy) {
-        clearCanvas();
-        c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
-        didDraw(clipBounds);
+    imageSource->adjustDrawRects(&srcRect, &dstRect);
+
+    if (srcRect.isEmpty())
+        return;
+
+    FloatRect dirtyRect = clipBounds;
+    if (imageSource->isVideoElement()) {
+        drawVideo(static_cast<HTMLVideoElement*>(imageSource), srcRect, dstRect);
+        computeDirtyRect(dstRect, clipBounds, &dirtyRect);
     } else {
-        FloatRect dirtyRect;
-        if (computeDirtyRect(normalizedDstRect, clipBounds, &dirtyRect)) {
-            c->drawImageBuffer(buffer, normalizedDstRect, normalizedSrcRect, state().m_globalComposite, state().m_globalBlend);
-            didDraw(dirtyRect);
+        if (rectContainsTransformedRect(dstRect, clipBounds)) {
+            c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+        } else if (isFullCanvasCompositeMode(op)) {
+            fullCanvasCompositedDrawImage(image.get(), dstRect, srcRect, op);
+        } else if (op == CompositeCopy) {
+            clearCanvas();
+            c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
+        } else {
+            FloatRect dirtyRect;
+            computeDirtyRect(dstRect, clipBounds, &dirtyRect);
+            c->drawImage(image.get(), dstRect, srcRect, op, blendMode);
         }
+
+        if (sourceImageStatus == ExternalSourceImageStatus && isAccelerated() && canvas()->buffer())
+            canvas()->buffer()->flush();
     }
 
-    // Flush canvas's ImageBuffer when drawImage from WebGL to HW accelerated 2d canvas
-    if (sourceContext && sourceContext->is3d() && is2d() && isAccelerated() && canvas()->buffer())
-        canvas()->buffer()->flush();
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, float x, float y, ExceptionState& exceptionState)
-{
-    if (!video) {
-        exceptionState.throwDOMException(TypeMismatchError, "The video element provided is invalid.");
-        return;
-    }
-    IntSize size = sizeFor(video);
-    drawImage(video, x, y, size.width(), size.height(), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
-    float x, float y, float width, float height, ExceptionState& exceptionState)
-{
-    if (!video) {
-        exceptionState.throwDOMException(TypeMismatchError, "The video element provided is invalid.");
-        return;
-    }
-    IntSize size = sizeFor(video);
-    drawImage(video, FloatRect(0, 0, size.width(), size.height()), FloatRect(x, y, width, height), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video,
-    float sx, float sy, float sw, float sh,
-    float dx, float dy, float dw, float dh, ExceptionState& exceptionState)
-{
-    drawImage(video, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), exceptionState);
-}
-
-void CanvasRenderingContext2D::drawImage(HTMLVideoElement* video, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState& exceptionState)
-{
-    if (!video) {
-        exceptionState.throwDOMException(TypeMismatchError, "The video element provided is invalid.");
-        return;
-    }
-
-    if (video->readyState() == HTMLMediaElement::HAVE_NOTHING || video->readyState() == HTMLMediaElement::HAVE_METADATA)
-        return;
-    if (!srcRect.width() || !srcRect.height())
-        return;
-
-    FloatRect videoRect = FloatRect(FloatPoint(), sizeFor(video));
-
-    FloatRect normalizedSrcRect = normalizeRect(srcRect);
-    FloatRect normalizedDstRect = normalizeRect(dstRect);
-
-    if (!videoRect.intersects(normalizedSrcRect) || !normalizedDstRect.width() || !normalizedDstRect.height())
-        return;
-
-    clipRectsToImageRect(videoRect, &normalizedSrcRect, &normalizedDstRect);
-
-    GraphicsContext* c = drawingContext();
-    if (!c)
-        return;
-    if (!state().m_invertibleCTM)
-        return;
-
-    checkOrigin(video);
-
-    FloatRect dirtyRect;
-    if (!computeDirtyRect(normalizedDstRect, &dirtyRect))
-        return;
-
-    GraphicsContextStateSaver stateSaver(*c);
-    c->clip(normalizedDstRect);
-    c->translate(normalizedDstRect.x(), normalizedDstRect.y());
-    c->scale(FloatSize(normalizedDstRect.width() / normalizedSrcRect.width(), normalizedDstRect.height() / normalizedSrcRect.height()));
-    c->translate(-normalizedSrcRect.x(), -normalizedSrcRect.y());
-    video->paintCurrentFrameInContext(c, IntRect(IntPoint(), sizeFor(video)));
-    stateSaver.restore();
+    if (canvas()->originClean() && imageSource->wouldTaintOrigin(canvas()->securityOrigin()))
+        canvas()->setOriginTainted();
 
     didDraw(dirtyRect);
 }
 
+void CanvasRenderingContext2D::drawVideo(HTMLVideoElement* video, FloatRect srcRect, FloatRect dstRect)
+{
+    GraphicsContext* c = drawingContext();
+    GraphicsContextStateSaver stateSaver(*c);
+    c->clip(dstRect);
+    c->translate(dstRect.x(), dstRect.y());
+    c->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()));
+    c->translate(-srcRect.x(), -srcRect.y());
+    video->paintCurrentFrameInContext(c, IntRect(IntPoint(), IntSize(video->videoWidth(), video->videoHeight())));
+    stateSaver.restore();
+}
+
 void CanvasRenderingContext2D::drawImageFromRect(HTMLImageElement* image,
     float sx, float sy, float sw, float sh,
     float dx, float dy, float dw, float dh,
@@ -1588,7 +1465,7 @@
     if (!parseCompositeAndBlendOperator(compositeOperation, op, blendOp) || blendOp != blink::WebBlendModeNormal)
         op = CompositeSourceOver;
 
-    drawImage(image, FloatRect(sx, sy, sw, sh), FloatRect(dx, dy, dw, dh), op, blink::WebBlendModeNormal, IGNORE_EXCEPTION);
+    drawImageInternal(image, sx, sy, sw, sh, dx, dy, dw, dh, IGNORE_EXCEPTION, op, blendOp);
 }
 
 void CanvasRenderingContext2D::setAlpha(float alpha)
@@ -1626,11 +1503,6 @@
     context->drawImage(image, dest, src, op);
 }
 
-static void drawImageToContext(ImageBuffer* imageBuffer, GraphicsContext* context, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
-{
-    context->drawImageBuffer(imageBuffer, dest, src, op);
-}
-
 template<class T> void  CanvasRenderingContext2D::fullCanvasCompositedDrawImage(T* image, const FloatRect& dest, const FloatRect& src, CompositeOperator op)
 {
     ASSERT(isFullCanvasCompositeMode(op));
@@ -1676,7 +1548,7 @@
         exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(y1, "y1"));
 
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), FloatPoint(x1, y1));
     return gradient.release();
@@ -1700,56 +1572,47 @@
         exceptionState.throwDOMException(IndexSizeError, String::format("The %s provided is less than 0.", r0 < 0 ? "r0" : "r1"));
 
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     RefPtr<CanvasGradient> gradient = CanvasGradient::create(FloatPoint(x0, y0), r0, FloatPoint(x1, y1), r1);
     return gradient.release();
 }
 
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLImageElement* image,
+PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(CanvasImageSource* imageSource,
     const String& repetitionType, ExceptionState& exceptionState)
 {
-    if (!image) {
-        exceptionState.throwDOMException(TypeMismatchError, "The image element provided is invalid.");
-        return 0;
+    if (!checkImageSource(imageSource, exceptionState))
+        return nullptr;
+    bool repeatX, repeatY;
+    CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
+    if (exceptionState.hadException())
+        return nullptr;
+
+    SourceImageStatus status;
+    RefPtr<Image> imageForRendering = imageSource->getSourceImageForCanvas(CopySourceImageIfVolatile, &status);
+
+    switch (status) {
+    case NormalSourceImageStatus:
+        break;
+    case ZeroSizeCanvasSourceImageStatus:
+        exceptionState.throwDOMException(InvalidStateError, String::format("The canvas %s is 0.", imageSource->sourceSize().width() ? "height" : "width"));
+        return nullptr;
+    case UndecodableSourceImageStatus:
+        exceptionState.throwDOMException(InvalidStateError, "Source image is in the 'broken' state.");
+        return nullptr;
+    case InvalidSourceImageStatus:
+        imageForRendering = Image::nullImage();
+        break;
+    case IncompleteSourceImageStatus:
+        return nullptr;
+    default:
+    case ExternalSourceImageStatus: // should not happen when mode is CopySourceImageIfVolatile
+        ASSERT_NOT_REACHED();
+        return nullptr;
     }
-    bool repeatX, repeatY;
-    CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
-    if (exceptionState.hadException())
-        return 0;
+    ASSERT(imageForRendering);
 
-    if (!image->complete())
-        return 0;
-
-    ImageResource* cachedImage = image->cachedImage();
-    Image* imageForRendering = cachedImage ? cachedImage->imageForRenderer(image->renderer()) : 0;
-    if (!imageForRendering)
-        return CanvasPattern::create(Image::nullImage(), repeatX, repeatY, true);
-
-    // We need to synthesize a container size if a renderer is not available to provide one.
-    if (!image->renderer() && imageForRendering->usesContainerSize())
-        imageForRendering->setContainerSize(imageForRendering->size());
-
-    bool originClean = cachedImage->isAccessAllowed(canvas()->securityOrigin());
-    return CanvasPattern::create(imageForRendering, repeatX, repeatY, originClean);
-}
-
-PassRefPtr<CanvasPattern> CanvasRenderingContext2D::createPattern(HTMLCanvasElement* canvas,
-    const String& repetitionType, ExceptionState& exceptionState)
-{
-    if (!canvas)
-        exceptionState.throwDOMException(TypeMismatchError, "The canvas element provided is invalid.");
-    else if (!canvas->width() || !canvas->height())
-        exceptionState.throwDOMException(InvalidStateError, String::format("The canvas %s is 0.", canvas->width() ? "height" : "width"));
-
-    if (exceptionState.hadException())
-        return 0;
-
-    bool repeatX, repeatY;
-    CanvasPattern::parseRepetitionType(repetitionType, repeatX, repeatY, exceptionState);
-    if (exceptionState.hadException())
-        return 0;
-    return CanvasPattern::create(canvas->copiedImage(), repeatX, repeatY, canvas->originClean());
+    return CanvasPattern::create(imageForRendering.release(), repeatX, repeatY, !imageSource->wouldTaintOrigin(canvas()->securityOrigin()));
 }
 
 bool CanvasRenderingContext2D::computeDirtyRect(const FloatRect& localRect, FloatRect* dirtyRect)
@@ -1807,22 +1670,19 @@
 
 static PassRefPtr<ImageData> createEmptyImageData(const IntSize& size)
 {
-    Checked<int, RecordOverflow> dataSize = 4;
-    dataSize *= size.width();
-    dataSize *= size.height();
-    if (dataSize.hasOverflowed())
-        return 0;
+    if (RefPtr<ImageData> data = ImageData::create(size)) {
+        data->data()->zeroFill();
+        return data.release();
+    }
 
-    RefPtr<ImageData> data = ImageData::create(size);
-    data->data()->zeroFill();
-    return data.release();
+    return nullptr;
 }
 
 PassRefPtr<ImageData> CanvasRenderingContext2D::createImageData(PassRefPtr<ImageData> imageData, ExceptionState& exceptionState) const
 {
     if (!imageData) {
-        exceptionState.throwDOMException(NotSupportedError, "The ImageData provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(1, "ImageData"));
+        return nullptr;
     }
 
     return createEmptyImageData(imageData->size());
@@ -1838,11 +1698,11 @@
         exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(sh, "source height"));
 
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     FloatSize logicalSize(fabs(sw), fabs(sh));
     if (!logicalSize.isExpressibleAsIntSize())
-        return 0;
+        return nullptr;
 
     IntSize size = expandedIntSize(logicalSize);
     if (size.width() < 1)
@@ -1874,7 +1734,7 @@
         exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(sh, "source height"));
 
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     if (sw < 0) {
         sx += sw;
@@ -1891,7 +1751,7 @@
     if (logicalRect.height() < 1)
         logicalRect.setHeight(1);
     if (!logicalRect.isExpressibleAsIntRect())
-        return 0;
+        return nullptr;
 
     IntRect imageDataRect = enclosingIntRect(logicalRect);
     ImageBuffer* buffer = canvas()->buffer();
@@ -1900,7 +1760,7 @@
 
     RefPtr<Uint8ClampedArray> byteArray = buffer->getUnmultipliedImageData(imageDataRect);
     if (!byteArray)
-        return 0;
+        return nullptr;
 
     return ImageData::create(imageDataRect.size(), byteArray.release());
 }
@@ -1908,7 +1768,7 @@
 void CanvasRenderingContext2D::putImageData(ImageData* data, float dx, float dy, ExceptionState& exceptionState)
 {
     if (!data) {
-        exceptionState.throwDOMException(TypeMismatchError, "The ImageData provided is invalid.");
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "ImageData"));
         return;
     }
     putImageData(data, dx, dy, 0, 0, data->width(), data->height(), exceptionState);
@@ -1918,7 +1778,7 @@
     float dirtyWidth, float dirtyHeight, ExceptionState& exceptionState)
 {
     if (!data)
-        exceptionState.throwDOMException(TypeMismatchError, "The ImageData provided is invalid.");
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "ImageData"));
     else if (!std::isfinite(dx))
         exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::notAFiniteNumber(dx, "dx"));
     else if (!std::isfinite(dy))
@@ -1973,11 +1833,11 @@
     StringBuilder serializedFont;
     const FontDescription& fontDescription = state().m_font.fontDescription();
 
-    if (fontDescription.italic())
+    if (fontDescription.style() == FontStyleItalic)
         serializedFont.appendLiteral("italic ");
     if (fontDescription.weight() == FontWeightBold)
         serializedFont.appendLiteral("bold ");
-    if (fontDescription.smallCaps() == FontSmallCapsOn)
+    if (fontDescription.variant() == FontVariantSmallCaps)
         serializedFont.appendLiteral("small-caps ");
 
     serializedFont.appendNumber(fontDescription.computedPixelSize());
@@ -2004,8 +1864,12 @@
 
 void CanvasRenderingContext2D::setFont(const String& newFont)
 {
+    // The style resolution required for rendering text is not available in frame-less documents.
+    if (!canvas()->document().frame())
+        return;
+
     MutableStylePropertyMap::iterator i = m_fetchedFonts.find(newFont);
-    RefPtr<MutableStylePropertySet> parsedStyle = i != m_fetchedFonts.end() ? i->value : 0;
+    RefPtr<MutableStylePropertySet> parsedStyle = i != m_fetchedFonts.end() ? i->value : nullptr;
 
     if (!parsedStyle) {
         parsedStyle = MutableStylePropertySet::create();
@@ -2122,10 +1986,42 @@
 
 PassRefPtr<TextMetrics> CanvasRenderingContext2D::measureText(const String& text)
 {
-    FontCachePurgePreventer fontCachePurgePreventer;
     RefPtr<TextMetrics> metrics = TextMetrics::create();
+
+    // The style resolution required for rendering text is not available in frame-less documents.
+    if (!canvas()->document().frame())
+        return metrics.release();
+
+    FontCachePurgePreventer fontCachePurgePreventer;
     canvas()->document().updateStyleIfNeeded();
-    metrics->setWidth(accessFont().width(TextRun(text)));
+    const Font& font = accessFont();
+    const TextRun textRun(text);
+    FloatRect textBounds = font.selectionRectForText(textRun, FloatPoint(), font.fontDescription().computedSize(), 0, -1, true);
+
+    // x direction
+    metrics->setWidth(font.width(textRun));
+    metrics->setActualBoundingBoxLeft(-textBounds.x());
+    metrics->setActualBoundingBoxRight(textBounds.maxX());
+
+    // y direction
+    const FontMetrics& fontMetrics = font.fontMetrics();
+    const float ascent = fontMetrics.floatAscent();
+    const float descent = fontMetrics.floatDescent();
+    const float baselineY = getFontBaseline(fontMetrics);
+
+    metrics->setFontBoundingBoxAscent(ascent - baselineY);
+    metrics->setFontBoundingBoxDescent(descent + baselineY);
+    metrics->setActualBoundingBoxAscent(-textBounds.y() - baselineY);
+    metrics->setActualBoundingBoxDescent(textBounds.maxY() + baselineY);
+
+    // Note : top/bottom and ascend/descend are currently the same, so there's no difference
+    //        between the EM box's top and bottom and the font's ascend and descend
+    metrics->setEmHeightAscent(0);
+    metrics->setEmHeightDescent(0);
+
+    metrics->setHangingBaseline(-0.8f * ascent + baselineY);
+    metrics->setAlphabeticBaseline(baselineY);
+    metrics->setIdeographicBaseline(descent + baselineY);
     return metrics.release();
 }
 
@@ -2141,6 +2037,10 @@
 
 void CanvasRenderingContext2D::drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth, bool useMaxWidth)
 {
+    // The style resolution required for rendering text is not available in frame-less documents.
+    if (!canvas()->document().frame())
+        return;
+
     // accessFont needs the style to be up to date, but updating style can cause script to run,
     // (e.g. due to autofocus) which can free the GraphicsContext, so update style before grabbing
     // the GraphicsContext.
@@ -2182,24 +2082,7 @@
 
     TextRun textRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override, true, TextRun::NoRounding);
     // Draw the item text at the correct point.
-    FloatPoint location(x, y);
-    switch (state().m_textBaseline) {
-    case TopTextBaseline:
-    case HangingTextBaseline:
-        location.setY(y + fontMetrics.ascent());
-        break;
-    case BottomTextBaseline:
-    case IdeographicTextBaseline:
-        location.setY(y - fontMetrics.descent());
-        break;
-    case MiddleTextBaseline:
-        location.setY(y - fontMetrics.descent() + fontMetrics.height() / 2);
-        break;
-    case AlphabeticTextBaseline:
-    default:
-         // Do nothing.
-        break;
-    }
+    FloatPoint location(x, y + getFontBaseline(fontMetrics));
 
     float fontWidth = font.width(TextRun(normalizedText, 0, 0, TextRun::AllowTrailingExpansion, direction, override));
 
@@ -2273,6 +2156,28 @@
     return state().m_font;
 }
 
+int CanvasRenderingContext2D::getFontBaseline(const FontMetrics& fontMetrics) const
+{
+    switch (state().m_textBaseline) {
+    case TopTextBaseline:
+        return fontMetrics.ascent();
+    case HangingTextBaseline:
+        // According to http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
+        // "FOP (Formatting Objects Processor) puts the hanging baseline at 80% of the ascender height"
+        return (fontMetrics.ascent() * 4) / 5;
+    case BottomTextBaseline:
+    case IdeographicTextBaseline:
+        return -fontMetrics.descent();
+    case MiddleTextBaseline:
+        return -fontMetrics.descent() + fontMetrics.height() / 2;
+    case AlphabeticTextBaseline:
+    default:
+        // Do nothing.
+        break;
+    }
+    return 0;
+}
+
 blink::WebLayer* CanvasRenderingContext2D::platformLayer() const
 {
     return canvas()->buffer() ? canvas()->buffer()->platformLayer() : 0;
@@ -2383,7 +2288,7 @@
         return;
 
     c->save();
-    c->setAlpha(1.0);
+    c->setAlphaAsFloat(1.0);
     c->clearShadow();
     c->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal);
 
diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.h b/Source/core/html/canvas/CanvasRenderingContext2D.h
index 90b1fc7..bb9d9df 100644
--- a/Source/core/html/canvas/CanvasRenderingContext2D.h
+++ b/Source/core/html/canvas/CanvasRenderingContext2D.h
@@ -26,11 +26,12 @@
 #ifndef CanvasRenderingContext2D_h
 #define CanvasRenderingContext2D_h
 
+#include "bindings/v8/ScriptWrappable.h"
 #include "core/css/CSSFontSelectorClient.h"
 #include "core/html/canvas/Canvas2DContextAttributes.h"
 #include "core/html/canvas/CanvasPathMethods.h"
 #include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/svg/SVGMatrix.h"
+#include "core/svg/SVGMatrixTearOff.h"
 #include "platform/fonts/Font.h"
 #include "platform/graphics/Color.h"
 #include "platform/geometry/FloatSize.h"
@@ -46,10 +47,11 @@
 
 namespace WebCore {
 
+class CanvasImageSource;
 class CanvasGradient;
 class CanvasPattern;
 class CanvasStyle;
-class DOMPath;
+class Path2D;
 class Element;
 class ExceptionState;
 class FloatRect;
@@ -63,7 +65,7 @@
 
 typedef HashMap<String, RefPtr<MutableStylePropertySet> > MutableStylePropertyMap;
 
-class CanvasRenderingContext2D FINAL : public CanvasRenderingContext, public CanvasPathMethods {
+class CanvasRenderingContext2D FINAL: public ScriptWrappable, public CanvasRenderingContext, public CanvasPathMethods {
 public:
     static PassOwnPtr<CanvasRenderingContext2D> create(HTMLCanvasElement* canvas, const Canvas2DContextAttributes* attrs, bool usesCSSCompatibilityParseMode)
     {
@@ -116,11 +118,11 @@
     void save() { ++m_stateStack.last().m_unrealizedSaveCount; }
     void restore();
 
-    SVGMatrix currentTransform() const
+    PassRefPtr<SVGMatrixTearOff> currentTransform() const
     {
-        return SVGMatrix(state().m_transform);
+        return SVGMatrixTearOff::create(state().m_transform);
     }
-    void setCurrentTransform(const SVGMatrix&);
+    void setCurrentTransform(PassRefPtr<SVGMatrixTearOff>, ExceptionState&);
 
     void scale(float sx, float sy);
     void rotate(float angleInRadians);
@@ -145,14 +147,22 @@
 
     void beginPath();
 
-    PassRefPtr<DOMPath> currentPath();
-    void setCurrentPath(DOMPath*);
+    PassRefPtr<Path2D> currentPath();
+    void setCurrentPath(Path2D*);
     void fill(const String& winding = "nonzero");
+    void fill(Path2D*, ExceptionState&);
+    void fill(Path2D*, const String& winding, ExceptionState&);
     void stroke();
+    void stroke(Path2D*, ExceptionState&);
     void clip(const String& winding = "nonzero");
+    void clip(Path2D*, ExceptionState&);
+    void clip(Path2D*, const String& winding, ExceptionState&);
 
     bool isPointInPath(const float x, const float y, const String& winding = "nonzero");
+    bool isPointInPath(Path2D*, const float x, const float y, ExceptionState&);
+    bool isPointInPath(Path2D*, const float x, const float y, const String& winding, ExceptionState&);
     bool isPointInStroke(const float x, const float y);
+    bool isPointInStroke(Path2D*, const float x, const float y, ExceptionState&);
 
     void clearRect(float x, float y, float width, float height);
     void fillRect(float x, float y, float width, float height);
@@ -168,22 +178,9 @@
 
     void clearShadow();
 
-    void drawImage(ImageBitmap*, float x, float y, ExceptionState&);
-    void drawImage(ImageBitmap*, float x, float y, float width, float height, ExceptionState&);
-    void drawImage(ImageBitmap*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
-    void drawImage(HTMLImageElement*, float x, float y, ExceptionState&);
-    void drawImage(HTMLImageElement*, float x, float y, float width, float height, ExceptionState&);
-    void drawImage(HTMLImageElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
-    void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
-    void drawImage(HTMLImageElement*, const FloatRect& srcRect, const FloatRect& dstRect, const CompositeOperator&, const blink::WebBlendMode&, ExceptionState&);
-    void drawImage(HTMLCanvasElement*, float x, float y, ExceptionState&);
-    void drawImage(HTMLCanvasElement*, float x, float y, float width, float height, ExceptionState&);
-    void drawImage(HTMLCanvasElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
-    void drawImage(HTMLCanvasElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
-    void drawImage(HTMLVideoElement*, float x, float y, ExceptionState&);
-    void drawImage(HTMLVideoElement*, float x, float y, float width, float height, ExceptionState&);
-    void drawImage(HTMLVideoElement*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
-    void drawImage(HTMLVideoElement*, const FloatRect& srcRect, const FloatRect& dstRect, ExceptionState&);
+    void drawImage(CanvasImageSource*, float x, float y, ExceptionState&);
+    void drawImage(CanvasImageSource*, float x, float y, float width, float height, ExceptionState&);
+    void drawImage(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&);
 
     void drawImageFromRect(HTMLImageElement*, float sx = 0, float sy = 0, float sw = 0, float sh = 0,
                            float dx = 0, float dy = 0, float dw = 0, float dh = 0, const String& compositeOperation = emptyString());
@@ -194,8 +191,7 @@
 
     PassRefPtr<CanvasGradient> createLinearGradient(float x0, float y0, float x1, float y1, ExceptionState&);
     PassRefPtr<CanvasGradient> createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, ExceptionState&);
-    PassRefPtr<CanvasPattern> createPattern(HTMLImageElement*, const String& repetitionType, ExceptionState&);
-    PassRefPtr<CanvasPattern> createPattern(HTMLCanvasElement*, const String& repetitionType, ExceptionState&);
+    PassRefPtr<CanvasPattern> createPattern(CanvasImageSource*, const String& repetitionType, ExceptionState&);
 
     PassRefPtr<ImageData> createImageData(PassRefPtr<ImageData>, ExceptionState&) const;
     PassRefPtr<ImageData> createImageData(float width, float height, ExceptionState&) const;
@@ -289,7 +285,6 @@
     void applyShadow();
     bool shouldDrawShadows() const;
 
-    void drawImageInternal(Image*, const FloatRect&, const FloatRect&, const CompositeOperator&, const blink::WebBlendMode&);
     bool computeDirtyRect(const FloatRect& localBounds, FloatRect*);
     bool computeDirtyRect(const FloatRect& localBounds, const FloatRect& transformedClipBounds, FloatRect*);
     void didDraw(const FloatRect&);
@@ -302,9 +297,20 @@
     void applyStrokePattern();
     void applyFillPattern();
 
+    void drawImageInternal(CanvasImageSource*, float sx, float sy, float sw, float sh, float dx, float dy, float dw, float dh, ExceptionState&, CompositeOperator, blink::WebBlendMode);
+    void drawVideo(HTMLVideoElement*, FloatRect srcRect, FloatRect dstRect);
+
+    void fillInternal(const Path&, const String& windingRuleString);
+    void strokeInternal(const Path&);
+    void clipInternal(const Path&, const String& windingRuleString);
+
+    bool isPointInPathInternal(const Path&, const float x, const float y, const String& windingRuleString);
+    bool isPointInStrokeInternal(const Path&, const float x, const float y);
+
     void drawTextInternal(const String& text, float x, float y, bool fill, float maxWidth = 0, bool useMaxWidth = false);
 
     const Font& accessFont();
+    int getFontBaseline(const FontMetrics&) const;
 
     void clearCanvas();
     bool rectContainsTransformedRect(const FloatRect&, const FloatRect&) const;
diff --git a/Source/core/html/canvas/CanvasRenderingContext2D.idl b/Source/core/html/canvas/CanvasRenderingContext2D.idl
index d99a6a0..b6b34f3 100644
--- a/Source/core/html/canvas/CanvasRenderingContext2D.idl
+++ b/Source/core/html/canvas/CanvasRenderingContext2D.idl
@@ -25,12 +25,14 @@
 
 enum CanvasWindingRule { "nonzero", "evenodd" };
 
-interface CanvasRenderingContext2D : CanvasRenderingContext {
+interface CanvasRenderingContext2D {
+
+    readonly attribute HTMLCanvasElement canvas;
 
     void save();
     void restore();
 
-    [RuntimeEnabled=ExperimentalCanvasFeatures, Immutable] attribute SVGMatrix currentTransform;
+    [StrictTypeChecking, RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException=Setter] attribute SVGMatrix currentTransform;
     void scale(float sx, float sy);
     void rotate(float angle);
     void translate(float tx, float ty);
@@ -63,24 +65,30 @@
 
     void beginPath();
 
-    attribute Path currentPath;
+    attribute Path2D currentPath;
 
-    // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
-    void closePath();
-    void moveTo(float x, float y);
-    void lineTo(float x, float y);
-    void quadraticCurveTo(float cpx, float cpy, float x, float y);
-    void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
-    [RaisesException] void arcTo(float x1, float y1, float x2, float y2, float radius);
-    void rect(float x, float y, float width, float height);
-    [RaisesException] void arc(float x, float y, float radius, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
-    [RaisesException] void ellipse(float x, float y, float radiusX, float radiusY, float rotation, float startAngle, float endAngle, [Default=Undefined] optional boolean anticlockwise);
-
-    void fill(optional CanvasWindingRule winding);
+    // FIXME: Simplify these using optional CanvasWindingRule once crbug.com/339000 gets fixed.
+    void fill();
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void fill(Path2D? path);
+    void fill(CanvasWindingRule winding);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void fill(Path2D? path, CanvasWindingRule winding);
     void stroke();
-    void clip(optional CanvasWindingRule winding);
-    boolean isPointInPath(float x, float y, optional CanvasWindingRule winding);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void stroke(Path2D? path);
+    // FIXME: Simplify these using optional CanvasWindingRule once crbug.com/339000 gets fixed.
+    void clip();
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void clip(Path2D? path);
+    void clip(CanvasWindingRule winding);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] void clip(Path2D? path, CanvasWindingRule winding);
+
+    // FIXME: Simplify these using optional CanvasWindingRule once crbug.com/339000 gets fixed.
+    boolean isPointInPath(float x, float y);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] boolean isPointInPath(Path2D? path, float x, float y);
+    boolean isPointInPath(float x, float y, CanvasWindingRule winding);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] boolean isPointInPath(Path2D? path, float x, float y, CanvasWindingRule winding);
+
+    // FIXME: Simplify these using optional CanvasWindingRule once crbug.com/339000 gets fixed.
     boolean isPointInStroke(float x, float y);
+    [RuntimeEnabled=ExperimentalCanvasFeatures, RaisesException] boolean isPointInStroke(Path2D? path, float x, float y);
 
     // text
     attribute DOMString font;
@@ -147,6 +155,7 @@
 
     [RaisesException] CanvasPattern createPattern(HTMLCanvasElement? canvas, [TreatNullAs=NullString] DOMString repetitionType);
     [RaisesException] CanvasPattern createPattern(HTMLImageElement? image, [TreatNullAs=NullString] DOMString repetitionType);
+    [RaisesException] CanvasPattern createPattern(HTMLVideoElement? image, [TreatNullAs=NullString] DOMString repetitionType);
     [RaisesException] ImageData createImageData(ImageData? imagedata);
     [RaisesException] ImageData createImageData(float sw, float sh);
 
@@ -170,3 +179,4 @@
     Canvas2DContextAttributes getContextAttributes();
 };
 
+CanvasRenderingContext2D implements CanvasPathMethods;
diff --git a/Source/core/html/canvas/CanvasStyle.cpp b/Source/core/html/canvas/CanvasStyle.cpp
index d722986..28877cd 100644
--- a/Source/core/html/canvas/CanvasStyle.cpp
+++ b/Source/core/html/canvas/CanvasStyle.cpp
@@ -42,13 +42,13 @@
 
 enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParsedSystemColor, ParseFailed };
 
-static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString, Document* document = 0)
+static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString)
 {
     if (equalIgnoringCase(colorString, "currentcolor"))
         return ParsedCurrentColor;
     if (BisonCSSParser::parseColor(parsedColor, colorString))
         return ParsedRGBA;
-    if (BisonCSSParser::parseSystemColor(parsedColor, colorString, document))
+    if (BisonCSSParser::parseSystemColor(parsedColor, colorString))
         return ParsedSystemColor;
     return ParseFailed;
 }
@@ -64,7 +64,7 @@
 
 bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas)
 {
-    ColorParseResult parseResult = parseColor(parsedColor, colorString, canvas ? &canvas->document() : 0);
+    ColorParseResult parseResult = parseColor(parsedColor, colorString);
     switch (parseResult) {
     case ParsedRGBA:
     case ParsedSystemColor:
@@ -123,10 +123,10 @@
 {
 }
 
-PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color, Document* document)
+PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color)
 {
     RGBA32 rgba;
-    ColorParseResult parseResult = parseColor(rgba, color, document);
+    ColorParseResult parseResult = parseColor(rgba, color);
     switch (parseResult) {
     case ParsedRGBA:
     case ParsedSystemColor:
@@ -134,10 +134,10 @@
     case ParsedCurrentColor:
         return adoptRef(new CanvasStyle(CurrentColor));
     case ParseFailed:
-        return 0;
+        return nullptr;
     default:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 }
 
@@ -151,23 +151,24 @@
     case ParsedCurrentColor:
         return adoptRef(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha));
     case ParseFailed:
-        return 0;
+        return nullptr;
     default:
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
 }
 
 PassRefPtr<CanvasStyle> CanvasStyle::createFromGradient(PassRefPtr<CanvasGradient> gradient)
 {
     if (!gradient)
-        return 0;
+        return nullptr;
     return adoptRef(new CanvasStyle(gradient));
 }
+
 PassRefPtr<CanvasStyle> CanvasStyle::createFromPattern(PassRefPtr<CanvasPattern> pattern)
 {
     if (!pattern)
-        return 0;
+        return nullptr;
     return adoptRef(new CanvasStyle(pattern));
 }
 
diff --git a/Source/core/html/canvas/CanvasStyle.h b/Source/core/html/canvas/CanvasStyle.h
index 526ab71..f939e3e 100644
--- a/Source/core/html/canvas/CanvasStyle.h
+++ b/Source/core/html/canvas/CanvasStyle.h
@@ -36,14 +36,13 @@
 
     class CanvasGradient;
     class CanvasPattern;
-    class Document;
     class GraphicsContext;
     class HTMLCanvasElement;
 
     class CanvasStyle : public RefCounted<CanvasStyle> {
     public:
         static PassRefPtr<CanvasStyle> createFromRGBA(RGBA32 rgba) { return adoptRef(new CanvasStyle(rgba)); }
-        static PassRefPtr<CanvasStyle> createFromString(const String& color, Document* = 0);
+        static PassRefPtr<CanvasStyle> createFromString(const String& color);
         static PassRefPtr<CanvasStyle> createFromStringWithOverrideAlpha(const String& color, float alpha);
         static PassRefPtr<CanvasStyle> createFromGrayLevelWithAlpha(float grayLevel, float alpha) { return adoptRef(new CanvasStyle(grayLevel, alpha)); }
         static PassRefPtr<CanvasStyle> createFromRGBAChannels(float r, float g, float b, float a) { return adoptRef(new CanvasStyle(r, g, b, a)); }
diff --git a/Source/core/html/canvas/DataView.cpp b/Source/core/html/canvas/DataView.cpp
index 7399476..41b6cb3 100644
--- a/Source/core/html/canvas/DataView.cpp
+++ b/Source/core/html/canvas/DataView.cpp
@@ -47,19 +47,19 @@
 {
     RefPtr<ArrayBuffer> buffer = ArrayBuffer::create(length, sizeof(uint8_t));
     if (!buffer.get())
-        return 0;
+        return nullptr;
     return create(buffer, 0, length);
 }
 
 PassRefPtr<DataView> DataView::create(PassRefPtr<ArrayBuffer> buffer, unsigned byteOffset, unsigned byteLength)
 {
     if (byteOffset > buffer->byteLength())
-        return 0;
+        return nullptr;
     CheckedInt<uint32_t> checkedOffset(byteOffset);
     CheckedInt<uint32_t> checkedLength(byteLength);
     CheckedInt<uint32_t> checkedMax = checkedOffset + checkedLength;
     if (!checkedMax.isValid() || checkedMax.value() > buffer->byteLength())
-        return 0;
+        return nullptr;
     return adoptRef(new DataView(buffer, byteOffset, byteLength));
 }
 
diff --git a/Source/core/html/canvas/EXTFragDepth.cpp b/Source/core/html/canvas/EXTFragDepth.cpp
index 16c7622..002deb3 100644
--- a/Source/core/html/canvas/EXTFragDepth.cpp
+++ b/Source/core/html/canvas/EXTFragDepth.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-EXTFragDepth::EXTFragDepth(WebGLRenderingContext* context)
+EXTFragDepth::EXTFragDepth(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName EXTFragDepth::name() const
+WebGLExtensionName EXTFragDepth::name() const
 {
     return EXTFragDepthName;
 }
 
-PassRefPtr<EXTFragDepth> EXTFragDepth::create(WebGLRenderingContext* context)
+PassRefPtr<EXTFragDepth> EXTFragDepth::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new EXTFragDepth(context));
 }
 
-bool EXTFragDepth::supported(WebGLRenderingContext* context)
+bool EXTFragDepth::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_EXT_frag_depth");
 }
diff --git a/Source/core/html/canvas/EXTFragDepth.h b/Source/core/html/canvas/EXTFragDepth.h
index 3c0563e..eee90dc 100644
--- a/Source/core/html/canvas/EXTFragDepth.h
+++ b/Source/core/html/canvas/EXTFragDepth.h
@@ -34,15 +34,15 @@
 
 class EXTFragDepth FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<EXTFragDepth> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<EXTFragDepth> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~EXTFragDepth();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    explicit EXTFragDepth(WebGLRenderingContext*);
+    explicit EXTFragDepth(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp b/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
index cf8775d..d98399a 100644
--- a/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
+++ b/Source/core/html/canvas/EXTTextureFilterAnisotropic.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContext* context)
+EXTTextureFilterAnisotropic::EXTTextureFilterAnisotropic(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName EXTTextureFilterAnisotropic::name() const
+WebGLExtensionName EXTTextureFilterAnisotropic::name() const
 {
     return EXTTextureFilterAnisotropicName;
 }
 
-PassRefPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContext* context)
+PassRefPtr<EXTTextureFilterAnisotropic> EXTTextureFilterAnisotropic::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new EXTTextureFilterAnisotropic(context));
 }
 
-bool EXTTextureFilterAnisotropic::supported(WebGLRenderingContext* context)
+bool EXTTextureFilterAnisotropic::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_EXT_texture_filter_anisotropic");
 }
diff --git a/Source/core/html/canvas/EXTTextureFilterAnisotropic.h b/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
index de1e77a..a69a9bc 100644
--- a/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
+++ b/Source/core/html/canvas/EXTTextureFilterAnisotropic.h
@@ -34,15 +34,15 @@
 
 class EXTTextureFilterAnisotropic FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<EXTTextureFilterAnisotropic> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~EXTTextureFilterAnisotropic();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    EXTTextureFilterAnisotropic(WebGLRenderingContext*);
+    EXTTextureFilterAnisotropic(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/OESElementIndexUint.cpp b/Source/core/html/canvas/OESElementIndexUint.cpp
index b8b872a..95fac41 100644
--- a/Source/core/html/canvas/OESElementIndexUint.cpp
+++ b/Source/core/html/canvas/OESElementIndexUint.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-OESElementIndexUint::OESElementIndexUint(WebGLRenderingContext* context)
+OESElementIndexUint::OESElementIndexUint(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName OESElementIndexUint::name() const
+WebGLExtensionName OESElementIndexUint::name() const
 {
     return OESElementIndexUintName;
 }
 
-PassRefPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContext* context)
+PassRefPtr<OESElementIndexUint> OESElementIndexUint::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new OESElementIndexUint(context));
 }
 
-bool OESElementIndexUint::supported(WebGLRenderingContext* context)
+bool OESElementIndexUint::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_OES_element_index_uint");
 }
diff --git a/Source/core/html/canvas/OESElementIndexUint.h b/Source/core/html/canvas/OESElementIndexUint.h
index cd050a4..f11ebd2 100644
--- a/Source/core/html/canvas/OESElementIndexUint.h
+++ b/Source/core/html/canvas/OESElementIndexUint.h
@@ -34,15 +34,15 @@
 
 class OESElementIndexUint FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<OESElementIndexUint> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<OESElementIndexUint> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~OESElementIndexUint();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    OESElementIndexUint(WebGLRenderingContext*);
+    OESElementIndexUint(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/OESStandardDerivatives.cpp b/Source/core/html/canvas/OESStandardDerivatives.cpp
index 251396c..49b7adf 100644
--- a/Source/core/html/canvas/OESStandardDerivatives.cpp
+++ b/Source/core/html/canvas/OESStandardDerivatives.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContext* context)
+OESStandardDerivatives::OESStandardDerivatives(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName OESStandardDerivatives::name() const
+WebGLExtensionName OESStandardDerivatives::name() const
 {
     return OESStandardDerivativesName;
 }
 
-PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContext* context)
+PassRefPtr<OESStandardDerivatives> OESStandardDerivatives::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new OESStandardDerivatives(context));
 }
 
-bool OESStandardDerivatives::supported(WebGLRenderingContext* context)
+bool OESStandardDerivatives::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_OES_standard_derivatives");
 }
diff --git a/Source/core/html/canvas/OESStandardDerivatives.h b/Source/core/html/canvas/OESStandardDerivatives.h
index e47e9c3..8eb7226 100644
--- a/Source/core/html/canvas/OESStandardDerivatives.h
+++ b/Source/core/html/canvas/OESStandardDerivatives.h
@@ -34,15 +34,15 @@
 
 class OESStandardDerivatives FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<OESStandardDerivatives> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<OESStandardDerivatives> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~OESStandardDerivatives();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    OESStandardDerivatives(WebGLRenderingContext*);
+    OESStandardDerivatives(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/OESTextureFloat.cpp b/Source/core/html/canvas/OESTextureFloat.cpp
index bc71c70..a949e5c 100644
--- a/Source/core/html/canvas/OESTextureFloat.cpp
+++ b/Source/core/html/canvas/OESTextureFloat.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-OESTextureFloat::OESTextureFloat(WebGLRenderingContext* context)
+OESTextureFloat::OESTextureFloat(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -44,17 +44,17 @@
 {
 }
 
-WebGLExtension::ExtensionName OESTextureFloat::name() const
+WebGLExtensionName OESTextureFloat::name() const
 {
     return OESTextureFloatName;
 }
 
-PassRefPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureFloat> OESTextureFloat::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new OESTextureFloat(context));
 }
 
-bool OESTextureFloat::supported(WebGLRenderingContext* context)
+bool OESTextureFloat::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_OES_texture_float");
 }
diff --git a/Source/core/html/canvas/OESTextureFloat.h b/Source/core/html/canvas/OESTextureFloat.h
index 29b7fcc..dfc5908 100644
--- a/Source/core/html/canvas/OESTextureFloat.h
+++ b/Source/core/html/canvas/OESTextureFloat.h
@@ -34,15 +34,15 @@
 
 class OESTextureFloat FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<OESTextureFloat> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<OESTextureFloat> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~OESTextureFloat();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    OESTextureFloat(WebGLRenderingContext*);
+    OESTextureFloat(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/OESTextureFloatLinear.cpp b/Source/core/html/canvas/OESTextureFloatLinear.cpp
index 29bd839..15a7cd3 100644
--- a/Source/core/html/canvas/OESTextureFloatLinear.cpp
+++ b/Source/core/html/canvas/OESTextureFloatLinear.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContext* context)
+OESTextureFloatLinear::OESTextureFloatLinear(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName OESTextureFloatLinear::name() const
+WebGLExtensionName OESTextureFloatLinear::name() const
 {
     return OESTextureFloatLinearName;
 }
 
-PassRefPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureFloatLinear> OESTextureFloatLinear::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new OESTextureFloatLinear(context));
 }
 
-bool OESTextureFloatLinear::supported(WebGLRenderingContext* context)
+bool OESTextureFloatLinear::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_OES_texture_float_linear");
 }
diff --git a/Source/core/html/canvas/OESTextureFloatLinear.h b/Source/core/html/canvas/OESTextureFloatLinear.h
index 0219b09..a0646cc 100644
--- a/Source/core/html/canvas/OESTextureFloatLinear.h
+++ b/Source/core/html/canvas/OESTextureFloatLinear.h
@@ -34,15 +34,15 @@
 
 class OESTextureFloatLinear FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<OESTextureFloatLinear> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<OESTextureFloatLinear> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~OESTextureFloatLinear();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    OESTextureFloatLinear(WebGLRenderingContext*);
+    OESTextureFloatLinear(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/OESTextureHalfFloat.cpp b/Source/core/html/canvas/OESTextureHalfFloat.cpp
index 6d792b6..dd7f119 100644
--- a/Source/core/html/canvas/OESTextureHalfFloat.cpp
+++ b/Source/core/html/canvas/OESTextureHalfFloat.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContext* context)
+OESTextureHalfFloat::OESTextureHalfFloat(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName OESTextureHalfFloat::name() const
+WebGLExtensionName OESTextureHalfFloat::name() const
 {
     return OESTextureHalfFloatName;
 }
 
-PassRefPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureHalfFloat> OESTextureHalfFloat::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new OESTextureHalfFloat(context));
 }
 
-bool OESTextureHalfFloat::supported(WebGLRenderingContext* context)
+bool OESTextureHalfFloat::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_OES_texture_half_float");
 }
diff --git a/Source/core/html/canvas/OESTextureHalfFloat.h b/Source/core/html/canvas/OESTextureHalfFloat.h
index 811f47c..dc5d917 100644
--- a/Source/core/html/canvas/OESTextureHalfFloat.h
+++ b/Source/core/html/canvas/OESTextureHalfFloat.h
@@ -34,15 +34,15 @@
 
 class OESTextureHalfFloat FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<OESTextureHalfFloat> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<OESTextureHalfFloat> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~OESTextureHalfFloat();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    OESTextureHalfFloat(WebGLRenderingContext*);
+    OESTextureHalfFloat(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp b/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
index 7f758d8..37ceabe 100644
--- a/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
+++ b/Source/core/html/canvas/OESTextureHalfFloatLinear.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContext* context)
+OESTextureHalfFloatLinear::OESTextureHalfFloatLinear(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName OESTextureHalfFloatLinear::name() const
+WebGLExtensionName OESTextureHalfFloatLinear::name() const
 {
     return OESTextureHalfFloatLinearName;
 }
 
-PassRefPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContext* context)
+PassRefPtr<OESTextureHalfFloatLinear> OESTextureHalfFloatLinear::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new OESTextureHalfFloatLinear(context));
 }
 
-bool OESTextureHalfFloatLinear::supported(WebGLRenderingContext* context)
+bool OESTextureHalfFloatLinear::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_OES_texture_half_float_linear");
 }
diff --git a/Source/core/html/canvas/OESTextureHalfFloatLinear.h b/Source/core/html/canvas/OESTextureHalfFloatLinear.h
index c817d7b..421bbbc 100644
--- a/Source/core/html/canvas/OESTextureHalfFloatLinear.h
+++ b/Source/core/html/canvas/OESTextureHalfFloatLinear.h
@@ -34,15 +34,15 @@
 
 class OESTextureHalfFloatLinear FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<OESTextureHalfFloatLinear> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~OESTextureHalfFloatLinear();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    OESTextureHalfFloatLinear(WebGLRenderingContext*);
+    OESTextureHalfFloatLinear(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/OESVertexArrayObject.cpp b/Source/core/html/canvas/OESVertexArrayObject.cpp
index 834b07c..9585e90 100644
--- a/Source/core/html/canvas/OESVertexArrayObject.cpp
+++ b/Source/core/html/canvas/OESVertexArrayObject.cpp
@@ -28,12 +28,12 @@
 #include "core/html/canvas/OESVertexArrayObject.h"
 
 #include "bindings/v8/ExceptionState.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 #include "core/html/canvas/WebGLVertexArrayObjectOES.h"
 
 namespace WebCore {
 
-OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContext* context)
+OESVertexArrayObject::OESVertexArrayObject(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -44,12 +44,12 @@
 {
 }
 
-WebGLExtension::ExtensionName OESVertexArrayObject::name() const
+WebGLExtensionName OESVertexArrayObject::name() const
 {
     return OESVertexArrayObjectName;
 }
 
-PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContext* context)
+PassRefPtr<OESVertexArrayObject> OESVertexArrayObject::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new OESVertexArrayObject(context));
 }
@@ -57,7 +57,7 @@
 PassRefPtr<WebGLVertexArrayObjectOES> OESVertexArrayObject::createVertexArrayOES()
 {
     if (isLost())
-        return 0;
+        return nullptr;
 
     RefPtr<WebGLVertexArrayObjectOES> o = WebGLVertexArrayObjectOES::create(m_context, WebGLVertexArrayObjectOES::VaoTypeUser);
     m_context->addContextObject(o.get());
@@ -70,7 +70,7 @@
         return;
 
     if (!arrayObject->isDefaultObject() && arrayObject == m_context->m_boundVertexArrayObject)
-        m_context->setBoundVertexArrayObject(0);
+        m_context->setBoundVertexArrayObject(nullptr);
 
     arrayObject->deleteObject(m_context->webGraphicsContext3D());
 }
@@ -103,11 +103,11 @@
         m_context->setBoundVertexArrayObject(arrayObject);
     } else {
         m_context->webGraphicsContext3D()->bindVertexArrayOES(0);
-        m_context->setBoundVertexArrayObject(0);
+        m_context->setBoundVertexArrayObject(nullptr);
     }
 }
 
-bool OESVertexArrayObject::supported(WebGLRenderingContext* context)
+bool OESVertexArrayObject::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_OES_vertex_array_object");
 }
diff --git a/Source/core/html/canvas/OESVertexArrayObject.h b/Source/core/html/canvas/OESVertexArrayObject.h
index d790bc0..3f616be 100644
--- a/Source/core/html/canvas/OESVertexArrayObject.h
+++ b/Source/core/html/canvas/OESVertexArrayObject.h
@@ -32,17 +32,17 @@
 
 namespace WebCore {
 
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
 class WebGLVertexArrayObjectOES;
 
 class OESVertexArrayObject FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<OESVertexArrayObject> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<OESVertexArrayObject> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~OESVertexArrayObject();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
     PassRefPtr<WebGLVertexArrayObjectOES> createVertexArrayOES();
     void deleteVertexArrayOES(WebGLVertexArrayObjectOES*);
@@ -50,7 +50,7 @@
     void bindVertexArrayOES(WebGLVertexArrayObjectOES*);
 
 private:
-    OESVertexArrayObject(WebGLRenderingContext*);
+    OESVertexArrayObject(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/Path.idl b/Source/core/html/canvas/Path.idl
deleted file mode 100644
index 66435a5..0000000
--- a/Source/core/html/canvas/Path.idl
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
- * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1.  Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- * 2.  Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
- * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
- * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
- * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
- * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-[
-    RuntimeEnabled=ExperimentalCanvasFeatures,
-    Constructor,
-    Constructor(Path path),
-    Constructor(DOMString text),
-    ImplementedAs=DOMPath
-] interface Path {
-
-    // FIXME: These methods should be shared with CanvasRenderingContext2D in the CanvasPathMethods interface.
-    void closePath();
-    void moveTo([Default=Undefined] optional float x,
-                [Default=Undefined] optional float y);
-    void lineTo([Default=Undefined] optional float x,
-                [Default=Undefined] optional float y);
-    void quadraticCurveTo([Default=Undefined] optional float cpx,
-                          [Default=Undefined] optional float cpy,
-                          [Default=Undefined] optional float x,
-                          [Default=Undefined] optional float y);
-    void bezierCurveTo([Default=Undefined] optional float cp1x,
-                       [Default=Undefined] optional float cp1y,
-                       [Default=Undefined] optional float cp2x,
-                       [Default=Undefined] optional float cp2y,
-                       [Default=Undefined] optional float x,
-                       [Default=Undefined] optional float y);
-    [RaisesException] void arcTo([Default=Undefined] optional float x1,
-               [Default=Undefined] optional float y1,
-               [Default=Undefined] optional float x2,
-               [Default=Undefined] optional float y2,
-               [Default=Undefined] optional float radius);
-    void rect([Default=Undefined] optional float x,
-              [Default=Undefined] optional float y,
-              [Default=Undefined] optional float width,
-              [Default=Undefined] optional float height);
-    [RaisesException] void arc([Default=Undefined] optional float x,
-             [Default=Undefined] optional float y,
-             [Default=Undefined] optional float radius,
-             [Default=Undefined] optional float startAngle,
-             [Default=Undefined] optional float endAngle,
-             [Default=Undefined] optional boolean anticlockwise);
-};
diff --git a/Source/core/html/canvas/DOMPath.h b/Source/core/html/canvas/Path2D.h
similarity index 60%
rename from Source/core/html/canvas/DOMPath.h
rename to Source/core/html/canvas/Path2D.h
index abb01a6..bc88663 100644
--- a/Source/core/html/canvas/DOMPath.h
+++ b/Source/core/html/canvas/Path2D.h
@@ -25,50 +25,60 @@
  * SUCH DAMAGE.
  */
 
-#ifndef DOMPath_h
-#define DOMPath_h
+#ifndef Path2D_h
+#define Path2D_h
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/html/canvas/CanvasPathMethods.h"
+#include "core/svg/SVGMatrixTearOff.h"
 #include "core/svg/SVGPathUtilities.h"
+#include "platform/transforms/AffineTransform.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-class DOMPath FINAL : public RefCounted<DOMPath>, public CanvasPathMethods, public ScriptWrappable {
-    WTF_MAKE_NONCOPYABLE(DOMPath); WTF_MAKE_FAST_ALLOCATED;
+class Path2D FINAL : public RefCounted<Path2D>, public CanvasPathMethods, public ScriptWrappable {
+    WTF_MAKE_NONCOPYABLE(Path2D); WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassRefPtr<DOMPath> create() { return adoptRef(new DOMPath); }
-    static PassRefPtr<DOMPath> create(const String& pathData) { return adoptRef(new DOMPath(pathData)); }
-    static PassRefPtr<DOMPath> create(DOMPath* path) { return adoptRef(new DOMPath(path)); }
+    static PassRefPtr<Path2D> create() { return adoptRef(new Path2D); }
+    static PassRefPtr<Path2D> create(const String& pathData) { return adoptRef(new Path2D(pathData)); }
+    static PassRefPtr<Path2D> create(Path2D* path) { return adoptRef(new Path2D(path)); }
 
-    static PassRefPtr<DOMPath> create(const Path& path) { return adoptRef(new DOMPath(path)); }
+    static PassRefPtr<Path2D> create(const Path& path) { return adoptRef(new Path2D(path)); }
 
     const Path& path() const { return m_path; }
 
-    virtual ~DOMPath() { }
+
+    void addPath(Path2D* path, SVGMatrixTearOff* transform, ExceptionState& exceptionState)
+    {
+        if (!path) {
+            exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Path"));
+            return;
+        }
+        Path src = path->path();
+        m_path.addPath(src, transform ? transform->value() : AffineTransform(1, 0, 0, 1, 0, 0));
+    }
+    virtual ~Path2D() { }
 private:
-    DOMPath() : CanvasPathMethods()
+    Path2D() : CanvasPathMethods()
     {
         ScriptWrappable::init(this);
     }
 
-    DOMPath(const Path& path)
-        : CanvasPathMethods()
+    Path2D(const Path& path)
+        : CanvasPathMethods(path)
     {
         ScriptWrappable::init(this);
-        m_path = path;
     }
 
-    DOMPath(DOMPath* path)
-        : CanvasPathMethods()
+    Path2D(Path2D* path)
+        : CanvasPathMethods(path->path())
     {
         ScriptWrappable::init(this);
-        m_path = path->path();
     }
 
-    DOMPath(const String& pathData)
+    Path2D(const String& pathData)
         : CanvasPathMethods()
     {
         ScriptWrappable::init(this);
diff --git a/Source/core/html/canvas/Path2D.idl b/Source/core/html/canvas/Path2D.idl
new file mode 100644
index 0000000..b67de6c
--- /dev/null
+++ b/Source/core/html/canvas/Path2D.idl
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2006 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2012, 2013 Adobe Systems Incorporated. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+ * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+[
+    RuntimeEnabled=ExperimentalCanvasFeatures,
+    Constructor,
+    Constructor(Path2D path),
+    Constructor(DOMString text)
+] interface Path2D {
+
+    [RaisesException] void addPath(Path2D? path, SVGMatrix? transform);
+};
+
+Path2D implements CanvasPathMethods;
diff --git a/Source/core/html/canvas/WebGLBuffer.cpp b/Source/core/html/canvas/WebGLBuffer.cpp
index b821654..26b73b5 100644
--- a/Source/core/html/canvas/WebGLBuffer.cpp
+++ b/Source/core/html/canvas/WebGLBuffer.cpp
@@ -27,16 +27,16 @@
 
 #include "core/html/canvas/WebGLBuffer.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLBuffer> WebGLBuffer::create(WebGLRenderingContextBase* ctx)
 {
     return adoptRef(new WebGLBuffer(ctx));
 }
 
-WebGLBuffer::WebGLBuffer(WebGLRenderingContext* ctx)
+WebGLBuffer::WebGLBuffer(WebGLRenderingContextBase* ctx)
     : WebGLSharedObject(ctx)
     , m_target(0)
 {
diff --git a/Source/core/html/canvas/WebGLBuffer.h b/Source/core/html/canvas/WebGLBuffer.h
index 56870e3..9f596be 100644
--- a/Source/core/html/canvas/WebGLBuffer.h
+++ b/Source/core/html/canvas/WebGLBuffer.h
@@ -37,7 +37,7 @@
 public:
     virtual ~WebGLBuffer();
 
-    static PassRefPtr<WebGLBuffer> create(WebGLRenderingContext*);
+    static PassRefPtr<WebGLBuffer> create(WebGLRenderingContextBase*);
 
     GLenum getTarget() const { return m_target; }
     void setTarget(GLenum);
@@ -45,7 +45,7 @@
     bool hasEverBeenBound() const { return object() && m_target; }
 
 protected:
-    WebGLBuffer(WebGLRenderingContext*);
+    WebGLBuffer(WebGLRenderingContextBase*);
 
     virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
 
diff --git a/Source/core/html/canvas/WebGLCompressedTextureATC.cpp b/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
index 0049bee..3bfd7d8 100644
--- a/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
+++ b/Source/core/html/canvas/WebGLCompressedTextureATC.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContext* context)
+WebGLCompressedTextureATC::WebGLCompressedTextureATC(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -42,17 +42,17 @@
 {
 }
 
-WebGLExtension::ExtensionName WebGLCompressedTextureATC::name() const
+WebGLExtensionName WebGLCompressedTextureATC::name() const
 {
     return WebGLCompressedTextureATCName;
 }
 
-PassRefPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTextureATC> WebGLCompressedTextureATC::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLCompressedTextureATC(context));
 }
 
-bool WebGLCompressedTextureATC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTextureATC::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_AMD_compressed_ATC_texture");
 }
diff --git a/Source/core/html/canvas/WebGLCompressedTextureATC.h b/Source/core/html/canvas/WebGLCompressedTextureATC.h
index 500b31b..069fe14 100644
--- a/Source/core/html/canvas/WebGLCompressedTextureATC.h
+++ b/Source/core/html/canvas/WebGLCompressedTextureATC.h
@@ -36,15 +36,15 @@
 
 class WebGLCompressedTextureATC FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<WebGLCompressedTextureATC> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLCompressedTextureATC> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLCompressedTextureATC();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    WebGLCompressedTextureATC(WebGLRenderingContext*);
+    WebGLCompressedTextureATC(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp b/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
index db35168..d1586ff 100644
--- a/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
+++ b/Source/core/html/canvas/WebGLCompressedTexturePVRTC.cpp
@@ -27,11 +27,11 @@
 
 #include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContext* context)
+WebGLCompressedTexturePVRTC::WebGLCompressedTexturePVRTC(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -45,17 +45,17 @@
 {
 }
 
-WebGLExtension::ExtensionName WebGLCompressedTexturePVRTC::name() const
+WebGLExtensionName WebGLCompressedTexturePVRTC::name() const
 {
     return WebGLCompressedTexturePVRTCName;
 }
 
-PassRefPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTexturePVRTC> WebGLCompressedTexturePVRTC::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLCompressedTexturePVRTC(context));
 }
 
-bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTexturePVRTC::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_IMG_texture_compression_pvrtc");
 }
diff --git a/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h b/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
index 786c821..27cde75 100644
--- a/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
+++ b/Source/core/html/canvas/WebGLCompressedTexturePVRTC.h
@@ -34,15 +34,15 @@
 
 class WebGLCompressedTexturePVRTC FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLCompressedTexturePVRTC> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLCompressedTexturePVRTC();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    WebGLCompressedTexturePVRTC(WebGLRenderingContext*);
+    WebGLCompressedTexturePVRTC(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp b/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
index 6db69fb..35834cc 100644
--- a/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
+++ b/Source/core/html/canvas/WebGLCompressedTextureS3TC.cpp
@@ -27,11 +27,11 @@
 
 #include "core/html/canvas/WebGLCompressedTextureS3TC.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContext* context)
+WebGLCompressedTextureS3TC::WebGLCompressedTextureS3TC(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -45,17 +45,17 @@
 {
 }
 
-WebGLExtension::ExtensionName WebGLCompressedTextureS3TC::name() const
+WebGLExtensionName WebGLCompressedTextureS3TC::name() const
 {
     return WebGLCompressedTextureS3TCName;
 }
 
-PassRefPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLCompressedTextureS3TC> WebGLCompressedTextureS3TC::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLCompressedTextureS3TC(context));
 }
 
-bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContext* context)
+bool WebGLCompressedTextureS3TC::supported(WebGLRenderingContextBase* context)
 {
     Extensions3DUtil* extensionsUtil = context->extensionsUtil();
     return extensionsUtil->supportsExtension("GL_EXT_texture_compression_s3tc")
diff --git a/Source/core/html/canvas/WebGLCompressedTextureS3TC.h b/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
index b43b565..aaed4a7 100644
--- a/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
+++ b/Source/core/html/canvas/WebGLCompressedTextureS3TC.h
@@ -36,15 +36,15 @@
 
 class WebGLCompressedTextureS3TC FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLCompressedTextureS3TC> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLCompressedTextureS3TC();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    WebGLCompressedTextureS3TC(WebGLRenderingContext*);
+    WebGLCompressedTextureS3TC(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLContextEvent.cpp b/Source/core/html/canvas/WebGLContextEvent.cpp
index 7f4cf7c..88ce367 100644
--- a/Source/core/html/canvas/WebGLContextEvent.cpp
+++ b/Source/core/html/canvas/WebGLContextEvent.cpp
@@ -62,4 +62,9 @@
     return EventNames::WebGLContextEvent;
 }
 
+void WebGLContextEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLContextEvent.h b/Source/core/html/canvas/WebGLContextEvent.h
index acba861..4326054 100644
--- a/Source/core/html/canvas/WebGLContextEvent.h
+++ b/Source/core/html/canvas/WebGLContextEvent.h
@@ -56,6 +56,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     WebGLContextEvent();
     WebGLContextEvent(const AtomicString& type, bool canBubble, bool cancelable, const String& statusMessage);
diff --git a/Source/core/html/canvas/WebGLContextGroup.cpp b/Source/core/html/canvas/WebGLContextGroup.cpp
index d82ec98..b75d820 100644
--- a/Source/core/html/canvas/WebGLContextGroup.cpp
+++ b/Source/core/html/canvas/WebGLContextGroup.cpp
@@ -49,16 +49,16 @@
 blink::WebGraphicsContext3D* WebGLContextGroup::getAWebGraphicsContext3D()
 {
     ASSERT(!m_contexts.isEmpty());
-    HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin();
+    HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin();
     return (*it)->webGraphicsContext3D();
 }
 
-void WebGLContextGroup::addContext(WebGLRenderingContext* context)
+void WebGLContextGroup::addContext(WebGLRenderingContextBase* context)
 {
     m_contexts.add(context);
 }
 
-void WebGLContextGroup::removeContext(WebGLRenderingContext* context)
+void WebGLContextGroup::removeContext(WebGLRenderingContextBase* context)
 {
     // We must call detachAndRemoveAllObjects before removing the last context.
     if (m_contexts.size() == 1 && m_contexts.contains(context))
@@ -85,13 +85,13 @@
     }
 }
 
-void WebGLContextGroup::loseContextGroup(WebGLRenderingContext::LostContextMode mode)
+void WebGLContextGroup::loseContextGroup(WebGLRenderingContextBase::LostContextMode mode)
 {
     // Detach must happen before loseContextImpl, which destroys the GraphicsContext3D
     // and prevents groupObjects from being properly deleted.
     detachAndRemoveAllObjects();
 
-    for (HashSet<WebGLRenderingContext*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
+    for (HashSet<WebGLRenderingContextBase*>::iterator it = m_contexts.begin(); it != m_contexts.end(); ++it)
         (*it)->loseContextImpl(mode);
 }
 
diff --git a/Source/core/html/canvas/WebGLContextGroup.h b/Source/core/html/canvas/WebGLContextGroup.h
index 9358690..6c2f995 100644
--- a/Source/core/html/canvas/WebGLContextGroup.h
+++ b/Source/core/html/canvas/WebGLContextGroup.h
@@ -26,7 +26,7 @@
 #ifndef WebGLContextGroup_h
 #define WebGLContextGroup_h
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 #include "wtf/HashSet.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -39,7 +39,7 @@
 
 class WebGLExtension;
 class WebGLSharedObject;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
 
 typedef int ExceptionCode;
 
@@ -48,15 +48,15 @@
     static PassRefPtr<WebGLContextGroup> create();
     ~WebGLContextGroup();
 
-    void addContext(WebGLRenderingContext*);
-    void removeContext(WebGLRenderingContext*);
+    void addContext(WebGLRenderingContextBase*);
+    void removeContext(WebGLRenderingContextBase*);
 
     void addObject(WebGLSharedObject*);
     void removeObject(WebGLSharedObject*);
 
     blink::WebGraphicsContext3D* getAWebGraphicsContext3D();
 
-    void loseContextGroup(WebGLRenderingContext::LostContextMode);
+    void loseContextGroup(WebGLRenderingContextBase::LostContextMode);
 
   private:
     friend class WebGLObject;
@@ -65,7 +65,7 @@
 
     void detachAndRemoveAllObjects();
 
-    HashSet<WebGLRenderingContext*> m_contexts;
+    HashSet<WebGLRenderingContextBase*> m_contexts;
     HashSet<WebGLSharedObject*> m_groupObjects;
 };
 
diff --git a/Source/core/html/canvas/WebGLContextObject.cpp b/Source/core/html/canvas/WebGLContextObject.cpp
index 0b1c980..66f572d 100644
--- a/Source/core/html/canvas/WebGLContextObject.cpp
+++ b/Source/core/html/canvas/WebGLContextObject.cpp
@@ -27,11 +27,11 @@
 
 #include "core/html/canvas/WebGLContextObject.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-WebGLContextObject::WebGLContextObject(WebGLRenderingContext* context)
+WebGLContextObject::WebGLContextObject(WebGLRenderingContextBase* context)
     : WebGLObject(context)
     , m_context(context)
 {
diff --git a/Source/core/html/canvas/WebGLContextObject.h b/Source/core/html/canvas/WebGLContextObject.h
index 99e56a4..21be7a5 100644
--- a/Source/core/html/canvas/WebGLContextObject.h
+++ b/Source/core/html/canvas/WebGLContextObject.h
@@ -34,17 +34,17 @@
 
 namespace WebCore {
 
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
 
 // WebGLContextObject the base class for objects that are owned by a specific
-// WebGLRenderingContext.
+// WebGLRenderingContextBase.
 class WebGLContextObject : public WebGLObject {
 public:
     virtual ~WebGLContextObject();
 
-    WebGLRenderingContext* context() const { return m_context; }
+    WebGLRenderingContextBase* context() const { return m_context; }
 
-    virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext* context) const OVERRIDE FINAL
+    virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase* context) const OVERRIDE FINAL
     {
         return context == m_context;
     }
@@ -52,7 +52,7 @@
     void detachContext();
 
 protected:
-    WebGLContextObject(WebGLRenderingContext*);
+    WebGLContextObject(WebGLRenderingContextBase*);
 
     virtual bool hasGroupOrContext() const OVERRIDE FINAL
     {
@@ -62,7 +62,7 @@
     virtual blink::WebGraphicsContext3D* getAWebGraphicsContext3D() const OVERRIDE FINAL;
 
 private:
-    WebGLRenderingContext* m_context;
+    WebGLRenderingContextBase* m_context;
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLDebugRendererInfo.cpp b/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
index bca809a..cc61d26 100644
--- a/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
+++ b/Source/core/html/canvas/WebGLDebugRendererInfo.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContext* context)
+WebGLDebugRendererInfo::WebGLDebugRendererInfo(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -39,17 +39,17 @@
 {
 }
 
-WebGLExtension::ExtensionName WebGLDebugRendererInfo::name() const
+WebGLExtensionName WebGLDebugRendererInfo::name() const
 {
     return WebGLDebugRendererInfoName;
 }
 
-PassRefPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDebugRendererInfo> WebGLDebugRendererInfo::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLDebugRendererInfo(context));
 }
 
-bool WebGLDebugRendererInfo::supported(WebGLRenderingContext*)
+bool WebGLDebugRendererInfo::supported(WebGLRenderingContextBase*)
 {
     return true;
 }
diff --git a/Source/core/html/canvas/WebGLDebugRendererInfo.h b/Source/core/html/canvas/WebGLDebugRendererInfo.h
index 221edb4..8863aeb 100644
--- a/Source/core/html/canvas/WebGLDebugRendererInfo.h
+++ b/Source/core/html/canvas/WebGLDebugRendererInfo.h
@@ -39,15 +39,15 @@
         UNMASKED_RENDERER_WEBGL = 0x9246
     };
 
-    static PassRefPtr<WebGLDebugRendererInfo> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLDebugRendererInfo> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLDebugRendererInfo();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    WebGLDebugRendererInfo(WebGLRenderingContext*);
+    WebGLDebugRendererInfo(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLDebugShaders.cpp b/Source/core/html/canvas/WebGLDebugShaders.cpp
index 20669e8..82d8155 100644
--- a/Source/core/html/canvas/WebGLDebugShaders.cpp
+++ b/Source/core/html/canvas/WebGLDebugShaders.cpp
@@ -27,12 +27,12 @@
 #include "core/html/canvas/WebGLDebugShaders.h"
 
 #include "bindings/v8/ExceptionState.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 #include "core/html/canvas/WebGLShader.h"
 
 namespace WebCore {
 
-WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContext* context)
+WebGLDebugShaders::WebGLDebugShaders(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -42,12 +42,12 @@
 {
 }
 
-WebGLExtension::ExtensionName WebGLDebugShaders::name() const
+WebGLExtensionName WebGLDebugShaders::name() const
 {
     return WebGLDebugShadersName;
 }
 
-PassRefPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDebugShaders> WebGLDebugShaders::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLDebugShaders(context));
 }
@@ -61,7 +61,7 @@
     return m_context->webGraphicsContext3D()->getTranslatedShaderSourceANGLE(shader->object());
 }
 
-bool WebGLDebugShaders::supported(WebGLRenderingContext* context)
+bool WebGLDebugShaders::supported(WebGLRenderingContextBase* context)
 {
     return context->extensionsUtil()->supportsExtension("GL_ANGLE_translated_shader_source");
 }
diff --git a/Source/core/html/canvas/WebGLDebugShaders.h b/Source/core/html/canvas/WebGLDebugShaders.h
index 2631050..f1ae4f0 100644
--- a/Source/core/html/canvas/WebGLDebugShaders.h
+++ b/Source/core/html/canvas/WebGLDebugShaders.h
@@ -36,17 +36,17 @@
 
 class WebGLDebugShaders FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<WebGLDebugShaders> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLDebugShaders> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLDebugShaders();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
     String getTranslatedShaderSource(WebGLShader*);
 
 private:
-    WebGLDebugShaders(WebGLRenderingContext*);
+    WebGLDebugShaders(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLDepthTexture.cpp b/Source/core/html/canvas/WebGLDepthTexture.cpp
index f3c5c65..eb2e41d 100644
--- a/Source/core/html/canvas/WebGLDepthTexture.cpp
+++ b/Source/core/html/canvas/WebGLDepthTexture.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContext* context)
+WebGLDepthTexture::WebGLDepthTexture(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,17 +40,17 @@
 {
 }
 
-WebGLExtension::ExtensionName WebGLDepthTexture::name() const
+WebGLExtensionName WebGLDepthTexture::name() const
 {
     return WebGLDepthTextureName;
 }
 
-PassRefPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDepthTexture> WebGLDepthTexture::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLDepthTexture(context));
 }
 
-bool WebGLDepthTexture::supported(WebGLRenderingContext* context)
+bool WebGLDepthTexture::supported(WebGLRenderingContextBase* context)
 {
     Extensions3DUtil* extensionsUtil = context->extensionsUtil();
     // Emulating the UNSIGNED_INT_24_8_WEBGL texture internal format in terms
diff --git a/Source/core/html/canvas/WebGLDepthTexture.h b/Source/core/html/canvas/WebGLDepthTexture.h
index a0d3925..34017ee 100644
--- a/Source/core/html/canvas/WebGLDepthTexture.h
+++ b/Source/core/html/canvas/WebGLDepthTexture.h
@@ -34,15 +34,15 @@
 
 class WebGLDepthTexture FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<WebGLDepthTexture> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLDepthTexture> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLDepthTexture();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
 private:
-    WebGLDepthTexture(WebGLRenderingContext*);
+    WebGLDepthTexture(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLDrawBuffers.cpp b/Source/core/html/canvas/WebGLDrawBuffers.cpp
index d1aa3a7..c85a988 100644
--- a/Source/core/html/canvas/WebGLDrawBuffers.cpp
+++ b/Source/core/html/canvas/WebGLDrawBuffers.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContext* context)
+WebGLDrawBuffers::WebGLDrawBuffers(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -40,18 +40,18 @@
 {
 }
 
-WebGLExtension::ExtensionName WebGLDrawBuffers::name() const
+WebGLExtensionName WebGLDrawBuffers::name() const
 {
-    return WebGLExtension::WebGLDrawBuffersName;
+    return WebGLDrawBuffersName;
 }
 
-PassRefPtr<WebGLDrawBuffers> WebGLDrawBuffers::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLDrawBuffers> WebGLDrawBuffers::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLDrawBuffers(context));
 }
 
 // static
-bool WebGLDrawBuffers::supported(WebGLRenderingContext* context)
+bool WebGLDrawBuffers::supported(WebGLRenderingContextBase* context)
 {
     return (context->extensionsUtil()->supportsExtension("GL_EXT_draw_buffers")
         && satisfiesWebGLRequirements(context));
@@ -97,7 +97,7 @@
 }
 
 // static
-bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContext* webglContext)
+bool WebGLDrawBuffers::satisfiesWebGLRequirements(WebGLRenderingContextBase* webglContext)
 {
     blink::WebGraphicsContext3D* context = webglContext->webGraphicsContext3D();
     Extensions3DUtil* extensionsUtil = webglContext->extensionsUtil();
diff --git a/Source/core/html/canvas/WebGLDrawBuffers.h b/Source/core/html/canvas/WebGLDrawBuffers.h
index 7b8c044..be66f91 100644
--- a/Source/core/html/canvas/WebGLDrawBuffers.h
+++ b/Source/core/html/canvas/WebGLDrawBuffers.h
@@ -34,19 +34,19 @@
 
 class WebGLDrawBuffers FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<WebGLDrawBuffers> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLDrawBuffers> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLDrawBuffers();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
 
     void drawBuffersWEBGL(const Vector<GLenum>& buffers);
 
 private:
-    WebGLDrawBuffers(WebGLRenderingContext*);
+    WebGLDrawBuffers(WebGLRenderingContextBase*);
 
-    static bool satisfiesWebGLRequirements(WebGLRenderingContext*);
+    static bool satisfiesWebGLRequirements(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLExtension.cpp b/Source/core/html/canvas/WebGLExtension.cpp
index 9d3c941..73efb94 100644
--- a/Source/core/html/canvas/WebGLExtension.cpp
+++ b/Source/core/html/canvas/WebGLExtension.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-WebGLExtension::WebGLExtension(WebGLRenderingContext* context)
+WebGLExtension::WebGLExtension(WebGLRenderingContextBase* context)
     : m_context(context)
 {
 }
diff --git a/Source/core/html/canvas/WebGLExtension.h b/Source/core/html/canvas/WebGLExtension.h
index 1bd4c8b..66e072e 100644
--- a/Source/core/html/canvas/WebGLExtension.h
+++ b/Source/core/html/canvas/WebGLExtension.h
@@ -26,7 +26,8 @@
 #ifndef WebGLExtension_h
 #define WebGLExtension_h
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLExtensionName.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
@@ -34,36 +35,14 @@
 class WebGLExtension : public RefCounted<WebGLExtension> {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    // Extension names are needed to properly wrap instances in JavaScript objects.
-    enum ExtensionName {
-        ANGLEInstancedArraysName,
-        EXTFragDepthName,
-        EXTTextureFilterAnisotropicName,
-        OESElementIndexUintName,
-        OESStandardDerivativesName,
-        OESTextureFloatLinearName,
-        OESTextureFloatName,
-        OESTextureHalfFloatLinearName,
-        OESTextureHalfFloatName,
-        OESVertexArrayObjectName,
-        WebGLCompressedTextureATCName,
-        WebGLCompressedTexturePVRTCName,
-        WebGLCompressedTextureS3TCName,
-        WebGLDebugRendererInfoName,
-        WebGLDebugShadersName,
-        WebGLDepthTextureName,
-        WebGLDrawBuffersName,
-        WebGLLoseContextName,
-    };
-
-    WebGLRenderingContext* context() { return m_context; }
+    WebGLRenderingContextBase* context() { return m_context; }
 
     virtual ~WebGLExtension();
-    virtual ExtensionName name() const = 0;
+    virtual WebGLExtensionName name() const = 0;
 
     // Lose this extension. Passing true = force loss. Some extensions
     // like WEBGL_lose_context are not normally lost when the context
-    // is lost but must be lost when destroying their WebGLRenderingContext.
+    // is lost but must be lost when destroying their WebGLRenderingContextBase.
     virtual void lose(bool)
     {
         m_context = 0;
@@ -75,9 +54,9 @@
     }
 
 protected:
-    WebGLExtension(WebGLRenderingContext*);
+    WebGLExtension(WebGLRenderingContextBase*);
 
-    WebGLRenderingContext* m_context;
+    WebGLRenderingContextBase* m_context;
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLExtensionName.h b/Source/core/html/canvas/WebGLExtensionName.h
new file mode 100644
index 0000000..ed96581
--- /dev/null
+++ b/Source/core/html/canvas/WebGLExtensionName.h
@@ -0,0 +1,35 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WebGLExtensionName_h
+#define WebGLExtensionName_h
+
+namespace WebCore {
+
+// Extension names are needed to properly wrap instances in JavaScript objects.
+enum WebGLExtensionName {
+    ANGLEInstancedArraysName,
+    EXTFragDepthName,
+    EXTTextureFilterAnisotropicName,
+    OESElementIndexUintName,
+    OESStandardDerivativesName,
+    OESTextureFloatLinearName,
+    OESTextureFloatName,
+    OESTextureHalfFloatLinearName,
+    OESTextureHalfFloatName,
+    OESVertexArrayObjectName,
+    WebGLCompressedTextureATCName,
+    WebGLCompressedTexturePVRTCName,
+    WebGLCompressedTextureS3TCName,
+    WebGLDebugRendererInfoName,
+    WebGLDebugShadersName,
+    WebGLDepthTextureName,
+    WebGLDrawBuffersName,
+    WebGLLoseContextName,
+    WebGLExtensionNameCount, // Must be the last entry
+};
+
+}
+
+#endif // WebGLExtensionName_h
diff --git a/Source/core/html/canvas/WebGLFramebuffer.cpp b/Source/core/html/canvas/WebGLFramebuffer.cpp
index 0522c46..2eadbeb 100644
--- a/Source/core/html/canvas/WebGLFramebuffer.cpp
+++ b/Source/core/html/canvas/WebGLFramebuffer.cpp
@@ -27,7 +27,7 @@
 
 #include "core/html/canvas/WebGLFramebuffer.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 #include "platform/NotImplemented.h"
 
 namespace WebCore {
@@ -253,12 +253,12 @@
 {
 }
 
-PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLFramebuffer> WebGLFramebuffer::create(WebGLRenderingContextBase* ctx)
 {
     return adoptRef(new WebGLFramebuffer(ctx));
 }
 
-WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContext* ctx)
+WebGLFramebuffer::WebGLFramebuffer(WebGLRenderingContextBase* ctx)
     : WebGLContextObject(ctx)
     , m_hasEverBeenBound(false)
 {
@@ -330,7 +330,7 @@
             }
         } else if (object->isTexture()) {
             GLenum type = attachedObject->type();
-            if (!(context()->m_webglDepthTexture && internalformat == GL_DEPTH_COMPONENT
+            if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_COMPONENT
                 && (type == GL_UNSIGNED_SHORT || type == GL_UNSIGNED_INT))) {
                 *reason = "the attached texture is not a depth texture";
                 return false;
@@ -353,14 +353,14 @@
             }
         } else if (object->isTexture()) {
             GLenum type = attachedObject->type();
-            if (!(context()->m_webglDepthTexture && internalformat == GL_DEPTH_STENCIL_OES
+            if (!(context()->extensionEnabled(WebGLDepthTextureName) && internalformat == GL_DEPTH_STENCIL_OES
                 && type == GL_UNSIGNED_INT_24_8_OES)) {
                 *reason = "the attached texture is not a DEPTH_STENCIL texture";
                 return false;
             }
         }
     } else if (attachment == GL_COLOR_ATTACHMENT0
-        || (context()->m_webglDrawBuffers && attachment > GL_COLOR_ATTACHMENT0
+        || (context()->extensionEnabled(WebGLDrawBuffersName) && attachment > GL_COLOR_ATTACHMENT0
             && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + context()->maxColorAttachments()))) {
         if (object->isRenderbuffer()) {
             if (!isColorRenderable(internalformat)) {
@@ -381,8 +381,8 @@
                 && type != GL_UNSIGNED_SHORT_5_6_5
                 && type != GL_UNSIGNED_SHORT_4_4_4_4
                 && type != GL_UNSIGNED_SHORT_5_5_5_1
-                && !(type == GL_FLOAT && context()->m_oesTextureFloat)
-                && !(type == GL_HALF_FLOAT_OES && context()->m_oesTextureHalfFloat)) {
+                && !(type == GL_FLOAT && context()->extensionEnabled(OESTextureFloatName))
+                && !(type == GL_HALF_FLOAT_OES && context()->extensionEnabled(OESTextureHalfFloatName))) {
                 *reason = "unsupported type: The attached texture is not supported to be rendered to";
                 return false;
             }
@@ -583,7 +583,7 @@
 
 void WebGLFramebuffer::drawBuffersIfNecessary(bool force)
 {
-    if (!context()->m_webglDrawBuffers)
+    if (!context()->extensionEnabled(WebGLDrawBuffersName))
         return;
     bool reset = force;
     // This filtering works around graphics driver bugs on Mac OS X.
diff --git a/Source/core/html/canvas/WebGLFramebuffer.h b/Source/core/html/canvas/WebGLFramebuffer.h
index 2e3e0f7..107f6f2 100644
--- a/Source/core/html/canvas/WebGLFramebuffer.h
+++ b/Source/core/html/canvas/WebGLFramebuffer.h
@@ -64,7 +64,7 @@
 
     virtual ~WebGLFramebuffer();
 
-    static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContext*);
+    static PassRefPtr<WebGLFramebuffer> create(WebGLRenderingContextBase*);
 
     void setAttachmentForBoundFramebuffer(GLenum attachment, GLenum texTarget, WebGLTexture*, GLint level);
     void setAttachmentForBoundFramebuffer(GLenum attachment, WebGLRenderbuffer*);
@@ -102,7 +102,7 @@
     GLenum getDrawBuffer(GLenum);
 
 protected:
-    WebGLFramebuffer(WebGLRenderingContext*);
+    WebGLFramebuffer(WebGLRenderingContextBase*);
 
     virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
 
diff --git a/Source/core/html/canvas/WebGLLoseContext.cpp b/Source/core/html/canvas/WebGLLoseContext.cpp
index ca1226a..e2fe7bd 100644
--- a/Source/core/html/canvas/WebGLLoseContext.cpp
+++ b/Source/core/html/canvas/WebGLLoseContext.cpp
@@ -27,11 +27,11 @@
 
 #include "core/html/canvas/WebGLLoseContext.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-WebGLLoseContext::WebGLLoseContext(WebGLRenderingContext* context)
+WebGLLoseContext::WebGLLoseContext(WebGLRenderingContextBase* context)
     : WebGLExtension(context)
 {
     ScriptWrappable::init(this);
@@ -47,12 +47,12 @@
         WebGLExtension::lose(true);
 }
 
-WebGLExtension::ExtensionName WebGLLoseContext::name() const
+WebGLExtensionName WebGLLoseContext::name() const
 {
     return WebGLLoseContextName;
 }
 
-PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContext* context)
+PassRefPtr<WebGLLoseContext> WebGLLoseContext::create(WebGLRenderingContextBase* context)
 {
     return adoptRef(new WebGLLoseContext(context));
 }
@@ -60,7 +60,7 @@
 void WebGLLoseContext::loseContext()
 {
     if (!isLost())
-        m_context->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
+        m_context->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
 }
 
 void WebGLLoseContext::restoreContext()
@@ -69,7 +69,7 @@
         m_context->forceRestoreContext();
 }
 
-bool WebGLLoseContext::supported(WebGLRenderingContext*)
+bool WebGLLoseContext::supported(WebGLRenderingContextBase*)
 {
     return true;
 }
diff --git a/Source/core/html/canvas/WebGLLoseContext.h b/Source/core/html/canvas/WebGLLoseContext.h
index e2a1141..cab49f3 100644
--- a/Source/core/html/canvas/WebGLLoseContext.h
+++ b/Source/core/html/canvas/WebGLLoseContext.h
@@ -32,23 +32,23 @@
 
 namespace WebCore {
 
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
 
 class WebGLLoseContext FINAL : public WebGLExtension, public ScriptWrappable {
 public:
-    static PassRefPtr<WebGLLoseContext> create(WebGLRenderingContext*);
-    static bool supported(WebGLRenderingContext*);
+    static PassRefPtr<WebGLLoseContext> create(WebGLRenderingContextBase*);
+    static bool supported(WebGLRenderingContextBase*);
     static const char* extensionName();
 
     virtual ~WebGLLoseContext();
-    virtual ExtensionName name() const OVERRIDE;
+    virtual WebGLExtensionName name() const OVERRIDE;
     virtual void lose(bool) OVERRIDE;
 
     void loseContext();
     void restoreContext();
 
 private:
-    WebGLLoseContext(WebGLRenderingContext*);
+    WebGLLoseContext(WebGLRenderingContextBase*);
 };
 
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLObject.cpp b/Source/core/html/canvas/WebGLObject.cpp
index e7c348a..14dd8ba 100644
--- a/Source/core/html/canvas/WebGLObject.cpp
+++ b/Source/core/html/canvas/WebGLObject.cpp
@@ -29,7 +29,7 @@
 
 namespace WebCore {
 
-WebGLObject::WebGLObject(WebGLRenderingContext*)
+WebGLObject::WebGLObject(WebGLRenderingContextBase*)
     : m_object(0)
     , m_attachmentCount(0)
     , m_deleted(false)
diff --git a/Source/core/html/canvas/WebGLObject.h b/Source/core/html/canvas/WebGLObject.h
index 159ef68..ae5c439 100644
--- a/Source/core/html/canvas/WebGLObject.h
+++ b/Source/core/html/canvas/WebGLObject.h
@@ -36,7 +36,7 @@
 namespace WebCore {
 
 class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
 
 class WebGLObject : public RefCounted<WebGLObject> {
 public:
@@ -58,10 +58,10 @@
     bool isDeleted() { return m_deleted; }
 
     // True if this object belongs to the group or context.
-    virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContext*) const = 0;
+    virtual bool validate(const WebGLContextGroup*, const WebGLRenderingContextBase*) const = 0;
 
 protected:
-    WebGLObject(WebGLRenderingContext*);
+    WebGLObject(WebGLRenderingContextBase*);
 
     // setObject should be only called once right after creating a WebGLObject.
     void setObject(Platform3DObject);
diff --git a/Source/core/html/canvas/WebGLProgram.cpp b/Source/core/html/canvas/WebGLProgram.cpp
index 9977889..dbdb28d 100644
--- a/Source/core/html/canvas/WebGLProgram.cpp
+++ b/Source/core/html/canvas/WebGLProgram.cpp
@@ -27,16 +27,16 @@
 
 #include "core/html/canvas/WebGLProgram.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLProgram> WebGLProgram::create(WebGLRenderingContextBase* ctx)
 {
     return adoptRef(new WebGLProgram(ctx));
 }
 
-WebGLProgram::WebGLProgram(WebGLRenderingContext* ctx)
+WebGLProgram::WebGLProgram(WebGLRenderingContextBase* ctx)
     : WebGLSharedObject(ctx)
     , m_linkStatus(false)
     , m_linkCount(0)
@@ -56,11 +56,11 @@
     context3d->deleteProgram(obj);
     if (m_vertexShader) {
         m_vertexShader->onDetached(context3d);
-        m_vertexShader = 0;
+        m_vertexShader = nullptr;
     }
     if (m_fragmentShader) {
         m_fragmentShader->onDetached(context3d);
-        m_fragmentShader = 0;
+        m_fragmentShader = nullptr;
     }
 }
 
@@ -146,12 +146,12 @@
     case GL_VERTEX_SHADER:
         if (m_vertexShader != shader)
             return false;
-        m_vertexShader = 0;
+        m_vertexShader = nullptr;
         return true;
     case GL_FRAGMENT_SHADER:
         if (m_fragmentShader != shader)
             return false;
-        m_fragmentShader = 0;
+        m_fragmentShader = nullptr;
         return true;
     default:
         return false;
diff --git a/Source/core/html/canvas/WebGLProgram.h b/Source/core/html/canvas/WebGLProgram.h
index 5827afe..aa343fb 100644
--- a/Source/core/html/canvas/WebGLProgram.h
+++ b/Source/core/html/canvas/WebGLProgram.h
@@ -38,7 +38,7 @@
 public:
     virtual ~WebGLProgram();
 
-    static PassRefPtr<WebGLProgram> create(WebGLRenderingContext*);
+    static PassRefPtr<WebGLProgram> create(WebGLRenderingContextBase*);
 
     unsigned numActiveAttribLocations();
     GLint getActiveAttribLocation(GLuint index);
@@ -61,7 +61,7 @@
     bool detachShader(WebGLShader*);
 
 protected:
-    WebGLProgram(WebGLRenderingContext*);
+    WebGLProgram(WebGLRenderingContextBase*);
 
     virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
 
diff --git a/Source/core/html/canvas/WebGLRenderbuffer.cpp b/Source/core/html/canvas/WebGLRenderbuffer.cpp
index d5c517f..ce1720a 100644
--- a/Source/core/html/canvas/WebGLRenderbuffer.cpp
+++ b/Source/core/html/canvas/WebGLRenderbuffer.cpp
@@ -27,11 +27,11 @@
 
 #include "core/html/canvas/WebGLRenderbuffer.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLRenderbuffer> WebGLRenderbuffer::create(WebGLRenderingContextBase* ctx)
 {
     return adoptRef(new WebGLRenderbuffer(ctx));
 }
@@ -41,7 +41,7 @@
     deleteObject(0);
 }
 
-WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContext* ctx)
+WebGLRenderbuffer::WebGLRenderbuffer(WebGLRenderingContextBase* ctx)
     : WebGLSharedObject(ctx)
     , m_internalFormat(GL_RGBA4)
     , m_width(0)
diff --git a/Source/core/html/canvas/WebGLRenderbuffer.h b/Source/core/html/canvas/WebGLRenderbuffer.h
index 8af0755..4c08712 100644
--- a/Source/core/html/canvas/WebGLRenderbuffer.h
+++ b/Source/core/html/canvas/WebGLRenderbuffer.h
@@ -36,7 +36,7 @@
 public:
     virtual ~WebGLRenderbuffer();
 
-    static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContext*);
+    static PassRefPtr<WebGLRenderbuffer> create(WebGLRenderingContextBase*);
 
     void setInternalFormat(GLenum internalformat)
     {
@@ -61,7 +61,7 @@
     void deleteEmulatedStencilBuffer(blink::WebGraphicsContext3D* context3d);
 
 protected:
-    WebGLRenderbuffer(WebGLRenderingContext*);
+    WebGLRenderbuffer(WebGLRenderingContextBase*);
 
     virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
 
diff --git a/Source/core/html/canvas/WebGLRenderingContext.cpp b/Source/core/html/canvas/WebGLRenderingContext.cpp
index 02a321e..619a418 100644
--- a/Source/core/html/canvas/WebGLRenderingContext.cpp
+++ b/Source/core/html/canvas/WebGLRenderingContext.cpp
@@ -26,15 +26,7 @@
 #include "config.h"
 #include "core/html/canvas/WebGLRenderingContext.h"
 
-#include "RuntimeEnabledFeatures.h"
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/fetch/ImageResource.h"
-#include "core/html/HTMLCanvasElement.h"
-#include "core/html/HTMLImageElement.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/html/ImageData.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/canvas/ANGLEInstancedArrays.h"
 #include "core/html/canvas/EXTFragDepth.h"
 #include "core/html/canvas/EXTTextureFilterAnisotropic.h"
@@ -45,445 +37,31 @@
 #include "core/html/canvas/OESTextureHalfFloat.h"
 #include "core/html/canvas/OESTextureHalfFloatLinear.h"
 #include "core/html/canvas/OESVertexArrayObject.h"
-#include "core/html/canvas/WebGLActiveInfo.h"
-#include "core/html/canvas/WebGLBuffer.h"
 #include "core/html/canvas/WebGLCompressedTextureATC.h"
 #include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
 #include "core/html/canvas/WebGLCompressedTextureS3TC.h"
 #include "core/html/canvas/WebGLContextAttributes.h"
 #include "core/html/canvas/WebGLContextEvent.h"
-#include "core/html/canvas/WebGLContextGroup.h"
 #include "core/html/canvas/WebGLDebugRendererInfo.h"
 #include "core/html/canvas/WebGLDebugShaders.h"
 #include "core/html/canvas/WebGLDepthTexture.h"
 #include "core/html/canvas/WebGLDrawBuffers.h"
-#include "core/html/canvas/WebGLFramebuffer.h"
 #include "core/html/canvas/WebGLLoseContext.h"
-#include "core/html/canvas/WebGLProgram.h"
-#include "core/html/canvas/WebGLRenderbuffer.h"
-#include "core/html/canvas/WebGLShader.h"
-#include "core/html/canvas/WebGLShaderPrecisionFormat.h"
-#include "core/html/canvas/WebGLTexture.h"
-#include "core/html/canvas/WebGLUniformLocation.h"
-#include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/RenderBox.h"
 #include "platform/CheckedInt.h"
 #include "platform/NotImplemented.h"
-#include "platform/geometry/IntSize.h"
-#include "platform/graphics/UnacceleratedImageBufferSurface.h"
 #include "platform/graphics/gpu/DrawingBuffer.h"
 #include "public/platform/Platform.h"
 
-#include "wtf/PassOwnPtr.h"
-#include "wtf/Uint32Array.h"
-#include "wtf/text/StringBuilder.h"
-
 namespace WebCore {
 
-const double secondsBetweenRestoreAttempts = 1.0;
-const int maxGLErrorsAllowedToConsole = 256;
-const unsigned maxGLActiveContexts = 16;
-
-Vector<WebGLRenderingContext*>& WebGLRenderingContext::activeContexts()
-{
-    DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, activeContexts, ());
-    return activeContexts;
-}
-
-Vector<WebGLRenderingContext*>& WebGLRenderingContext::forciblyEvictedContexts()
-{
-    DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContext*>, forciblyEvictedContexts, ());
-    return forciblyEvictedContexts;
-}
-
-void WebGLRenderingContext::forciblyLoseOldestContext(const String& reason)
-{
-    size_t candidateID = oldestContextIndex();
-    if (candidateID >= activeContexts().size())
-        return;
-
-    WebGLRenderingContext* candidate = activeContexts()[candidateID];
-
-    activeContexts().remove(candidateID);
-
-    candidate->printWarningToConsole(reason);
-    InspectorInstrumentation::didFireWebGLWarning(candidate->canvas());
-
-    // This will call deactivateContext once the context has actually been lost.
-    candidate->forceLostContext(WebGLRenderingContext::SyntheticLostContext);
-}
-
-size_t WebGLRenderingContext::oldestContextIndex()
-{
-    if (!activeContexts().size())
-        return maxGLActiveContexts;
-
-    WebGLRenderingContext* candidate = activeContexts().first();
-    size_t candidateID = 0;
-    for (size_t ii = 1; ii < activeContexts().size(); ++ii) {
-        WebGLRenderingContext* context = activeContexts()[ii];
-        if (context->webGraphicsContext3D() && candidate->webGraphicsContext3D() && context->webGraphicsContext3D()->lastFlushID() < candidate->webGraphicsContext3D()->lastFlushID()) {
-            candidate = context;
-            candidateID = ii;
-        }
-    }
-
-    return candidateID;
-}
-
-IntSize WebGLRenderingContext::oldestContextSize()
-{
-    IntSize size;
-
-    size_t candidateID = oldestContextIndex();
-    if (candidateID < activeContexts().size()) {
-        WebGLRenderingContext* candidate = activeContexts()[candidateID];
-        size.setWidth(candidate->drawingBufferWidth());
-        size.setHeight(candidate->drawingBufferHeight());
-    }
-
-    return size;
-}
-
-void WebGLRenderingContext::activateContext(WebGLRenderingContext* context)
-{
-    unsigned removedContexts = 0;
-    while (activeContexts().size() >= maxGLActiveContexts && removedContexts < maxGLActiveContexts) {
-        forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Oldest context will be lost.");
-        removedContexts++;
-    }
-
-    if (!activeContexts().contains(context))
-        activeContexts().append(context);
-}
-
-void WebGLRenderingContext::deactivateContext(WebGLRenderingContext* context, bool addToEvictedList)
-{
-    size_t position = activeContexts().find(context);
-    if (position != WTF::kNotFound)
-        activeContexts().remove(position);
-
-    if (addToEvictedList && !forciblyEvictedContexts().contains(context))
-        forciblyEvictedContexts().append(context);
-}
-
-void WebGLRenderingContext::willDestroyContext(WebGLRenderingContext* context)
-{
-    size_t position = forciblyEvictedContexts().find(context);
-    if (position != WTF::kNotFound)
-        forciblyEvictedContexts().remove(position);
-
-    deactivateContext(context, false);
-
-    // Try to re-enable the oldest inactive contexts.
-    while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContexts().size()) {
-        WebGLRenderingContext* evictedContext = forciblyEvictedContexts().first();
-        if (!evictedContext->m_restoreAllowed) {
-            forciblyEvictedContexts().remove(0);
-            continue;
-        }
-
-        IntSize desiredSize = evictedContext->m_drawingBuffer->adjustSize(evictedContext->clampedCanvasSize());
-
-        // If there's room in the pixel budget for this context, restore it.
-        if (!desiredSize.isEmpty()) {
-            forciblyEvictedContexts().remove(0);
-            evictedContext->forceRestoreContext();
-            activeContexts().append(evictedContext);
-        }
-        break;
-    }
-}
-
-class WebGLRenderingContextEvictionManager : public ContextEvictionManager {
-public:
-    void forciblyLoseOldestContext(const String& reason) {
-        WebGLRenderingContext::forciblyLoseOldestContext(reason);
-    };
-    IntSize oldestContextSize() {
-        return WebGLRenderingContext::oldestContextSize();
-    };
-};
-
-namespace {
-
-    class ScopedDrawingBufferBinder {
-    public:
-        ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
-            : m_drawingBuffer(drawingBuffer)
-            , m_framebufferBinding(framebufferBinding)
-        {
-            // Commit DrawingBuffer if needed (e.g., for multisampling)
-            if (!m_framebufferBinding && m_drawingBuffer)
-                m_drawingBuffer->commit();
-        }
-
-        ~ScopedDrawingBufferBinder()
-        {
-            // Restore DrawingBuffer if needed
-            if (!m_framebufferBinding && m_drawingBuffer)
-                m_drawingBuffer->bind();
-        }
-
-    private:
-        DrawingBuffer* m_drawingBuffer;
-        WebGLFramebuffer* m_framebufferBinding;
-    };
-
-    Platform3DObject objectOrZero(WebGLObject* object)
-    {
-        return object ? object->object() : 0;
-    }
-
-    GLint clamp(GLint value, GLint min, GLint max)
-    {
-        if (value < min)
-            value = min;
-        if (value > max)
-            value = max;
-        return value;
-    }
-
-    // Return true if a character belongs to the ASCII subset as defined in
-    // GLSL ES 1.0 spec section 3.1.
-    bool validateCharacter(unsigned char c)
-    {
-        // Printing characters are valid except " $ ` @ \ ' DEL.
-        if (c >= 32 && c <= 126
-            && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
-            return true;
-        // Horizontal tab, line feed, vertical tab, form feed, carriage return
-        // are also valid.
-        if (c >= 9 && c <= 13)
-            return true;
-        return false;
-    }
-
-    bool isPrefixReserved(const String& name)
-    {
-        if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
-            return true;
-        return false;
-    }
-
-    // Strips comments from shader text. This allows non-ASCII characters
-    // to be used in comments without potentially breaking OpenGL
-    // implementations not expecting characters outside the GLSL ES set.
-    class StripComments {
-    public:
-        StripComments(const String& str)
-            : m_parseState(BeginningOfLine)
-            , m_sourceString(str)
-            , m_length(str.length())
-            , m_position(0)
-        {
-            parse();
-        }
-
-        String result()
-        {
-            return m_builder.toString();
-        }
-
-    private:
-        bool hasMoreCharacters() const
-        {
-            return (m_position < m_length);
-        }
-
-        void parse()
-        {
-            while (hasMoreCharacters()) {
-                process(current());
-                // process() might advance the position.
-                if (hasMoreCharacters())
-                    advance();
-            }
-        }
-
-        void process(UChar);
-
-        bool peek(UChar& character) const
-        {
-            if (m_position + 1 >= m_length)
-                return false;
-            character = m_sourceString[m_position + 1];
-            return true;
-        }
-
-        UChar current()
-        {
-            ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
-            return m_sourceString[m_position];
-        }
-
-        void advance()
-        {
-            ++m_position;
-        }
-
-        static bool isNewline(UChar character)
-        {
-            // Don't attempt to canonicalize newline related characters.
-            return (character == '\n' || character == '\r');
-        }
-
-        void emit(UChar character)
-        {
-            m_builder.append(character);
-        }
-
-        enum ParseState {
-            // Have not seen an ASCII non-whitespace character yet on
-            // this line. Possible that we might see a preprocessor
-            // directive.
-            BeginningOfLine,
-
-            // Have seen at least one ASCII non-whitespace character
-            // on this line.
-            MiddleOfLine,
-
-            // Handling a preprocessor directive. Passes through all
-            // characters up to the end of the line. Disables comment
-            // processing.
-            InPreprocessorDirective,
-
-            // Handling a single-line comment. The comment text is
-            // replaced with a single space.
-            InSingleLineComment,
-
-            // Handling a multi-line comment. Newlines are passed
-            // through to preserve line numbers.
-            InMultiLineComment
-        };
-
-        ParseState m_parseState;
-        String m_sourceString;
-        unsigned m_length;
-        unsigned m_position;
-        StringBuilder m_builder;
-    };
-
-    void StripComments::process(UChar c)
-    {
-        if (isNewline(c)) {
-            // No matter what state we are in, pass through newlines
-            // so we preserve line numbers.
-            emit(c);
-
-            if (m_parseState != InMultiLineComment)
-                m_parseState = BeginningOfLine;
-
-            return;
-        }
-
-        UChar temp = 0;
-        switch (m_parseState) {
-        case BeginningOfLine:
-            if (WTF::isASCIISpace(c)) {
-                emit(c);
-                break;
-            }
-
-            if (c == '#') {
-                m_parseState = InPreprocessorDirective;
-                emit(c);
-                break;
-            }
-
-            // Transition to normal state and re-handle character.
-            m_parseState = MiddleOfLine;
-            process(c);
-            break;
-
-        case MiddleOfLine:
-            if (c == '/' && peek(temp)) {
-                if (temp == '/') {
-                    m_parseState = InSingleLineComment;
-                    emit(' ');
-                    advance();
-                    break;
-                }
-
-                if (temp == '*') {
-                    m_parseState = InMultiLineComment;
-                    // Emit the comment start in case the user has
-                    // an unclosed comment and we want to later
-                    // signal an error.
-                    emit('/');
-                    emit('*');
-                    advance();
-                    break;
-                }
-            }
-
-            emit(c);
-            break;
-
-        case InPreprocessorDirective:
-            // No matter what the character is, just pass it
-            // through. Do not parse comments in this state. This
-            // might not be the right thing to do long term, but it
-            // should handle the #error preprocessor directive.
-            emit(c);
-            break;
-
-        case InSingleLineComment:
-            // The newline code at the top of this function takes care
-            // of resetting our state when we get out of the
-            // single-line comment. Swallow all other characters.
-            break;
-
-        case InMultiLineComment:
-            if (c == '*' && peek(temp) && temp == '/') {
-                emit('*');
-                emit('/');
-                m_parseState = MiddleOfLine;
-                advance();
-                break;
-            }
-
-            // Swallow all other characters. Unclear whether we may
-            // want or need to just emit a space per character to try
-            // to preserve column numbers for debugging purposes.
-            break;
-        }
-    }
-} // namespace anonymous
-
-class WebGLRenderingContextLostCallback : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    explicit WebGLRenderingContextLostCallback(WebGLRenderingContext* cb) : m_context(cb) { }
-    virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContext::RealLostContext); }
-    virtual ~WebGLRenderingContextLostCallback() {}
-private:
-    WebGLRenderingContext* m_context;
-};
-
-class WebGLRenderingContextErrorMessageCallback : public blink::WebGraphicsContext3D::WebGraphicsErrorMessageCallback {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContext* cb) : m_context(cb) { }
-    virtual void onErrorMessage(const blink::WebString& message, blink::WGC3Dint)
-    {
-        if (m_context->m_synthesizedErrorsToConsole)
-            m_context->printGLErrorToConsole(message);
-        InspectorInstrumentation::didFireWebGLErrorOrWarning(m_context->canvas(), message);
-    }
-    virtual ~WebGLRenderingContextErrorMessageCallback() { }
-private:
-    WebGLRenderingContext* m_context;
-};
-
 PassOwnPtr<WebGLRenderingContext> WebGLRenderingContext::create(HTMLCanvasElement* canvas, WebGLContextAttributes* attrs)
 {
     Document& document = canvas->document();
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     if (!frame)
         return nullptr;
     Settings* settings = frame->settings();
@@ -501,7 +79,7 @@
         defaultAttrs = WebGLContextAttributes::create();
         attrs = defaultAttrs.get();
     }
-    blink::WebGraphicsContext3D::Attributes attributes = attrs->attributes(document.topDocument()->url().string(), settings);
+    blink::WebGraphicsContext3D::Attributes attributes = attrs->attributes(document.topDocument().url().string(), settings);
     OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes));
     if (!context || !context->makeContextCurrent()) {
         canvas->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextcreationerror, false, true, "Could not create a WebGL context."));
@@ -513,6 +91,7 @@
         context->pushGroupMarkerEXT("WebGLRenderingContext");
 
     OwnPtr<WebGLRenderingContext> renderingContext = adoptPtr(new WebGLRenderingContext(canvas, context.release(), attrs));
+    renderingContext->registerContextExtensions();
     renderingContext->suspendIfNeeded();
 
     if (renderingContext->m_drawingBuffer->isZeroSized()) {
@@ -524,45 +103,18 @@
 }
 
 WebGLRenderingContext::WebGLRenderingContext(HTMLCanvasElement* passedCanvas, PassOwnPtr<blink::WebGraphicsContext3D> context, WebGLContextAttributes* requestedAttributes)
-    : CanvasRenderingContext(passedCanvas)
-    , ActiveDOMObject(&passedCanvas->document())
-    , m_context(context)
-    , m_drawingBuffer(0)
-    , m_dispatchContextLostEventTimer(this, &WebGLRenderingContext::dispatchContextLostEvent)
-    , m_restoreAllowed(false)
-    , m_restoreTimer(this, &WebGLRenderingContext::maybeRestoreContext)
-    , m_generatedImageCache(4)
-    , m_contextLost(false)
-    , m_contextLostMode(SyntheticLostContext)
-    , m_requestedAttributes(requestedAttributes->clone())
-    , m_synthesizedErrorsToConsole(true)
-    , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
-    , m_multisamplingAllowed(false)
-    , m_multisamplingObserverRegistered(false)
-    , m_onePlusMaxEnabledAttribIndex(0)
-    , m_onePlusMaxNonDefaultTextureUnit(0)
+    : WebGLRenderingContextBase(passedCanvas, context, requestedAttributes)
 {
-    ASSERT(m_context);
     ScriptWrappable::init(this);
+}
 
-    m_contextGroup = WebGLContextGroup::create();
-    m_contextGroup->addContext(this);
+WebGLRenderingContext::~WebGLRenderingContext()
+{
 
-    m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
-    m_context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims);
+}
 
-    RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
-
-    // Create the DrawingBuffer and initialize the platform layer.
-    DrawingBuffer::PreserveDrawingBuffer preserve = requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
-    m_drawingBuffer = DrawingBuffer::create(m_context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
-
-    if (!m_drawingBuffer->isZeroSized()) {
-        m_drawingBuffer->bind();
-        setupFlags();
-        initializeNewContext();
-    }
-
+void WebGLRenderingContext::registerContextExtensions()
+{
     // Register extensions.
     static const char* const webkitPrefix[] = { "WEBKIT_", 0, };
     static const char* const bothPrefixes[] = { "", "WEBKIT_", 0, };
@@ -591,5041 +143,4 @@
     registerExtension<WebGLDebugShaders>(m_webglDebugShaders, PrivilegedExtension);
 }
 
-void WebGLRenderingContext::initializeNewContext()
-{
-    ASSERT(!isContextLost());
-    m_needsUpdate = true;
-    m_markedCanvasDirty = false;
-    m_activeTextureUnit = 0;
-    m_packAlignment = 4;
-    m_unpackAlignment = 4;
-    m_unpackFlipY = false;
-    m_unpackPremultiplyAlpha = false;
-    m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
-    m_boundArrayBuffer = 0;
-    m_currentProgram = 0;
-    m_framebufferBinding = 0;
-    m_renderbufferBinding = 0;
-    m_depthMask = true;
-    m_stencilEnabled = false;
-    m_stencilMask = 0xFFFFFFFF;
-    m_stencilMaskBack = 0xFFFFFFFF;
-    m_stencilFuncRef = 0;
-    m_stencilFuncRefBack = 0;
-    m_stencilFuncMask = 0xFFFFFFFF;
-    m_stencilFuncMaskBack = 0xFFFFFFFF;
-    m_layerCleared = false;
-    m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
-
-    m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
-    m_scissorEnabled = false;
-    m_clearDepth = 1;
-    m_clearStencil = 0;
-    m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
-
-    GLint numCombinedTextureImageUnits = 0;
-    m_context->getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
-    m_textureUnits.clear();
-    m_textureUnits.resize(numCombinedTextureImageUnits);
-
-    GLint numVertexAttribs = 0;
-    m_context->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
-    m_maxVertexAttribs = numVertexAttribs;
-
-    m_maxTextureSize = 0;
-    m_context->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
-    m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
-    m_maxCubeMapTextureSize = 0;
-    m_context->getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
-    m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
-    m_maxRenderbufferSize = 0;
-    m_context->getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
-
-    // These two values from EXT_draw_buffers are lazily queried.
-    m_maxDrawBuffers = 0;
-    m_maxColorAttachments = 0;
-
-    m_backDrawBuffer = GL_BACK;
-
-    m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
-    addContextObject(m_defaultVertexArrayObject.get());
-    m_boundVertexArrayObject = m_defaultVertexArrayObject;
-
-    m_vertexAttribValue.resize(m_maxVertexAttribs);
-
-    createFallbackBlackTextures1x1();
-
-    IntSize canvasSize = clampedCanvasSize();
-    m_drawingBuffer->reset(canvasSize);
-
-    m_context->viewport(0, 0, canvasSize.width(), canvasSize.height());
-    m_context->scissor(0, 0, canvasSize.width(), canvasSize.height());
-
-    m_contextLostCallbackAdapter = adoptPtr(new WebGLRenderingContextLostCallback(this));
-    m_errorMessageCallbackAdapter = adoptPtr(new WebGLRenderingContextErrorMessageCallback(this));
-
-    m_context->setContextLostCallback(m_contextLostCallbackAdapter.get());
-    m_context->setErrorMessageCallback(m_errorMessageCallbackAdapter.get());
-
-    // This ensures that the context has a valid "lastFlushID" and won't be mistakenly identified as the "least recently used" context.
-    m_context->flush();
-
-    activateContext(this);
-}
-
-void WebGLRenderingContext::setupFlags()
-{
-    ASSERT(m_context);
-    if (Page* p = canvas()->document().page()) {
-        m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled();
-
-        if (!m_multisamplingObserverRegistered && m_requestedAttributes->antialias()) {
-            m_multisamplingAllowed = m_drawingBuffer->multisample();
-            p->addMultisamplingChangedObserver(this);
-            m_multisamplingObserverRegistered = true;
-        }
-    }
-
-    m_isGLES2NPOTStrict = !extensionsUtil()->isExtensionEnabled("GL_OES_texture_npot");
-    m_isDepthStencilSupported = extensionsUtil()->isExtensionEnabled("GL_OES_packed_depth_stencil");
-}
-
-bool WebGLRenderingContext::allowPrivilegedExtensions() const
-{
-    if (Page* p = canvas()->document().page())
-        return p->settings().privilegedWebGLExtensionsEnabled();
-    return false;
-}
-
-bool WebGLRenderingContext::allowWebGLDebugRendererInfo() const
-{
-    return true;
-}
-
-void WebGLRenderingContext::addCompressedTextureFormat(GLenum format)
-{
-    if (!m_compressedTextureFormats.contains(format))
-        m_compressedTextureFormats.append(format);
-}
-
-void WebGLRenderingContext::removeAllCompressedTextureFormats()
-{
-    m_compressedTextureFormats.clear();
-}
-
-WebGLRenderingContext::~WebGLRenderingContext()
-{
-    // Remove all references to WebGLObjects so if they are the last reference
-    // they will be freed before the last context is removed from the context group.
-    m_boundArrayBuffer = 0;
-    m_defaultVertexArrayObject = 0;
-    m_boundVertexArrayObject = 0;
-    m_vertexAttrib0Buffer = 0;
-    m_currentProgram = 0;
-    m_framebufferBinding = 0;
-    m_renderbufferBinding = 0;
-
-    for (size_t i = 0; i < m_textureUnits.size(); ++i) {
-      m_textureUnits[i].m_texture2DBinding = 0;
-      m_textureUnits[i].m_textureCubeMapBinding = 0;
-    }
-
-    m_blackTexture2D = 0;
-    m_blackTextureCubeMap = 0;
-
-    detachAndRemoveAllObjects();
-
-    // release all extensions
-    for (size_t i = 0; i < m_extensions.size(); ++i)
-        delete m_extensions[i];
-
-    // Context must be removed from the group prior to the destruction of the
-    // WebGraphicsContext3D, otherwise shared objects may not be properly deleted.
-    m_contextGroup->removeContext(this);
-
-    destroyContext();
-
-    if (m_multisamplingObserverRegistered) {
-        Page* page = canvas()->document().page();
-        if (page)
-            page->removeMultisamplingChangedObserver(this);
-    }
-
-    willDestroyContext(this);
-}
-
-void WebGLRenderingContext::destroyContext()
-{
-    m_contextLost = true;
-
-    // The drawing buffer holds a context reference. It must also be destroyed
-    // in order for the context to be released.
-    m_drawingBuffer->releaseResources();
-
-    m_extensionsUtil.clear();
-
-    if (m_context) {
-        m_context->setContextLostCallback(0);
-        m_context->setErrorMessageCallback(0);
-        m_context.clear();
-    }
-}
-
-void WebGLRenderingContext::markContextChanged()
-{
-    if (m_framebufferBinding || isContextLost())
-        return;
-
-    m_drawingBuffer->markContentsChanged();
-
-    m_layerCleared = false;
-    RenderBox* renderBox = canvas()->renderBox();
-    if (renderBox && renderBox->hasAcceleratedCompositing()) {
-        m_markedCanvasDirty = true;
-        canvas()->clearCopiedImage();
-        renderBox->contentChanged(CanvasChanged);
-    } else {
-        if (!m_markedCanvasDirty) {
-            m_markedCanvasDirty = true;
-            canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
-        }
-    }
-}
-
-bool WebGLRenderingContext::clearIfComposited(GLbitfield mask)
-{
-    if (isContextLost())
-        return false;
-
-    if (!m_drawingBuffer->layerComposited() || m_layerCleared
-        || m_requestedAttributes->preserveDrawingBuffer() || (mask && m_framebufferBinding))
-        return false;
-
-    RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
-
-    // Determine if it's possible to combine the clear the user asked for and this clear.
-    bool combinedClear = mask && !m_scissorEnabled;
-
-    m_context->disable(GL_SCISSOR_TEST);
-    if (combinedClear && (mask & GL_COLOR_BUFFER_BIT))
-        m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
-                              m_colorMask[1] ? m_clearColor[1] : 0,
-                              m_colorMask[2] ? m_clearColor[2] : 0,
-                              m_colorMask[3] ? m_clearColor[3] : 0);
-    else
-        m_context->clearColor(0, 0, 0, 0);
-    m_context->colorMask(true, true, true, true);
-    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
-    if (contextAttributes->depth()) {
-        if (!combinedClear || !m_depthMask || !(mask & GL_DEPTH_BUFFER_BIT))
-            m_context->clearDepth(1.0f);
-        clearMask |= GL_DEPTH_BUFFER_BIT;
-        m_context->depthMask(true);
-    }
-    if (contextAttributes->stencil()) {
-        if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT))
-            m_context->clearStencil(m_clearStencil & m_stencilMask);
-        else
-            m_context->clearStencil(0);
-        clearMask |= GL_STENCIL_BUFFER_BIT;
-        m_context->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
-    }
-
-    m_drawingBuffer->clearFramebuffers(clearMask);
-
-    restoreStateAfterClear();
-    if (m_framebufferBinding)
-        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-    m_layerCleared = true;
-
-    return combinedClear;
-}
-
-void WebGLRenderingContext::restoreStateAfterClear()
-{
-    if (isContextLost())
-        return;
-
-    // Restore the state that the context set.
-    if (m_scissorEnabled)
-        m_context->enable(GL_SCISSOR_TEST);
-    m_context->clearColor(m_clearColor[0], m_clearColor[1],
-                          m_clearColor[2], m_clearColor[3]);
-    m_context->colorMask(m_colorMask[0], m_colorMask[1],
-                         m_colorMask[2], m_colorMask[3]);
-    m_context->clearDepth(m_clearDepth);
-    m_context->clearStencil(m_clearStencil);
-    m_context->stencilMaskSeparate(GL_FRONT, m_stencilMask);
-    m_context->depthMask(m_depthMask);
-}
-
-void WebGLRenderingContext::markLayerComposited()
-{
-    if (!isContextLost())
-        m_drawingBuffer->markLayerComposited();
-}
-
-void WebGLRenderingContext::paintRenderingResultsToCanvas()
-{
-    if (isContextLost()) {
-        canvas()->clearPresentationCopy();
-        return;
-    }
-
-    if (canvas()->document().printing())
-        canvas()->clearPresentationCopy();
-
-    // Until the canvas is written to by the application, the clear that
-    // happened after it was composited should be ignored by the compositor.
-    if (m_drawingBuffer->layerComposited() && !m_requestedAttributes->preserveDrawingBuffer()) {
-        m_drawingBuffer->paintCompositedResultsToCanvas(canvas()->buffer());
-
-        canvas()->makePresentationCopy();
-    } else
-        canvas()->clearPresentationCopy();
-    clearIfComposited();
-
-    if (!m_markedCanvasDirty && !m_layerCleared)
-        return;
-
-    canvas()->clearCopiedImage();
-    m_markedCanvasDirty = false;
-
-    m_drawingBuffer->commit();
-    if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get())) {
-        canvas()->ensureUnacceleratedImageBuffer();
-        if (canvas()->hasImageBuffer())
-            m_drawingBuffer->paintRenderingResultsToCanvas(canvas()->buffer());
-    }
-
-    if (m_framebufferBinding)
-        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-    else
-        m_drawingBuffer->bind();
-}
-
-PassRefPtr<ImageData> WebGLRenderingContext::paintRenderingResultsToImageData()
-{
-    if (isContextLost())
-        return 0;
-
-    clearIfComposited();
-    m_drawingBuffer->commit();
-    int width, height;
-    RefPtr<Uint8ClampedArray> imageDataPixels = m_drawingBuffer->paintRenderingResultsToImageData(width, height);
-    if (!imageDataPixels)
-        return 0;
-
-    if (m_framebufferBinding)
-        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-    else
-        m_drawingBuffer->bind();
-
-    return ImageData::create(IntSize(width, height), imageDataPixels);
-}
-
-void WebGLRenderingContext::reshape(int width, int height)
-{
-    if (isContextLost())
-        return;
-
-    // This is an approximation because at WebGLRenderingContext level we don't
-    // know if the underlying FBO uses textures or renderbuffers.
-    GLint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
-    // Limit drawing buffer size to 4k to avoid memory exhaustion.
-    const int sizeUpperLimit = 4096;
-    maxSize = std::min(maxSize, sizeUpperLimit);
-    GLint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
-    GLint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
-    width = clamp(width, 1, maxWidth);
-    height = clamp(height, 1, maxHeight);
-
-    if (m_needsUpdate) {
-        RenderBox* renderBox = canvas()->renderBox();
-        if (renderBox && renderBox->hasAcceleratedCompositing())
-            renderBox->contentChanged(CanvasChanged);
-        m_needsUpdate = false;
-    }
-
-    // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
-    // clear (and this matches what reshape will do).
-    m_drawingBuffer->reset(IntSize(width, height));
-    restoreStateAfterClear();
-
-    m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()));
-    m_context->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
-    if (m_framebufferBinding)
-        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
-}
-
-int WebGLRenderingContext::drawingBufferWidth() const
-{
-    return m_drawingBuffer->size().width();
-}
-
-int WebGLRenderingContext::drawingBufferHeight() const
-{
-    return m_drawingBuffer->size().height();
-}
-
-unsigned WebGLRenderingContext::sizeInBytes(GLenum type)
-{
-    switch (type) {
-    case GL_BYTE:
-        return sizeof(GLbyte);
-    case GL_UNSIGNED_BYTE:
-        return sizeof(GLubyte);
-    case GL_SHORT:
-        return sizeof(GLshort);
-    case GL_UNSIGNED_SHORT:
-        return sizeof(GLushort);
-    case GL_INT:
-        return sizeof(GLint);
-    case GL_UNSIGNED_INT:
-        return sizeof(GLuint);
-    case GL_FLOAT:
-        return sizeof(GLfloat);
-    }
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-void WebGLRenderingContext::activeTexture(GLenum texture)
-{
-    if (isContextLost())
-        return;
-    if (texture - GL_TEXTURE0 >= m_textureUnits.size()) {
-        synthesizeGLError(GL_INVALID_ENUM, "activeTexture", "texture unit out of range");
-        return;
-    }
-    m_activeTextureUnit = texture - GL_TEXTURE0;
-    m_context->activeTexture(texture);
-
-    m_drawingBuffer->setActiveTextureUnit(texture);
-
-}
-
-void WebGLRenderingContext::attachShader(WebGLProgram* program, WebGLShader* shader)
-{
-    if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
-        return;
-    if (!program->attachShader(shader)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachment already has shader");
-        return;
-    }
-    m_context->attachShader(objectOrZero(program), objectOrZero(shader));
-    shader->onAttached();
-}
-
-void WebGLRenderingContext::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name)
-{
-    if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
-        return;
-    if (!validateLocationLength("bindAttribLocation", name))
-        return;
-    if (!validateString("bindAttribLocation", name))
-        return;
-    if (isPrefixReserved(name)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
-        return;
-    }
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, "bindAttribLocation", "index out of range");
-        return;
-    }
-    m_context->bindAttribLocation(objectOrZero(program), index, name.utf8().data());
-}
-
-bool WebGLRenderingContext::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
-{
-    deleted = false;
-    if (isContextLost())
-        return false;
-    if (object) {
-        if (!object->validate(contextGroup(), this)) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "object not from this context");
-            return false;
-        }
-        deleted = !object->object();
-    }
-    return true;
-}
-
-void WebGLRenderingContext::bindBuffer(GLenum target, WebGLBuffer* buffer)
-{
-    bool deleted;
-    if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
-        return;
-    if (deleted)
-        buffer = 0;
-    if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
-        synthesizeGLError(GL_INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
-        return;
-    }
-    if (target == GL_ARRAY_BUFFER)
-        m_boundArrayBuffer = buffer;
-    else if (target == GL_ELEMENT_ARRAY_BUFFER)
-        m_boundVertexArrayObject->setElementArrayBuffer(buffer);
-    else {
-        synthesizeGLError(GL_INVALID_ENUM, "bindBuffer", "invalid target");
-        return;
-    }
-
-    m_context->bindBuffer(target, objectOrZero(buffer));
-    if (buffer)
-        buffer->setTarget(target);
-}
-
-void WebGLRenderingContext::bindFramebuffer(GLenum target, WebGLFramebuffer* buffer)
-{
-    bool deleted;
-    if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
-        return;
-    if (deleted)
-        buffer = 0;
-    if (target != GL_FRAMEBUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target");
-        return;
-    }
-    m_framebufferBinding = buffer;
-    m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
-    if (!m_framebufferBinding) {
-        // Instead of binding fb 0, bind the drawing buffer.
-        m_drawingBuffer->bind();
-    } else
-        m_context->bindFramebuffer(target, objectOrZero(buffer));
-    if (buffer)
-        buffer->setHasEverBeenBound();
-    applyStencilTest();
-}
-
-void WebGLRenderingContext::bindRenderbuffer(GLenum target, WebGLRenderbuffer* renderBuffer)
-{
-    bool deleted;
-    if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
-        return;
-    if (deleted)
-        renderBuffer = 0;
-    if (target != GL_RENDERBUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target");
-        return;
-    }
-    m_renderbufferBinding = renderBuffer;
-    m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
-    if (renderBuffer)
-        renderBuffer->setHasEverBeenBound();
-}
-
-void WebGLRenderingContext::bindTexture(GLenum target, WebGLTexture* texture)
-{
-    bool deleted;
-    if (!checkObjectToBeBound("bindTexture", texture, deleted))
-        return;
-    if (deleted)
-        texture = 0;
-    if (texture && texture->getTarget() && texture->getTarget() != target) {
-        synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
-        return;
-    }
-    GLint maxLevel = 0;
-    if (target == GL_TEXTURE_2D) {
-        m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
-        maxLevel = m_maxTextureLevel;
-
-        if (!m_activeTextureUnit)
-            m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
-
-    } else if (target == GL_TEXTURE_CUBE_MAP) {
-        m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
-        maxLevel = m_maxCubeMapTextureLevel;
-    } else {
-        synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
-        return;
-    }
-
-    m_context->bindTexture(target, objectOrZero(texture));
-    if (texture) {
-        texture->setTarget(target, maxLevel);
-        m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit);
-    } else {
-        // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index
-        if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) {
-            findNewMaxNonDefaultTextureUnit();
-        }
-    }
-
-    // Note: previously we used to automatically set the TEXTURE_WRAP_R
-    // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
-    // ES 2.0 doesn't expose this flag (a bug in the specification) and
-    // otherwise the application has no control over the seams in this
-    // dimension. However, it appears that supporting this properly on all
-    // platforms is fairly involved (will require a HashMap from texture ID
-    // in all ports), and we have not had any complaints, so the logic has
-    // been removed.
-
-}
-
-void WebGLRenderingContext::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
-{
-    if (isContextLost())
-        return;
-    m_context->blendColor(red, green, blue, alpha);
-}
-
-void WebGLRenderingContext::blendEquation(GLenum mode)
-{
-    if (isContextLost() || !validateBlendEquation("blendEquation", mode))
-        return;
-    m_context->blendEquation(mode);
-}
-
-void WebGLRenderingContext::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
-{
-    if (isContextLost() || !validateBlendEquation("blendEquationSeparate", modeRGB) || !validateBlendEquation("blendEquationSeparate", modeAlpha))
-        return;
-    m_context->blendEquationSeparate(modeRGB, modeAlpha);
-}
-
-
-void WebGLRenderingContext::blendFunc(GLenum sfactor, GLenum dfactor)
-{
-    if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
-        return;
-    m_context->blendFunc(sfactor, dfactor);
-}
-
-void WebGLRenderingContext::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
-{
-    // Note: Alpha does not have the same restrictions as RGB.
-    if (isContextLost() || !validateBlendFuncFactors("blendFuncSeparate", srcRGB, dstRGB))
-        return;
-    m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
-}
-
-void WebGLRenderingContext::bufferData(GLenum target, long long size, GLenum usage)
-{
-    if (isContextLost())
-        return;
-    WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
-    if (!buffer)
-        return;
-    if (size < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size < 0");
-        return;
-    }
-    if (!size) {
-        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0");
-        return;
-    }
-
-    m_context->bufferData(target, static_cast<GLsizeiptr>(size), 0, usage);
-}
-
-void WebGLRenderingContext::bufferData(GLenum target, ArrayBuffer* data, GLenum usage)
-{
-    if (isContextLost())
-        return;
-    WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
-    if (!buffer)
-        return;
-    if (!data) {
-        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
-        return;
-    }
-    m_context->bufferData(target, data->byteLength(), data->data(), usage);
-}
-
-void WebGLRenderingContext::bufferData(GLenum target, ArrayBufferView* data, GLenum usage)
-{
-    if (isContextLost())
-        return;
-    WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
-    if (!buffer)
-        return;
-    if (!data) {
-        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
-        return;
-    }
-
-    m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
-}
-
-void WebGLRenderingContext::bufferSubData(GLenum target, long long offset, ArrayBuffer* data)
-{
-    if (isContextLost())
-        return;
-    WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
-    if (!buffer)
-        return;
-    if (offset < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
-        return;
-    }
-    if (!data)
-        return;
-
-    m_context->bufferSubData(target, static_cast<GLintptr>(offset), data->byteLength(), data->data());
-}
-
-void WebGLRenderingContext::bufferSubData(GLenum target, long long offset, ArrayBufferView* data)
-{
-    if (isContextLost())
-        return;
-    WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
-    if (!buffer)
-        return;
-    if (offset < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
-        return;
-    }
-    if (!data)
-        return;
-
-    m_context->bufferSubData(target, static_cast<GLintptr>(offset), data->byteLength(), data->baseAddress());
-}
-
-GLenum WebGLRenderingContext::checkFramebufferStatus(GLenum target)
-{
-    if (isContextLost())
-        return GL_FRAMEBUFFER_UNSUPPORTED;
-    if (target != GL_FRAMEBUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid target");
-        return 0;
-    }
-    if (!m_framebufferBinding || !m_framebufferBinding->object())
-        return GL_FRAMEBUFFER_COMPLETE;
-    const char* reason = "framebuffer incomplete";
-    GLenum result = m_framebufferBinding->checkStatus(&reason);
-    if (result != GL_FRAMEBUFFER_COMPLETE) {
-        emitGLWarning("checkFramebufferStatus", reason);
-        return result;
-    }
-    result = m_context->checkFramebufferStatus(target);
-    return result;
-}
-
-void WebGLRenderingContext::clear(GLbitfield mask)
-{
-    if (isContextLost())
-        return;
-    if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
-        synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask");
-        return;
-    }
-    const char* reason = "framebuffer incomplete";
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
-        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
-        return;
-    }
-    if (!clearIfComposited(mask))
-        m_context->clear(mask);
-    markContextChanged();
-}
-
-void WebGLRenderingContext::clearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
-{
-    if (isContextLost())
-        return;
-    if (std::isnan(r))
-        r = 0;
-    if (std::isnan(g))
-        g = 0;
-    if (std::isnan(b))
-        b = 0;
-    if (std::isnan(a))
-        a = 1;
-    m_clearColor[0] = r;
-    m_clearColor[1] = g;
-    m_clearColor[2] = b;
-    m_clearColor[3] = a;
-    m_context->clearColor(r, g, b, a);
-}
-
-void WebGLRenderingContext::clearDepth(GLfloat depth)
-{
-    if (isContextLost())
-        return;
-    m_clearDepth = depth;
-    m_context->clearDepth(depth);
-}
-
-void WebGLRenderingContext::clearStencil(GLint s)
-{
-    if (isContextLost())
-        return;
-    m_clearStencil = s;
-    m_context->clearStencil(s);
-}
-
-void WebGLRenderingContext::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
-{
-    if (isContextLost())
-        return;
-    m_colorMask[0] = red;
-    m_colorMask[1] = green;
-    m_colorMask[2] = blue;
-    m_colorMask[3] = alpha;
-    m_context->colorMask(red, green, blue, alpha);
-}
-
-void WebGLRenderingContext::compileShader(WebGLShader* shader)
-{
-    if (isContextLost() || !validateWebGLObject("compileShader", shader))
-        return;
-    m_context->compileShader(objectOrZero(shader));
-}
-
-void WebGLRenderingContext::compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data)
-{
-    if (isContextLost())
-        return;
-    if (!validateTexFuncLevel("compressedTexImage2D", target, level))
-        return;
-
-    if (!validateCompressedTexFormat(internalformat)) {
-        synthesizeGLError(GL_INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
-        return;
-    }
-    if (border) {
-        synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0");
-        return;
-    }
-    if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, internalformat))
-        return;
-    if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
-        return;
-
-    WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
-    if (!tex)
-        return;
-    if (!isGLES2NPOTStrict()) {
-        if (level && WebGLTexture::isNPOT(width, height)) {
-            synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
-            return;
-        }
-    }
-    m_context->compressedTexImage2D(target, level, internalformat, width, height,
-                                              border, data->byteLength(), data->baseAddress());
-    tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
-}
-
-void WebGLRenderingContext::compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data)
-{
-    if (isContextLost())
-        return;
-    if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
-        return;
-    if (!validateCompressedTexFormat(format)) {
-        synthesizeGLError(GL_INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
-        return;
-    }
-    if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
-        return;
-
-    WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
-    if (!tex)
-        return;
-
-    if (format != tex->getInternalFormat(target, level)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
-        return;
-    }
-
-    if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
-        return;
-
-    m_context->compressedTexSubImage2D(target, level, xoffset, yoffset,
-                                                 width, height, format, data->byteLength(), data->baseAddress());
-}
-
-bool WebGLRenderingContext::validateSettableTexFormat(const char* functionName, GLenum format)
-{
-    if (WebGLImageConversion::getClearBitsByFormat(format) & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to");
-        return false;
-    }
-    return true;
-}
-
-void WebGLRenderingContext::copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
-{
-    if (isContextLost())
-        return;
-    if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GL_UNSIGNED_BYTE))
-        return;
-    if (!validateSettableTexFormat("copyTexImage2D", internalformat))
-        return;
-    WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
-    if (!tex)
-        return;
-    if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
-        synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
-        return;
-    }
-    if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
-        synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
-        return;
-    }
-    const char* reason = "framebuffer incomplete";
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
-        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
-        return;
-    }
-    clearIfComposited();
-    ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
-    m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
-    // FIXME: if the framebuffer is not complete, none of the below should be executed.
-    tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
-}
-
-void WebGLRenderingContext::copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    if (isContextLost())
-        return;
-    if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
-        return;
-    WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
-    if (!tex)
-        return;
-    if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
-        return;
-    // Before checking if it is in the range, check if overflow happens first.
-    Checked<GLint, RecordOverflow> maxX = xoffset;
-    maxX += width;
-    Checked<GLint, RecordOverflow> maxY = yoffset;
-    maxY += height;
-    if (maxX.hasOverflowed() || maxY.hasOverflowed()) {
-        synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
-        return;
-    }
-    if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > tex->getHeight(target, level)) {
-        synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
-        return;
-    }
-    GLenum internalformat = tex->getInternalFormat(target, level);
-    if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
-        return;
-    if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
-        synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
-        return;
-    }
-    const char* reason = "framebuffer incomplete";
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
-        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
-        return;
-    }
-    clearIfComposited();
-    ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
-    m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
-}
-
-PassRefPtr<WebGLBuffer> WebGLRenderingContext::createBuffer()
-{
-    if (isContextLost())
-        return 0;
-    RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
-    addSharedObject(o.get());
-    return o;
-}
-
-PassRefPtr<WebGLFramebuffer> WebGLRenderingContext::createFramebuffer()
-{
-    if (isContextLost())
-        return 0;
-    RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
-    addContextObject(o.get());
-    return o;
-}
-
-PassRefPtr<WebGLTexture> WebGLRenderingContext::createTexture()
-{
-    if (isContextLost())
-        return 0;
-    RefPtr<WebGLTexture> o = WebGLTexture::create(this);
-    addSharedObject(o.get());
-    return o;
-}
-
-PassRefPtr<WebGLProgram> WebGLRenderingContext::createProgram()
-{
-    if (isContextLost())
-        return 0;
-    RefPtr<WebGLProgram> o = WebGLProgram::create(this);
-    addSharedObject(o.get());
-    return o;
-}
-
-PassRefPtr<WebGLRenderbuffer> WebGLRenderingContext::createRenderbuffer()
-{
-    if (isContextLost())
-        return 0;
-    RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
-    addSharedObject(o.get());
-    return o;
-}
-
-WebGLRenderbuffer* WebGLRenderingContext::ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer* renderbuffer)
-{
-    if (isContextLost())
-        return 0;
-    if (!renderbuffer->emulatedStencilBuffer()) {
-        renderbuffer->setEmulatedStencilBuffer(createRenderbuffer());
-        m_context->bindRenderbuffer(target, objectOrZero(renderbuffer->emulatedStencilBuffer()));
-        m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
-    }
-    return renderbuffer->emulatedStencilBuffer();
-}
-
-PassRefPtr<WebGLShader> WebGLRenderingContext::createShader(GLenum type)
-{
-    if (isContextLost())
-        return 0;
-    if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
-        synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type");
-        return 0;
-    }
-
-    RefPtr<WebGLShader> o = WebGLShader::create(this, type);
-    addSharedObject(o.get());
-    return o;
-}
-
-void WebGLRenderingContext::cullFace(GLenum mode)
-{
-    if (isContextLost())
-        return;
-    switch (mode) {
-    case GL_FRONT_AND_BACK:
-    case GL_FRONT:
-    case GL_BACK:
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "cullFace", "invalid mode");
-        return;
-    }
-    m_context->cullFace(mode);
-}
-
-bool WebGLRenderingContext::deleteObject(WebGLObject* object)
-{
-    if (isContextLost() || !object)
-        return false;
-    if (!object->validate(contextGroup(), this)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "delete", "object does not belong to this context");
-        return false;
-    }
-    if (object->object()) {
-        // We need to pass in context here because we want
-        // things in this context unbound.
-        object->deleteObject(m_context.get());
-    }
-    return true;
-}
-
-void WebGLRenderingContext::deleteBuffer(WebGLBuffer* buffer)
-{
-    if (!deleteObject(buffer))
-        return;
-    if (m_boundArrayBuffer == buffer)
-        m_boundArrayBuffer = 0;
-
-    m_boundVertexArrayObject->unbindBuffer(buffer);
-}
-
-void WebGLRenderingContext::deleteFramebuffer(WebGLFramebuffer* framebuffer)
-{
-    if (!deleteObject(framebuffer))
-        return;
-    if (framebuffer == m_framebufferBinding) {
-        m_framebufferBinding = 0;
-        m_drawingBuffer->setFramebufferBinding(0);
-        // Have to call bindFramebuffer here to bind back to internal fbo.
-        m_drawingBuffer->bind();
-    }
-}
-
-void WebGLRenderingContext::deleteProgram(WebGLProgram* program)
-{
-    deleteObject(program);
-    // We don't reset m_currentProgram to 0 here because the deletion of the
-    // current program is delayed.
-}
-
-void WebGLRenderingContext::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
-    if (!deleteObject(renderbuffer))
-        return;
-    if (renderbuffer == m_renderbufferBinding)
-        m_renderbufferBinding = 0;
-    if (m_framebufferBinding)
-        m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
-}
-
-void WebGLRenderingContext::deleteShader(WebGLShader* shader)
-{
-    deleteObject(shader);
-}
-
-void WebGLRenderingContext::deleteTexture(WebGLTexture* texture)
-{
-    if (!deleteObject(texture))
-        return;
-
-    int maxBoundTextureIndex = -1;
-    for (size_t i = 0; i < m_onePlusMaxNonDefaultTextureUnit; ++i) {
-        if (texture == m_textureUnits[i].m_texture2DBinding) {
-            m_textureUnits[i].m_texture2DBinding = 0;
-            maxBoundTextureIndex = i;
-            if (!i)
-                m_drawingBuffer->setTexture2DBinding(0);
-        }
-        if (texture == m_textureUnits[i].m_textureCubeMapBinding) {
-            m_textureUnits[i].m_textureCubeMapBinding = 0;
-            maxBoundTextureIndex = i;
-        }
-    }
-    if (m_framebufferBinding)
-        m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
-
-    // If the deleted was bound to the the current maximum index, trace backwards to find the new max texture index
-    if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBoundTextureIndex + 1)) {
-        findNewMaxNonDefaultTextureUnit();
-    }
-}
-
-void WebGLRenderingContext::depthFunc(GLenum func)
-{
-    if (isContextLost())
-        return;
-    if (!validateStencilOrDepthFunc("depthFunc", func))
-        return;
-    m_context->depthFunc(func);
-}
-
-void WebGLRenderingContext::depthMask(GLboolean flag)
-{
-    if (isContextLost())
-        return;
-    m_depthMask = flag;
-    m_context->depthMask(flag);
-}
-
-void WebGLRenderingContext::depthRange(GLfloat zNear, GLfloat zFar)
-{
-    if (isContextLost())
-        return;
-    if (zNear > zFar) {
-        synthesizeGLError(GL_INVALID_OPERATION, "depthRange", "zNear > zFar");
-        return;
-    }
-    m_context->depthRange(zNear, zFar);
-}
-
-void WebGLRenderingContext::detachShader(WebGLProgram* program, WebGLShader* shader)
-{
-    if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
-        return;
-    if (!program->detachShader(shader)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not attached");
-        return;
-    }
-    m_context->detachShader(objectOrZero(program), objectOrZero(shader));
-    shader->onDetached(m_context.get());
-}
-
-void WebGLRenderingContext::disable(GLenum cap)
-{
-    if (isContextLost() || !validateCapability("disable", cap))
-        return;
-    if (cap == GL_STENCIL_TEST) {
-        m_stencilEnabled = false;
-        applyStencilTest();
-        return;
-    }
-    if (cap == GL_SCISSOR_TEST) {
-        m_scissorEnabled = false;
-        m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
-    }
-    m_context->disable(cap);
-}
-
-void WebGLRenderingContext::disableVertexAttribArray(GLuint index)
-{
-    if (isContextLost())
-        return;
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, "disableVertexAttribArray", "index out of range");
-        return;
-    }
-
-    WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
-    state.enabled = false;
-
-    // If the disabled index is the current maximum, trace backwards to find the new max enabled attrib index
-    if (m_onePlusMaxEnabledAttribIndex == index + 1) {
-        findNewMaxEnabledAttribIndex();
-    }
-
-    m_context->disableVertexAttribArray(index);
-}
-
-bool WebGLRenderingContext::validateRenderingState(const char* functionName)
-{
-    if (!m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no valid shader program in use");
-        return false;
-    }
-
-    // Look in each enabled vertex attrib and check if they've been bound to a buffer.
-    for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
-        const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
-        if (state.enabled
-            && (!state.bufferBinding || !state.bufferBinding->object())) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, String::format("attribute %d is enabled but has no buffer bound", i).utf8().data());
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool WebGLRenderingContext::validateWebGLObject(const char* functionName, WebGLObject* object)
-{
-    if (!object || !object->object()) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no object or object deleted");
-        return false;
-    }
-    if (!object->validate(contextGroup(), this)) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "object does not belong to this context");
-        return false;
-    }
-    return true;
-}
-
-void WebGLRenderingContext::drawArrays(GLenum mode, GLint first, GLsizei count)
-{
-    if (!validateDrawArrays("drawArrays", mode, first, count))
-        return;
-
-    clearIfComposited();
-
-    handleTextureCompleteness("drawArrays", true);
-    m_context->drawArrays(mode, first, count);
-    handleTextureCompleteness("drawArrays", false);
-    markContextChanged();
-}
-
-void WebGLRenderingContext::drawElements(GLenum mode, GLsizei count, GLenum type, long long offset)
-{
-    if (!validateDrawElements("drawElements", mode, count, type, offset))
-        return;
-
-    clearIfComposited();
-
-    handleTextureCompleteness("drawElements", true);
-    m_context->drawElements(mode, count, type, static_cast<GLintptr>(offset));
-    handleTextureCompleteness("drawElements", false);
-    markContextChanged();
-}
-
-void WebGLRenderingContext::drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
-{
-    if (!validateDrawArrays("drawArraysInstancedANGLE", mode, first, count))
-        return;
-
-    if (!validateDrawInstanced("drawArraysInstancedANGLE", primcount))
-        return;
-
-    clearIfComposited();
-
-    handleTextureCompleteness("drawArraysInstancedANGLE", true);
-    m_context->drawArraysInstancedANGLE(mode, first, count, primcount);
-    handleTextureCompleteness("drawArraysInstancedANGLE", false);
-    markContextChanged();
-}
-
-void WebGLRenderingContext::drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount)
-{
-    if (!validateDrawElements("drawElementsInstancedANGLE", mode, count, type, offset))
-        return;
-
-    if (!validateDrawInstanced("drawElementsInstancedANGLE", primcount))
-        return;
-
-    clearIfComposited();
-
-    handleTextureCompleteness("drawElementsInstancedANGLE", true);
-    m_context->drawElementsInstancedANGLE(mode, count, type, static_cast<GLintptr>(offset), primcount);
-    handleTextureCompleteness("drawElementsInstancedANGLE", false);
-    markContextChanged();
-}
-
-void WebGLRenderingContext::enable(GLenum cap)
-{
-    if (isContextLost() || !validateCapability("enable", cap))
-        return;
-    if (cap == GL_STENCIL_TEST) {
-        m_stencilEnabled = true;
-        applyStencilTest();
-        return;
-    }
-    if (cap == GL_SCISSOR_TEST) {
-        m_scissorEnabled = true;
-        m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
-    }
-    m_context->enable(cap);
-}
-
-void WebGLRenderingContext::enableVertexAttribArray(GLuint index)
-{
-    if (isContextLost())
-        return;
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, "enableVertexAttribArray", "index out of range");
-        return;
-    }
-
-    WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
-    state.enabled = true;
-
-    m_onePlusMaxEnabledAttribIndex = max(index + 1, m_onePlusMaxEnabledAttribIndex);
-
-    m_context->enableVertexAttribArray(index);
-}
-
-void WebGLRenderingContext::finish()
-{
-    if (isContextLost())
-        return;
-    m_context->flush(); // Intentionally a flush, not a finish.
-}
-
-void WebGLRenderingContext::flush()
-{
-    if (isContextLost())
-        return;
-    m_context->flush();
-}
-
-void WebGLRenderingContext::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer* buffer)
-{
-    if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
-        return;
-    if (renderbuffertarget != GL_RENDERBUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
-        return;
-    }
-    if (buffer && !buffer->validate(contextGroup(), this)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
-        return;
-    }
-    // Don't allow the default framebuffer to be mutated; all current
-    // implementations use an FBO internally in place of the default
-    // FBO.
-    if (!m_framebufferBinding || !m_framebufferBinding->object()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
-        return;
-    }
-    Platform3DObject bufferObject = objectOrZero(buffer);
-    switch (attachment) {
-    case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
-        if (isDepthStencilSupported() || !buffer) {
-            m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
-            m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
-        } else {
-            WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(renderbuffertarget, buffer);
-            if (!emulatedStencilBuffer) {
-                synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "out of memory");
-                return;
-            }
-            m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
-            m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
-        }
-        break;
-    default:
-        m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
-    }
-    m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
-    applyStencilTest();
-}
-
-void WebGLRenderingContext::framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level)
-{
-    if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
-        return;
-    if (level) {
-        synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0");
-        return;
-    }
-    if (texture && !texture->validate(contextGroup(), this)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
-        return;
-    }
-    // Don't allow the default framebuffer to be mutated; all current
-    // implementations use an FBO internally in place of the default
-    // FBO.
-    if (!m_framebufferBinding || !m_framebufferBinding->object()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
-        return;
-    }
-    Platform3DObject textureObject = objectOrZero(texture);
-    switch (attachment) {
-    case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
-        m_context->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, textureObject, level);
-        m_context->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, textureObject, level);
-        break;
-    case GL_DEPTH_ATTACHMENT:
-        m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
-        break;
-    case GL_STENCIL_ATTACHMENT:
-        m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
-        break;
-    default:
-        m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
-    }
-    m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
-    applyStencilTest();
-}
-
-void WebGLRenderingContext::frontFace(GLenum mode)
-{
-    if (isContextLost())
-        return;
-    switch (mode) {
-    case GL_CW:
-    case GL_CCW:
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "frontFace", "invalid mode");
-        return;
-    }
-    m_context->frontFace(mode);
-}
-
-void WebGLRenderingContext::generateMipmap(GLenum target)
-{
-    if (isContextLost())
-        return;
-    WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
-    if (!tex)
-        return;
-    if (!tex->canGenerateMipmaps()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
-        return;
-    }
-    if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
-        return;
-
-    // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
-    // on Mac.  Remove the hack once this driver bug is fixed.
-#if OS(MACOSX)
-    bool needToResetMinFilter = false;
-    if (tex->getMinFilter() != GL_NEAREST_MIPMAP_LINEAR) {
-        m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
-        needToResetMinFilter = true;
-    }
-#endif
-    m_context->generateMipmap(target);
-#if OS(MACOSX)
-    if (needToResetMinFilter)
-        m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, tex->getMinFilter());
-#endif
-    tex->generateMipmapLevelInfo();
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveAttrib(WebGLProgram* program, GLuint index)
-{
-    if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
-        return 0;
-    blink::WebGraphicsContext3D::ActiveInfo info;
-    if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
-        return 0;
-    return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-PassRefPtr<WebGLActiveInfo> WebGLRenderingContext::getActiveUniform(WebGLProgram* program, GLuint index)
-{
-    if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
-        return 0;
-    blink::WebGraphicsContext3D::ActiveInfo info;
-    if (!m_context->getActiveUniform(objectOrZero(program), index, info))
-        return 0;
-    return WebGLActiveInfo::create(info.name, info.type, info.size);
-}
-
-bool WebGLRenderingContext::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader> >& shaderObjects)
-{
-    shaderObjects.clear();
-    if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
-        return false;
-
-    const GLenum shaderType[] = {
-        GL_VERTEX_SHADER,
-        GL_FRAGMENT_SHADER
-    };
-    for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GLenum); ++i) {
-        WebGLShader* shader = program->getAttachedShader(shaderType[i]);
-        if (shader)
-            shaderObjects.append(shader);
-    }
-    return true;
-}
-
-GLint WebGLRenderingContext::getAttribLocation(WebGLProgram* program, const String& name)
-{
-    if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
-        return -1;
-    if (!validateLocationLength("getAttribLocation", name))
-        return -1;
-    if (!validateString("getAttribLocation", name))
-        return -1;
-    if (isPrefixReserved(name))
-        return -1;
-    if (!program->linkStatus()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "getAttribLocation", "program not linked");
-        return 0;
-    }
-    return m_context->getAttribLocation(objectOrZero(program), name.utf8().data());
-}
-
-WebGLGetInfo WebGLRenderingContext::getBufferParameter(GLenum target, GLenum pname)
-{
-    if (isContextLost())
-        return WebGLGetInfo();
-    if (target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid target");
-        return WebGLGetInfo();
-    }
-
-    if (pname != GL_BUFFER_SIZE && pname != GL_BUFFER_USAGE) {
-        synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-
-    GLint value = 0;
-    m_context->getBufferParameteriv(target, pname, &value);
-    if (pname == GL_BUFFER_SIZE)
-        return WebGLGetInfo(value);
-    return WebGLGetInfo(static_cast<unsigned>(value));
-}
-
-PassRefPtr<WebGLContextAttributes> WebGLRenderingContext::getContextAttributes()
-{
-    if (isContextLost())
-        return 0;
-    // We always need to return a new WebGLContextAttributes object to
-    // prevent the user from mutating any cached version.
-    blink::WebGraphicsContext3D::Attributes attrs = m_context->getContextAttributes();
-    RefPtr<WebGLContextAttributes> attributes = m_requestedAttributes->clone();
-    // Some requested attributes may not be honored, so we need to query the underlying
-    // context/drawing buffer and adjust accordingly.
-    if (m_requestedAttributes->depth() && !attrs.depth)
-        attributes->setDepth(false);
-    if (m_requestedAttributes->stencil() && !attrs.stencil)
-        attributes->setStencil(false);
-    attributes->setAntialias(m_drawingBuffer->multisample());
-    return attributes.release();
-}
-
-GLenum WebGLRenderingContext::getError()
-{
-    if (m_lostContextErrors.size()) {
-        GLenum err = m_lostContextErrors.first();
-        m_lostContextErrors.remove(0);
-        return err;
-    }
-
-    if (isContextLost())
-        return GL_NO_ERROR;
-
-    return m_context->getError();
-}
-
-bool WebGLRenderingContext::ExtensionTracker::matchesNameWithPrefixes(const String& name) const
-{
-    static const char* const unprefixed[] = { "", 0, };
-
-    const char* const* prefixes = m_prefixes ? m_prefixes : unprefixed;
-    for (; *prefixes; ++prefixes) {
-        String prefixedName = String(*prefixes) + extensionName();
-        if (equalIgnoringCase(prefixedName, name)) {
-            return true;
-        }
-    }
-    return false;
-}
-
-PassRefPtr<WebGLExtension> WebGLRenderingContext::getExtension(const String& name)
-{
-    if (isContextLost())
-        return 0;
-
-    for (size_t i = 0; i < m_extensions.size(); ++i) {
-        ExtensionTracker* tracker = m_extensions[i];
-        if (tracker->matchesNameWithPrefixes(name)) {
-            if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
-                return 0;
-            if (tracker->privileged() && !allowPrivilegedExtensions())
-                return 0;
-            if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
-                return 0;
-            if (!tracker->supported(this))
-                return 0;
-            return tracker->getExtension(this);
-        }
-    }
-
-    return 0;
-}
-
-WebGLGetInfo WebGLRenderingContext::getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname)
-{
-    if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
-        return WebGLGetInfo();
-
-    if (!m_framebufferBinding || !m_framebufferBinding->object()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
-        return WebGLGetInfo();
-    }
-
-    WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
-    if (!object) {
-        if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
-            return WebGLGetInfo(GL_NONE);
-        // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
-        // specifies INVALID_OPERATION.
-        synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-
-    ASSERT(object->isTexture() || object->isRenderbuffer());
-    if (object->isTexture()) {
-        switch (pname) {
-        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-            return WebGLGetInfo(GL_TEXTURE);
-        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-            return WebGLGetInfo(PassRefPtr<WebGLTexture>(static_cast<WebGLTexture*>(object)));
-        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
-        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
-            {
-                GLint value = 0;
-                m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
-                return WebGLGetInfo(value);
-            }
-        default:
-            synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
-            return WebGLGetInfo();
-        }
-    } else {
-        switch (pname) {
-        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
-            return WebGLGetInfo(GL_RENDERBUFFER);
-        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
-            return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(static_cast<WebGLRenderbuffer*>(object)));
-        default:
-            synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
-            return WebGLGetInfo();
-        }
-    }
-}
-
-WebGLGetInfo WebGLRenderingContext::getParameter(GLenum pname)
-{
-    if (isContextLost())
-        return WebGLGetInfo();
-    const int intZero = 0;
-    switch (pname) {
-    case GL_ACTIVE_TEXTURE:
-        return getUnsignedIntParameter(pname);
-    case GL_ALIASED_LINE_WIDTH_RANGE:
-        return getWebGLFloatArrayParameter(pname);
-    case GL_ALIASED_POINT_SIZE_RANGE:
-        return getWebGLFloatArrayParameter(pname);
-    case GL_ALPHA_BITS:
-        return getIntParameter(pname);
-    case GL_ARRAY_BUFFER_BINDING:
-        return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
-    case GL_BLEND:
-        return getBooleanParameter(pname);
-    case GL_BLEND_COLOR:
-        return getWebGLFloatArrayParameter(pname);
-    case GL_BLEND_DST_ALPHA:
-        return getUnsignedIntParameter(pname);
-    case GL_BLEND_DST_RGB:
-        return getUnsignedIntParameter(pname);
-    case GL_BLEND_EQUATION_ALPHA:
-        return getUnsignedIntParameter(pname);
-    case GL_BLEND_EQUATION_RGB:
-        return getUnsignedIntParameter(pname);
-    case GL_BLEND_SRC_ALPHA:
-        return getUnsignedIntParameter(pname);
-    case GL_BLEND_SRC_RGB:
-        return getUnsignedIntParameter(pname);
-    case GL_BLUE_BITS:
-        return getIntParameter(pname);
-    case GL_COLOR_CLEAR_VALUE:
-        return getWebGLFloatArrayParameter(pname);
-    case GL_COLOR_WRITEMASK:
-        return getBooleanArrayParameter(pname);
-    case GL_COMPRESSED_TEXTURE_FORMATS:
-        return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
-    case GL_CULL_FACE:
-        return getBooleanParameter(pname);
-    case GL_CULL_FACE_MODE:
-        return getUnsignedIntParameter(pname);
-    case GL_CURRENT_PROGRAM:
-        return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
-    case GL_DEPTH_BITS:
-        if (!m_framebufferBinding && !m_requestedAttributes->depth())
-            return WebGLGetInfo(intZero);
-        return getIntParameter(pname);
-    case GL_DEPTH_CLEAR_VALUE:
-        return getFloatParameter(pname);
-    case GL_DEPTH_FUNC:
-        return getUnsignedIntParameter(pname);
-    case GL_DEPTH_RANGE:
-        return getWebGLFloatArrayParameter(pname);
-    case GL_DEPTH_TEST:
-        return getBooleanParameter(pname);
-    case GL_DEPTH_WRITEMASK:
-        return getBooleanParameter(pname);
-    case GL_DITHER:
-        return getBooleanParameter(pname);
-    case GL_ELEMENT_ARRAY_BUFFER_BINDING:
-        return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->boundElementArrayBuffer()));
-    case GL_FRAMEBUFFER_BINDING:
-        return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
-    case GL_FRONT_FACE:
-        return getUnsignedIntParameter(pname);
-    case GL_GENERATE_MIPMAP_HINT:
-        return getUnsignedIntParameter(pname);
-    case GL_GREEN_BITS:
-        return getIntParameter(pname);
-    case GL_LINE_WIDTH:
-        return getFloatParameter(pname);
-    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
-        return getIntParameter(pname);
-    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
-        return getIntParameter(pname);
-    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
-        return getIntParameter(pname);
-    case GL_MAX_RENDERBUFFER_SIZE:
-        return getIntParameter(pname);
-    case GL_MAX_TEXTURE_IMAGE_UNITS:
-        return getIntParameter(pname);
-    case GL_MAX_TEXTURE_SIZE:
-        return getIntParameter(pname);
-    case GL_MAX_VARYING_VECTORS:
-        return getIntParameter(pname);
-    case GL_MAX_VERTEX_ATTRIBS:
-        return getIntParameter(pname);
-    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
-        return getIntParameter(pname);
-    case GL_MAX_VERTEX_UNIFORM_VECTORS:
-        return getIntParameter(pname);
-    case GL_MAX_VIEWPORT_DIMS:
-        return getWebGLIntArrayParameter(pname);
-    case GL_NUM_SHADER_BINARY_FORMATS:
-        // FIXME: should we always return 0 for this?
-        return getIntParameter(pname);
-    case GL_PACK_ALIGNMENT:
-        return getIntParameter(pname);
-    case GL_POLYGON_OFFSET_FACTOR:
-        return getFloatParameter(pname);
-    case GL_POLYGON_OFFSET_FILL:
-        return getBooleanParameter(pname);
-    case GL_POLYGON_OFFSET_UNITS:
-        return getFloatParameter(pname);
-    case GL_RED_BITS:
-        return getIntParameter(pname);
-    case GL_RENDERBUFFER_BINDING:
-        return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
-    case GL_RENDERER:
-        return WebGLGetInfo(String("WebKit WebGL"));
-    case GL_SAMPLE_BUFFERS:
-        return getIntParameter(pname);
-    case GL_SAMPLE_COVERAGE_INVERT:
-        return getBooleanParameter(pname);
-    case GL_SAMPLE_COVERAGE_VALUE:
-        return getFloatParameter(pname);
-    case GL_SAMPLES:
-        return getIntParameter(pname);
-    case GL_SCISSOR_BOX:
-        return getWebGLIntArrayParameter(pname);
-    case GL_SCISSOR_TEST:
-        return getBooleanParameter(pname);
-    case GL_SHADING_LANGUAGE_VERSION:
-        return WebGLGetInfo("WebGL GLSL ES 1.0 (" + String(m_context->getString(GL_SHADING_LANGUAGE_VERSION)) + ")");
-    case GL_STENCIL_BACK_FAIL:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_BACK_FUNC:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_BACK_PASS_DEPTH_PASS:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_BACK_REF:
-        return getIntParameter(pname);
-    case GL_STENCIL_BACK_VALUE_MASK:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_BACK_WRITEMASK:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_BITS:
-        if (!m_framebufferBinding && !m_requestedAttributes->stencil())
-            return WebGLGetInfo(intZero);
-        return getIntParameter(pname);
-    case GL_STENCIL_CLEAR_VALUE:
-        return getIntParameter(pname);
-    case GL_STENCIL_FAIL:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_FUNC:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_PASS_DEPTH_FAIL:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_PASS_DEPTH_PASS:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_REF:
-        return getIntParameter(pname);
-    case GL_STENCIL_TEST:
-        return getBooleanParameter(pname);
-    case GL_STENCIL_VALUE_MASK:
-        return getUnsignedIntParameter(pname);
-    case GL_STENCIL_WRITEMASK:
-        return getUnsignedIntParameter(pname);
-    case GL_SUBPIXEL_BITS:
-        return getIntParameter(pname);
-    case GL_TEXTURE_BINDING_2D:
-        return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
-    case GL_TEXTURE_BINDING_CUBE_MAP:
-        return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
-    case GL_UNPACK_ALIGNMENT:
-        return getIntParameter(pname);
-    case GC3D_UNPACK_FLIP_Y_WEBGL:
-        return WebGLGetInfo(m_unpackFlipY);
-    case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
-        return WebGLGetInfo(m_unpackPremultiplyAlpha);
-    case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
-        return WebGLGetInfo(m_unpackColorspaceConversion);
-    case GL_VENDOR:
-        return WebGLGetInfo(String("WebKit"));
-    case GL_VERSION:
-        return WebGLGetInfo("WebGL 1.0 (" + String(m_context->getString(GL_VERSION)) + ")");
-    case GL_VIEWPORT:
-        return getWebGLIntArrayParameter(pname);
-    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
-        if (m_oesStandardDerivatives)
-            return getUnsignedIntParameter(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
-        return WebGLGetInfo();
-    case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
-        if (m_webglDebugRendererInfo)
-            return WebGLGetInfo(m_context->getString(GL_RENDERER));
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
-        return WebGLGetInfo();
-    case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
-        if (m_webglDebugRendererInfo)
-            return WebGLGetInfo(m_context->getString(GL_VENDOR));
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
-        return WebGLGetInfo();
-    case GL_VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
-        if (m_oesVertexArrayObject) {
-            if (!m_boundVertexArrayObject->isDefaultObject())
-                return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
-            return WebGLGetInfo();
-        }
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
-        return WebGLGetInfo();
-    case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
-        if (m_extTextureFilterAnisotropic)
-            return getUnsignedIntParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
-        return WebGLGetInfo();
-    case GL_MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
-        if (m_webglDrawBuffers)
-            return WebGLGetInfo(maxColorAttachments());
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
-        return WebGLGetInfo();
-    case GL_MAX_DRAW_BUFFERS_EXT:
-        if (m_webglDrawBuffers)
-            return WebGLGetInfo(maxDrawBuffers());
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
-        return WebGLGetInfo();
-    default:
-        if (m_webglDrawBuffers
-            && pname >= GL_DRAW_BUFFER0_EXT
-            && pname < static_cast<GLenum>(GL_DRAW_BUFFER0_EXT + maxDrawBuffers())) {
-            GLint value = GL_NONE;
-            if (m_framebufferBinding)
-                value = m_framebufferBinding->getDrawBuffer(pname);
-            else // emulated backbuffer
-                value = m_backDrawBuffer;
-            return WebGLGetInfo(value);
-        }
-        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-}
-
-WebGLGetInfo WebGLRenderingContext::getProgramParameter(WebGLProgram* program, GLenum pname)
-{
-    if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
-        return WebGLGetInfo();
-
-    GLint value = 0;
-    switch (pname) {
-    case GL_DELETE_STATUS:
-        return WebGLGetInfo(program->isDeleted());
-    case GL_VALIDATE_STATUS:
-        m_context->getProgramiv(objectOrZero(program), pname, &value);
-        return WebGLGetInfo(static_cast<bool>(value));
-    case GL_LINK_STATUS:
-        return WebGLGetInfo(program->linkStatus());
-    case GL_ATTACHED_SHADERS:
-    case GL_ACTIVE_ATTRIBUTES:
-    case GL_ACTIVE_UNIFORMS:
-        m_context->getProgramiv(objectOrZero(program), pname, &value);
-        return WebGLGetInfo(value);
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-}
-
-String WebGLRenderingContext::getProgramInfoLog(WebGLProgram* program)
-{
-    if (isContextLost())
-        return String();
-    if (!validateWebGLObject("getProgramInfoLog", program))
-        return "";
-    return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
-}
-
-WebGLGetInfo WebGLRenderingContext::getRenderbufferParameter(GLenum target, GLenum pname)
-{
-    if (isContextLost())
-        return WebGLGetInfo();
-    if (target != GL_RENDERBUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target");
-        return WebGLGetInfo();
-    }
-    if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
-        return WebGLGetInfo();
-    }
-
-    GLint value = 0;
-    switch (pname) {
-    case GL_RENDERBUFFER_WIDTH:
-    case GL_RENDERBUFFER_HEIGHT:
-    case GL_RENDERBUFFER_RED_SIZE:
-    case GL_RENDERBUFFER_GREEN_SIZE:
-    case GL_RENDERBUFFER_BLUE_SIZE:
-    case GL_RENDERBUFFER_ALPHA_SIZE:
-    case GL_RENDERBUFFER_DEPTH_SIZE:
-        m_context->getRenderbufferParameteriv(target, pname, &value);
-        return WebGLGetInfo(value);
-    case GL_RENDERBUFFER_STENCIL_SIZE:
-        if (m_renderbufferBinding->emulatedStencilBuffer()) {
-            m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding->emulatedStencilBuffer()));
-            m_context->getRenderbufferParameteriv(target, pname, &value);
-            m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
-        } else {
-            m_context->getRenderbufferParameteriv(target, pname, &value);
-        }
-        return WebGLGetInfo(value);
-    case GL_RENDERBUFFER_INTERNAL_FORMAT:
-        return WebGLGetInfo(m_renderbufferBinding->internalFormat());
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-}
-
-WebGLGetInfo WebGLRenderingContext::getShaderParameter(WebGLShader* shader, GLenum pname)
-{
-    if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
-        return WebGLGetInfo();
-    GLint value = 0;
-    switch (pname) {
-    case GL_DELETE_STATUS:
-        return WebGLGetInfo(shader->isDeleted());
-    case GL_COMPILE_STATUS:
-        m_context->getShaderiv(objectOrZero(shader), pname, &value);
-        return WebGLGetInfo(static_cast<bool>(value));
-    case GL_SHADER_TYPE:
-        m_context->getShaderiv(objectOrZero(shader), pname, &value);
-        return WebGLGetInfo(static_cast<unsigned>(value));
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-}
-
-String WebGLRenderingContext::getShaderInfoLog(WebGLShader* shader)
-{
-    if (isContextLost())
-        return String();
-    if (!validateWebGLObject("getShaderInfoLog", shader))
-        return "";
-    return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
-}
-
-PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContext::getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType)
-{
-    if (isContextLost())
-        return 0;
-    switch (shaderType) {
-    case GL_VERTEX_SHADER:
-    case GL_FRAGMENT_SHADER:
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
-        return 0;
-    }
-    switch (precisionType) {
-    case GL_LOW_FLOAT:
-    case GL_MEDIUM_FLOAT:
-    case GL_HIGH_FLOAT:
-    case GL_LOW_INT:
-    case GL_MEDIUM_INT:
-    case GL_HIGH_INT:
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
-        return 0;
-    }
-
-    GLint range[2] = {0, 0};
-    GLint precision = 0;
-    m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
-    return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
-}
-
-String WebGLRenderingContext::getShaderSource(WebGLShader* shader)
-{
-    if (isContextLost())
-        return String();
-    if (!validateWebGLObject("getShaderSource", shader))
-        return "";
-    return ensureNotNull(shader->source());
-}
-
-Vector<String> WebGLRenderingContext::getSupportedExtensions()
-{
-    Vector<String> result;
-    if (isContextLost())
-        return result;
-
-    for (size_t i = 0; i < m_extensions.size(); ++i) {
-        ExtensionTracker* tracker = m_extensions[i];
-        if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
-            continue;
-        if (tracker->privileged() && !allowPrivilegedExtensions())
-            continue;
-        if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
-            continue;
-        if (tracker->supported(this))
-            result.append(String(tracker->prefixed()  ? "WEBKIT_" : "") + tracker->extensionName());
-    }
-
-    return result;
-}
-
-WebGLGetInfo WebGLRenderingContext::getTexParameter(GLenum target, GLenum pname)
-{
-    if (isContextLost())
-        return WebGLGetInfo();
-    WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
-    if (!tex)
-        return WebGLGetInfo();
-    GLint value = 0;
-    switch (pname) {
-    case GL_TEXTURE_MAG_FILTER:
-    case GL_TEXTURE_MIN_FILTER:
-    case GL_TEXTURE_WRAP_S:
-    case GL_TEXTURE_WRAP_T:
-        m_context->getTexParameteriv(target, pname, &value);
-        return WebGLGetInfo(static_cast<unsigned>(value));
-    case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
-        if (m_extTextureFilterAnisotropic) {
-            m_context->getTexParameteriv(target, pname, &value);
-            return WebGLGetInfo(static_cast<unsigned>(value));
-        }
-        synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
-        return WebGLGetInfo();
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-}
-
-WebGLGetInfo WebGLRenderingContext::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation)
-{
-    if (isContextLost() || !validateWebGLObject("getUniform", program))
-        return WebGLGetInfo();
-    if (!uniformLocation || uniformLocation->program() != program) {
-        synthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
-        return WebGLGetInfo();
-    }
-    GLint location = uniformLocation->location();
-
-    // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
-    GLint activeUniforms = 0;
-    m_context->getProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS, &activeUniforms);
-    for (GLint i = 0; i < activeUniforms; i++) {
-        blink::WebGraphicsContext3D::ActiveInfo info;
-        if (!m_context->getActiveUniform(objectOrZero(program), i, info))
-            return WebGLGetInfo();
-        String name = info.name;
-        StringBuilder nameBuilder;
-        // Strip "[0]" from the name if it's an array.
-        if (info.size > 1 && name.endsWith("[0]"))
-            info.name = name.left(name.length() - 3);
-        // If it's an array, we need to iterate through each element, appending "[index]" to the name.
-        for (GLint index = 0; index < info.size; ++index) {
-            nameBuilder.clear();
-            nameBuilder.append(info.name);
-            if (info.size > 1 && index >= 1) {
-                nameBuilder.append('[');
-                nameBuilder.append(String::number(index));
-                nameBuilder.append(']');
-            }
-            // Now need to look this up by name again to find its location
-            GLint loc = m_context->getUniformLocation(objectOrZero(program), nameBuilder.toString().utf8().data());
-            if (loc == location) {
-                // Found it. Use the type in the ActiveInfo to determine the return type.
-                GLenum baseType;
-                unsigned length;
-                switch (info.type) {
-                case GL_BOOL:
-                    baseType = GL_BOOL;
-                    length = 1;
-                    break;
-                case GL_BOOL_VEC2:
-                    baseType = GL_BOOL;
-                    length = 2;
-                    break;
-                case GL_BOOL_VEC3:
-                    baseType = GL_BOOL;
-                    length = 3;
-                    break;
-                case GL_BOOL_VEC4:
-                    baseType = GL_BOOL;
-                    length = 4;
-                    break;
-                case GL_INT:
-                    baseType = GL_INT;
-                    length = 1;
-                    break;
-                case GL_INT_VEC2:
-                    baseType = GL_INT;
-                    length = 2;
-                    break;
-                case GL_INT_VEC3:
-                    baseType = GL_INT;
-                    length = 3;
-                    break;
-                case GL_INT_VEC4:
-                    baseType = GL_INT;
-                    length = 4;
-                    break;
-                case GL_FLOAT:
-                    baseType = GL_FLOAT;
-                    length = 1;
-                    break;
-                case GL_FLOAT_VEC2:
-                    baseType = GL_FLOAT;
-                    length = 2;
-                    break;
-                case GL_FLOAT_VEC3:
-                    baseType = GL_FLOAT;
-                    length = 3;
-                    break;
-                case GL_FLOAT_VEC4:
-                    baseType = GL_FLOAT;
-                    length = 4;
-                    break;
-                case GL_FLOAT_MAT2:
-                    baseType = GL_FLOAT;
-                    length = 4;
-                    break;
-                case GL_FLOAT_MAT3:
-                    baseType = GL_FLOAT;
-                    length = 9;
-                    break;
-                case GL_FLOAT_MAT4:
-                    baseType = GL_FLOAT;
-                    length = 16;
-                    break;
-                case GL_SAMPLER_2D:
-                case GL_SAMPLER_CUBE:
-                    baseType = GL_INT;
-                    length = 1;
-                    break;
-                default:
-                    // Can't handle this type
-                    synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type");
-                    return WebGLGetInfo();
-                }
-                switch (baseType) {
-                case GL_FLOAT: {
-                    GLfloat value[16] = {0};
-                    m_context->getUniformfv(objectOrZero(program), location, value);
-                    if (length == 1)
-                        return WebGLGetInfo(value[0]);
-                    return WebGLGetInfo(Float32Array::create(value, length));
-                }
-                case GL_INT: {
-                    GLint value[4] = {0};
-                    m_context->getUniformiv(objectOrZero(program), location, value);
-                    if (length == 1)
-                        return WebGLGetInfo(value[0]);
-                    return WebGLGetInfo(Int32Array::create(value, length));
-                }
-                case GL_BOOL: {
-                    GLint value[4] = {0};
-                    m_context->getUniformiv(objectOrZero(program), location, value);
-                    if (length > 1) {
-                        bool boolValue[16] = {0};
-                        for (unsigned j = 0; j < length; j++)
-                            boolValue[j] = static_cast<bool>(value[j]);
-                        return WebGLGetInfo(boolValue, length);
-                    }
-                    return WebGLGetInfo(static_cast<bool>(value[0]));
-                }
-                default:
-                    notImplemented();
-                }
-            }
-        }
-    }
-    // If we get here, something went wrong in our unfortunately complex logic above
-    synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error");
-    return WebGLGetInfo();
-}
-
-PassRefPtr<WebGLUniformLocation> WebGLRenderingContext::getUniformLocation(WebGLProgram* program, const String& name)
-{
-    if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
-        return 0;
-    if (!validateLocationLength("getUniformLocation", name))
-        return 0;
-    if (!validateString("getUniformLocation", name))
-        return 0;
-    if (isPrefixReserved(name))
-        return 0;
-    if (!program->linkStatus()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "getUniformLocation", "program not linked");
-        return 0;
-    }
-    GLint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name.utf8().data());
-    if (uniformLocation == -1)
-        return 0;
-    return WebGLUniformLocation::create(program, uniformLocation);
-}
-
-WebGLGetInfo WebGLRenderingContext::getVertexAttrib(GLuint index, GLenum pname)
-{
-    if (isContextLost())
-        return WebGLGetInfo();
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range");
-        return WebGLGetInfo();
-    }
-    const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
-
-    if (m_angleInstancedArrays && pname == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
-        return WebGLGetInfo(state.divisor);
-
-    switch (pname) {
-    case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
-        if (!state.bufferBinding || !state.bufferBinding->object())
-            return WebGLGetInfo();
-        return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
-    case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
-        return WebGLGetInfo(state.enabled);
-    case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
-        return WebGLGetInfo(state.normalized);
-    case GL_VERTEX_ATTRIB_ARRAY_SIZE:
-        return WebGLGetInfo(state.size);
-    case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
-        return WebGLGetInfo(state.originalStride);
-    case GL_VERTEX_ATTRIB_ARRAY_TYPE:
-        return WebGLGetInfo(state.type);
-    case GL_CURRENT_VERTEX_ATTRIB:
-        return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
-        return WebGLGetInfo();
-    }
-}
-
-long long WebGLRenderingContext::getVertexAttribOffset(GLuint index, GLenum pname)
-{
-    if (isContextLost())
-        return 0;
-    if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) {
-        synthesizeGLError(GL_INVALID_ENUM, "getVertexAttribOffset", "invalid parameter name");
-        return 0;
-    }
-    GLsizeiptr result = m_context->getVertexAttribOffset(index, pname);
-    return static_cast<long long>(result);
-}
-
-void WebGLRenderingContext::hint(GLenum target, GLenum mode)
-{
-    if (isContextLost())
-        return;
-    bool isValid = false;
-    switch (target) {
-    case GL_GENERATE_MIPMAP_HINT:
-        isValid = true;
-        break;
-    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
-        if (m_oesStandardDerivatives)
-            isValid = true;
-        break;
-    }
-    if (!isValid) {
-        synthesizeGLError(GL_INVALID_ENUM, "hint", "invalid target");
-        return;
-    }
-    m_context->hint(target, mode);
-}
-
-GLboolean WebGLRenderingContext::isBuffer(WebGLBuffer* buffer)
-{
-    if (!buffer || isContextLost())
-        return 0;
-
-    if (!buffer->hasEverBeenBound())
-        return 0;
-
-    return m_context->isBuffer(buffer->object());
-}
-
-bool WebGLRenderingContext::isContextLost()
-{
-    return m_contextLost;
-}
-
-GLboolean WebGLRenderingContext::isEnabled(GLenum cap)
-{
-    if (isContextLost() || !validateCapability("isEnabled", cap))
-        return 0;
-    if (cap == GL_STENCIL_TEST)
-        return m_stencilEnabled;
-    return m_context->isEnabled(cap);
-}
-
-GLboolean WebGLRenderingContext::isFramebuffer(WebGLFramebuffer* framebuffer)
-{
-    if (!framebuffer || isContextLost())
-        return 0;
-
-    if (!framebuffer->hasEverBeenBound())
-        return 0;
-
-    return m_context->isFramebuffer(framebuffer->object());
-}
-
-GLboolean WebGLRenderingContext::isProgram(WebGLProgram* program)
-{
-    if (!program || isContextLost())
-        return 0;
-
-    return m_context->isProgram(program->object());
-}
-
-GLboolean WebGLRenderingContext::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
-{
-    if (!renderbuffer || isContextLost())
-        return 0;
-
-    if (!renderbuffer->hasEverBeenBound())
-        return 0;
-
-    return m_context->isRenderbuffer(renderbuffer->object());
-}
-
-GLboolean WebGLRenderingContext::isShader(WebGLShader* shader)
-{
-    if (!shader || isContextLost())
-        return 0;
-
-    return m_context->isShader(shader->object());
-}
-
-GLboolean WebGLRenderingContext::isTexture(WebGLTexture* texture)
-{
-    if (!texture || isContextLost())
-        return 0;
-
-    if (!texture->hasEverBeenBound())
-        return 0;
-
-    return m_context->isTexture(texture->object());
-}
-
-void WebGLRenderingContext::lineWidth(GLfloat width)
-{
-    if (isContextLost())
-        return;
-    m_context->lineWidth(width);
-}
-
-void WebGLRenderingContext::linkProgram(WebGLProgram* program)
-{
-    if (isContextLost() || !validateWebGLObject("linkProgram", program))
-        return;
-
-    m_context->linkProgram(objectOrZero(program));
-    program->increaseLinkCount();
-}
-
-void WebGLRenderingContext::pixelStorei(GLenum pname, GLint param)
-{
-    if (isContextLost())
-        return;
-    switch (pname) {
-    case GC3D_UNPACK_FLIP_Y_WEBGL:
-        m_unpackFlipY = param;
-        break;
-    case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
-        m_unpackPremultiplyAlpha = param;
-        break;
-    case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
-        if (static_cast<GLenum>(param) == GC3D_BROWSER_DEFAULT_WEBGL || param == GL_NONE) {
-            m_unpackColorspaceConversion = static_cast<GLenum>(param);
-        } else {
-            synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
-            return;
-        }
-        break;
-    case GL_PACK_ALIGNMENT:
-    case GL_UNPACK_ALIGNMENT:
-        if (param == 1 || param == 2 || param == 4 || param == 8) {
-            if (pname == GL_PACK_ALIGNMENT) {
-                m_packAlignment = param;
-                m_drawingBuffer->setPackAlignment(param);
-            } else { // GL_UNPACK_ALIGNMENT:
-                m_unpackAlignment = param;
-            }
-            m_context->pixelStorei(pname, param);
-        } else {
-            synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
-            return;
-        }
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "pixelStorei", "invalid parameter name");
-        return;
-    }
-}
-
-void WebGLRenderingContext::polygonOffset(GLfloat factor, GLfloat units)
-{
-    if (isContextLost())
-        return;
-    m_context->polygonOffset(factor, units);
-}
-
-void WebGLRenderingContext::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels)
-{
-    if (isContextLost())
-        return;
-    // Due to WebGL's same-origin restrictions, it is not possible to
-    // taint the origin using the WebGL API.
-    ASSERT(canvas()->originClean());
-    // Validate input parameters.
-    if (!pixels) {
-        synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
-        return;
-    }
-    switch (format) {
-    case GL_ALPHA:
-    case GL_RGB:
-    case GL_RGBA:
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid format");
-        return;
-    }
-    switch (type) {
-    case GL_UNSIGNED_BYTE:
-    case GL_UNSIGNED_SHORT_5_6_5:
-    case GL_UNSIGNED_SHORT_4_4_4_4:
-    case GL_UNSIGNED_SHORT_5_5_5_1:
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid type");
-        return;
-    }
-    if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
-        synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
-        return;
-    }
-    // Validate array type against pixel type.
-    if (pixels->type() != ArrayBufferView::TypeUint8) {
-        synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
-        return;
-    }
-    const char* reason = "framebuffer incomplete";
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
-        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
-        return;
-    }
-    // Calculate array size, taking into consideration of PACK_ALIGNMENT.
-    unsigned totalBytesRequired = 0;
-    unsigned padding = 0;
-    GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
-    if (error != GL_NO_ERROR) {
-        synthesizeGLError(error, "readPixels", "invalid dimensions");
-        return;
-    }
-    if (pixels->byteLength() < totalBytesRequired) {
-        synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
-        return;
-    }
-
-    clearIfComposited();
-    void* data = pixels->baseAddress();
-
-    {
-        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
-        m_context->readPixels(x, y, width, height, format, type, data);
-    }
-
-#if OS(MACOSX)
-    // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
-    // when alpha is off, readPixels should set alpha to 255 instead of 0.
-    if (!m_framebufferBinding && !m_context->getContextAttributes().alpha) {
-        unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
-        for (GLsizei iy = 0; iy < height; ++iy) {
-            for (GLsizei ix = 0; ix < width; ++ix) {
-                pixels[3] = 255;
-                pixels += 4;
-            }
-            pixels += padding;
-        }
-    }
-#endif
-}
-
-void WebGLRenderingContext::renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
-{
-    if (isContextLost())
-        return;
-    if (target != GL_RENDERBUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid target");
-        return;
-    }
-    if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
-        return;
-    }
-    if (!validateSize("renderbufferStorage", width, height))
-        return;
-    switch (internalformat) {
-    case GL_DEPTH_COMPONENT16:
-    case GL_RGBA4:
-    case GL_RGB5_A1:
-    case GL_RGB565:
-    case GL_STENCIL_INDEX8:
-        m_context->renderbufferStorage(target, internalformat, width, height);
-        m_renderbufferBinding->setInternalFormat(internalformat);
-        m_renderbufferBinding->setSize(width, height);
-        m_renderbufferBinding->deleteEmulatedStencilBuffer(m_context.get());
-        break;
-    case GL_DEPTH_STENCIL_OES:
-        if (isDepthStencilSupported()) {
-            m_context->renderbufferStorage(target, GL_DEPTH24_STENCIL8_OES, width, height);
-        } else {
-            WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(target, m_renderbufferBinding.get());
-            if (!emulatedStencilBuffer) {
-                synthesizeGLError(GL_OUT_OF_MEMORY, "renderbufferStorage", "out of memory");
-                return;
-            }
-            m_context->renderbufferStorage(target, GL_DEPTH_COMPONENT16, width, height);
-            m_context->bindRenderbuffer(target, objectOrZero(emulatedStencilBuffer));
-            m_context->renderbufferStorage(target, GL_STENCIL_INDEX8, width, height);
-            m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
-            emulatedStencilBuffer->setSize(width, height);
-            emulatedStencilBuffer->setInternalFormat(GL_STENCIL_INDEX8);
-        }
-        m_renderbufferBinding->setSize(width, height);
-        m_renderbufferBinding->setInternalFormat(internalformat);
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
-        return;
-    }
-    applyStencilTest();
-}
-
-void WebGLRenderingContext::sampleCoverage(GLfloat value, GLboolean invert)
-{
-    if (isContextLost())
-        return;
-    m_context->sampleCoverage(value, invert);
-}
-
-void WebGLRenderingContext::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    if (isContextLost())
-        return;
-    if (!validateSize("scissor", width, height))
-        return;
-    m_context->scissor(x, y, width, height);
-}
-
-void WebGLRenderingContext::shaderSource(WebGLShader* shader, const String& string)
-{
-    if (isContextLost() || !validateWebGLObject("shaderSource", shader))
-        return;
-    String stringWithoutComments = StripComments(string).result();
-    if (!validateString("shaderSource", stringWithoutComments))
-        return;
-    shader->setSource(string);
-    m_context->shaderSource(objectOrZero(shader), stringWithoutComments.utf8().data());
-}
-
-void WebGLRenderingContext::stencilFunc(GLenum func, GLint ref, GLuint mask)
-{
-    if (isContextLost())
-        return;
-    if (!validateStencilOrDepthFunc("stencilFunc", func))
-        return;
-    m_stencilFuncRef = ref;
-    m_stencilFuncRefBack = ref;
-    m_stencilFuncMask = mask;
-    m_stencilFuncMaskBack = mask;
-    m_context->stencilFunc(func, ref, mask);
-}
-
-void WebGLRenderingContext::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
-{
-    if (isContextLost())
-        return;
-    if (!validateStencilOrDepthFunc("stencilFuncSeparate", func))
-        return;
-    switch (face) {
-    case GL_FRONT_AND_BACK:
-        m_stencilFuncRef = ref;
-        m_stencilFuncRefBack = ref;
-        m_stencilFuncMask = mask;
-        m_stencilFuncMaskBack = mask;
-        break;
-    case GL_FRONT:
-        m_stencilFuncRef = ref;
-        m_stencilFuncMask = mask;
-        break;
-    case GL_BACK:
-        m_stencilFuncRefBack = ref;
-        m_stencilFuncMaskBack = mask;
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "stencilFuncSeparate", "invalid face");
-        return;
-    }
-    m_context->stencilFuncSeparate(face, func, ref, mask);
-}
-
-void WebGLRenderingContext::stencilMask(GLuint mask)
-{
-    if (isContextLost())
-        return;
-    m_stencilMask = mask;
-    m_stencilMaskBack = mask;
-    m_context->stencilMask(mask);
-}
-
-void WebGLRenderingContext::stencilMaskSeparate(GLenum face, GLuint mask)
-{
-    if (isContextLost())
-        return;
-    switch (face) {
-    case GL_FRONT_AND_BACK:
-        m_stencilMask = mask;
-        m_stencilMaskBack = mask;
-        break;
-    case GL_FRONT:
-        m_stencilMask = mask;
-        break;
-    case GL_BACK:
-        m_stencilMaskBack = mask;
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "stencilMaskSeparate", "invalid face");
-        return;
-    }
-    m_context->stencilMaskSeparate(face, mask);
-}
-
-void WebGLRenderingContext::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
-{
-    if (isContextLost())
-        return;
-    m_context->stencilOp(fail, zfail, zpass);
-}
-
-void WebGLRenderingContext::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
-{
-    if (isContextLost())
-        return;
-    m_context->stencilOpSeparate(face, fail, zfail, zpass);
-}
-
-GLenum WebGLRenderingContext::convertTexInternalFormat(GLenum internalformat, GLenum type)
-{
-    // Convert to sized internal formats that are renderable with GL_CHROMIUM_color_buffer_float_rgb(a).
-    if (type == GL_FLOAT && internalformat == GL_RGBA
-        && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"))
-        return GL_RGBA32F_EXT;
-    if (type == GL_FLOAT && internalformat == GL_RGB
-        && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"))
-        return GL_RGB32F_EXT;
-    return internalformat;
-}
-
-void WebGLRenderingContext::texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
-{
-    // All calling functions check isContextLost, so a duplicate check is not needed here.
-    // FIXME: Handle errors.
-    WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
-    ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
-    ASSERT(tex);
-    ASSERT(!level || !WebGLTexture::isNPOT(width, height));
-    ASSERT(!pixels || validateSettableTexFormat("texImage2D", internalformat));
-    m_context->texImage2D(target, level, convertTexInternalFormat(internalformat, type), width, height, border, format, type, pixels);
-    tex->setLevelInfo(target, level, internalformat, width, height, type);
-}
-
-void WebGLRenderingContext::texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
-{
-    // All calling functions check isContextLost, so a duplicate check is not needed here.
-    Vector<uint8_t> data;
-    WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
-    if (!imageExtractor.extractSucceeded()) {
-        synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
-        return;
-    }
-    WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
-    WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
-    const void* imagePixelData = imageExtractor.imagePixelData();
-
-    bool needConversion = true;
-    if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
-        needConversion = false;
-    else {
-        if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
-            synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error");
-            return;
-        }
-    }
-
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData, exceptionState);
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-bool WebGLRenderingContext::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset)
-{
-    if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
-        return false;
-
-    WebGLTexture* texture = validateTextureBinding(functionName, target, true);
-    if (!texture)
-        return false;
-
-    if (functionType == NotTexSubImage2D) {
-        if (level && WebGLTexture::isNPOT(width, height)) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not power of 2");
-            return false;
-        }
-        // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
-        // by checking if the ArrayBufferView is null or not.
-        if (sourceType != SourceArrayBufferView) {
-            if (!validateSettableTexFormat(functionName, format))
-                return false;
-        }
-    } else {
-        if (!validateSettableTexFormat(functionName, format))
-            return false;
-        if (!validateSize(functionName, xoffset, yoffset))
-            return false;
-        // Before checking if it is in the range, check if overflow happens first.
-        if (xoffset + width < 0 || yoffset + height < 0) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions");
-            return false;
-        }
-        if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
-            return false;
-        }
-        if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type and format do not match texture");
-            return false;
-        }
-    }
-
-    return true;
-}
-
-PassRefPtr<Image> WebGLRenderingContext::drawImageIntoBuffer(Image* image, int width, int height)
-{
-    IntSize size(width, height);
-    ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
-    if (!buf) {
-        synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
-        return 0;
-    }
-
-    IntRect srcRect(IntPoint(), image->size());
-    IntRect destRect(0, 0, size.width(), size.height());
-    buf->context()->drawImage(image, destRect, srcRect);
-    return buf->copyImage(ImageBuffer::fastCopyImageMode());
-}
-
-void WebGLRenderingContext::texImage2D(GLenum target, GLint level, GLenum internalformat,
-    GLsizei width, GLsizei height, GLint border,
-    GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
-        || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
-        return;
-    void* data = pixels ? pixels->baseAddress() : 0;
-    Vector<uint8_t> tempData;
-    bool changeUnpackAlignment = false;
-    if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
-        if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
-            return;
-        data = tempData.data();
-        changeUnpackAlignment = true;
-    }
-    if (changeUnpackAlignment)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    texImage2DBase(target, level, internalformat, width, height, border, format, type, data, exceptionState);
-    if (changeUnpackAlignment)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texImage2D(GLenum target, GLint level, GLenum internalformat,
-    GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
-        return;
-    Vector<uint8_t> data;
-    bool needConversion = true;
-    // The data from ImageData is always of format RGBA8.
-    // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
-    if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE)
-        needConversion = false;
-    else {
-        if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
-            synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
-            return;
-        }
-    }
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texImage2D(GLenum target, GLint level, GLenum internalformat,
-    GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateHTMLImageElement("texImage2D", image, exceptionState))
-        return;
-
-    RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
-    if (imageForRender->isSVGImage())
-        imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height());
-
-    if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
-        return;
-
-    texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texImage2D(GLenum target, GLint level, GLenum internalformat,
-    GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exceptionState) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
-        return;
-
-    WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
-    // If possible, copy from the canvas element directly to the texture
-    // via the GPU, without a read-back to system memory.
-    if (GL_TEXTURE_2D == target && texture) {
-        if (!canvas->is3D()) {
-            ImageBuffer* buffer = canvas->buffer();
-            if (buffer && buffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
-                level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
-                texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
-                return;
-            }
-        } else {
-            WebGLRenderingContext* gl = toWebGLRenderingContext(canvas->renderingContext());
-            if (gl && gl->m_drawingBuffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
-                level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
-                texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
-                return;
-            }
-        }
-    }
-
-    RefPtr<ImageData> imageData = canvas->getImageData();
-    if (imageData)
-        texImage2D(target, level, internalformat, format, type, imageData.get(), exceptionState);
-    else
-        texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-PassRefPtr<Image> WebGLRenderingContext::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
-{
-    IntSize size(video->videoWidth(), video->videoHeight());
-    ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
-    if (!buf) {
-        synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
-        return 0;
-    }
-    IntRect destRect(0, 0, size.width(), size.height());
-    // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
-    video->paintCurrentFrameInContext(buf->context(), destRect);
-    return buf->copyImage(backingStoreCopy);
-}
-
-void WebGLRenderingContext::texImage2D(GLenum target, GLint level, GLenum internalformat,
-    GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, exceptionState)
-        || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
-        return;
-
-    // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
-    // Otherwise, it will fall back to the normal SW path.
-    WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
-    if (GL_TEXTURE_2D == target && texture) {
-        if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
-            texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
-            return;
-        }
-    }
-
-    // Normal pure SW path.
-    RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
-    if (!image)
-        return;
-    texImage2DImpl(target, level, internalformat, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texParameter(GLenum target, GLenum pname, GLfloat paramf, GLint parami, bool isFloat)
-{
-    if (isContextLost())
-        return;
-    WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
-    if (!tex)
-        return;
-    switch (pname) {
-    case GL_TEXTURE_MIN_FILTER:
-    case GL_TEXTURE_MAG_FILTER:
-        break;
-    case GL_TEXTURE_WRAP_S:
-    case GL_TEXTURE_WRAP_T:
-        if ((isFloat && paramf != GL_CLAMP_TO_EDGE && paramf != GL_MIRRORED_REPEAT && paramf != GL_REPEAT)
-            || (!isFloat && parami != GL_CLAMP_TO_EDGE && parami != GL_MIRRORED_REPEAT && parami != GL_REPEAT)) {
-            synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter");
-            return;
-        }
-        break;
-    case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
-        if (!m_extTextureFilterAnisotropic) {
-            synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
-            return;
-        }
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter name");
-        return;
-    }
-    if (isFloat) {
-        tex->setParameterf(pname, paramf);
-        m_context->texParameterf(target, pname, paramf);
-    } else {
-        tex->setParameteri(pname, parami);
-        m_context->texParameteri(target, pname, parami);
-    }
-}
-
-void WebGLRenderingContext::texParameterf(GLenum target, GLenum pname, GLfloat param)
-{
-    texParameter(target, pname, param, 0, true);
-}
-
-void WebGLRenderingContext::texParameteri(GLenum target, GLenum pname, GLint param)
-{
-    texParameter(target, pname, 0, param, false);
-}
-
-void WebGLRenderingContext::texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
-{
-    // FIXME: Handle errors.
-    ASSERT(!isContextLost());
-    ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
-    ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
-    ASSERT(validateSettableTexFormat("texSubImage2D", format));
-    WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
-    if (!tex) {
-        ASSERT_NOT_REACHED();
-        return;
-    }
-    ASSERT((xoffset + width) >= 0);
-    ASSERT((yoffset + height) >= 0);
-    ASSERT(tex->getWidth(target, level) >= (xoffset + width));
-    ASSERT(tex->getHeight(target, level) >= (yoffset + height));
-    ASSERT(tex->getInternalFormat(target, level) == format);
-    ASSERT(tex->getType(target, level) == type);
-    m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
-}
-
-void WebGLRenderingContext::texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
-{
-    // All calling functions check isContextLost, so a duplicate check is not needed here.
-    Vector<uint8_t> data;
-    WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
-    if (!imageExtractor.extractSucceeded()) {
-        synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
-        return;
-    }
-    WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
-    WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
-    const void* imagePixelData = imageExtractor.imagePixelData();
-
-    bool needConversion = true;
-    if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
-        needConversion = false;
-    else {
-        if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
-            synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
-            return;
-        }
-    }
-
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type,  needConversion ? data.data() : imagePixelData, exceptionState);
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-    GLsizei width, GLsizei height,
-    GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
-        || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
-        return;
-    void* data = pixels->baseAddress();
-    Vector<uint8_t> tempData;
-    bool changeUnpackAlignment = false;
-    if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
-        if (!WebGLImageConversion::extractTextureData(width, height, format, type,
-                                           m_unpackAlignment,
-                                           m_unpackFlipY, m_unpackPremultiplyAlpha,
-                                           data,
-                                           tempData))
-            return;
-        data = tempData.data();
-        changeUnpackAlignment = true;
-    }
-    if (changeUnpackAlignment)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, exceptionState);
-    if (changeUnpackAlignment)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-    GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format,  pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
-        return;
-
-    Vector<uint8_t> data;
-    bool needConversion = true;
-    // The data from ImageData is always of format RGBA8.
-    // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
-    if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
-        needConversion = false;
-    else {
-        if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
-            synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
-            return;
-        }
-    }
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
-    texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
-    if (m_unpackAlignment != 1)
-        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
-}
-
-void WebGLRenderingContext::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-    GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, exceptionState))
-        return;
-
-    RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
-    if (imageForRender->isSVGImage())
-        imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height());
-
-    if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
-        return;
-
-    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-    GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)
-        || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
-        return;
-
-    RefPtr<ImageData> imageData = canvas->getImageData();
-    if (imageData)
-        texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), exceptionState);
-    else
-        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-    GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
-    if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, exceptionState)
-        || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
-        return;
-
-    RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
-    if (!image)
-        return;
-    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
-}
-
-void WebGLRenderingContext::uniform1f(const WebGLUniformLocation* location, GLfloat x)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for current program");
-        return;
-    }
-
-    m_context->uniform1f(location->location(), x);
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, Float32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
-        return;
-
-    m_context->uniform1fv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContext::uniform1fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
-        return;
-
-    m_context->uniform1fv(location->location(), size, v);
-}
-
-void WebGLRenderingContext::uniform1i(const WebGLUniformLocation* location, GLint x)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform1i", "location not for current program");
-        return;
-    }
-
-    m_context->uniform1i(location->location(), x);
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, Int32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
-        return;
-
-    m_context->uniform1iv(location->location(), v->length(), v->data());
-}
-
-void WebGLRenderingContext::uniform1iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
-        return;
-
-    m_context->uniform1iv(location->location(), size, v);
-}
-
-void WebGLRenderingContext::uniform2f(const WebGLUniformLocation* location, GLfloat x, GLfloat y)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform2f", "location not for current program");
-        return;
-    }
-
-    m_context->uniform2f(location->location(), x, y);
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, Float32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
-        return;
-
-    m_context->uniform2fv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContext::uniform2fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
-        return;
-
-    m_context->uniform2fv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContext::uniform2i(const WebGLUniformLocation* location, GLint x, GLint y)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform2i", "location not for current program");
-        return;
-    }
-
-    m_context->uniform2i(location->location(), x, y);
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, Int32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
-        return;
-
-    m_context->uniform2iv(location->location(), v->length() / 2, v->data());
-}
-
-void WebGLRenderingContext::uniform2iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
-        return;
-
-    m_context->uniform2iv(location->location(), size / 2, v);
-}
-
-void WebGLRenderingContext::uniform3f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform3f", "location not for current program");
-        return;
-    }
-
-    m_context->uniform3f(location->location(), x, y, z);
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, Float32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
-        return;
-
-    m_context->uniform3fv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContext::uniform3fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
-        return;
-
-    m_context->uniform3fv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContext::uniform3i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform3i", "location not for current program");
-        return;
-    }
-
-    m_context->uniform3i(location->location(), x, y, z);
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, Int32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
-        return;
-
-    m_context->uniform3iv(location->location(), v->length() / 3, v->data());
-}
-
-void WebGLRenderingContext::uniform3iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
-        return;
-
-    m_context->uniform3iv(location->location(), size / 3, v);
-}
-
-void WebGLRenderingContext::uniform4f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform4f", "location not for current program");
-        return;
-    }
-
-    m_context->uniform4f(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, Float32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
-        return;
-
-    m_context->uniform4fv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContext::uniform4fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
-        return;
-
-    m_context->uniform4fv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContext::uniform4i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z, GLint w)
-{
-    if (isContextLost() || !location)
-        return;
-
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, "uniform4i", "location not for current program");
-        return;
-    }
-
-    m_context->uniform4i(location->location(), x, y, z, w);
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, Int32Array* v)
-{
-    if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
-        return;
-
-    m_context->uniform4iv(location->location(), v->length() / 4, v->data());
-}
-
-void WebGLRenderingContext::uniform4iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
-        return;
-
-    m_context->uniform4iv(location->location(), size / 4, v);
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
-{
-    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
-        return;
-    m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
-        return;
-    m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
-{
-    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
-        return;
-    m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
-        return;
-    m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
-{
-    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
-        return;
-    m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
-}
-
-void WebGLRenderingContext::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
-{
-    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
-        return;
-    m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
-}
-
-void WebGLRenderingContext::useProgram(WebGLProgram* program)
-{
-    bool deleted;
-    if (!checkObjectToBeBound("useProgram", program, deleted))
-        return;
-    if (deleted)
-        program = 0;
-    if (program && !program->linkStatus()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "useProgram", "program not valid");
-        return;
-    }
-    if (m_currentProgram != program) {
-        if (m_currentProgram)
-            m_currentProgram->onDetached(m_context.get());
-        m_currentProgram = program;
-        m_context->useProgram(objectOrZero(program));
-        if (program)
-            program->onAttached();
-    }
-}
-
-void WebGLRenderingContext::validateProgram(WebGLProgram* program)
-{
-    if (isContextLost() || !validateWebGLObject("validateProgram", program))
-        return;
-    m_context->validateProgram(objectOrZero(program));
-}
-
-void WebGLRenderingContext::vertexAttrib1f(GLuint index, GLfloat v0)
-{
-    vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GLuint index, Float32Array* v)
-{
-    vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib1fv(GLuint index, GLfloat* v, GLsizei size)
-{
-    vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
-}
-
-void WebGLRenderingContext::vertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1)
-{
-    vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GLuint index, Float32Array* v)
-{
-    vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib2fv(GLuint index, GLfloat* v, GLsizei size)
-{
-    vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
-}
-
-void WebGLRenderingContext::vertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2)
-{
-    vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GLuint index, Float32Array* v)
-{
-    vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib3fv(GLuint index, GLfloat* v, GLsizei size)
-{
-    vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
-}
-
-void WebGLRenderingContext::vertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
-{
-    vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GLuint index, Float32Array* v)
-{
-    vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
-}
-
-void WebGLRenderingContext::vertexAttrib4fv(GLuint index, GLfloat* v, GLsizei size)
-{
-    vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
-}
-
-void WebGLRenderingContext::vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, long long offset)
-{
-    if (isContextLost())
-        return;
-    switch (type) {
-    case GL_BYTE:
-    case GL_UNSIGNED_BYTE:
-    case GL_SHORT:
-    case GL_UNSIGNED_SHORT:
-    case GL_FLOAT:
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
-        return;
-    }
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "index out of range");
-        return;
-    }
-    if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
-        return;
-    }
-    if (!m_boundArrayBuffer) {
-        synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
-        return;
-    }
-    // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
-    unsigned typeSize = sizeInBytes(type);
-    if (!typeSize) {
-        synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
-        return;
-    }
-    if ((stride % typeSize) || (static_cast<GLintptr>(offset) % typeSize)) {
-        synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
-        return;
-    }
-    GLsizei bytesPerElement = size * typeSize;
-
-    m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GLintptr>(offset), m_boundArrayBuffer);
-    m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GLintptr>(offset));
-}
-
-void WebGLRenderingContext::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
-{
-    if (isContextLost())
-        return;
-
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index out of range");
-        return;
-    }
-
-    m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
-    m_context->vertexAttribDivisorANGLE(index, divisor);
-}
-
-void WebGLRenderingContext::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
-{
-    if (isContextLost())
-        return;
-    if (!validateSize("viewport", width, height))
-        return;
-    m_context->viewport(x, y, width, height);
-}
-
-void WebGLRenderingContext::forceLostContext(WebGLRenderingContext::LostContextMode mode)
-{
-    if (isContextLost()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost");
-        return;
-    }
-
-    m_contextGroup->loseContextGroup(mode);
-}
-
-void WebGLRenderingContext::loseContextImpl(WebGLRenderingContext::LostContextMode mode)
-{
-    if (isContextLost())
-        return;
-
-    m_contextLost = true;
-    m_contextLostMode = mode;
-
-    if (mode == RealLostContext) {
-        // Inform the embedder that a lost context was received. In response, the embedder might
-        // decide to take action such as asking the user for permission to use WebGL again.
-        if (Frame* frame = canvas()->document().frame())
-            frame->loader().client()->didLoseWebGLContext(m_context->getGraphicsResetStatusARB());
-    }
-
-    // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
-    m_drawingBuffer->setTexture2DBinding(0);
-    m_drawingBuffer->setFramebufferBinding(0);
-
-    detachAndRemoveAllObjects();
-
-    // Lose all the extensions.
-    for (size_t i = 0; i < m_extensions.size(); ++i) {
-        ExtensionTracker* tracker = m_extensions[i];
-        tracker->loseExtension();
-    }
-
-    removeAllCompressedTextureFormats();
-
-    if (mode != RealLostContext)
-        destroyContext();
-
-    ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
-    synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
-
-    // Don't allow restoration unless the context lost event has both been
-    // dispatched and its default behavior prevented.
-    m_restoreAllowed = false;
-
-    // Always defer the dispatch of the context lost event, to implement
-    // the spec behavior of queueing a task.
-    m_dispatchContextLostEventTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::forceRestoreContext()
-{
-    if (!isContextLost()) {
-        synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not lost");
-        return;
-    }
-
-    if (!m_restoreAllowed) {
-        if (m_contextLostMode == SyntheticLostContext)
-            synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context restoration not allowed");
-        return;
-    }
-
-    if (!m_restoreTimer.isActive())
-        m_restoreTimer.startOneShot(0);
-}
-
-blink::WebLayer* WebGLRenderingContext::platformLayer() const
-{
-    return m_drawingBuffer->platformLayer();
-}
-
-Extensions3DUtil* WebGLRenderingContext::extensionsUtil()
-{
-    if (!m_extensionsUtil)
-        m_extensionsUtil = adoptPtr(new Extensions3DUtil(m_context.get()));
-    return m_extensionsUtil.get();
-}
-
-void WebGLRenderingContext::removeSharedObject(WebGLSharedObject* object)
-{
-    m_contextGroup->removeObject(object);
-}
-
-void WebGLRenderingContext::addSharedObject(WebGLSharedObject* object)
-{
-    ASSERT(!isContextLost());
-    m_contextGroup->addObject(object);
-}
-
-void WebGLRenderingContext::removeContextObject(WebGLContextObject* object)
-{
-    m_contextObjects.remove(object);
-}
-
-void WebGLRenderingContext::addContextObject(WebGLContextObject* object)
-{
-    ASSERT(!isContextLost());
-    m_contextObjects.add(object);
-}
-
-void WebGLRenderingContext::detachAndRemoveAllObjects()
-{
-    while (m_contextObjects.size() > 0) {
-        HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
-        (*it)->detachContext();
-    }
-}
-
-bool WebGLRenderingContext::hasPendingActivity() const
-{
-    return false;
-}
-
-void WebGLRenderingContext::stop()
-{
-    if (!isContextLost()) {
-        forceLostContext(SyntheticLostContext);
-        destroyContext();
-    }
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanParameter(GLenum pname)
-{
-    GLboolean value = 0;
-    if (!isContextLost())
-        m_context->getBooleanv(pname, &value);
-    return WebGLGetInfo(static_cast<bool>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getBooleanArrayParameter(GLenum pname)
-{
-    if (pname != GL_COLOR_WRITEMASK) {
-        notImplemented();
-        return WebGLGetInfo(0, 0);
-    }
-    GLboolean value[4] = {0};
-    if (!isContextLost())
-        m_context->getBooleanv(pname, value);
-    bool boolValue[4];
-    for (int ii = 0; ii < 4; ++ii)
-        boolValue[ii] = static_cast<bool>(value[ii]);
-    return WebGLGetInfo(boolValue, 4);
-}
-
-WebGLGetInfo WebGLRenderingContext::getFloatParameter(GLenum pname)
-{
-    GLfloat value = 0;
-    if (!isContextLost())
-        m_context->getFloatv(pname, &value);
-    return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getIntParameter(GLenum pname)
-{
-    GLint value = 0;
-    if (!isContextLost())
-        m_context->getIntegerv(pname, &value);
-    return WebGLGetInfo(value);
-}
-
-WebGLGetInfo WebGLRenderingContext::getUnsignedIntParameter(GLenum pname)
-{
-    GLint value = 0;
-    if (!isContextLost())
-        m_context->getIntegerv(pname, &value);
-    return WebGLGetInfo(static_cast<unsigned>(value));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLFloatArrayParameter(GLenum pname)
-{
-    GLfloat value[4] = {0};
-    if (!isContextLost())
-        m_context->getFloatv(pname, value);
-    unsigned length = 0;
-    switch (pname) {
-    case GL_ALIASED_POINT_SIZE_RANGE:
-    case GL_ALIASED_LINE_WIDTH_RANGE:
-    case GL_DEPTH_RANGE:
-        length = 2;
-        break;
-    case GL_BLEND_COLOR:
-    case GL_COLOR_CLEAR_VALUE:
-        length = 4;
-        break;
-    default:
-        notImplemented();
-    }
-    return WebGLGetInfo(Float32Array::create(value, length));
-}
-
-WebGLGetInfo WebGLRenderingContext::getWebGLIntArrayParameter(GLenum pname)
-{
-    GLint value[4] = {0};
-    if (!isContextLost())
-        m_context->getIntegerv(pname, value);
-    unsigned length = 0;
-    switch (pname) {
-    case GL_MAX_VIEWPORT_DIMS:
-        length = 2;
-        break;
-    case GL_SCISSOR_BOX:
-    case GL_VIEWPORT:
-        length = 4;
-        break;
-    default:
-        notImplemented();
-    }
-    return WebGLGetInfo(Int32Array::create(value, length));
-}
-
-void WebGLRenderingContext::handleTextureCompleteness(const char* functionName, bool prepareToDraw)
-{
-    // All calling functions check isContextLost, so a duplicate check is not needed here.
-    bool resetActiveUnit = false;
-    WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((m_oesTextureFloatLinear ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0)
-        | (m_oesTextureHalfFloatLinear ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0));
-    for (unsigned ii = 0; ii < m_onePlusMaxNonDefaultTextureUnit; ++ii) {
-        if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
-            || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) {
-            if (ii != m_activeTextureUnit) {
-                m_context->activeTexture(ii);
-                resetActiveUnit = true;
-            } else if (resetActiveUnit) {
-                m_context->activeTexture(ii);
-                resetActiveUnit = false;
-            }
-            WebGLTexture* tex2D;
-            WebGLTexture* texCubeMap;
-            if (prepareToDraw) {
-                String msg(String("texture bound to texture unit ") + String::number(ii)
-                    + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'."
-                    + " Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.");
-                emitGLWarning(functionName, msg.utf8().data());
-                tex2D = m_blackTexture2D.get();
-                texCubeMap = m_blackTextureCubeMap.get();
-            } else {
-                tex2D = m_textureUnits[ii].m_texture2DBinding.get();
-                texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
-            }
-            if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
-                m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(tex2D));
-            if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))
-                m_context->bindTexture(GL_TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
-        }
-    }
-    if (resetActiveUnit)
-        m_context->activeTexture(m_activeTextureUnit);
-}
-
-void WebGLRenderingContext::createFallbackBlackTextures1x1()
-{
-    // All calling functions check isContextLost, so a duplicate check is not needed here.
-    unsigned char black[] = {0, 0, 0, 255};
-    m_blackTexture2D = createTexture();
-    m_context->bindTexture(GL_TEXTURE_2D, m_blackTexture2D->object());
-    m_context->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
-        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
-    m_context->bindTexture(GL_TEXTURE_2D, 0);
-    m_blackTextureCubeMap = createTexture();
-    m_context->bindTexture(GL_TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
-    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1,
-        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
-    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1,
-        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
-    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1,
-        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
-    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1,
-        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
-    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1,
-        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
-    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 1, 1,
-        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
-    m_context->bindTexture(GL_TEXTURE_CUBE_MAP, 0);
-}
-
-bool WebGLRenderingContext::isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat)
-{
-    unsigned need = WebGLImageConversion::getChannelBitsByFormat(texInternalFormat);
-    unsigned have = WebGLImageConversion::getChannelBitsByFormat(colorBufferFormat);
-    return (need & have) == need;
-}
-
-GLenum WebGLRenderingContext::boundFramebufferColorFormat()
-{
-    if (m_framebufferBinding && m_framebufferBinding->object())
-        return m_framebufferBinding->colorBufferFormat();
-    if (m_requestedAttributes->alpha())
-        return GL_RGBA;
-    return GL_RGB;
-}
-
-int WebGLRenderingContext::boundFramebufferWidth()
-{
-    if (m_framebufferBinding && m_framebufferBinding->object())
-        return m_framebufferBinding->colorBufferWidth();
-    return m_drawingBuffer->size().width();
-}
-
-int WebGLRenderingContext::boundFramebufferHeight()
-{
-    if (m_framebufferBinding && m_framebufferBinding->object())
-        return m_framebufferBinding->colorBufferHeight();
-    return m_drawingBuffer->size().height();
-}
-
-WebGLTexture* WebGLRenderingContext::validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap)
-{
-    WebGLTexture* tex = 0;
-    switch (target) {
-    case GL_TEXTURE_2D:
-        tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get();
-        break;
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        if (!useSixEnumsForCubeMap) {
-            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
-            return 0;
-        }
-        tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
-        break;
-    case GL_TEXTURE_CUBE_MAP:
-        if (useSixEnumsForCubeMap) {
-            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
-            return 0;
-        }
-        tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
-        return 0;
-    }
-    if (!tex)
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture");
-    return tex;
-}
-
-bool WebGLRenderingContext::validateLocationLength(const char* functionName, const String& string)
-{
-    const unsigned maxWebGLLocationLength = 256;
-    if (string.length() > maxWebGLLocationLength) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateSize(const char* functionName, GLint x, GLint y)
-{
-    if (x < 0 || y < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateString(const char* functionName, const String& string)
-{
-    for (size_t i = 0; i < string.length(); ++i) {
-        if (!validateCharacter(string[i])) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "string not ASCII");
-            return false;
-        }
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level)
-{
-    switch (format) {
-    case GL_ALPHA:
-    case GL_LUMINANCE:
-    case GL_LUMINANCE_ALPHA:
-    case GL_RGB:
-    case GL_RGBA:
-        break;
-    case GL_DEPTH_STENCIL_OES:
-    case GL_DEPTH_COMPONENT:
-        if (m_webglDepthTexture)
-            break;
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "depth texture formats not enabled");
-        return false;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture format");
-        return false;
-    }
-
-    switch (type) {
-    case GL_UNSIGNED_BYTE:
-    case GL_UNSIGNED_SHORT_5_6_5:
-    case GL_UNSIGNED_SHORT_4_4_4_4:
-    case GL_UNSIGNED_SHORT_5_5_5_1:
-        break;
-    case GL_FLOAT:
-        if (m_oesTextureFloat)
-            break;
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
-        return false;
-    case GL_HALF_FLOAT_OES:
-        if (m_oesTextureHalfFloat)
-            break;
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
-        return false;
-    case GL_UNSIGNED_INT:
-    case GL_UNSIGNED_INT_24_8_OES:
-    case GL_UNSIGNED_SHORT:
-        if (m_webglDepthTexture)
-            break;
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
-        return false;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
-        return false;
-    }
-
-    // Verify that the combination of format and type is supported.
-    switch (format) {
-    case GL_ALPHA:
-    case GL_LUMINANCE:
-    case GL_LUMINANCE_ALPHA:
-        if (type != GL_UNSIGNED_BYTE
-            && type != GL_FLOAT
-            && type != GL_HALF_FLOAT_OES) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for format");
-            return false;
-        }
-        break;
-    case GL_RGB:
-        if (type != GL_UNSIGNED_BYTE
-            && type != GL_UNSIGNED_SHORT_5_6_5
-            && type != GL_FLOAT
-            && type != GL_HALF_FLOAT_OES) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGB format");
-            return false;
-        }
-        break;
-    case GL_RGBA:
-        if (type != GL_UNSIGNED_BYTE
-            && type != GL_UNSIGNED_SHORT_4_4_4_4
-            && type != GL_UNSIGNED_SHORT_5_5_5_1
-            && type != GL_FLOAT
-            && type != GL_HALF_FLOAT_OES) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGBA format");
-            return false;
-        }
-        break;
-    case GL_DEPTH_COMPONENT:
-        if (!m_webglDepthTexture) {
-            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
-            return false;
-        }
-        if (type != GL_UNSIGNED_SHORT
-            && type != GL_UNSIGNED_INT) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
-            return false;
-        }
-        if (level > 0) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
-            return false;
-        }
-        break;
-    case GL_DEPTH_STENCIL_OES:
-        if (!m_webglDepthTexture) {
-            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
-            return false;
-        }
-        if (type != GL_UNSIGNED_INT_24_8_OES) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
-            return false;
-        }
-        if (level > 0) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
-            return false;
-        }
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
-    return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncLevel(const char* functionName, GLenum target, GLint level)
-{
-    if (level < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "level < 0");
-        return false;
-    }
-    switch (target) {
-    case GL_TEXTURE_2D:
-        if (level >= m_maxTextureLevel) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
-            return false;
-        }
-        break;
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        if (level >= m_maxCubeMapTextureLevel) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
-            return false;
-        }
-        break;
-    }
-    // This function only checks if level is legal, so we return true and don't
-    // generate INVALID_ENUM if target is illegal.
-    return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType functionType,
-    GLenum target, GLint level, GLsizei width, GLsizei height)
-{
-    if (width < 0 || height < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
-        return false;
-    }
-
-    switch (target) {
-    case GL_TEXTURE_2D:
-        if (width > (m_maxTextureSize >> level) || height > (m_maxTextureSize >> level)) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range");
-            return false;
-        }
-        break;
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
-    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
-    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
-        if (functionType != TexSubImage2D && width != height) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "width != height for cube map");
-            return false;
-        }
-        // No need to check height here. For texImage width == height.
-        // For texSubImage that will be checked when checking yoffset + height is in range.
-        if (width > (m_maxCubeMapTextureSize >> level)) {
-            synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range for cube map");
-            return false;
-        }
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target,
-    GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type)
-{
-    // We absolutely have to validate the format and type combination.
-    // The texImage2D entry points taking HTMLImage, etc. will produce
-    // temporary data based on this combination, so it must be legal.
-    if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
-        return false;
-
-    if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
-        return false;
-
-    if (format != internalformat) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "format != internalformat");
-        return false;
-    }
-
-    if (border) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "border != 0");
-        return false;
-    }
-
-    return true;
-}
-
-bool WebGLRenderingContext::validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition disposition)
-{
-    // All calling functions check isContextLost, so a duplicate check is not needed here.
-    if (!pixels) {
-        if (disposition == NullAllowed)
-            return true;
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
-        return false;
-    }
-
-    if (!validateTexFuncFormatAndType(functionName, format, type, level))
-        return false;
-    if (!validateSettableTexFormat(functionName, format))
-        return false;
-
-    switch (type) {
-    case GL_UNSIGNED_BYTE:
-        if (pixels->type() != ArrayBufferView::TypeUint8) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
-            return false;
-        }
-        break;
-    case GL_UNSIGNED_SHORT_5_6_5:
-    case GL_UNSIGNED_SHORT_4_4_4_4:
-    case GL_UNSIGNED_SHORT_5_5_5_1:
-        if (pixels->type() != ArrayBufferView::TypeUint16) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
-            return false;
-        }
-        break;
-    case GL_FLOAT: // OES_texture_float
-        if (pixels->type() != ArrayBufferView::TypeFloat32) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
-            return false;
-        }
-        break;
-    case GL_HALF_FLOAT_OES: // OES_texture_half_float
-        // As per the specification, ArrayBufferView should be null when
-        // OES_texture_half_float is enabled.
-        if (pixels) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
-            return false;
-        }
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-    }
-
-    unsigned totalBytesRequired;
-    GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
-    if (error != GL_NO_ERROR) {
-        synthesizeGLError(error, functionName, "invalid texture dimensions");
-        return false;
-    }
-    if (pixels->byteLength() < totalBytesRequired) {
-        if (m_unpackAlignment != 1) {
-            error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
-            if (pixels->byteLength() == totalBytesRequired) {
-                synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
-                return false;
-            }
-        }
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexFormat(GLenum format)
-{
-    return m_compressedTextureFormats.contains(format);
-}
-
-bool WebGLRenderingContext::validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels)
-{
-    if (!pixels) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
-        return false;
-    }
-    if (width < 0 || height < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
-        return false;
-    }
-
-    unsigned bytesRequired = 0;
-
-    switch (format) {
-    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-        {
-            const int kBlockWidth = 4;
-            const int kBlockHeight = 4;
-            const int kBlockSize = 8;
-            int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
-            int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
-            int numBlocks = numBlocksAcross * numBlocksDown;
-            bytesRequired = numBlocks * kBlockSize;
-        }
-        break;
-    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-        {
-            const int kBlockWidth = 4;
-            const int kBlockHeight = 4;
-            const int kBlockSize = 16;
-            int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
-            int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
-            int numBlocks = numBlocksAcross * numBlocksDown;
-            bytesRequired = numBlocks * kBlockSize;
-        }
-        break;
-    case GC3D_COMPRESSED_ATC_RGB_AMD:
-        {
-            bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 8;
-        }
-        break;
-    case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
-    case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
-        {
-            bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 16;
-        }
-        break;
-    case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
-    case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
-        {
-            bytesRequired = max(width, 8) * max(height, 8) / 2;
-        }
-        break;
-    case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
-    case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
-        {
-            bytesRequired = max(width, 8) * max(height, 8) / 4;
-        }
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format");
-        return false;
-    }
-
-    if (pixels->byteLength() != bytesRequired) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
-        return false;
-    }
-
-    return true;
-}
-
-bool WebGLRenderingContext::validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format)
-{
-    if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
-        return false;
-
-    switch (format) {
-    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
-        const int kBlockWidth = 4;
-        const int kBlockHeight = 4;
-        bool widthValid = (level && width == 1) || (level && width == 2) || !(width % kBlockWidth);
-        bool heightValid = (level && height == 1) || (level && height == 2) || !(height % kBlockHeight);
-        if (!widthValid || !heightValid) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "width or height invalid for level");
-            return false;
-        }
-        return true;
-    }
-    default:
-        return false;
-    }
-}
-
-bool WebGLRenderingContext::validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture* tex)
-{
-    if (xoffset < 0 || yoffset < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "xoffset or yoffset < 0");
-        return false;
-    }
-
-    switch (format) {
-    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
-        const int kBlockWidth = 4;
-        const int kBlockHeight = 4;
-        if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
-            return false;
-        }
-        if (width - xoffset > tex->getWidth(target, level)
-            || height - yoffset > tex->getHeight(target, level)) {
-            synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range");
-            return false;
-        }
-        return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
-    }
-    default:
-        return false;
-    }
-}
-
-bool WebGLRenderingContext::validateDrawMode(const char* functionName, GLenum mode)
-{
-    switch (mode) {
-    case GL_POINTS:
-    case GL_LINE_STRIP:
-    case GL_LINE_LOOP:
-    case GL_LINES:
-    case GL_TRIANGLE_STRIP:
-    case GL_TRIANGLE_FAN:
-    case GL_TRIANGLES:
-        return true;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid draw mode");
-        return false;
-    }
-}
-
-bool WebGLRenderingContext::validateStencilSettings(const char* functionName)
-{
-    if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "front and back stencils settings do not match");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateStencilOrDepthFunc(const char* functionName, GLenum func)
-{
-    switch (func) {
-    case GL_NEVER:
-    case GL_LESS:
-    case GL_LEQUAL:
-    case GL_GREATER:
-    case GL_GEQUAL:
-    case GL_EQUAL:
-    case GL_NOTEQUAL:
-    case GL_ALWAYS:
-        return true;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid function");
-        return false;
-    }
-}
-
-void WebGLRenderingContext::printGLErrorToConsole(const String& message)
-{
-    if (!m_numGLErrorsToConsoleAllowed)
-        return;
-
-    --m_numGLErrorsToConsoleAllowed;
-    printWarningToConsole(message);
-
-    if (!m_numGLErrorsToConsoleAllowed)
-        printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
-
-    return;
-}
-
-void WebGLRenderingContext::printWarningToConsole(const String& message)
-{
-    if (!canvas())
-        return;
-    canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
-}
-
-bool WebGLRenderingContext::validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment)
-{
-    if (target != GL_FRAMEBUFFER) {
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
-        return false;
-    }
-    switch (attachment) {
-    case GL_COLOR_ATTACHMENT0:
-    case GL_DEPTH_ATTACHMENT:
-    case GL_STENCIL_ATTACHMENT:
-    case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
-        break;
-    default:
-        if (m_webglDrawBuffers
-            && attachment > GL_COLOR_ATTACHMENT0
-            && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments()))
-            break;
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateBlendEquation(const char* functionName, GLenum mode)
-{
-    switch (mode) {
-    case GL_FUNC_ADD:
-    case GL_FUNC_SUBTRACT:
-    case GL_FUNC_REVERSE_SUBTRACT:
-        return true;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
-        return false;
-    }
-}
-
-bool WebGLRenderingContext::validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst)
-{
-    if (((src == GL_CONSTANT_COLOR || src == GL_ONE_MINUS_CONSTANT_COLOR)
-        && (dst == GL_CONSTANT_ALPHA || dst == GL_ONE_MINUS_CONSTANT_ALPHA))
-        || ((dst == GL_CONSTANT_COLOR || dst == GL_ONE_MINUS_CONSTANT_COLOR)
-        && (src == GL_CONSTANT_ALPHA || src == GL_ONE_MINUS_CONSTANT_ALPHA))) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "incompatible src and dst");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateCapability(const char* functionName, GLenum cap)
-{
-    switch (cap) {
-    case GL_BLEND:
-    case GL_CULL_FACE:
-    case GL_DEPTH_TEST:
-    case GL_DITHER:
-    case GL_POLYGON_OFFSET_FILL:
-    case GL_SAMPLE_ALPHA_TO_COVERAGE:
-    case GL_SAMPLE_COVERAGE:
-    case GL_SCISSOR_TEST:
-    case GL_STENCIL_TEST:
-        return true;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid capability");
-        return false;
-    }
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GLsizei requiredMinSize)
-{
-    if (!v) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
-        return false;
-    }
-    return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GLsizei requiredMinSize)
-{
-    if (!v) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
-        return false;
-    }
-    return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GLsizei size, GLsizei requiredMinSize)
-{
-    return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v, GLsizei requiredMinSize)
-{
-    if (!v) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
-        return false;
-    }
-    return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
-}
-
-bool WebGLRenderingContext::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, void* v, GLsizei size, GLsizei requiredMinSize)
-{
-    if (!location)
-        return false;
-    if (location->program() != m_currentProgram) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "location is not from current program");
-        return false;
-    }
-    if (!v) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
-        return false;
-    }
-    if (transpose) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "transpose not FALSE");
-        return false;
-    }
-    if (size < requiredMinSize || (size % requiredMinSize)) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
-        return false;
-    }
-    return true;
-}
-
-WebGLBuffer* WebGLRenderingContext::validateBufferDataParameters(const char* functionName, GLenum target, GLenum usage)
-{
-    WebGLBuffer* buffer = 0;
-    switch (target) {
-    case GL_ELEMENT_ARRAY_BUFFER:
-        buffer = m_boundVertexArrayObject->boundElementArrayBuffer().get();
-        break;
-    case GL_ARRAY_BUFFER:
-        buffer = m_boundArrayBuffer.get();
-        break;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
-        return 0;
-    }
-    if (!buffer) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no buffer");
-        return 0;
-    }
-    switch (usage) {
-    case GL_STREAM_DRAW:
-    case GL_STATIC_DRAW:
-    case GL_DYNAMIC_DRAW:
-        return buffer;
-    }
-    synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid usage");
-    return 0;
-}
-
-bool WebGLRenderingContext::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionState& exceptionState)
-{
-    if (!image || !image->cachedImage()) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no image");
-        return false;
-    }
-    const KURL& url = image->cachedImage()->response().url();
-    if (url.isNull() || url.isEmpty() || !url.isValid()) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid image");
-        return false;
-    }
-    if (wouldTaintOrigin(image)) {
-        exceptionState.throwSecurityError("The cross-origin image at " + url.elidedString() + " may not be loaded.");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
-{
-    if (!canvas || !canvas->buffer()) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no canvas");
-        return false;
-    }
-    if (wouldTaintOrigin(canvas)) {
-        exceptionState.throwSecurityError("Tainted canvases may not be loaded.");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionState& exceptionState)
-{
-    if (!video || !video->videoWidth() || !video->videoHeight()) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no video");
-        return false;
-    }
-    if (wouldTaintOrigin(video)) {
-        exceptionState.throwSecurityError("The video element contains cross-origin data, and may not be loaded.");
-        return false;
-    }
-    return true;
-}
-
-bool WebGLRenderingContext::validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count)
-{
-    if (isContextLost() || !validateDrawMode(functionName, mode))
-        return false;
-
-    if (!validateStencilSettings(functionName))
-        return false;
-
-    if (first < 0 || count < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "first or count < 0");
-        return false;
-    }
-
-    if (!count) {
-        markContextChanged();
-        return false;
-    }
-
-    if (!validateRenderingState(functionName)) {
-        return false;
-    }
-
-    const char* reason = "framebuffer incomplete";
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
-        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
-        return false;
-    }
-
-    return true;
-}
-
-bool WebGLRenderingContext::validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset)
-{
-    if (isContextLost() || !validateDrawMode(functionName, mode))
-        return false;
-
-    if (!validateStencilSettings(functionName))
-        return false;
-
-    switch (type) {
-    case GL_UNSIGNED_BYTE:
-    case GL_UNSIGNED_SHORT:
-        break;
-    case GL_UNSIGNED_INT:
-        if (m_oesElementIndexUint)
-            break;
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
-        return false;
-    default:
-        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
-        return false;
-    }
-
-    if (count < 0 || offset < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "count or offset < 0");
-        return false;
-    }
-
-    if (!count) {
-        markContextChanged();
-        return false;
-    }
-
-    if (!m_boundVertexArrayObject->boundElementArrayBuffer()) {
-        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
-        return false;
-    }
-
-    if (!validateRenderingState(functionName)) {
-        return false;
-    }
-
-    const char* reason = "framebuffer incomplete";
-    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
-        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
-        return false;
-    }
-
-    return true;
-}
-
-// Helper function to validate draw*Instanced calls
-bool WebGLRenderingContext::validateDrawInstanced(const char* functionName, GLsizei primcount)
-{
-    if (primcount < 0) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "primcount < 0");
-        return false;
-    }
-
-    // Ensure at least one enabled vertex attrib has a divisor of 0.
-    for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
-        const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
-        if (state.enabled && !state.divisor)
-            return true;
-    }
-
-    synthesizeGLError(GL_INVALID_OPERATION, functionName, "at least one enabled attribute must have a divisor of 0");
-    return false;
-}
-
-void WebGLRenderingContext::vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
-{
-    if (isContextLost())
-        return;
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
-        return;
-    }
-    // In GL, we skip setting vertexAttrib0 values.
-    switch (expectedSize) {
-    case 1:
-        m_context->vertexAttrib1f(index, v0);
-        break;
-    case 2:
-        m_context->vertexAttrib2f(index, v0, v1);
-        break;
-    case 3:
-        m_context->vertexAttrib3f(index, v0, v1, v2);
-        break;
-    case 4:
-        m_context->vertexAttrib4f(index, v0, v1, v2, v3);
-        break;
-    }
-    VertexAttribValue& attribValue = m_vertexAttribValue[index];
-    attribValue.value[0] = v0;
-    attribValue.value[1] = v1;
-    attribValue.value[2] = v2;
-    attribValue.value[3] = v3;
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array* v, GLsizei expectedSize)
-{
-    if (isContextLost())
-        return;
-    if (!v) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
-        return;
-    }
-    vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
-}
-
-void WebGLRenderingContext::vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat* v, GLsizei size, GLsizei expectedSize)
-{
-    if (isContextLost())
-        return;
-    if (!v) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
-        return;
-    }
-    if (size < expectedSize) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
-        return;
-    }
-    if (index >= m_maxVertexAttribs) {
-        synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
-        return;
-    }
-    // In GL, we skip setting vertexAttrib0 values.
-    switch (expectedSize) {
-    case 1:
-        m_context->vertexAttrib1fv(index, v);
-        break;
-    case 2:
-        m_context->vertexAttrib2fv(index, v);
-        break;
-    case 3:
-        m_context->vertexAttrib3fv(index, v);
-        break;
-    case 4:
-        m_context->vertexAttrib4fv(index, v);
-        break;
-    }
-    VertexAttribValue& attribValue = m_vertexAttribValue[index];
-    attribValue.initValue();
-    for (int ii = 0; ii < expectedSize; ++ii)
-        attribValue.value[ii] = v[ii];
-}
-
-void WebGLRenderingContext::dispatchContextLostEvent(Timer<WebGLRenderingContext>*)
-{
-    RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(EventTypeNames::webglcontextlost, false, true, "");
-    canvas()->dispatchEvent(event);
-    m_restoreAllowed = event->defaultPrevented();
-    deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAllowed);
-    if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecoverSyntheticLostContext) && m_restoreAllowed)
-        m_restoreTimer.startOneShot(0);
-}
-
-void WebGLRenderingContext::maybeRestoreContext(Timer<WebGLRenderingContext>*)
-{
-    ASSERT(isContextLost());
-
-    // The rendering context is not restored unless the default behavior of the
-    // webglcontextlost event was prevented earlier.
-    //
-    // Because of the way m_restoreTimer is set up for real vs. synthetic lost
-    // context events, we don't have to worry about this test short-circuiting
-    // the retry loop for real context lost events.
-    if (!m_restoreAllowed)
-        return;
-
-    Frame* frame = canvas()->document().frame();
-    if (!frame)
-        return;
-
-    Settings* settings = frame->settings();
-
-    if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled()))
-        return;
-
-    blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes->attributes(canvas()->document().topDocument()->url().string(), settings);
-    OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes));
-    if (!context) {
-        if (m_contextLostMode == RealLostContext) {
-            m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts);
-        } else {
-            // This likely shouldn't happen but is the best way to report it to the WebGL app.
-            synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context");
-        }
-        return;
-    }
-
-    RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
-
-    // Construct a new drawing buffer with the new WebGraphicsContext3D.
-    m_drawingBuffer->releaseResources();
-    DrawingBuffer::PreserveDrawingBuffer preserve = m_requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
-    m_drawingBuffer = DrawingBuffer::create(context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
-
-    if (m_drawingBuffer->isZeroSized())
-        return;
-
-    m_drawingBuffer->bind();
-
-    m_lostContextErrors.clear();
-
-    m_context = context.release();
-    m_contextLost = false;
-
-    setupFlags();
-    initializeNewContext();
-    canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextrestored, false, true, ""));
-}
-
-String WebGLRenderingContext::ensureNotNull(const String& text) const
-{
-    if (text.isNull())
-        return WTF::emptyString();
-    return text;
-}
-
-WebGLRenderingContext::LRUImageBufferCache::LRUImageBufferCache(int capacity)
-    : m_buffers(adoptArrayPtr(new OwnPtr<ImageBuffer>[capacity]))
-    , m_capacity(capacity)
-{
-}
-
-ImageBuffer* WebGLRenderingContext::LRUImageBufferCache::imageBuffer(const IntSize& size)
-{
-    int i;
-    for (i = 0; i < m_capacity; ++i) {
-        ImageBuffer* buf = m_buffers[i].get();
-        if (!buf)
-            break;
-        if (buf->size() != size)
-            continue;
-        bubbleToFront(i);
-        return buf;
-    }
-
-    OwnPtr<ImageBuffer> temp(ImageBuffer::create(size));
-    if (!temp)
-        return 0;
-    i = std::min(m_capacity - 1, i);
-    m_buffers[i] = temp.release();
-
-    ImageBuffer* buf = m_buffers[i].get();
-    bubbleToFront(i);
-    return buf;
-}
-
-void WebGLRenderingContext::LRUImageBufferCache::bubbleToFront(int idx)
-{
-    for (int i = idx; i > 0; --i)
-        m_buffers[i].swap(m_buffers[i-1]);
-}
-
-namespace {
-
-    String GetErrorString(GLenum error)
-    {
-        switch (error) {
-        case GL_INVALID_ENUM:
-            return "INVALID_ENUM";
-        case GL_INVALID_VALUE:
-            return "INVALID_VALUE";
-        case GL_INVALID_OPERATION:
-            return "INVALID_OPERATION";
-        case GL_OUT_OF_MEMORY:
-            return "OUT_OF_MEMORY";
-        case GL_INVALID_FRAMEBUFFER_OPERATION:
-            return "INVALID_FRAMEBUFFER_OPERATION";
-        case GC3D_CONTEXT_LOST_WEBGL:
-            return "CONTEXT_LOST_WEBGL";
-        default:
-            return String::format("WebGL ERROR(0x%04X)", error);
-        }
-    }
-
-} // namespace anonymous
-
-void WebGLRenderingContext::synthesizeGLError(GLenum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
-{
-    String errorType = GetErrorString(error);
-    if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
-        String message = String("WebGL: ") + errorType +  ": " + String(functionName) + ": " + String(description);
-        printGLErrorToConsole(message);
-    }
-    if (!isContextLost())
-        m_context->synthesizeGLError(error);
-    else {
-        if (m_lostContextErrors.find(error) == WTF::kNotFound)
-            m_lostContextErrors.append(error);
-    }
-    InspectorInstrumentation::didFireWebGLError(canvas(), errorType);
-}
-
-void WebGLRenderingContext::emitGLWarning(const char* functionName, const char* description)
-{
-    if (m_synthesizedErrorsToConsole) {
-        String message = String("WebGL: ") + String(functionName) + ": " + String(description);
-        printGLErrorToConsole(message);
-    }
-    InspectorInstrumentation::didFireWebGLWarning(canvas());
-}
-
-void WebGLRenderingContext::applyStencilTest()
-{
-    bool haveStencilBuffer = false;
-
-    if (m_framebufferBinding)
-        haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
-    else {
-        RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
-        haveStencilBuffer = attributes->stencil();
-    }
-    enableOrDisable(GL_STENCIL_TEST,
-                    m_stencilEnabled && haveStencilBuffer);
-}
-
-void WebGLRenderingContext::enableOrDisable(GLenum capability, bool enable)
-{
-    if (isContextLost())
-        return;
-    if (enable)
-        m_context->enable(capability);
-    else
-        m_context->disable(capability);
-}
-
-IntSize WebGLRenderingContext::clampedCanvasSize()
-{
-    return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
-                   clamp(canvas()->height(), 1, m_maxViewportDims[1]));
-}
-
-GLint WebGLRenderingContext::maxDrawBuffers()
-{
-    if (isContextLost() || !m_webglDrawBuffers)
-        return 0;
-    if (!m_maxDrawBuffers)
-        m_context->getIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
-    if (!m_maxColorAttachments)
-        m_context->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
-    // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
-    return std::min(m_maxDrawBuffers, m_maxColorAttachments);
-}
-
-GLint WebGLRenderingContext::maxColorAttachments()
-{
-    if (isContextLost() || !m_webglDrawBuffers)
-        return 0;
-    if (!m_maxColorAttachments)
-        m_context->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
-    return m_maxColorAttachments;
-}
-
-void WebGLRenderingContext::setBackDrawBuffer(GLenum buf)
-{
-    m_backDrawBuffer = buf;
-}
-
-void WebGLRenderingContext::restoreCurrentFramebuffer()
-{
-    bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get());
-}
-
-void WebGLRenderingContext::restoreCurrentTexture2D()
-{
-    bindTexture(GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
-}
-
-void WebGLRenderingContext::multisamplingChanged(bool enabled)
-{
-    if (m_multisamplingAllowed != enabled) {
-        m_multisamplingAllowed = enabled;
-        forceLostContext(WebGLRenderingContext::AutoRecoverSyntheticLostContext);
-    }
-}
-
-void WebGLRenderingContext::findNewMaxEnabledAttribIndex()
-{
-    // Trace backwards from the current max to find the new max enabled attrib index
-    int startIndex = m_onePlusMaxEnabledAttribIndex - 1;
-    for (int i = startIndex; i >= 0; --i) {
-        if (m_boundVertexArrayObject->getVertexAttribState(i).enabled) {
-            m_onePlusMaxEnabledAttribIndex = i + 1;
-            return;
-        }
-    }
-    m_onePlusMaxEnabledAttribIndex = 0;
-}
-
-void WebGLRenderingContext::findNewMaxNonDefaultTextureUnit()
-{
-    // Trace backwards from the current max to find the new max non-default texture unit
-    int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1;
-    for (int i = startIndex; i >= 0; --i) {
-        if (m_textureUnits[i].m_texture2DBinding
-            || m_textureUnits[i].m_textureCubeMapBinding) {
-            m_onePlusMaxNonDefaultTextureUnit = i + 1;
-            return;
-        }
-    }
-    m_onePlusMaxNonDefaultTextureUnit = 0;
-}
-
 } // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLRenderingContext.h b/Source/core/html/canvas/WebGLRenderingContext.h
index 04c7c95..be5de57 100644
--- a/Source/core/html/canvas/WebGLRenderingContext.h
+++ b/Source/core/html/canvas/WebGLRenderingContext.h
@@ -26,504 +26,21 @@
 #ifndef WebGLRenderingContext_h
 #define WebGLRenderingContext_h
 
-#include "core/dom/ActiveDOMObject.h"
-#include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/html/canvas/WebGLGetInfo.h"
-#include "core/page/Page.h"
-#include "platform/Timer.h"
-#include "platform/graphics/GraphicsTypes3D.h"
-#include "platform/graphics/ImageBuffer.h"
-#include "platform/graphics/gpu/Extensions3DUtil.h"
-#include "platform/graphics/gpu/WebGLImageConversion.h"
-#include "public/platform/WebGraphicsContext3D.h"
-#include "wtf/Float32Array.h"
-#include "wtf/Int32Array.h"
-#include "wtf/OwnPtr.h"
-#include "wtf/text/WTFString.h"
-
-namespace blink {
-class WebLayer;
-}
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-class ANGLEInstancedArrays;
-class DrawingBuffer;
-class EXTFragDepth;
-class EXTTextureFilterAnisotropic;
-class ExceptionState;
-class HTMLImageElement;
-class HTMLVideoElement;
-class ImageBuffer;
-class ImageData;
-class IntSize;
-class OESElementIndexUint;
-class OESStandardDerivatives;
-class OESTextureFloat;
-class OESTextureFloatLinear;
-class OESTextureHalfFloat;
-class OESTextureHalfFloatLinear;
-class OESVertexArrayObject;
-class WebGLActiveInfo;
-class WebGLBuffer;
-class WebGLCompressedTextureATC;
-class WebGLCompressedTexturePVRTC;
-class WebGLCompressedTextureS3TC;
-class WebGLContextAttributes;
-class WebGLContextGroup;
-class WebGLContextObject;
-class WebGLDebugRendererInfo;
-class WebGLDebugShaders;
-class WebGLDepthTexture;
-class WebGLDrawBuffers;
-class WebGLExtension;
-class WebGLFramebuffer;
-class WebGLLoseContext;
-class WebGLObject;
-class WebGLProgram;
-class WebGLRenderbuffer;
-class WebGLShader;
-class WebGLShaderPrecisionFormat;
-class WebGLSharedObject;
-class WebGLTexture;
-class WebGLUniformLocation;
-class WebGLVertexArrayObjectOES;
-
-class WebGLRenderingContextLostCallback;
-class WebGLRenderingContextErrorMessageCallback;
-
-class WebGLRenderingContext FINAL : public CanvasRenderingContext, public ActiveDOMObject, private Page::MultisamplingChangedObserver {
+class WebGLRenderingContext FINAL : public WebGLRenderingContextBase {
 public:
     static PassOwnPtr<WebGLRenderingContext> create(HTMLCanvasElement*, WebGLContextAttributes*);
     virtual ~WebGLRenderingContext();
 
-    virtual bool is3d() const OVERRIDE { return true; }
-    virtual bool isAccelerated() const OVERRIDE { return true; }
+    virtual unsigned version() const OVERRIDE { return 1; }
+    virtual String contextName() const OVERRIDE { return "WebGLRenderingContext"; }
+    virtual void registerContextExtensions() OVERRIDE;
 
-    int drawingBufferWidth() const;
-    int drawingBufferHeight() const;
-
-    void activeTexture(GLenum texture);
-    void attachShader(WebGLProgram*, WebGLShader*);
-    void bindAttribLocation(WebGLProgram*, GLuint index, const String& name);
-    void bindBuffer(GLenum target, WebGLBuffer*);
-    void bindFramebuffer(GLenum target, WebGLFramebuffer*);
-    void bindRenderbuffer(GLenum target, WebGLRenderbuffer*);
-    void bindTexture(GLenum target, WebGLTexture*);
-    void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-    void blendEquation(GLenum mode);
-    void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
-    void blendFunc(GLenum sfactor, GLenum dfactor);
-    void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
-
-    void bufferData(GLenum target, long long size, GLenum usage);
-    void bufferData(GLenum target, ArrayBuffer* data, GLenum usage);
-    void bufferData(GLenum target, ArrayBufferView* data, GLenum usage);
-    void bufferSubData(GLenum target, long long offset, ArrayBuffer* data);
-    void bufferSubData(GLenum target, long long offset, ArrayBufferView* data);
-
-    GLenum checkFramebufferStatus(GLenum target);
-    void clear(GLbitfield mask);
-    void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
-    void clearDepth(GLfloat);
-    void clearStencil(GLint);
-    void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-    void compileShader(WebGLShader*);
-
-    void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data);
-    void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data);
-
-    void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
-    void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-
-    PassRefPtr<WebGLBuffer> createBuffer();
-    PassRefPtr<WebGLFramebuffer> createFramebuffer();
-    PassRefPtr<WebGLProgram> createProgram();
-    PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
-    PassRefPtr<WebGLShader> createShader(GLenum type);
-    PassRefPtr<WebGLTexture> createTexture();
-
-    void cullFace(GLenum mode);
-
-    void deleteBuffer(WebGLBuffer*);
-    void deleteFramebuffer(WebGLFramebuffer*);
-    void deleteProgram(WebGLProgram*);
-    void deleteRenderbuffer(WebGLRenderbuffer*);
-    void deleteShader(WebGLShader*);
-    void deleteTexture(WebGLTexture*);
-
-    void depthFunc(GLenum);
-    void depthMask(GLboolean);
-    void depthRange(GLfloat zNear, GLfloat zFar);
-    void detachShader(WebGLProgram*, WebGLShader*);
-    void disable(GLenum cap);
-    void disableVertexAttribArray(GLuint index);
-    void drawArrays(GLenum mode, GLint first, GLsizei count);
-    void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset);
-
-    void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
-    void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount);
-
-    void enable(GLenum cap);
-    void enableVertexAttribArray(GLuint index);
-    void finish();
-    void flush();
-    void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer*);
-    void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture*, GLint level);
-    void frontFace(GLenum mode);
-    void generateMipmap(GLenum target);
-
-    PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GLuint index);
-    PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GLuint index);
-    bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&);
-    GLint getAttribLocation(WebGLProgram*, const String& name);
-    WebGLGetInfo getBufferParameter(GLenum target, GLenum pname);
-    PassRefPtr<WebGLContextAttributes> getContextAttributes();
-    GLenum getError();
-    PassRefPtr<WebGLExtension> getExtension(const String& name);
-    WebGLGetInfo getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
-    WebGLGetInfo getParameter(GLenum pname);
-    WebGLGetInfo getProgramParameter(WebGLProgram*, GLenum pname);
-    String getProgramInfoLog(WebGLProgram*);
-    WebGLGetInfo getRenderbufferParameter(GLenum target, GLenum pname);
-    WebGLGetInfo getShaderParameter(WebGLShader*, GLenum pname);
-    String getShaderInfoLog(WebGLShader*);
-    PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType);
-    String getShaderSource(WebGLShader*);
-    Vector<String> getSupportedExtensions();
-    WebGLGetInfo getTexParameter(GLenum target, GLenum pname);
-    WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
-    PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
-    WebGLGetInfo getVertexAttrib(GLuint index, GLenum pname);
-    long long getVertexAttribOffset(GLuint index, GLenum pname);
-
-    void hint(GLenum target, GLenum mode);
-    GLboolean isBuffer(WebGLBuffer*);
-    bool isContextLost();
-    GLboolean isEnabled(GLenum cap);
-    GLboolean isFramebuffer(WebGLFramebuffer*);
-    GLboolean isProgram(WebGLProgram*);
-    GLboolean isRenderbuffer(WebGLRenderbuffer*);
-    GLboolean isShader(WebGLShader*);
-    GLboolean isTexture(WebGLTexture*);
-
-    void lineWidth(GLfloat);
-    void linkProgram(WebGLProgram*);
-    void pixelStorei(GLenum pname, GLint param);
-    void polygonOffset(GLfloat factor, GLfloat units);
-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels);
-    void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-    void sampleCoverage(GLfloat value, GLboolean invert);
-    void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
-    void shaderSource(WebGLShader*, const String&);
-    void stencilFunc(GLenum func, GLint ref, GLuint mask);
-    void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
-    void stencilMask(GLuint);
-    void stencilMaskSeparate(GLenum face, GLuint mask);
-    void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
-    void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-
-    void texImage2D(GLenum target, GLint level, GLenum internalformat,
-        GLsizei width, GLsizei height, GLint border,
-        GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
-    void texImage2D(GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, ImageData*, ExceptionState&);
-    void texImage2D(GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
-    void texImage2D(GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
-    void texImage2D(GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
-
-    void texParameterf(GLenum target, GLenum pname, GLfloat param);
-    void texParameteri(GLenum target, GLenum pname, GLint param);
-
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLsizei width, GLsizei height,
-        GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, ImageData*, ExceptionState&);
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
-    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
-
-    void uniform1f(const WebGLUniformLocation*, GLfloat x);
-    void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
-    void uniform1fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
-    void uniform1i(const WebGLUniformLocation*, GLint x);
-    void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
-    void uniform1iv(const WebGLUniformLocation*, GLint* v, GLsizei);
-    void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
-    void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
-    void uniform2fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
-    void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
-    void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
-    void uniform2iv(const WebGLUniformLocation*, GLint* v, GLsizei);
-    void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
-    void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
-    void uniform3fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
-    void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
-    void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
-    void uniform3iv(const WebGLUniformLocation*, GLint* v, GLsizei);
-    void uniform4f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-    void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
-    void uniform4fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
-    void uniform4i(const WebGLUniformLocation*, GLint x, GLint y, GLint z, GLint w);
-    void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
-    void uniform4iv(const WebGLUniformLocation*, GLint* v, GLsizei);
-    void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
-    void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
-    void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
-    void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
-    void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
-    void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
-
-    void useProgram(WebGLProgram*);
-    void validateProgram(WebGLProgram*);
-
-    void vertexAttrib1f(GLuint index, GLfloat x);
-    void vertexAttrib1fv(GLuint index, Float32Array* values);
-    void vertexAttrib1fv(GLuint index, GLfloat* values, GLsizei);
-    void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
-    void vertexAttrib2fv(GLuint index, Float32Array* values);
-    void vertexAttrib2fv(GLuint index, GLfloat* values, GLsizei);
-    void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
-    void vertexAttrib3fv(GLuint index, Float32Array* values);
-    void vertexAttrib3fv(GLuint index, GLfloat* values, GLsizei);
-    void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-    void vertexAttrib4fv(GLuint index, Float32Array* values);
-    void vertexAttrib4fv(GLuint index, GLfloat* values, GLsizei);
-    void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
-        GLsizei stride, long long offset);
-
-    void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
-
-    void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
-
-    // WEBKIT_lose_context support
-    enum LostContextMode {
-        // Lost context occurred at the graphics system level.
-        RealLostContext,
-
-        // Lost context provoked by WEBKIT_lose_context.
-        SyntheticLostContext,
-
-        // A synthetic lost context that should attempt to recover automatically
-        AutoRecoverSyntheticLostContext
-    };
-    void forceLostContext(LostContextMode);
-    void forceRestoreContext();
-    void loseContextImpl(LostContextMode);
-
-    blink::WebGraphicsContext3D* webGraphicsContext3D() const { return m_context.get(); }
-    WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
-    virtual blink::WebLayer* platformLayer() const OVERRIDE;
-    Extensions3DUtil* extensionsUtil();
-
-    void reshape(int width, int height);
-
-    void markLayerComposited();
-    virtual void paintRenderingResultsToCanvas() OVERRIDE;
-    PassRefPtr<ImageData> paintRenderingResultsToImageData();
-
-    void removeSharedObject(WebGLSharedObject*);
-    void removeContextObject(WebGLContextObject*);
-
-    unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
-
-    // ActiveDOMObject notifications
-    virtual bool hasPendingActivity() const OVERRIDE;
-    virtual void stop() OVERRIDE;
-
-  private:
-    friend class WebGLDrawBuffers;
-    friend class WebGLFramebuffer;
-    friend class WebGLObject;
-    friend class OESVertexArrayObject;
-    friend class WebGLDebugShaders;
-    friend class WebGLCompressedTextureATC;
-    friend class WebGLCompressedTexturePVRTC;
-    friend class WebGLCompressedTextureS3TC;
-    friend class WebGLRenderingContextErrorMessageCallback;
-    friend class WebGLVertexArrayObjectOES;
-
+private:
     WebGLRenderingContext(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
-    void initializeNewContext();
-    void setupFlags();
-
-    void addSharedObject(WebGLSharedObject*);
-    void addContextObject(WebGLContextObject*);
-    void detachAndRemoveAllObjects();
-
-    void destroyContext();
-    void markContextChanged();
-
-    // Query if the GL implementation is NPOT strict.
-    bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
-    // Query if depth_stencil buffer is supported.
-    bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
-
-    // Helper to return the size in bytes of OpenGL data types
-    // like GL_FLOAT, GL_INT, etc.
-    unsigned sizeInBytes(GLenum type);
-
-    // Check if each enabled vertex attribute is bound to a buffer.
-    bool validateRenderingState(const char*);
-
-    bool validateWebGLObject(const char*, WebGLObject*);
-
-    // Adds a compressed texture format.
-    void addCompressedTextureFormat(GLenum);
-    void removeAllCompressedTextureFormats();
-
-    PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height);
-
-    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
-
-    WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*);
-
-    OwnPtr<blink::WebGraphicsContext3D> m_context;
-    RefPtr<WebGLContextGroup> m_contextGroup;
-
-    // Structure for rendering to a DrawingBuffer, instead of directly
-    // to the back-buffer of m_context.
-    RefPtr<DrawingBuffer> m_drawingBuffer;
-
-    // Dispatches a context lost event once it is determined that one is needed.
-    // This is used both for synthetic and real context losses. For real ones, it's
-    // likely that there's no JavaScript on the stack, but that might be dependent
-    // on how exactly the platform discovers that the context was lost. For better
-    // portability we always defer the dispatch of the event.
-    Timer<WebGLRenderingContext> m_dispatchContextLostEventTimer;
-    bool m_restoreAllowed;
-    Timer<WebGLRenderingContext> m_restoreTimer;
-
-    bool m_needsUpdate;
-    bool m_markedCanvasDirty;
-    HashSet<WebGLContextObject*> m_contextObjects;
-
-    OwnPtr<WebGLRenderingContextLostCallback> m_contextLostCallbackAdapter;
-    OwnPtr<WebGLRenderingContextErrorMessageCallback> m_errorMessageCallbackAdapter;
-
-    // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
-    RefPtr<WebGLBuffer> m_boundArrayBuffer;
-
-    RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
-    RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
-    void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
-    {
-        if (arrayObject)
-            m_boundVertexArrayObject = arrayObject;
-        else
-            m_boundVertexArrayObject = m_defaultVertexArrayObject;
-    }
-
-    class VertexAttribValue {
-    public:
-        VertexAttribValue()
-        {
-            initValue();
-        }
-
-        void initValue()
-        {
-            value[0] = 0.0f;
-            value[1] = 0.0f;
-            value[2] = 0.0f;
-            value[3] = 1.0f;
-        }
-
-        GLfloat value[4];
-    };
-    Vector<VertexAttribValue> m_vertexAttribValue;
-    unsigned m_maxVertexAttribs;
-    RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
-    long m_vertexAttrib0BufferSize;
-    GLfloat m_vertexAttrib0BufferValue[4];
-    bool m_forceAttrib0BufferRefill;
-    bool m_vertexAttrib0UsedBefore;
-
-    RefPtr<WebGLProgram> m_currentProgram;
-    RefPtr<WebGLFramebuffer> m_framebufferBinding;
-    RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
-    class TextureUnitState {
-    public:
-        RefPtr<WebGLTexture> m_texture2DBinding;
-        RefPtr<WebGLTexture> m_textureCubeMapBinding;
-    };
-    Vector<TextureUnitState> m_textureUnits;
-    unsigned long m_activeTextureUnit;
-
-    RefPtr<WebGLTexture> m_blackTexture2D;
-    RefPtr<WebGLTexture> m_blackTextureCubeMap;
-
-    Vector<GLenum> m_compressedTextureFormats;
-
-    // Fixed-size cache of reusable image buffers for video texImage2D calls.
-    class LRUImageBufferCache {
-    public:
-        LRUImageBufferCache(int capacity);
-        // The pointer returned is owned by the image buffer map.
-        ImageBuffer* imageBuffer(const IntSize& size);
-    private:
-        void bubbleToFront(int idx);
-        OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers;
-        int m_capacity;
-    };
-    LRUImageBufferCache m_generatedImageCache;
-
-    GLint m_maxTextureSize;
-    GLint m_maxCubeMapTextureSize;
-    GLint m_maxRenderbufferSize;
-    GLint m_maxViewportDims[2];
-    GLint m_maxTextureLevel;
-    GLint m_maxCubeMapTextureLevel;
-
-    GLint m_maxDrawBuffers;
-    GLint m_maxColorAttachments;
-    GLenum m_backDrawBuffer;
-    bool m_drawBuffersWebGLRequirementsChecked;
-    bool m_drawBuffersSupported;
-
-    GLint m_packAlignment;
-    GLint m_unpackAlignment;
-    bool m_unpackFlipY;
-    bool m_unpackPremultiplyAlpha;
-    GLenum m_unpackColorspaceConversion;
-    bool m_contextLost;
-    LostContextMode m_contextLostMode;
-    RefPtr<WebGLContextAttributes> m_requestedAttributes;
-
-    bool m_layerCleared;
-    GLfloat m_clearColor[4];
-    bool m_scissorEnabled;
-    GLfloat m_clearDepth;
-    GLint m_clearStencil;
-    GLboolean m_colorMask[4];
-    GLboolean m_depthMask;
-
-    bool m_stencilEnabled;
-    GLuint m_stencilMask, m_stencilMaskBack;
-    GLint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
-    GLuint m_stencilFuncMask, m_stencilFuncMaskBack;
-
-    bool m_isGLES2NPOTStrict;
-    bool m_isDepthStencilSupported;
-
-    bool m_synthesizedErrorsToConsole;
-    int m_numGLErrorsToConsoleAllowed;
-
-    bool m_multisamplingAllowed;
-    bool m_multisamplingObserverRegistered;
-
-    GLuint m_onePlusMaxEnabledAttribIndex;
-    unsigned long m_onePlusMaxNonDefaultTextureUnit;
-
-    bool m_preserveDrawingBuffer;
-    OwnPtr<Extensions3DUtil> m_extensionsUtil;
 
     // Enabled extension objects.
     RefPtr<ANGLEInstancedArrays> m_angleInstancedArrays;
@@ -544,389 +61,11 @@
     RefPtr<WebGLCompressedTexturePVRTC> m_webglCompressedTexturePVRTC;
     RefPtr<WebGLCompressedTextureS3TC> m_webglCompressedTextureS3TC;
     RefPtr<WebGLDepthTexture> m_webglDepthTexture;
-
-    enum ExtensionFlags {
-        ApprovedExtension   = 0x00,
-        DraftExtension      = 0x01,
-        PrivilegedExtension = 0x02,
-        PrefixedExtension   = 0x04,
-        WebGLDebugRendererInfoExtension = 0x08,
-    };
-
-    class ExtensionTracker {
-    public:
-        ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
-            : m_privileged(flags & PrivilegedExtension)
-            , m_draft(flags & DraftExtension)
-            , m_prefixed(flags & PrefixedExtension)
-            , m_webglDebugRendererInfo(flags & WebGLDebugRendererInfoExtension)
-            , m_prefixes(prefixes)
-        {
-        }
-
-        virtual ~ExtensionTracker()
-        {
-        }
-
-        bool prefixed() const
-        {
-            return m_prefixed;
-        }
-
-        bool privileged() const
-        {
-            return m_privileged;
-        }
-
-        bool draft() const
-        {
-            return m_draft;
-        }
-
-        bool webglDebugRendererInfo() const
-        {
-            return m_webglDebugRendererInfo;
-        }
-
-        bool matchesNameWithPrefixes(const String&) const;
-
-        virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext*) const = 0;
-        virtual bool supported(WebGLRenderingContext*) const = 0;
-        virtual const char* extensionName() const = 0;
-        virtual void loseExtension() = 0;
-
-    private:
-        bool m_privileged;
-        bool m_draft;
-        bool m_prefixed;
-        bool m_webglDebugRendererInfo;
-        const char* const* m_prefixes;
-    };
-
-    template <typename T>
-    class TypedExtensionTracker FINAL : public ExtensionTracker {
-    public:
-        TypedExtensionTracker(RefPtr<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
-            : ExtensionTracker(flags, prefixes)
-            , m_extensionField(extensionField)
-        {
-        }
-
-        ~TypedExtensionTracker()
-        {
-            if (m_extensionField) {
-                m_extensionField->lose(true);
-                m_extensionField = 0;
-            }
-        }
-
-        virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContext* context) const OVERRIDE
-        {
-            if (!m_extensionField)
-                m_extensionField = T::create(context);
-
-            return m_extensionField;
-        }
-
-        virtual bool supported(WebGLRenderingContext* context) const OVERRIDE
-        {
-            return T::supported(context);
-        }
-
-        virtual const char* extensionName() const OVERRIDE
-        {
-            return T::extensionName();
-        }
-
-        virtual void loseExtension() OVERRIDE
-        {
-            if (m_extensionField) {
-                m_extensionField->lose(false);
-                if (m_extensionField->isLost())
-                    m_extensionField = 0;
-            }
-        }
-
-    private:
-        RefPtr<T>& m_extensionField;
-    };
-
-    Vector<ExtensionTracker*> m_extensions;
-
-    template <typename T>
-    void registerExtension(RefPtr<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0)
-    {
-        m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, flags, prefixes));
-    }
-
-    // Errors raised by synthesizeGLError() while the context is lost.
-    Vector<GLenum> m_lostContextErrors;
-
-    // Helpers for getParameter and others
-    WebGLGetInfo getBooleanParameter(GLenum);
-    WebGLGetInfo getBooleanArrayParameter(GLenum);
-    WebGLGetInfo getFloatParameter(GLenum);
-    WebGLGetInfo getIntParameter(GLenum);
-    WebGLGetInfo getUnsignedIntParameter(GLenum);
-    WebGLGetInfo getWebGLFloatArrayParameter(GLenum);
-    WebGLGetInfo getWebGLIntArrayParameter(GLenum);
-
-    // Clear the backbuffer if it was composited since the last operation.
-    // clearMask is set to the bitfield of any clear that would happen anyway at this time
-    // and the function returns true if that clear is now unnecessary.
-    bool clearIfComposited(GLbitfield clearMask = 0);
-
-    // Helper to restore state that clearing the framebuffer may destroy.
-    void restoreStateAfterClear();
-
-    // Convert texture internal format.
-    GLenum convertTexInternalFormat(GLenum internalformat, GLenum type);
-
-    void texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState&);
-    void texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
-    void texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState&);
-    void texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
-
-    void handleTextureCompleteness(const char*, bool);
-    void createFallbackBlackTextures1x1();
-
-    // Helper function for copyTex{Sub}Image, check whether the internalformat
-    // and the color buffer format of the current bound framebuffer combination
-    // is valid.
-    bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat);
-
-    // Helper function to get the bound framebuffer's color buffer format.
-    GLenum boundFramebufferColorFormat();
-
-    // Helper function to get the bound framebuffer's width.
-    int boundFramebufferWidth();
-
-    // Helper function to get the bound framebuffer's height.
-    int boundFramebufferHeight();
-
-    // Helper function to verify limits on the length of uniform and attribute locations.
-    bool validateLocationLength(const char* functionName, const String&);
-
-    // Helper function to check if size is non-negative.
-    // Generate GL error and return false for negative inputs; otherwise, return true.
-    bool validateSize(const char* functionName, GLint x, GLint y);
-
-    // Helper function to check if all characters in the string belong to the
-    // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
-    bool validateString(const char* functionName, const String&);
-
-    // Helper function to check target and texture bound to the target.
-    // Generate GL errors and return 0 if target is invalid or texture bound is
-    // null.  Otherwise, return the texture bound to the target.
-    WebGLTexture* validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap);
-
-    // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
-    // Generates GL error and returns false if parameters are invalid.
-    bool validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level);
-
-    // Helper function to check input level for functions {copy}Tex{Sub}Image.
-    // Generates GL error and returns false if level is invalid.
-    bool validateTexFuncLevel(const char* functionName, GLenum target, GLint level);
-
-    enum TexFuncValidationFunctionType {
-        NotTexSubImage2D,
-        TexSubImage2D,
-    };
-
-    enum TexFuncValidationSourceType {
-        SourceArrayBufferView,
-        SourceImageData,
-        SourceHTMLImageElement,
-        SourceHTMLCanvasElement,
-        SourceHTMLVideoElement,
-    };
-
-    // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
-    // Otherwise, it would return quickly without doing other work.
-    bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width,
-        GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset);
-
-    // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image.
-    // Generates GL error and returns false if width or height is invalid.
-    bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height);
-
-    // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
-    // Generates GL error and returns false if parameters are invalid.
-    bool validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
-
-    enum NullDisposition {
-        NullAllowed,
-        NullNotAllowed
-    };
-
-    // Helper function to validate that the given ArrayBufferView
-    // is of the correct type and contains enough data for the texImage call.
-    // Generates GL error and returns false if parameters are invalid.
-    bool validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition);
-
-    // Helper function to validate a given texture format is settable as in
-    // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
-    // copyTexSubImage2D.
-    // Generates GL error and returns false if the format is not settable.
-    bool validateSettableTexFormat(const char* functionName, GLenum format);
-
-    // Helper function to validate compressed texture data is correct size
-    // for the given format and dimensions.
-    bool validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels);
-
-    // Helper function for validating compressed texture formats.
-    bool validateCompressedTexFormat(GLenum format);
-
-    // Helper function to validate compressed texture dimensions are valid for
-    // the given format.
-    bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format);
-
-    // Helper function to validate compressed texture dimensions are valid for
-    // the given format.
-    bool validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture*);
-
-    // Helper function to validate mode for draw{Arrays/Elements}.
-    bool validateDrawMode(const char* functionName, GLenum);
-
-    // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
-    bool validateStencilSettings(const char* functionName);
-
-    // Helper function to validate stencil or depth func.
-    bool validateStencilOrDepthFunc(const char* functionName, GLenum);
-
-    // Helper function for texParameterf and texParameteri.
-    void texParameter(GLenum target, GLenum pname, GLfloat parami, GLint paramf, bool isFloat);
-
-    // Helper function to print GL errors to console.
-    void printGLErrorToConsole(const String&);
-
-    // Helper function to print warnings to console. Currently
-    // used only to warn about use of obsolete functions.
-    void printWarningToConsole(const String&);
-
-    // Helper function to validate input parameters for framebuffer functions.
-    // Generate GL error if parameters are illegal.
-    bool validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment);
-
-    // Helper function to validate blend equation mode.
-    bool validateBlendEquation(const char* functionName, GLenum);
-
-    // Helper function to validate blend func factors.
-    bool validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst);
-
-    // Helper function to validate a GL capability.
-    bool validateCapability(const char* functionName, GLenum);
-
-    // Helper function to validate input parameters for uniform functions.
-    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GLsizei mod);
-    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GLsizei mod);
-    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GLsizei, GLsizei mod);
-    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, Float32Array*, GLsizei mod);
-    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, void*, GLsizei, GLsizei mod);
-
-    // Helper function to validate parameters for bufferData.
-    // Return the current bound buffer to target, or 0 if parameters are invalid.
-    WebGLBuffer* validateBufferDataParameters(const char* functionName, GLenum target, GLenum usage);
-
-    // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
-    bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
-
-    // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
-    bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
-
-    // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
-    bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
-
-    // Helper function to validate drawArrays(Instanced) calls
-    bool validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count);
-
-    // Helper function to validate drawElements(Instanced) calls
-    bool validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset);
-
-    // Helper function to validate draw*Instanced calls
-    bool validateDrawInstanced(const char* functionName, GLsizei primcount);
-
-    // Helper functions for vertexAttribNf{v}.
-    void vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat, GLfloat, GLfloat, GLfloat);
-    void vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array*, GLsizei expectedSize);
-    void vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat*, GLsizei, GLsizei expectedSize);
-
-    // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
-    // Return false if caller should return without further processing.
-    bool deleteObject(WebGLObject*);
-
-    // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
-    // If the object has already been deleted, set deleted to true upon return.
-    // Return false if caller should return without further processing.
-    bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
-
-    void dispatchContextLostEvent(Timer<WebGLRenderingContext>*);
-    // Helper for restoration after context lost.
-    void maybeRestoreContext(Timer<WebGLRenderingContext>*);
-
-    // Determine if we are running privileged code in the browser, for example,
-    // a Safari or Chrome extension.
-    bool allowPrivilegedExtensions() const;
-
-    // Determine if WEBGL_debug_renderer_info extension is enabled. For the
-    // moment it can be enabled either through a chromium finch experiment
-    // or for privileged code in the browser.
-    bool allowWebGLDebugRendererInfo() const;
-
-    enum ConsoleDisplayPreference {
-        DisplayInConsole,
-        DontDisplayInConsole
-    };
-
-    // Wrapper for WebGraphicsContext3D::synthesizeGLError that sends a message
-    // to the JavaScript console.
-    void synthesizeGLError(GLenum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
-    void emitGLWarning(const char* function, const char* reason);
-
-    String ensureNotNull(const String&) const;
-
-    // Enable or disable stencil test based on user setting and
-    // whether the current FBO has a stencil buffer.
-    void applyStencilTest();
-
-    // Helper for enabling or disabling a capability.
-    void enableOrDisable(GLenum capability, bool enable);
-
-    // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
-    IntSize clampedCanvasSize();
-
-    // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
-    // Later, return the cached value.
-    GLint maxDrawBuffers();
-    GLint maxColorAttachments();
-
-    void setBackDrawBuffer(GLenum);
-
-    void restoreCurrentFramebuffer();
-    void restoreCurrentTexture2D();
-
-    virtual void multisamplingChanged(bool) OVERRIDE;
-
-    void findNewMaxEnabledAttribIndex();
-    void findNewMaxNonDefaultTextureUnit();
-
-    friend class WebGLStateRestorer;
-    friend class WebGLRenderingContextEvictionManager;
-
-    static Vector<WebGLRenderingContext*>& activeContexts();
-    static Vector<WebGLRenderingContext*>& forciblyEvictedContexts();
-
-    static void activateContext(WebGLRenderingContext*);
-    static void deactivateContext(WebGLRenderingContext*, bool addToInactiveList);
-    static void willDestroyContext(WebGLRenderingContext*);
-    static void forciblyLoseOldestContext(const String& reason);
-    // Return the least recently used context's position in the active context vector.
-    // If the vector is empty, return the maximum allowed active context number.
-    static size_t oldestContextIndex();
-    static IntSize oldestContextSize();
 };
 
-DEFINE_TYPE_CASTS(WebGLRenderingContext, CanvasRenderingContext, context, context->is3d(), context.is3d());
+DEFINE_TYPE_CASTS(WebGLRenderingContext, CanvasRenderingContext, context,
+    context->is3d() && WebGLRenderingContextBase::getWebGLVersion(context) == 1,
+    context.is3d() && WebGLRenderingContextBase::getWebGLVersion(&context) == 1);
 
 } // namespace WebCore
 
diff --git a/Source/core/html/canvas/WebGLRenderingContext.idl b/Source/core/html/canvas/WebGLRenderingContext.idl
index ef8746e..119c9a9 100644
--- a/Source/core/html/canvas/WebGLRenderingContext.idl
+++ b/Source/core/html/canvas/WebGLRenderingContext.idl
@@ -23,652 +23,5 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-typedef unsigned long  GLenum;
-typedef boolean        GLboolean;
-typedef unsigned long  GLbitfield;
-typedef byte           GLbyte;         /* 'byte' should be a signed 8 bit type. */
-typedef short          GLshort;
-typedef long           GLint;
-typedef long           GLsizei;
-typedef long long      GLintptr;
-typedef long long      GLsizeiptr;
-typedef octet          GLubyte;        /* 'octet' should be an unsigned 8 bit type. */
-typedef unsigned short GLushort;
-typedef unsigned long  GLuint;
-typedef /*unrestricted*/ float GLfloat;
-typedef /*unrestricted*/ float GLclampf;
-
-[
-    DoNotCheckConstants,
-    StrictTypeChecking,
-] interface WebGLRenderingContext : CanvasRenderingContext {
-
-    /* ClearBufferMask */
-    const GLenum DEPTH_BUFFER_BIT               = 0x00000100;
-    const GLenum STENCIL_BUFFER_BIT             = 0x00000400;
-    const GLenum COLOR_BUFFER_BIT               = 0x00004000;
-
-    /* BeginMode */
-    const GLenum POINTS                         = 0x0000;
-    const GLenum LINES                          = 0x0001;
-    const GLenum LINE_LOOP                      = 0x0002;
-    const GLenum LINE_STRIP                     = 0x0003;
-    const GLenum TRIANGLES                      = 0x0004;
-    const GLenum TRIANGLE_STRIP                 = 0x0005;
-    const GLenum TRIANGLE_FAN                   = 0x0006;
-
-    /* AlphaFunction (not supported in ES20) */
-    /*      NEVER */
-    /*      LESS */
-    /*      EQUAL */
-    /*      LEQUAL */
-    /*      GREATER */
-    /*      NOTEQUAL */
-    /*      GEQUAL */
-    /*      ALWAYS */
-
-    /* BlendingFactorDest */
-    const GLenum ZERO                           = 0;
-    const GLenum ONE                            = 1;
-    const GLenum SRC_COLOR                      = 0x0300;
-    const GLenum ONE_MINUS_SRC_COLOR            = 0x0301;
-    const GLenum SRC_ALPHA                      = 0x0302;
-    const GLenum ONE_MINUS_SRC_ALPHA            = 0x0303;
-    const GLenum DST_ALPHA                      = 0x0304;
-    const GLenum ONE_MINUS_DST_ALPHA            = 0x0305;
-
-    /* BlendingFactorSrc */
-    /*      ZERO */
-    /*      ONE */
-    const GLenum DST_COLOR                      = 0x0306;
-    const GLenum ONE_MINUS_DST_COLOR            = 0x0307;
-    const GLenum SRC_ALPHA_SATURATE             = 0x0308;
-    /*      SRC_ALPHA */
-    /*      ONE_MINUS_SRC_ALPHA */
-    /*      DST_ALPHA */
-    /*      ONE_MINUS_DST_ALPHA */
-
-    /* BlendEquationSeparate */
-    const GLenum FUNC_ADD                       = 0x8006;
-    const GLenum BLEND_EQUATION                 = 0x8009;
-    const GLenum BLEND_EQUATION_RGB             = 0x8009;   /* same as BLEND_EQUATION */
-    const GLenum BLEND_EQUATION_ALPHA           = 0x883D;
-
-    /* BlendSubtract */
-    const GLenum FUNC_SUBTRACT                  = 0x800A;
-    const GLenum FUNC_REVERSE_SUBTRACT          = 0x800B;
-
-    /* Separate Blend Functions */
-    const GLenum BLEND_DST_RGB                  = 0x80C8;
-    const GLenum BLEND_SRC_RGB                  = 0x80C9;
-    const GLenum BLEND_DST_ALPHA                = 0x80CA;
-    const GLenum BLEND_SRC_ALPHA                = 0x80CB;
-    const GLenum CONSTANT_COLOR                 = 0x8001;
-    const GLenum ONE_MINUS_CONSTANT_COLOR       = 0x8002;
-    const GLenum CONSTANT_ALPHA                 = 0x8003;
-    const GLenum ONE_MINUS_CONSTANT_ALPHA       = 0x8004;
-    const GLenum BLEND_COLOR                    = 0x8005;
-
-    /* Buffer Objects */
-    const GLenum ARRAY_BUFFER                   = 0x8892;
-    const GLenum ELEMENT_ARRAY_BUFFER           = 0x8893;
-    const GLenum ARRAY_BUFFER_BINDING           = 0x8894;
-    const GLenum ELEMENT_ARRAY_BUFFER_BINDING   = 0x8895;
-
-    const GLenum STREAM_DRAW                    = 0x88E0;
-    const GLenum STATIC_DRAW                    = 0x88E4;
-    const GLenum DYNAMIC_DRAW                   = 0x88E8;
-
-    const GLenum BUFFER_SIZE                    = 0x8764;
-    const GLenum BUFFER_USAGE                   = 0x8765;
-
-    const GLenum CURRENT_VERTEX_ATTRIB          = 0x8626;
-
-    /* CullFaceMode */
-    const GLenum FRONT                          = 0x0404;
-    const GLenum BACK                           = 0x0405;
-    const GLenum FRONT_AND_BACK                 = 0x0408;
-
-    /* DepthFunction */
-    /*      NEVER */
-    /*      LESS */
-    /*      EQUAL */
-    /*      LEQUAL */
-    /*      GREATER */
-    /*      NOTEQUAL */
-    /*      GEQUAL */
-    /*      ALWAYS */
-
-    /* EnableCap */
-    const GLenum TEXTURE_2D                     = 0x0DE1;
-    const GLenum CULL_FACE                      = 0x0B44;
-    const GLenum BLEND                          = 0x0BE2;
-    const GLenum DITHER                         = 0x0BD0;
-    const GLenum STENCIL_TEST                   = 0x0B90;
-    const GLenum DEPTH_TEST                     = 0x0B71;
-    const GLenum SCISSOR_TEST                   = 0x0C11;
-    const GLenum POLYGON_OFFSET_FILL            = 0x8037;
-    const GLenum SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
-    const GLenum SAMPLE_COVERAGE                = 0x80A0;
-
-    /* ErrorCode */
-    const GLenum NO_ERROR                       = 0;
-    const GLenum INVALID_ENUM                   = 0x0500;
-    const GLenum INVALID_VALUE                  = 0x0501;
-    const GLenum INVALID_OPERATION              = 0x0502;
-    const GLenum OUT_OF_MEMORY                  = 0x0505;
-
-    /* FrontFaceDirection */
-    const GLenum CW                             = 0x0900;
-    const GLenum CCW                            = 0x0901;
-
-    /* GetPName */
-    const GLenum LINE_WIDTH                     = 0x0B21;
-    const GLenum ALIASED_POINT_SIZE_RANGE       = 0x846D;
-    const GLenum ALIASED_LINE_WIDTH_RANGE       = 0x846E;
-    const GLenum CULL_FACE_MODE                 = 0x0B45;
-    const GLenum FRONT_FACE                     = 0x0B46;
-    const GLenum DEPTH_RANGE                    = 0x0B70;
-    const GLenum DEPTH_WRITEMASK                = 0x0B72;
-    const GLenum DEPTH_CLEAR_VALUE              = 0x0B73;
-    const GLenum DEPTH_FUNC                     = 0x0B74;
-    const GLenum STENCIL_CLEAR_VALUE            = 0x0B91;
-    const GLenum STENCIL_FUNC                   = 0x0B92;
-    const GLenum STENCIL_FAIL                   = 0x0B94;
-    const GLenum STENCIL_PASS_DEPTH_FAIL        = 0x0B95;
-    const GLenum STENCIL_PASS_DEPTH_PASS        = 0x0B96;
-    const GLenum STENCIL_REF                    = 0x0B97;
-    const GLenum STENCIL_VALUE_MASK             = 0x0B93;
-    const GLenum STENCIL_WRITEMASK              = 0x0B98;
-    const GLenum STENCIL_BACK_FUNC              = 0x8800;
-    const GLenum STENCIL_BACK_FAIL              = 0x8801;
-    const GLenum STENCIL_BACK_PASS_DEPTH_FAIL   = 0x8802;
-    const GLenum STENCIL_BACK_PASS_DEPTH_PASS   = 0x8803;
-    const GLenum STENCIL_BACK_REF               = 0x8CA3;
-    const GLenum STENCIL_BACK_VALUE_MASK        = 0x8CA4;
-    const GLenum STENCIL_BACK_WRITEMASK         = 0x8CA5;
-    const GLenum VIEWPORT                       = 0x0BA2;
-    const GLenum SCISSOR_BOX                    = 0x0C10;
-    /*      SCISSOR_TEST */
-    const GLenum COLOR_CLEAR_VALUE              = 0x0C22;
-    const GLenum COLOR_WRITEMASK                = 0x0C23;
-    const GLenum UNPACK_ALIGNMENT               = 0x0CF5;
-    const GLenum PACK_ALIGNMENT                 = 0x0D05;
-    const GLenum MAX_TEXTURE_SIZE               = 0x0D33;
-    const GLenum MAX_VIEWPORT_DIMS              = 0x0D3A;
-    const GLenum SUBPIXEL_BITS                  = 0x0D50;
-    const GLenum RED_BITS                       = 0x0D52;
-    const GLenum GREEN_BITS                     = 0x0D53;
-    const GLenum BLUE_BITS                      = 0x0D54;
-    const GLenum ALPHA_BITS                     = 0x0D55;
-    const GLenum DEPTH_BITS                     = 0x0D56;
-    const GLenum STENCIL_BITS                   = 0x0D57;
-    const GLenum POLYGON_OFFSET_UNITS           = 0x2A00;
-    /*      POLYGON_OFFSET_FILL */
-    const GLenum POLYGON_OFFSET_FACTOR          = 0x8038;
-    const GLenum TEXTURE_BINDING_2D             = 0x8069;
-    const GLenum SAMPLE_BUFFERS                 = 0x80A8;
-    const GLenum SAMPLES                        = 0x80A9;
-    const GLenum SAMPLE_COVERAGE_VALUE          = 0x80AA;
-    const GLenum SAMPLE_COVERAGE_INVERT         = 0x80AB;
-
-    /* GetTextureParameter */
-    /*      TEXTURE_MAG_FILTER */
-    /*      TEXTURE_MIN_FILTER */
-    /*      TEXTURE_WRAP_S */
-    /*      TEXTURE_WRAP_T */
-
-    const GLenum COMPRESSED_TEXTURE_FORMATS     = 0x86A3;
-
-    /* HintMode */
-    const GLenum DONT_CARE                      = 0x1100;
-    const GLenum FASTEST                        = 0x1101;
-    const GLenum NICEST                         = 0x1102;
-
-    /* HintTarget */
-    const GLenum GENERATE_MIPMAP_HINT            = 0x8192;
-
-    /* DataType */
-    const GLenum BYTE                           = 0x1400;
-    const GLenum UNSIGNED_BYTE                  = 0x1401;
-    const GLenum SHORT                          = 0x1402;
-    const GLenum UNSIGNED_SHORT                 = 0x1403;
-    const GLenum INT                            = 0x1404;
-    const GLenum UNSIGNED_INT                   = 0x1405;
-    const GLenum FLOAT                          = 0x1406;
-
-    /* PixelFormat */
-    const GLenum DEPTH_COMPONENT                = 0x1902;
-    const GLenum ALPHA                          = 0x1906;
-    const GLenum RGB                            = 0x1907;
-    const GLenum RGBA                           = 0x1908;
-    const GLenum LUMINANCE                      = 0x1909;
-    const GLenum LUMINANCE_ALPHA                = 0x190A;
-
-    /* PixelType */
-    /*      UNSIGNED_BYTE */
-    const GLenum UNSIGNED_SHORT_4_4_4_4         = 0x8033;
-    const GLenum UNSIGNED_SHORT_5_5_5_1         = 0x8034;
-    const GLenum UNSIGNED_SHORT_5_6_5           = 0x8363;
-
-    /* Shaders */
-    const GLenum FRAGMENT_SHADER                  = 0x8B30;
-    const GLenum VERTEX_SHADER                    = 0x8B31;
-    const GLenum MAX_VERTEX_ATTRIBS               = 0x8869;
-    const GLenum MAX_VERTEX_UNIFORM_VECTORS       = 0x8DFB;
-    const GLenum MAX_VARYING_VECTORS              = 0x8DFC;
-    const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
-    const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS   = 0x8B4C;
-    const GLenum MAX_TEXTURE_IMAGE_UNITS          = 0x8872;
-    const GLenum MAX_FRAGMENT_UNIFORM_VECTORS     = 0x8DFD;
-    const GLenum SHADER_TYPE                      = 0x8B4F;
-    const GLenum DELETE_STATUS                    = 0x8B80;
-    const GLenum LINK_STATUS                      = 0x8B82;
-    const GLenum VALIDATE_STATUS                  = 0x8B83;
-    const GLenum ATTACHED_SHADERS                 = 0x8B85;
-    const GLenum ACTIVE_UNIFORMS                  = 0x8B86;
-    const GLenum ACTIVE_ATTRIBUTES                = 0x8B89;
-    const GLenum SHADING_LANGUAGE_VERSION         = 0x8B8C;
-    const GLenum CURRENT_PROGRAM                  = 0x8B8D;
-
-    /* StencilFunction */
-    const GLenum NEVER                          = 0x0200;
-    const GLenum LESS                           = 0x0201;
-    const GLenum EQUAL                          = 0x0202;
-    const GLenum LEQUAL                         = 0x0203;
-    const GLenum GREATER                        = 0x0204;
-    const GLenum NOTEQUAL                       = 0x0205;
-    const GLenum GEQUAL                         = 0x0206;
-    const GLenum ALWAYS                         = 0x0207;
-
-    /* StencilOp */
-    /*      ZERO */
-    const GLenum KEEP                           = 0x1E00;
-    const GLenum REPLACE                        = 0x1E01;
-    const GLenum INCR                           = 0x1E02;
-    const GLenum DECR                           = 0x1E03;
-    const GLenum INVERT                         = 0x150A;
-    const GLenum INCR_WRAP                      = 0x8507;
-    const GLenum DECR_WRAP                      = 0x8508;
-
-    /* StringName */
-    const GLenum VENDOR                         = 0x1F00;
-    const GLenum RENDERER                       = 0x1F01;
-    const GLenum VERSION                        = 0x1F02;
-
-    /* TextureMagFilter */
-    const GLenum NEAREST                        = 0x2600;
-    const GLenum LINEAR                         = 0x2601;
-
-    /* TextureMinFilter */
-    /*      NEAREST */
-    /*      LINEAR */
-    const GLenum NEAREST_MIPMAP_NEAREST         = 0x2700;
-    const GLenum LINEAR_MIPMAP_NEAREST          = 0x2701;
-    const GLenum NEAREST_MIPMAP_LINEAR          = 0x2702;
-    const GLenum LINEAR_MIPMAP_LINEAR           = 0x2703;
-
-    /* TextureParameterName */
-    const GLenum TEXTURE_MAG_FILTER             = 0x2800;
-    const GLenum TEXTURE_MIN_FILTER             = 0x2801;
-    const GLenum TEXTURE_WRAP_S                 = 0x2802;
-    const GLenum TEXTURE_WRAP_T                 = 0x2803;
-
-    /* TextureTarget */
-    /*      TEXTURE_2D */
-    const GLenum TEXTURE                        = 0x1702;
-
-    const GLenum TEXTURE_CUBE_MAP               = 0x8513;
-    const GLenum TEXTURE_BINDING_CUBE_MAP       = 0x8514;
-    const GLenum TEXTURE_CUBE_MAP_POSITIVE_X    = 0x8515;
-    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X    = 0x8516;
-    const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y    = 0x8517;
-    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y    = 0x8518;
-    const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z    = 0x8519;
-    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z    = 0x851A;
-    const GLenum MAX_CUBE_MAP_TEXTURE_SIZE      = 0x851C;
-
-    /* TextureUnit */
-    const GLenum TEXTURE0                       = 0x84C0;
-    const GLenum TEXTURE1                       = 0x84C1;
-    const GLenum TEXTURE2                       = 0x84C2;
-    const GLenum TEXTURE3                       = 0x84C3;
-    const GLenum TEXTURE4                       = 0x84C4;
-    const GLenum TEXTURE5                       = 0x84C5;
-    const GLenum TEXTURE6                       = 0x84C6;
-    const GLenum TEXTURE7                       = 0x84C7;
-    const GLenum TEXTURE8                       = 0x84C8;
-    const GLenum TEXTURE9                       = 0x84C9;
-    const GLenum TEXTURE10                      = 0x84CA;
-    const GLenum TEXTURE11                      = 0x84CB;
-    const GLenum TEXTURE12                      = 0x84CC;
-    const GLenum TEXTURE13                      = 0x84CD;
-    const GLenum TEXTURE14                      = 0x84CE;
-    const GLenum TEXTURE15                      = 0x84CF;
-    const GLenum TEXTURE16                      = 0x84D0;
-    const GLenum TEXTURE17                      = 0x84D1;
-    const GLenum TEXTURE18                      = 0x84D2;
-    const GLenum TEXTURE19                      = 0x84D3;
-    const GLenum TEXTURE20                      = 0x84D4;
-    const GLenum TEXTURE21                      = 0x84D5;
-    const GLenum TEXTURE22                      = 0x84D6;
-    const GLenum TEXTURE23                      = 0x84D7;
-    const GLenum TEXTURE24                      = 0x84D8;
-    const GLenum TEXTURE25                      = 0x84D9;
-    const GLenum TEXTURE26                      = 0x84DA;
-    const GLenum TEXTURE27                      = 0x84DB;
-    const GLenum TEXTURE28                      = 0x84DC;
-    const GLenum TEXTURE29                      = 0x84DD;
-    const GLenum TEXTURE30                      = 0x84DE;
-    const GLenum TEXTURE31                      = 0x84DF;
-    const GLenum ACTIVE_TEXTURE                 = 0x84E0;
-
-    /* TextureWrapMode */
-    const GLenum REPEAT                         = 0x2901;
-    const GLenum CLAMP_TO_EDGE                  = 0x812F;
-    const GLenum MIRRORED_REPEAT                = 0x8370;
-
-    /* Uniform Types */
-    const GLenum FLOAT_VEC2                     = 0x8B50;
-    const GLenum FLOAT_VEC3                     = 0x8B51;
-    const GLenum FLOAT_VEC4                     = 0x8B52;
-    const GLenum INT_VEC2                       = 0x8B53;
-    const GLenum INT_VEC3                       = 0x8B54;
-    const GLenum INT_VEC4                       = 0x8B55;
-    const GLenum BOOL                           = 0x8B56;
-    const GLenum BOOL_VEC2                      = 0x8B57;
-    const GLenum BOOL_VEC3                      = 0x8B58;
-    const GLenum BOOL_VEC4                      = 0x8B59;
-    const GLenum FLOAT_MAT2                     = 0x8B5A;
-    const GLenum FLOAT_MAT3                     = 0x8B5B;
-    const GLenum FLOAT_MAT4                     = 0x8B5C;
-    const GLenum SAMPLER_2D                     = 0x8B5E;
-    const GLenum SAMPLER_CUBE                   = 0x8B60;
-
-    /* Vertex Arrays */
-    const GLenum VERTEX_ATTRIB_ARRAY_ENABLED        = 0x8622;
-    const GLenum VERTEX_ATTRIB_ARRAY_SIZE           = 0x8623;
-    const GLenum VERTEX_ATTRIB_ARRAY_STRIDE         = 0x8624;
-    const GLenum VERTEX_ATTRIB_ARRAY_TYPE           = 0x8625;
-    const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED     = 0x886A;
-    const GLenum VERTEX_ATTRIB_ARRAY_POINTER        = 0x8645;
-    const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
-
-    /* Shader Source */
-    const GLenum COMPILE_STATUS                 = 0x8B81;
-
-    /* Shader Precision-Specified Types */
-    const GLenum LOW_FLOAT                      = 0x8DF0;
-    const GLenum MEDIUM_FLOAT                   = 0x8DF1;
-    const GLenum HIGH_FLOAT                     = 0x8DF2;
-    const GLenum LOW_INT                        = 0x8DF3;
-    const GLenum MEDIUM_INT                     = 0x8DF4;
-    const GLenum HIGH_INT                       = 0x8DF5;
-
-    /* Framebuffer Object. */
-    const GLenum FRAMEBUFFER                    = 0x8D40;
-    const GLenum RENDERBUFFER                   = 0x8D41;
-
-    const GLenum RGBA4                          = 0x8056;
-    const GLenum RGB5_A1                        = 0x8057;
-    const GLenum RGB565                         = 0x8D62;
-    const GLenum DEPTH_COMPONENT16              = 0x81A5;
-    const GLenum STENCIL_INDEX                  = 0x1901;
-    const GLenum STENCIL_INDEX8                 = 0x8D48;
-    const GLenum DEPTH_STENCIL                  = 0x84F9;
-
-    const GLenum RENDERBUFFER_WIDTH             = 0x8D42;
-    const GLenum RENDERBUFFER_HEIGHT            = 0x8D43;
-    const GLenum RENDERBUFFER_INTERNAL_FORMAT   = 0x8D44;
-    const GLenum RENDERBUFFER_RED_SIZE          = 0x8D50;
-    const GLenum RENDERBUFFER_GREEN_SIZE        = 0x8D51;
-    const GLenum RENDERBUFFER_BLUE_SIZE         = 0x8D52;
-    const GLenum RENDERBUFFER_ALPHA_SIZE        = 0x8D53;
-    const GLenum RENDERBUFFER_DEPTH_SIZE        = 0x8D54;
-    const GLenum RENDERBUFFER_STENCIL_SIZE      = 0x8D55;
-
-    const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           = 0x8CD0;
-    const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           = 0x8CD1;
-    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         = 0x8CD2;
-    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
-
-    const GLenum COLOR_ATTACHMENT0              = 0x8CE0;
-    const GLenum DEPTH_ATTACHMENT               = 0x8D00;
-    const GLenum STENCIL_ATTACHMENT             = 0x8D20;
-    const GLenum DEPTH_STENCIL_ATTACHMENT       = 0x821A;
-
-    const GLenum NONE                           = 0;
-
-    const GLenum FRAMEBUFFER_COMPLETE                      = 0x8CD5;
-    const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = 0x8CD6;
-    const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
-    const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = 0x8CD9;
-    const GLenum FRAMEBUFFER_UNSUPPORTED                   = 0x8CDD;
-
-    const GLenum FRAMEBUFFER_BINDING            = 0x8CA6;
-    const GLenum RENDERBUFFER_BINDING           = 0x8CA7;
-    const GLenum MAX_RENDERBUFFER_SIZE          = 0x84E8;
-
-    const GLenum INVALID_FRAMEBUFFER_OPERATION  = 0x0506;
-
-    /* WebGL-specific enums */
-    const GLenum UNPACK_FLIP_Y_WEBGL                = 0x9240;
-    const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL     = 0x9241;
-    const GLenum CONTEXT_LOST_WEBGL                 = 0x9242;
-    const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
-    const GLenum BROWSER_DEFAULT_WEBGL              = 0x9244;
-
-    readonly attribute GLsizei drawingBufferWidth;
-    readonly attribute GLsizei drawingBufferHeight;
-
-    void activeTexture(GLenum texture);
-    void attachShader(WebGLProgram? program, WebGLShader? shader);
-    void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
-    void bindBuffer(GLenum target, WebGLBuffer? buffer);
-    void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
-    void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
-    void bindTexture(GLenum target, WebGLTexture? texture);
-    void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
-    void blendEquation(GLenum mode);
-    void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
-    void blendFunc(GLenum sfactor, GLenum dfactor);
-    void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
-    void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
-    void bufferData(GLenum target, ArrayBufferView? data, GLenum usage);
-    void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
-    void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
-    void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView? data);
-
-    GLenum checkFramebufferStatus(GLenum target);
-    void clear(GLbitfield mask);
-    void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
-    void clearDepth(GLclampf depth);
-    void clearStencil(GLint s);
-    void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
-    void compileShader(WebGLShader? shader);
-
-    void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
-                              GLsizei width, GLsizei height, GLint border, ArrayBufferView? data);
-    void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
-                                 GLsizei width, GLsizei height, GLenum format, ArrayBufferView? data);
-
-    void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
-    void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
-
-    WebGLBuffer createBuffer();
-    WebGLFramebuffer createFramebuffer();
-    WebGLProgram createProgram();
-    WebGLRenderbuffer createRenderbuffer();
-    WebGLShader createShader(GLenum type);
-    WebGLTexture createTexture();
-
-    void cullFace(GLenum mode);
-
-    void deleteBuffer(WebGLBuffer? buffer);
-    void deleteFramebuffer(WebGLFramebuffer? framebuffer);
-    void deleteProgram(WebGLProgram? program);
-    void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
-    void deleteShader(WebGLShader? shader);
-    void deleteTexture(WebGLTexture? texture);
-
-    void depthFunc(GLenum func);
-    void depthMask(GLboolean flag);
-    void depthRange(GLclampf zNear, GLclampf zFar);
-    void detachShader(WebGLProgram? program, WebGLShader? shader);
-    void disable(GLenum cap);
-    void disableVertexAttribArray(GLuint index);
-    void drawArrays(GLenum mode, GLint first, GLsizei count);
-    void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
-
-    void enable(GLenum cap);
-    void enableVertexAttribArray(GLuint index);
-    void finish();
-    void flush();
-    void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer? renderbuffer);
-    void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture? texture, GLint level);
-    void frontFace(GLenum mode);
-    void generateMipmap(GLenum target);
-
-    WebGLActiveInfo getActiveAttrib(WebGLProgram? program, GLuint index);
-    WebGLActiveInfo getActiveUniform(WebGLProgram? program, GLuint index);
-
-    [Custom] void getAttachedShaders(WebGLProgram? program);
-
-    GLint getAttribLocation(WebGLProgram? program, DOMString name);
-
-    [Custom] any getBufferParameter(GLenum target, GLenum pname);
-
-    WebGLContextAttributes getContextAttributes();
-
-    GLenum getError();
-
-    // object getExtension(DOMString name);
-    [Custom] any getExtension(DOMString name);
-
-    [Custom] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
-    [Custom] any getParameter(GLenum pname);
-    [Custom] any getProgramParameter(WebGLProgram? program, GLenum pname);
-    [TreatReturnedNullStringAs=Null] DOMString getProgramInfoLog(WebGLProgram? program);
-    [Custom] any getRenderbufferParameter(GLenum target, GLenum pname);
-    [Custom] any getShaderParameter(WebGLShader? shader, GLenum pname);
-
-    [TreatReturnedNullStringAs=Null] DOMString    getShaderInfoLog(WebGLShader? shader);
-
-    WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
-
-    [TreatReturnedNullStringAs=Null] DOMString    getShaderSource(WebGLShader? shader);
-
-    [Custom] sequence<DOMString> getSupportedExtensions();
-
-    [Custom] any getTexParameter(GLenum target, GLenum pname);
-
-    [Custom] any getUniform(WebGLProgram? program, WebGLUniformLocation location);
-
-    WebGLUniformLocation getUniformLocation(WebGLProgram? program, DOMString name);
-
-    [Custom] any getVertexAttrib(GLuint index, GLenum pname);
-
-    GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
-
-    void hint(GLenum target, GLenum mode);
-    GLboolean isBuffer(WebGLBuffer? buffer);
-    GLboolean isContextLost();
-    GLboolean isEnabled(GLenum cap);
-    GLboolean isFramebuffer(WebGLFramebuffer? framebuffer);
-    GLboolean isProgram(WebGLProgram? program);
-    GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
-    GLboolean isShader(WebGLShader? shader);
-    GLboolean isTexture(WebGLTexture? texture);
-    void lineWidth(GLfloat width);
-    void linkProgram(WebGLProgram? program);
-    void pixelStorei(GLenum pname, GLint param);
-    void polygonOffset(GLfloat factor, GLfloat units);
-
-    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels);
-
-    void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
-    void sampleCoverage(GLclampf value, GLboolean invert);
-    void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
-    void shaderSource(WebGLShader? shader, DOMString string);
-    void stencilFunc(GLenum func, GLint ref, GLuint mask);
-    void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
-    void stencilMask(GLuint mask);
-    void stencilMaskSeparate(GLenum face, GLuint mask);
-    void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
-    void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
-
-    void texParameterf(GLenum target, GLenum pname, GLfloat param);
-    void texParameteri(GLenum target, GLenum pname, GLint param);
-
-    // Supported forms:
-    [RaisesException] void texImage2D(
-        GLenum target, GLint level, GLenum internalformat,
-        GLsizei width, GLsizei height, GLint border,
-        GLenum format, GLenum type, ArrayBufferView? pixels);
-    [RaisesException] void texImage2D(
-        GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, ImageData? pixels);
-    [RaisesException] void texImage2D(
-        GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, HTMLImageElement? image);
-    [RaisesException] void texImage2D(
-        GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, HTMLCanvasElement? canvas);
-    [RaisesException] void texImage2D(
-        GLenum target, GLint level, GLenum internalformat,
-        GLenum format, GLenum type, HTMLVideoElement? video);
-
-    [RaisesException] void texSubImage2D(
-        GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLsizei width, GLsizei height,
-        GLenum format, GLenum type, ArrayBufferView? pixels);
-    [RaisesException] void texSubImage2D(
-        GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, ImageData? pixels);
-    [RaisesException] void texSubImage2D(
-        GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, HTMLImageElement? image);
-    [RaisesException] void texSubImage2D(
-        GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, HTMLCanvasElement? canvas);
-    [RaisesException] void texSubImage2D(
-        GLenum target, GLint level, GLint xoffset, GLint yoffset,
-        GLenum format, GLenum type, HTMLVideoElement? video);
-
-    void uniform1f(WebGLUniformLocation? location, GLfloat x);
-    [Custom] void uniform1fv(WebGLUniformLocation? location, Float32Array v);
-    void uniform1i(WebGLUniformLocation? location, GLint x);
-    [Custom] void uniform1iv(WebGLUniformLocation? location, Int32Array v);
-    void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
-    [Custom] void uniform2fv(WebGLUniformLocation? location, Float32Array v);
-    void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
-    [Custom] void uniform2iv(WebGLUniformLocation? location, Int32Array v);
-    void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
-    [Custom] void uniform3fv(WebGLUniformLocation? location, Float32Array v);
-    void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
-    [Custom] void uniform3iv(WebGLUniformLocation? location, Int32Array v);
-    void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-    [Custom] void uniform4fv(WebGLUniformLocation? location, Float32Array v);
-    void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
-    [Custom] void uniform4iv(WebGLUniformLocation? location, Int32Array v);
-
-    [Custom] void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
-    [Custom] void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
-    [Custom] void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
-
-    void useProgram(WebGLProgram? program);
-    void validateProgram(WebGLProgram? program);
-
-    void vertexAttrib1f(GLuint indx, GLfloat x);
-    [Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
-    void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
-    [Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
-    void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
-    [Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
-    void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-    [Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
-    void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
-                             GLsizei stride, GLintptr offset);
-
-    void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+interface WebGLRenderingContext : WebGLRenderingContextBase {
 };
diff --git a/Source/core/html/canvas/WebGLRenderingContextBase.cpp b/Source/core/html/canvas/WebGLRenderingContextBase.cpp
new file mode 100644
index 0000000..7a058de
--- /dev/null
+++ b/Source/core/html/canvas/WebGLRenderingContextBase.cpp
@@ -0,0 +1,5568 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
+
+#include "RuntimeEnabledFeatures.h"
+#include "bindings/v8/ExceptionMessages.h"
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/fetch/ImageResource.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLCanvasElement.h"
+#include "core/html/HTMLImageElement.h"
+#include "core/html/HTMLVideoElement.h"
+#include "core/html/ImageData.h"
+#include "core/html/canvas/ANGLEInstancedArrays.h"
+#include "core/html/canvas/EXTFragDepth.h"
+#include "core/html/canvas/EXTTextureFilterAnisotropic.h"
+#include "core/html/canvas/OESElementIndexUint.h"
+#include "core/html/canvas/OESStandardDerivatives.h"
+#include "core/html/canvas/OESTextureFloat.h"
+#include "core/html/canvas/OESTextureFloatLinear.h"
+#include "core/html/canvas/OESTextureHalfFloat.h"
+#include "core/html/canvas/OESTextureHalfFloatLinear.h"
+#include "core/html/canvas/OESVertexArrayObject.h"
+#include "core/html/canvas/WebGLActiveInfo.h"
+#include "core/html/canvas/WebGLBuffer.h"
+#include "core/html/canvas/WebGLCompressedTextureATC.h"
+#include "core/html/canvas/WebGLCompressedTexturePVRTC.h"
+#include "core/html/canvas/WebGLCompressedTextureS3TC.h"
+#include "core/html/canvas/WebGLContextAttributes.h"
+#include "core/html/canvas/WebGLContextEvent.h"
+#include "core/html/canvas/WebGLContextGroup.h"
+#include "core/html/canvas/WebGLDebugRendererInfo.h"
+#include "core/html/canvas/WebGLDebugShaders.h"
+#include "core/html/canvas/WebGLDepthTexture.h"
+#include "core/html/canvas/WebGLDrawBuffers.h"
+#include "core/html/canvas/WebGLFramebuffer.h"
+#include "core/html/canvas/WebGLLoseContext.h"
+#include "core/html/canvas/WebGLProgram.h"
+#include "core/html/canvas/WebGLRenderbuffer.h"
+#include "core/html/canvas/WebGLShader.h"
+#include "core/html/canvas/WebGLShaderPrecisionFormat.h"
+#include "core/html/canvas/WebGLTexture.h"
+#include "core/html/canvas/WebGLUniformLocation.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/rendering/RenderBox.h"
+#include "platform/CheckedInt.h"
+#include "platform/NotImplemented.h"
+#include "platform/geometry/IntSize.h"
+#include "platform/graphics/UnacceleratedImageBufferSurface.h"
+#include "platform/graphics/gpu/DrawingBuffer.h"
+#include "public/platform/Platform.h"
+
+#include "wtf/PassOwnPtr.h"
+#include "wtf/Uint32Array.h"
+#include "wtf/text/StringBuilder.h"
+
+namespace WebCore {
+
+const double secondsBetweenRestoreAttempts = 1.0;
+const int maxGLErrorsAllowedToConsole = 256;
+const unsigned maxGLActiveContexts = 16;
+
+Vector<WebGLRenderingContextBase*>& WebGLRenderingContextBase::activeContexts()
+{
+    DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContextBase*>, activeContexts, ());
+    return activeContexts;
+}
+
+Vector<WebGLRenderingContextBase*>& WebGLRenderingContextBase::forciblyEvictedContexts()
+{
+    DEFINE_STATIC_LOCAL(Vector<WebGLRenderingContextBase*>, forciblyEvictedContexts, ());
+    return forciblyEvictedContexts;
+}
+
+void WebGLRenderingContextBase::forciblyLoseOldestContext(const String& reason)
+{
+    size_t candidateID = oldestContextIndex();
+    if (candidateID >= activeContexts().size())
+        return;
+
+    WebGLRenderingContextBase* candidate = activeContexts()[candidateID];
+
+    activeContexts().remove(candidateID);
+
+    candidate->printWarningToConsole(reason);
+    InspectorInstrumentation::didFireWebGLWarning(candidate->canvas());
+
+    // This will call deactivateContext once the context has actually been lost.
+    candidate->forceLostContext(WebGLRenderingContextBase::SyntheticLostContext);
+}
+
+size_t WebGLRenderingContextBase::oldestContextIndex()
+{
+    if (!activeContexts().size())
+        return maxGLActiveContexts;
+
+    WebGLRenderingContextBase* candidate = activeContexts().first();
+    size_t candidateID = 0;
+    for (size_t ii = 1; ii < activeContexts().size(); ++ii) {
+        WebGLRenderingContextBase* context = activeContexts()[ii];
+        if (context->webGraphicsContext3D() && candidate->webGraphicsContext3D() && context->webGraphicsContext3D()->lastFlushID() < candidate->webGraphicsContext3D()->lastFlushID()) {
+            candidate = context;
+            candidateID = ii;
+        }
+    }
+
+    return candidateID;
+}
+
+IntSize WebGLRenderingContextBase::oldestContextSize()
+{
+    IntSize size;
+
+    size_t candidateID = oldestContextIndex();
+    if (candidateID < activeContexts().size()) {
+        WebGLRenderingContextBase* candidate = activeContexts()[candidateID];
+        size.setWidth(candidate->drawingBufferWidth());
+        size.setHeight(candidate->drawingBufferHeight());
+    }
+
+    return size;
+}
+
+void WebGLRenderingContextBase::activateContext(WebGLRenderingContextBase* context)
+{
+    unsigned removedContexts = 0;
+    while (activeContexts().size() >= maxGLActiveContexts && removedContexts < maxGLActiveContexts) {
+        forciblyLoseOldestContext("WARNING: Too many active WebGL contexts. Oldest context will be lost.");
+        removedContexts++;
+    }
+
+    if (!activeContexts().contains(context))
+        activeContexts().append(context);
+}
+
+void WebGLRenderingContextBase::deactivateContext(WebGLRenderingContextBase* context, bool addToEvictedList)
+{
+    size_t position = activeContexts().find(context);
+    if (position != WTF::kNotFound)
+        activeContexts().remove(position);
+
+    if (addToEvictedList && !forciblyEvictedContexts().contains(context))
+        forciblyEvictedContexts().append(context);
+}
+
+void WebGLRenderingContextBase::willDestroyContext(WebGLRenderingContextBase* context)
+{
+    size_t position = forciblyEvictedContexts().find(context);
+    if (position != WTF::kNotFound)
+        forciblyEvictedContexts().remove(position);
+
+    deactivateContext(context, false);
+
+    // Try to re-enable the oldest inactive contexts.
+    while(activeContexts().size() < maxGLActiveContexts && forciblyEvictedContexts().size()) {
+        WebGLRenderingContextBase* evictedContext = forciblyEvictedContexts().first();
+        if (!evictedContext->m_restoreAllowed) {
+            forciblyEvictedContexts().remove(0);
+            continue;
+        }
+
+        IntSize desiredSize = evictedContext->m_drawingBuffer->adjustSize(evictedContext->clampedCanvasSize());
+
+        // If there's room in the pixel budget for this context, restore it.
+        if (!desiredSize.isEmpty()) {
+            forciblyEvictedContexts().remove(0);
+            evictedContext->forceRestoreContext();
+            activeContexts().append(evictedContext);
+        }
+        break;
+    }
+}
+
+class WebGLRenderingContextEvictionManager : public ContextEvictionManager {
+public:
+    void forciblyLoseOldestContext(const String& reason) {
+        WebGLRenderingContextBase::forciblyLoseOldestContext(reason);
+    };
+    IntSize oldestContextSize() {
+        return WebGLRenderingContextBase::oldestContextSize();
+    };
+};
+
+namespace {
+
+    class ScopedDrawingBufferBinder {
+    public:
+        ScopedDrawingBufferBinder(DrawingBuffer* drawingBuffer, WebGLFramebuffer* framebufferBinding)
+            : m_drawingBuffer(drawingBuffer)
+            , m_framebufferBinding(framebufferBinding)
+        {
+            // Commit DrawingBuffer if needed (e.g., for multisampling)
+            if (!m_framebufferBinding && m_drawingBuffer)
+                m_drawingBuffer->commit();
+        }
+
+        ~ScopedDrawingBufferBinder()
+        {
+            // Restore DrawingBuffer if needed
+            if (!m_framebufferBinding && m_drawingBuffer)
+                m_drawingBuffer->bind();
+        }
+
+    private:
+        DrawingBuffer* m_drawingBuffer;
+        WebGLFramebuffer* m_framebufferBinding;
+    };
+
+    Platform3DObject objectOrZero(WebGLObject* object)
+    {
+        return object ? object->object() : 0;
+    }
+
+    GLint clamp(GLint value, GLint min, GLint max)
+    {
+        if (value < min)
+            value = min;
+        if (value > max)
+            value = max;
+        return value;
+    }
+
+    // Return true if a character belongs to the ASCII subset as defined in
+    // GLSL ES 1.0 spec section 3.1.
+    bool validateCharacter(unsigned char c)
+    {
+        // Printing characters are valid except " $ ` @ \ ' DEL.
+        if (c >= 32 && c <= 126
+            && c != '"' && c != '$' && c != '`' && c != '@' && c != '\\' && c != '\'')
+            return true;
+        // Horizontal tab, line feed, vertical tab, form feed, carriage return
+        // are also valid.
+        if (c >= 9 && c <= 13)
+            return true;
+        return false;
+    }
+
+    bool isPrefixReserved(const String& name)
+    {
+        if (name.startsWith("gl_") || name.startsWith("webgl_") || name.startsWith("_webgl_"))
+            return true;
+        return false;
+    }
+
+    // Strips comments from shader text. This allows non-ASCII characters
+    // to be used in comments without potentially breaking OpenGL
+    // implementations not expecting characters outside the GLSL ES set.
+    class StripComments {
+    public:
+        StripComments(const String& str)
+            : m_parseState(BeginningOfLine)
+            , m_sourceString(str)
+            , m_length(str.length())
+            , m_position(0)
+        {
+            parse();
+        }
+
+        String result()
+        {
+            return m_builder.toString();
+        }
+
+    private:
+        bool hasMoreCharacters() const
+        {
+            return (m_position < m_length);
+        }
+
+        void parse()
+        {
+            while (hasMoreCharacters()) {
+                process(current());
+                // process() might advance the position.
+                if (hasMoreCharacters())
+                    advance();
+            }
+        }
+
+        void process(UChar);
+
+        bool peek(UChar& character) const
+        {
+            if (m_position + 1 >= m_length)
+                return false;
+            character = m_sourceString[m_position + 1];
+            return true;
+        }
+
+        UChar current()
+        {
+            ASSERT_WITH_SECURITY_IMPLICATION(m_position < m_length);
+            return m_sourceString[m_position];
+        }
+
+        void advance()
+        {
+            ++m_position;
+        }
+
+        static bool isNewline(UChar character)
+        {
+            // Don't attempt to canonicalize newline related characters.
+            return (character == '\n' || character == '\r');
+        }
+
+        void emit(UChar character)
+        {
+            m_builder.append(character);
+        }
+
+        enum ParseState {
+            // Have not seen an ASCII non-whitespace character yet on
+            // this line. Possible that we might see a preprocessor
+            // directive.
+            BeginningOfLine,
+
+            // Have seen at least one ASCII non-whitespace character
+            // on this line.
+            MiddleOfLine,
+
+            // Handling a preprocessor directive. Passes through all
+            // characters up to the end of the line. Disables comment
+            // processing.
+            InPreprocessorDirective,
+
+            // Handling a single-line comment. The comment text is
+            // replaced with a single space.
+            InSingleLineComment,
+
+            // Handling a multi-line comment. Newlines are passed
+            // through to preserve line numbers.
+            InMultiLineComment
+        };
+
+        ParseState m_parseState;
+        String m_sourceString;
+        unsigned m_length;
+        unsigned m_position;
+        StringBuilder m_builder;
+    };
+
+    void StripComments::process(UChar c)
+    {
+        if (isNewline(c)) {
+            // No matter what state we are in, pass through newlines
+            // so we preserve line numbers.
+            emit(c);
+
+            if (m_parseState != InMultiLineComment)
+                m_parseState = BeginningOfLine;
+
+            return;
+        }
+
+        UChar temp = 0;
+        switch (m_parseState) {
+        case BeginningOfLine:
+            if (WTF::isASCIISpace(c)) {
+                emit(c);
+                break;
+            }
+
+            if (c == '#') {
+                m_parseState = InPreprocessorDirective;
+                emit(c);
+                break;
+            }
+
+            // Transition to normal state and re-handle character.
+            m_parseState = MiddleOfLine;
+            process(c);
+            break;
+
+        case MiddleOfLine:
+            if (c == '/' && peek(temp)) {
+                if (temp == '/') {
+                    m_parseState = InSingleLineComment;
+                    emit(' ');
+                    advance();
+                    break;
+                }
+
+                if (temp == '*') {
+                    m_parseState = InMultiLineComment;
+                    // Emit the comment start in case the user has
+                    // an unclosed comment and we want to later
+                    // signal an error.
+                    emit('/');
+                    emit('*');
+                    advance();
+                    break;
+                }
+            }
+
+            emit(c);
+            break;
+
+        case InPreprocessorDirective:
+            // No matter what the character is, just pass it
+            // through. Do not parse comments in this state. This
+            // might not be the right thing to do long term, but it
+            // should handle the #error preprocessor directive.
+            emit(c);
+            break;
+
+        case InSingleLineComment:
+            // The newline code at the top of this function takes care
+            // of resetting our state when we get out of the
+            // single-line comment. Swallow all other characters.
+            break;
+
+        case InMultiLineComment:
+            if (c == '*' && peek(temp) && temp == '/') {
+                emit('*');
+                emit('/');
+                m_parseState = MiddleOfLine;
+                advance();
+                break;
+            }
+
+            // Swallow all other characters. Unclear whether we may
+            // want or need to just emit a space per character to try
+            // to preserve column numbers for debugging purposes.
+            break;
+        }
+    }
+} // namespace anonymous
+
+class WebGLRenderingContextLostCallback : public blink::WebGraphicsContext3D::WebGraphicsContextLostCallback {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit WebGLRenderingContextLostCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+    virtual void onContextLost() { m_context->forceLostContext(WebGLRenderingContextBase::RealLostContext); }
+    virtual ~WebGLRenderingContextLostCallback() {}
+private:
+    WebGLRenderingContextBase* m_context;
+};
+
+class WebGLRenderingContextErrorMessageCallback : public blink::WebGraphicsContext3D::WebGraphicsErrorMessageCallback {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    explicit WebGLRenderingContextErrorMessageCallback(WebGLRenderingContextBase* cb) : m_context(cb) { }
+    virtual void onErrorMessage(const blink::WebString& message, blink::WGC3Dint)
+    {
+        if (m_context->m_synthesizedErrorsToConsole)
+            m_context->printGLErrorToConsole(message);
+        InspectorInstrumentation::didFireWebGLErrorOrWarning(m_context->canvas(), message);
+    }
+    virtual ~WebGLRenderingContextErrorMessageCallback() { }
+private:
+    WebGLRenderingContextBase* m_context;
+};
+
+WebGLRenderingContextBase::WebGLRenderingContextBase(HTMLCanvasElement* passedCanvas, PassOwnPtr<blink::WebGraphicsContext3D> context, WebGLContextAttributes* requestedAttributes)
+    : CanvasRenderingContext(passedCanvas)
+    , ActiveDOMObject(&passedCanvas->document())
+    , m_context(context)
+    , m_drawingBuffer(nullptr)
+    , m_dispatchContextLostEventTimer(this, &WebGLRenderingContextBase::dispatchContextLostEvent)
+    , m_restoreAllowed(false)
+    , m_restoreTimer(this, &WebGLRenderingContextBase::maybeRestoreContext)
+    , m_generatedImageCache(4)
+    , m_contextLost(false)
+    , m_contextLostMode(SyntheticLostContext)
+    , m_requestedAttributes(requestedAttributes->clone())
+    , m_synthesizedErrorsToConsole(true)
+    , m_numGLErrorsToConsoleAllowed(maxGLErrorsAllowedToConsole)
+    , m_multisamplingAllowed(false)
+    , m_multisamplingObserverRegistered(false)
+    , m_onePlusMaxEnabledAttribIndex(0)
+    , m_onePlusMaxNonDefaultTextureUnit(0)
+{
+    ASSERT(m_context);
+    ScriptWrappable::init(this);
+
+    m_contextGroup = WebGLContextGroup::create();
+    m_contextGroup->addContext(this);
+
+    m_maxViewportDims[0] = m_maxViewportDims[1] = 0;
+    m_context->getIntegerv(GL_MAX_VIEWPORT_DIMS, m_maxViewportDims);
+
+    RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
+
+    // Create the DrawingBuffer and initialize the platform layer.
+    DrawingBuffer::PreserveDrawingBuffer preserve = requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
+    m_drawingBuffer = DrawingBuffer::create(m_context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
+
+    if (!m_drawingBuffer->isZeroSized()) {
+        m_drawingBuffer->bind();
+        setupFlags();
+        initializeNewContext();
+    }
+}
+
+void WebGLRenderingContextBase::initializeNewContext()
+{
+    ASSERT(!isContextLost());
+    m_needsUpdate = true;
+    m_markedCanvasDirty = false;
+    m_activeTextureUnit = 0;
+    m_packAlignment = 4;
+    m_unpackAlignment = 4;
+    m_unpackFlipY = false;
+    m_unpackPremultiplyAlpha = false;
+    m_unpackColorspaceConversion = GC3D_BROWSER_DEFAULT_WEBGL;
+    m_boundArrayBuffer = nullptr;
+    m_currentProgram = nullptr;
+    m_framebufferBinding = nullptr;
+    m_renderbufferBinding = nullptr;
+    m_depthMask = true;
+    m_stencilEnabled = false;
+    m_stencilMask = 0xFFFFFFFF;
+    m_stencilMaskBack = 0xFFFFFFFF;
+    m_stencilFuncRef = 0;
+    m_stencilFuncRefBack = 0;
+    m_stencilFuncMask = 0xFFFFFFFF;
+    m_stencilFuncMaskBack = 0xFFFFFFFF;
+    m_layerCleared = false;
+    m_numGLErrorsToConsoleAllowed = maxGLErrorsAllowedToConsole;
+
+    m_clearColor[0] = m_clearColor[1] = m_clearColor[2] = m_clearColor[3] = 0;
+    m_scissorEnabled = false;
+    m_clearDepth = 1;
+    m_clearStencil = 0;
+    m_colorMask[0] = m_colorMask[1] = m_colorMask[2] = m_colorMask[3] = true;
+
+    GLint numCombinedTextureImageUnits = 0;
+    m_context->getIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &numCombinedTextureImageUnits);
+    m_textureUnits.clear();
+    m_textureUnits.resize(numCombinedTextureImageUnits);
+
+    GLint numVertexAttribs = 0;
+    m_context->getIntegerv(GL_MAX_VERTEX_ATTRIBS, &numVertexAttribs);
+    m_maxVertexAttribs = numVertexAttribs;
+
+    m_maxTextureSize = 0;
+    m_context->getIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
+    m_maxTextureLevel = WebGLTexture::computeLevelCount(m_maxTextureSize, m_maxTextureSize);
+    m_maxCubeMapTextureSize = 0;
+    m_context->getIntegerv(GL_MAX_CUBE_MAP_TEXTURE_SIZE, &m_maxCubeMapTextureSize);
+    m_maxCubeMapTextureLevel = WebGLTexture::computeLevelCount(m_maxCubeMapTextureSize, m_maxCubeMapTextureSize);
+    m_maxRenderbufferSize = 0;
+    m_context->getIntegerv(GL_MAX_RENDERBUFFER_SIZE, &m_maxRenderbufferSize);
+
+    // These two values from EXT_draw_buffers are lazily queried.
+    m_maxDrawBuffers = 0;
+    m_maxColorAttachments = 0;
+
+    m_backDrawBuffer = GL_BACK;
+
+    m_defaultVertexArrayObject = WebGLVertexArrayObjectOES::create(this, WebGLVertexArrayObjectOES::VaoTypeDefault);
+    addContextObject(m_defaultVertexArrayObject.get());
+    m_boundVertexArrayObject = m_defaultVertexArrayObject;
+
+    m_vertexAttribValue.resize(m_maxVertexAttribs);
+
+    createFallbackBlackTextures1x1();
+
+    m_drawingBuffer->reset(clampedCanvasSize());
+
+    m_context->viewport(0, 0, drawingBufferWidth(), drawingBufferHeight());
+    m_context->scissor(0, 0, drawingBufferWidth(), drawingBufferHeight());
+
+    m_contextLostCallbackAdapter = adoptPtr(new WebGLRenderingContextLostCallback(this));
+    m_errorMessageCallbackAdapter = adoptPtr(new WebGLRenderingContextErrorMessageCallback(this));
+
+    m_context->setContextLostCallback(m_contextLostCallbackAdapter.get());
+    m_context->setErrorMessageCallback(m_errorMessageCallbackAdapter.get());
+
+    // This ensures that the context has a valid "lastFlushID" and won't be mistakenly identified as the "least recently used" context.
+    m_context->flush();
+
+    for (int i = 0; i < WebGLExtensionNameCount; ++i)
+        m_extensionEnabled[i] = false;
+
+    activateContext(this);
+}
+
+void WebGLRenderingContextBase::setupFlags()
+{
+    ASSERT(m_context);
+    if (Page* p = canvas()->document().page()) {
+        m_synthesizedErrorsToConsole = p->settings().webGLErrorsToConsoleEnabled();
+
+        if (!m_multisamplingObserverRegistered && m_requestedAttributes->antialias()) {
+            m_multisamplingAllowed = m_drawingBuffer->multisample();
+            p->addMultisamplingChangedObserver(this);
+            m_multisamplingObserverRegistered = true;
+        }
+    }
+
+    m_isGLES2NPOTStrict = !extensionsUtil()->isExtensionEnabled("GL_OES_texture_npot");
+    m_isDepthStencilSupported = extensionsUtil()->isExtensionEnabled("GL_OES_packed_depth_stencil");
+}
+
+bool WebGLRenderingContextBase::allowPrivilegedExtensions() const
+{
+    if (Page* p = canvas()->document().page())
+        return p->settings().privilegedWebGLExtensionsEnabled();
+    return false;
+}
+
+bool WebGLRenderingContextBase::allowWebGLDebugRendererInfo() const
+{
+    return true;
+}
+
+void WebGLRenderingContextBase::addCompressedTextureFormat(GLenum format)
+{
+    if (!m_compressedTextureFormats.contains(format))
+        m_compressedTextureFormats.append(format);
+}
+
+void WebGLRenderingContextBase::removeAllCompressedTextureFormats()
+{
+    m_compressedTextureFormats.clear();
+}
+
+// Helper function for V8 bindings to identify what version of WebGL a CanvasRenderingContext supports.
+unsigned WebGLRenderingContextBase::getWebGLVersion(const CanvasRenderingContext* context)
+{
+    if (!context->is3d())
+        return 0;
+    return static_cast<const WebGLRenderingContextBase*>(context)->version();
+}
+
+WebGLRenderingContextBase::~WebGLRenderingContextBase()
+{
+    // Remove all references to WebGLObjects so if they are the last reference
+    // they will be freed before the last context is removed from the context group.
+    m_boundArrayBuffer = nullptr;
+    m_defaultVertexArrayObject = nullptr;
+    m_boundVertexArrayObject = nullptr;
+    m_vertexAttrib0Buffer = nullptr;
+    m_currentProgram = nullptr;
+    m_framebufferBinding = nullptr;
+    m_renderbufferBinding = nullptr;
+
+    for (size_t i = 0; i < m_textureUnits.size(); ++i) {
+      m_textureUnits[i].m_texture2DBinding = nullptr;
+      m_textureUnits[i].m_textureCubeMapBinding = nullptr;
+    }
+
+    m_blackTexture2D = nullptr;
+    m_blackTextureCubeMap = nullptr;
+
+    detachAndRemoveAllObjects();
+
+    // release all extensions
+    for (size_t i = 0; i < m_extensions.size(); ++i)
+        delete m_extensions[i];
+
+    // Context must be removed from the group prior to the destruction of the
+    // WebGraphicsContext3D, otherwise shared objects may not be properly deleted.
+    m_contextGroup->removeContext(this);
+
+    destroyContext();
+
+    if (m_multisamplingObserverRegistered) {
+        Page* page = canvas()->document().page();
+        if (page)
+            page->removeMultisamplingChangedObserver(this);
+    }
+
+    willDestroyContext(this);
+}
+
+void WebGLRenderingContextBase::destroyContext()
+{
+    m_contextLost = true;
+
+    // The drawing buffer holds a context reference. It must also be destroyed
+    // in order for the context to be released.
+    m_drawingBuffer->releaseResources();
+
+    m_extensionsUtil.clear();
+
+    if (m_context) {
+        m_context->setContextLostCallback(0);
+        m_context->setErrorMessageCallback(0);
+        m_context.clear();
+    }
+}
+
+void WebGLRenderingContextBase::markContextChanged(ContentChangeType changeType)
+{
+    if (m_framebufferBinding || isContextLost())
+        return;
+
+    m_drawingBuffer->markContentsChanged();
+
+    m_layerCleared = false;
+    RenderBox* renderBox = canvas()->renderBox();
+    if (renderBox && renderBox->hasAcceleratedCompositing()) {
+        m_markedCanvasDirty = true;
+        canvas()->clearCopiedImage();
+        renderBox->contentChanged(changeType);
+    } else {
+        if (!m_markedCanvasDirty) {
+            m_markedCanvasDirty = true;
+            canvas()->didDraw(FloatRect(FloatPoint(0, 0), clampedCanvasSize()));
+        }
+    }
+}
+
+bool WebGLRenderingContextBase::clearIfComposited(GLbitfield mask)
+{
+    if (isContextLost())
+        return false;
+
+    if (!m_drawingBuffer->layerComposited() || m_layerCleared
+        || m_requestedAttributes->preserveDrawingBuffer() || (mask && m_framebufferBinding))
+        return false;
+
+    RefPtr<WebGLContextAttributes> contextAttributes = getContextAttributes();
+
+    // Determine if it's possible to combine the clear the user asked for and this clear.
+    bool combinedClear = mask && !m_scissorEnabled;
+
+    m_context->disable(GL_SCISSOR_TEST);
+    if (combinedClear && (mask & GL_COLOR_BUFFER_BIT))
+        m_context->clearColor(m_colorMask[0] ? m_clearColor[0] : 0,
+                              m_colorMask[1] ? m_clearColor[1] : 0,
+                              m_colorMask[2] ? m_clearColor[2] : 0,
+                              m_colorMask[3] ? m_clearColor[3] : 0);
+    else
+        m_context->clearColor(0, 0, 0, 0);
+    m_context->colorMask(true, true, true, true);
+    GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
+    if (contextAttributes->depth()) {
+        if (!combinedClear || !m_depthMask || !(mask & GL_DEPTH_BUFFER_BIT))
+            m_context->clearDepth(1.0f);
+        clearMask |= GL_DEPTH_BUFFER_BIT;
+        m_context->depthMask(true);
+    }
+    if (contextAttributes->stencil()) {
+        if (combinedClear && (mask & GL_STENCIL_BUFFER_BIT))
+            m_context->clearStencil(m_clearStencil & m_stencilMask);
+        else
+            m_context->clearStencil(0);
+        clearMask |= GL_STENCIL_BUFFER_BIT;
+        m_context->stencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
+    }
+
+    m_drawingBuffer->clearFramebuffers(clearMask);
+
+    restoreStateAfterClear();
+    if (m_framebufferBinding)
+        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+    m_layerCleared = true;
+
+    return combinedClear;
+}
+
+void WebGLRenderingContextBase::restoreStateAfterClear()
+{
+    if (isContextLost())
+        return;
+
+    // Restore the state that the context set.
+    if (m_scissorEnabled)
+        m_context->enable(GL_SCISSOR_TEST);
+    m_context->clearColor(m_clearColor[0], m_clearColor[1],
+                          m_clearColor[2], m_clearColor[3]);
+    m_context->colorMask(m_colorMask[0], m_colorMask[1],
+                         m_colorMask[2], m_colorMask[3]);
+    m_context->clearDepth(m_clearDepth);
+    m_context->clearStencil(m_clearStencil);
+    m_context->stencilMaskSeparate(GL_FRONT, m_stencilMask);
+    m_context->depthMask(m_depthMask);
+}
+
+void WebGLRenderingContextBase::markLayerComposited()
+{
+    if (!isContextLost())
+        m_drawingBuffer->markLayerComposited();
+}
+
+void WebGLRenderingContextBase::paintRenderingResultsToCanvas()
+{
+    if (isContextLost()) {
+        canvas()->clearPresentationCopy();
+        return;
+    }
+
+    if (canvas()->document().printing())
+        canvas()->clearPresentationCopy();
+
+    // Until the canvas is written to by the application, the clear that
+    // happened after it was composited should be ignored by the compositor.
+    if (m_drawingBuffer->layerComposited() && !m_requestedAttributes->preserveDrawingBuffer()) {
+        m_drawingBuffer->paintCompositedResultsToCanvas(canvas()->buffer());
+
+        canvas()->makePresentationCopy();
+    } else
+        canvas()->clearPresentationCopy();
+    clearIfComposited();
+
+    if (!m_markedCanvasDirty && !m_layerCleared)
+        return;
+
+    canvas()->clearCopiedImage();
+    m_markedCanvasDirty = false;
+
+    m_drawingBuffer->commit();
+    if (!(canvas()->buffer())->copyRenderingResultsFromDrawingBuffer(m_drawingBuffer.get())) {
+        canvas()->ensureUnacceleratedImageBuffer();
+        if (canvas()->hasImageBuffer())
+            m_drawingBuffer->paintRenderingResultsToCanvas(canvas()->buffer());
+    }
+
+    if (m_framebufferBinding)
+        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+    else
+        m_drawingBuffer->bind();
+}
+
+PassRefPtr<ImageData> WebGLRenderingContextBase::paintRenderingResultsToImageData()
+{
+    if (isContextLost())
+        return nullptr;
+
+    clearIfComposited();
+    m_drawingBuffer->commit();
+    int width, height;
+    RefPtr<Uint8ClampedArray> imageDataPixels = m_drawingBuffer->paintRenderingResultsToImageData(width, height);
+    if (!imageDataPixels)
+        return nullptr;
+
+    if (m_framebufferBinding)
+        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+    else
+        m_drawingBuffer->bind();
+
+    return ImageData::create(IntSize(width, height), imageDataPixels);
+}
+
+void WebGLRenderingContextBase::reshape(int width, int height)
+{
+    if (isContextLost())
+        return;
+
+    // This is an approximation because at WebGLRenderingContextBase level we don't
+    // know if the underlying FBO uses textures or renderbuffers.
+    GLint maxSize = std::min(m_maxTextureSize, m_maxRenderbufferSize);
+    // Limit drawing buffer size to 4k to avoid memory exhaustion.
+    const int sizeUpperLimit = 4096;
+    maxSize = std::min(maxSize, sizeUpperLimit);
+    GLint maxWidth = std::min(maxSize, m_maxViewportDims[0]);
+    GLint maxHeight = std::min(maxSize, m_maxViewportDims[1]);
+    width = clamp(width, 1, maxWidth);
+    height = clamp(height, 1, maxHeight);
+
+    if (m_needsUpdate) {
+        RenderBox* renderBox = canvas()->renderBox();
+        if (renderBox && renderBox->hasAcceleratedCompositing())
+            renderBox->contentChanged(CanvasChanged);
+        m_needsUpdate = false;
+    }
+
+    // We don't have to mark the canvas as dirty, since the newly created image buffer will also start off
+    // clear (and this matches what reshape will do).
+    m_drawingBuffer->reset(IntSize(width, height));
+    restoreStateAfterClear();
+
+    m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get()));
+    m_context->bindRenderbuffer(GL_RENDERBUFFER, objectOrZero(m_renderbufferBinding.get()));
+    if (m_framebufferBinding)
+        m_context->bindFramebuffer(GL_FRAMEBUFFER, objectOrZero(m_framebufferBinding.get()));
+}
+
+int WebGLRenderingContextBase::drawingBufferWidth() const
+{
+    return m_drawingBuffer->size().width();
+}
+
+int WebGLRenderingContextBase::drawingBufferHeight() const
+{
+    return m_drawingBuffer->size().height();
+}
+
+unsigned WebGLRenderingContextBase::sizeInBytes(GLenum type)
+{
+    switch (type) {
+    case GL_BYTE:
+        return sizeof(GLbyte);
+    case GL_UNSIGNED_BYTE:
+        return sizeof(GLubyte);
+    case GL_SHORT:
+        return sizeof(GLshort);
+    case GL_UNSIGNED_SHORT:
+        return sizeof(GLushort);
+    case GL_INT:
+        return sizeof(GLint);
+    case GL_UNSIGNED_INT:
+        return sizeof(GLuint);
+    case GL_FLOAT:
+        return sizeof(GLfloat);
+    }
+    ASSERT_NOT_REACHED();
+    return 0;
+}
+
+void WebGLRenderingContextBase::activeTexture(GLenum texture)
+{
+    if (isContextLost())
+        return;
+    if (texture - GL_TEXTURE0 >= m_textureUnits.size()) {
+        synthesizeGLError(GL_INVALID_ENUM, "activeTexture", "texture unit out of range");
+        return;
+    }
+    m_activeTextureUnit = texture - GL_TEXTURE0;
+    m_context->activeTexture(texture);
+
+    m_drawingBuffer->setActiveTextureUnit(texture);
+
+}
+
+void WebGLRenderingContextBase::attachShader(WebGLProgram* program, WebGLShader* shader)
+{
+    if (isContextLost() || !validateWebGLObject("attachShader", program) || !validateWebGLObject("attachShader", shader))
+        return;
+    if (!program->attachShader(shader)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "attachShader", "shader attachment already has shader");
+        return;
+    }
+    m_context->attachShader(objectOrZero(program), objectOrZero(shader));
+    shader->onAttached();
+}
+
+void WebGLRenderingContextBase::bindAttribLocation(WebGLProgram* program, GLuint index, const String& name)
+{
+    if (isContextLost() || !validateWebGLObject("bindAttribLocation", program))
+        return;
+    if (!validateLocationLength("bindAttribLocation", name))
+        return;
+    if (!validateString("bindAttribLocation", name))
+        return;
+    if (isPrefixReserved(name)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "bindAttribLocation", "reserved prefix");
+        return;
+    }
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, "bindAttribLocation", "index out of range");
+        return;
+    }
+    m_context->bindAttribLocation(objectOrZero(program), index, name.utf8().data());
+}
+
+bool WebGLRenderingContextBase::checkObjectToBeBound(const char* functionName, WebGLObject* object, bool& deleted)
+{
+    deleted = false;
+    if (isContextLost())
+        return false;
+    if (object) {
+        if (!object->validate(contextGroup(), this)) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "object not from this context");
+            return false;
+        }
+        deleted = !object->object();
+    }
+    return true;
+}
+
+void WebGLRenderingContextBase::bindBuffer(GLenum target, WebGLBuffer* buffer)
+{
+    bool deleted;
+    if (!checkObjectToBeBound("bindBuffer", buffer, deleted))
+        return;
+    if (deleted)
+        buffer = 0;
+    if (buffer && buffer->getTarget() && buffer->getTarget() != target) {
+        synthesizeGLError(GL_INVALID_OPERATION, "bindBuffer", "buffers can not be used with multiple targets");
+        return;
+    }
+    if (target == GL_ARRAY_BUFFER)
+        m_boundArrayBuffer = buffer;
+    else if (target == GL_ELEMENT_ARRAY_BUFFER)
+        m_boundVertexArrayObject->setElementArrayBuffer(buffer);
+    else {
+        synthesizeGLError(GL_INVALID_ENUM, "bindBuffer", "invalid target");
+        return;
+    }
+
+    m_context->bindBuffer(target, objectOrZero(buffer));
+    if (buffer)
+        buffer->setTarget(target);
+}
+
+void WebGLRenderingContextBase::bindFramebuffer(GLenum target, WebGLFramebuffer* buffer)
+{
+    bool deleted;
+    if (!checkObjectToBeBound("bindFramebuffer", buffer, deleted))
+        return;
+    if (deleted)
+        buffer = 0;
+    if (target != GL_FRAMEBUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, "bindFramebuffer", "invalid target");
+        return;
+    }
+    m_framebufferBinding = buffer;
+    m_drawingBuffer->setFramebufferBinding(objectOrZero(m_framebufferBinding.get()));
+    if (!m_framebufferBinding) {
+        // Instead of binding fb 0, bind the drawing buffer.
+        m_drawingBuffer->bind();
+    } else
+        m_context->bindFramebuffer(target, objectOrZero(buffer));
+    if (buffer)
+        buffer->setHasEverBeenBound();
+    applyStencilTest();
+}
+
+void WebGLRenderingContextBase::bindRenderbuffer(GLenum target, WebGLRenderbuffer* renderBuffer)
+{
+    bool deleted;
+    if (!checkObjectToBeBound("bindRenderbuffer", renderBuffer, deleted))
+        return;
+    if (deleted)
+        renderBuffer = 0;
+    if (target != GL_RENDERBUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, "bindRenderbuffer", "invalid target");
+        return;
+    }
+    m_renderbufferBinding = renderBuffer;
+    m_context->bindRenderbuffer(target, objectOrZero(renderBuffer));
+    if (renderBuffer)
+        renderBuffer->setHasEverBeenBound();
+}
+
+void WebGLRenderingContextBase::bindTexture(GLenum target, WebGLTexture* texture)
+{
+    bool deleted;
+    if (!checkObjectToBeBound("bindTexture", texture, deleted))
+        return;
+    if (deleted)
+        texture = 0;
+    if (texture && texture->getTarget() && texture->getTarget() != target) {
+        synthesizeGLError(GL_INVALID_OPERATION, "bindTexture", "textures can not be used with multiple targets");
+        return;
+    }
+    GLint maxLevel = 0;
+    if (target == GL_TEXTURE_2D) {
+        m_textureUnits[m_activeTextureUnit].m_texture2DBinding = texture;
+        maxLevel = m_maxTextureLevel;
+
+        if (!m_activeTextureUnit)
+            m_drawingBuffer->setTexture2DBinding(objectOrZero(texture));
+
+    } else if (target == GL_TEXTURE_CUBE_MAP) {
+        m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding = texture;
+        maxLevel = m_maxCubeMapTextureLevel;
+    } else {
+        synthesizeGLError(GL_INVALID_ENUM, "bindTexture", "invalid target");
+        return;
+    }
+
+    m_context->bindTexture(target, objectOrZero(texture));
+    if (texture) {
+        texture->setTarget(target, maxLevel);
+        m_onePlusMaxNonDefaultTextureUnit = max(m_activeTextureUnit + 1, m_onePlusMaxNonDefaultTextureUnit);
+    } else {
+        // If the disabled index is the current maximum, trace backwards to find the new max enabled texture index
+        if (m_onePlusMaxNonDefaultTextureUnit == m_activeTextureUnit + 1) {
+            findNewMaxNonDefaultTextureUnit();
+        }
+    }
+
+    // Note: previously we used to automatically set the TEXTURE_WRAP_R
+    // repeat mode to CLAMP_TO_EDGE for cube map textures, because OpenGL
+    // ES 2.0 doesn't expose this flag (a bug in the specification) and
+    // otherwise the application has no control over the seams in this
+    // dimension. However, it appears that supporting this properly on all
+    // platforms is fairly involved (will require a HashMap from texture ID
+    // in all ports), and we have not had any complaints, so the logic has
+    // been removed.
+
+}
+
+void WebGLRenderingContextBase::blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha)
+{
+    if (isContextLost())
+        return;
+    m_context->blendColor(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::blendEquation(GLenum mode)
+{
+    if (isContextLost() || !validateBlendEquation("blendEquation", mode))
+        return;
+    m_context->blendEquation(mode);
+}
+
+void WebGLRenderingContextBase::blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha)
+{
+    if (isContextLost() || !validateBlendEquation("blendEquationSeparate", modeRGB) || !validateBlendEquation("blendEquationSeparate", modeAlpha))
+        return;
+    m_context->blendEquationSeparate(modeRGB, modeAlpha);
+}
+
+
+void WebGLRenderingContextBase::blendFunc(GLenum sfactor, GLenum dfactor)
+{
+    if (isContextLost() || !validateBlendFuncFactors("blendFunc", sfactor, dfactor))
+        return;
+    m_context->blendFunc(sfactor, dfactor);
+}
+
+void WebGLRenderingContextBase::blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha)
+{
+    // Note: Alpha does not have the same restrictions as RGB.
+    if (isContextLost() || !validateBlendFuncFactors("blendFuncSeparate", srcRGB, dstRGB))
+        return;
+    m_context->blendFuncSeparate(srcRGB, dstRGB, srcAlpha, dstAlpha);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, long long size, GLenum usage)
+{
+    if (isContextLost())
+        return;
+    WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+    if (!buffer)
+        return;
+    if (size < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size < 0");
+        return;
+    }
+    if (!size) {
+        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "size == 0");
+        return;
+    }
+
+    m_context->bufferData(target, static_cast<GLsizeiptr>(size), 0, usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, ArrayBuffer* data, GLenum usage)
+{
+    if (isContextLost())
+        return;
+    WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+    if (!buffer)
+        return;
+    if (!data) {
+        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
+        return;
+    }
+    m_context->bufferData(target, data->byteLength(), data->data(), usage);
+}
+
+void WebGLRenderingContextBase::bufferData(GLenum target, ArrayBufferView* data, GLenum usage)
+{
+    if (isContextLost())
+        return;
+    WebGLBuffer* buffer = validateBufferDataParameters("bufferData", target, usage);
+    if (!buffer)
+        return;
+    if (!data) {
+        synthesizeGLError(GL_INVALID_VALUE, "bufferData", "no data");
+        return;
+    }
+
+    m_context->bufferData(target, data->byteLength(), data->baseAddress(), usage);
+}
+
+void WebGLRenderingContextBase::bufferSubData(GLenum target, long long offset, ArrayBuffer* data)
+{
+    if (isContextLost())
+        return;
+    WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
+    if (!buffer)
+        return;
+    if (offset < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
+        return;
+    }
+    if (!data)
+        return;
+
+    m_context->bufferSubData(target, static_cast<GLintptr>(offset), data->byteLength(), data->data());
+}
+
+void WebGLRenderingContextBase::bufferSubData(GLenum target, long long offset, ArrayBufferView* data)
+{
+    if (isContextLost())
+        return;
+    WebGLBuffer* buffer = validateBufferDataParameters("bufferSubData", target, GL_STATIC_DRAW);
+    if (!buffer)
+        return;
+    if (offset < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, "bufferSubData", "offset < 0");
+        return;
+    }
+    if (!data)
+        return;
+
+    m_context->bufferSubData(target, static_cast<GLintptr>(offset), data->byteLength(), data->baseAddress());
+}
+
+GLenum WebGLRenderingContextBase::checkFramebufferStatus(GLenum target)
+{
+    if (isContextLost())
+        return GL_FRAMEBUFFER_UNSUPPORTED;
+    if (target != GL_FRAMEBUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, "checkFramebufferStatus", "invalid target");
+        return 0;
+    }
+    if (!m_framebufferBinding || !m_framebufferBinding->object())
+        return GL_FRAMEBUFFER_COMPLETE;
+    const char* reason = "framebuffer incomplete";
+    GLenum result = m_framebufferBinding->checkStatus(&reason);
+    if (result != GL_FRAMEBUFFER_COMPLETE) {
+        emitGLWarning("checkFramebufferStatus", reason);
+        return result;
+    }
+    result = m_context->checkFramebufferStatus(target);
+    return result;
+}
+
+void WebGLRenderingContextBase::clear(GLbitfield mask)
+{
+    if (isContextLost())
+        return;
+    if (mask & ~(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
+        synthesizeGLError(GL_INVALID_VALUE, "clear", "invalid mask");
+        return;
+    }
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
+        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "clear", reason);
+        return;
+    }
+    if (!clearIfComposited(mask))
+        m_context->clear(mask);
+    markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::clearColor(GLfloat r, GLfloat g, GLfloat b, GLfloat a)
+{
+    if (isContextLost())
+        return;
+    if (std::isnan(r))
+        r = 0;
+    if (std::isnan(g))
+        g = 0;
+    if (std::isnan(b))
+        b = 0;
+    if (std::isnan(a))
+        a = 1;
+    m_clearColor[0] = r;
+    m_clearColor[1] = g;
+    m_clearColor[2] = b;
+    m_clearColor[3] = a;
+    m_context->clearColor(r, g, b, a);
+}
+
+void WebGLRenderingContextBase::clearDepth(GLfloat depth)
+{
+    if (isContextLost())
+        return;
+    m_clearDepth = depth;
+    m_context->clearDepth(depth);
+}
+
+void WebGLRenderingContextBase::clearStencil(GLint s)
+{
+    if (isContextLost())
+        return;
+    m_clearStencil = s;
+    m_context->clearStencil(s);
+}
+
+void WebGLRenderingContextBase::colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha)
+{
+    if (isContextLost())
+        return;
+    m_colorMask[0] = red;
+    m_colorMask[1] = green;
+    m_colorMask[2] = blue;
+    m_colorMask[3] = alpha;
+    m_context->colorMask(red, green, blue, alpha);
+}
+
+void WebGLRenderingContextBase::compileShader(WebGLShader* shader)
+{
+    if (isContextLost() || !validateWebGLObject("compileShader", shader))
+        return;
+    m_context->compileShader(objectOrZero(shader));
+}
+
+void WebGLRenderingContextBase::compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data)
+{
+    if (isContextLost())
+        return;
+    if (!validateTexFuncLevel("compressedTexImage2D", target, level))
+        return;
+
+    if (!validateCompressedTexFormat(internalformat)) {
+        synthesizeGLError(GL_INVALID_ENUM, "compressedTexImage2D", "invalid internalformat");
+        return;
+    }
+    if (border) {
+        synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "border not 0");
+        return;
+    }
+    if (!validateCompressedTexDimensions("compressedTexImage2D", NotTexSubImage2D, target, level, width, height, internalformat))
+        return;
+    if (!validateCompressedTexFuncData("compressedTexImage2D", width, height, internalformat, data))
+        return;
+
+    WebGLTexture* tex = validateTextureBinding("compressedTexImage2D", target, true);
+    if (!tex)
+        return;
+    if (!isGLES2NPOTStrict()) {
+        if (level && WebGLTexture::isNPOT(width, height)) {
+            synthesizeGLError(GL_INVALID_VALUE, "compressedTexImage2D", "level > 0 not power of 2");
+            return;
+        }
+    }
+    m_context->compressedTexImage2D(target, level, internalformat, width, height,
+                                              border, data->byteLength(), data->baseAddress());
+    tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
+}
+
+void WebGLRenderingContextBase::compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data)
+{
+    if (isContextLost())
+        return;
+    if (!validateTexFuncLevel("compressedTexSubImage2D", target, level))
+        return;
+    if (!validateCompressedTexFormat(format)) {
+        synthesizeGLError(GL_INVALID_ENUM, "compressedTexSubImage2D", "invalid format");
+        return;
+    }
+    if (!validateCompressedTexFuncData("compressedTexSubImage2D", width, height, format, data))
+        return;
+
+    WebGLTexture* tex = validateTextureBinding("compressedTexSubImage2D", target, true);
+    if (!tex)
+        return;
+
+    if (format != tex->getInternalFormat(target, level)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "compressedTexSubImage2D", "format does not match texture format");
+        return;
+    }
+
+    if (!validateCompressedTexSubDimensions("compressedTexSubImage2D", target, level, xoffset, yoffset, width, height, format, tex))
+        return;
+
+    m_context->compressedTexSubImage2D(target, level, xoffset, yoffset,
+                                                 width, height, format, data->byteLength(), data->baseAddress());
+}
+
+bool WebGLRenderingContextBase::validateSettableTexFormat(const char* functionName, GLenum format)
+{
+    if (WebGLImageConversion::getClearBitsByFormat(format) & (GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT)) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "format can not be set, only rendered to");
+        return false;
+    }
+    return true;
+}
+
+void WebGLRenderingContextBase::copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border)
+{
+    if (isContextLost())
+        return;
+    if (!validateTexFuncParameters("copyTexImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, internalformat, GL_UNSIGNED_BYTE))
+        return;
+    if (!validateSettableTexFormat("copyTexImage2D", internalformat))
+        return;
+    WebGLTexture* tex = validateTextureBinding("copyTexImage2D", target, true);
+    if (!tex)
+        return;
+    if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
+        synthesizeGLError(GL_INVALID_OPERATION, "copyTexImage2D", "framebuffer is incompatible format");
+        return;
+    }
+    if (!isGLES2NPOTStrict() && level && WebGLTexture::isNPOT(width, height)) {
+        synthesizeGLError(GL_INVALID_VALUE, "copyTexImage2D", "level > 0 not power of 2");
+        return;
+    }
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
+        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexImage2D", reason);
+        return;
+    }
+    clearIfComposited();
+    ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+    m_context->copyTexImage2D(target, level, internalformat, x, y, width, height, border);
+    // FIXME: if the framebuffer is not complete, none of the below should be executed.
+    tex->setLevelInfo(target, level, internalformat, width, height, GL_UNSIGNED_BYTE);
+}
+
+void WebGLRenderingContextBase::copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    if (isContextLost())
+        return;
+    if (!validateTexFuncLevel("copyTexSubImage2D", target, level))
+        return;
+    WebGLTexture* tex = validateTextureBinding("copyTexSubImage2D", target, true);
+    if (!tex)
+        return;
+    if (!validateSize("copyTexSubImage2D", xoffset, yoffset) || !validateSize("copyTexSubImage2D", width, height))
+        return;
+    // Before checking if it is in the range, check if overflow happens first.
+    Checked<GLint, RecordOverflow> maxX = xoffset;
+    maxX += width;
+    Checked<GLint, RecordOverflow> maxY = yoffset;
+    maxY += height;
+    if (maxX.hasOverflowed() || maxY.hasOverflowed()) {
+        synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "bad dimensions");
+        return;
+    }
+    if (maxX.unsafeGet() > tex->getWidth(target, level) || maxY.unsafeGet() > tex->getHeight(target, level)) {
+        synthesizeGLError(GL_INVALID_VALUE, "copyTexSubImage2D", "rectangle out of range");
+        return;
+    }
+    GLenum internalformat = tex->getInternalFormat(target, level);
+    if (!validateSettableTexFormat("copyTexSubImage2D", internalformat))
+        return;
+    if (!isTexInternalFormatColorBufferCombinationValid(internalformat, boundFramebufferColorFormat())) {
+        synthesizeGLError(GL_INVALID_OPERATION, "copyTexSubImage2D", "framebuffer is incompatible format");
+        return;
+    }
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
+        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "copyTexSubImage2D", reason);
+        return;
+    }
+    clearIfComposited();
+    ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+    m_context->copyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
+}
+
+PassRefPtr<WebGLBuffer> WebGLRenderingContextBase::createBuffer()
+{
+    if (isContextLost())
+        return nullptr;
+    RefPtr<WebGLBuffer> o = WebGLBuffer::create(this);
+    addSharedObject(o.get());
+    return o;
+}
+
+PassRefPtr<WebGLFramebuffer> WebGLRenderingContextBase::createFramebuffer()
+{
+    if (isContextLost())
+        return nullptr;
+    RefPtr<WebGLFramebuffer> o = WebGLFramebuffer::create(this);
+    addContextObject(o.get());
+    return o;
+}
+
+PassRefPtr<WebGLTexture> WebGLRenderingContextBase::createTexture()
+{
+    if (isContextLost())
+        return nullptr;
+    RefPtr<WebGLTexture> o = WebGLTexture::create(this);
+    addSharedObject(o.get());
+    return o;
+}
+
+PassRefPtr<WebGLProgram> WebGLRenderingContextBase::createProgram()
+{
+    if (isContextLost())
+        return nullptr;
+    RefPtr<WebGLProgram> o = WebGLProgram::create(this);
+    addSharedObject(o.get());
+    return o;
+}
+
+PassRefPtr<WebGLRenderbuffer> WebGLRenderingContextBase::createRenderbuffer()
+{
+    if (isContextLost())
+        return nullptr;
+    RefPtr<WebGLRenderbuffer> o = WebGLRenderbuffer::create(this);
+    addSharedObject(o.get());
+    return o;
+}
+
+WebGLRenderbuffer* WebGLRenderingContextBase::ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer* renderbuffer)
+{
+    if (isContextLost())
+        return 0;
+    if (!renderbuffer->emulatedStencilBuffer()) {
+        renderbuffer->setEmulatedStencilBuffer(createRenderbuffer());
+        m_context->bindRenderbuffer(target, objectOrZero(renderbuffer->emulatedStencilBuffer()));
+        m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+    }
+    return renderbuffer->emulatedStencilBuffer();
+}
+
+PassRefPtr<WebGLShader> WebGLRenderingContextBase::createShader(GLenum type)
+{
+    if (isContextLost())
+        return nullptr;
+    if (type != GL_VERTEX_SHADER && type != GL_FRAGMENT_SHADER) {
+        synthesizeGLError(GL_INVALID_ENUM, "createShader", "invalid shader type");
+        return nullptr;
+    }
+
+    RefPtr<WebGLShader> o = WebGLShader::create(this, type);
+    addSharedObject(o.get());
+    return o;
+}
+
+void WebGLRenderingContextBase::cullFace(GLenum mode)
+{
+    if (isContextLost())
+        return;
+    switch (mode) {
+    case GL_FRONT_AND_BACK:
+    case GL_FRONT:
+    case GL_BACK:
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "cullFace", "invalid mode");
+        return;
+    }
+    m_context->cullFace(mode);
+}
+
+bool WebGLRenderingContextBase::deleteObject(WebGLObject* object)
+{
+    if (isContextLost() || !object)
+        return false;
+    if (!object->validate(contextGroup(), this)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "delete", "object does not belong to this context");
+        return false;
+    }
+    if (object->object()) {
+        // We need to pass in context here because we want
+        // things in this context unbound.
+        object->deleteObject(m_context.get());
+    }
+    return true;
+}
+
+void WebGLRenderingContextBase::deleteBuffer(WebGLBuffer* buffer)
+{
+    if (!deleteObject(buffer))
+        return;
+    if (m_boundArrayBuffer == buffer)
+        m_boundArrayBuffer = nullptr;
+
+    m_boundVertexArrayObject->unbindBuffer(buffer);
+}
+
+void WebGLRenderingContextBase::deleteFramebuffer(WebGLFramebuffer* framebuffer)
+{
+    if (!deleteObject(framebuffer))
+        return;
+    if (framebuffer == m_framebufferBinding) {
+        m_framebufferBinding = nullptr;
+        m_drawingBuffer->setFramebufferBinding(0);
+        // Have to call bindFramebuffer here to bind back to internal fbo.
+        m_drawingBuffer->bind();
+    }
+}
+
+void WebGLRenderingContextBase::deleteProgram(WebGLProgram* program)
+{
+    deleteObject(program);
+    // We don't reset m_currentProgram to 0 here because the deletion of the
+    // current program is delayed.
+}
+
+void WebGLRenderingContextBase::deleteRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+    if (!deleteObject(renderbuffer))
+        return;
+    if (renderbuffer == m_renderbufferBinding)
+        m_renderbufferBinding = nullptr;
+    if (m_framebufferBinding)
+        m_framebufferBinding->removeAttachmentFromBoundFramebuffer(renderbuffer);
+}
+
+void WebGLRenderingContextBase::deleteShader(WebGLShader* shader)
+{
+    deleteObject(shader);
+}
+
+void WebGLRenderingContextBase::deleteTexture(WebGLTexture* texture)
+{
+    if (!deleteObject(texture))
+        return;
+
+    int maxBoundTextureIndex = -1;
+    for (size_t i = 0; i < m_onePlusMaxNonDefaultTextureUnit; ++i) {
+        if (texture == m_textureUnits[i].m_texture2DBinding) {
+            m_textureUnits[i].m_texture2DBinding = nullptr;
+            maxBoundTextureIndex = i;
+            if (!i)
+                m_drawingBuffer->setTexture2DBinding(0);
+        }
+        if (texture == m_textureUnits[i].m_textureCubeMapBinding) {
+            m_textureUnits[i].m_textureCubeMapBinding = nullptr;
+            maxBoundTextureIndex = i;
+        }
+    }
+    if (m_framebufferBinding)
+        m_framebufferBinding->removeAttachmentFromBoundFramebuffer(texture);
+
+    // If the deleted was bound to the the current maximum index, trace backwards to find the new max texture index
+    if (m_onePlusMaxNonDefaultTextureUnit == static_cast<unsigned long>(maxBoundTextureIndex + 1)) {
+        findNewMaxNonDefaultTextureUnit();
+    }
+}
+
+void WebGLRenderingContextBase::depthFunc(GLenum func)
+{
+    if (isContextLost())
+        return;
+    if (!validateStencilOrDepthFunc("depthFunc", func))
+        return;
+    m_context->depthFunc(func);
+}
+
+void WebGLRenderingContextBase::depthMask(GLboolean flag)
+{
+    if (isContextLost())
+        return;
+    m_depthMask = flag;
+    m_context->depthMask(flag);
+}
+
+void WebGLRenderingContextBase::depthRange(GLfloat zNear, GLfloat zFar)
+{
+    if (isContextLost())
+        return;
+    if (zNear > zFar) {
+        synthesizeGLError(GL_INVALID_OPERATION, "depthRange", "zNear > zFar");
+        return;
+    }
+    m_context->depthRange(zNear, zFar);
+}
+
+void WebGLRenderingContextBase::detachShader(WebGLProgram* program, WebGLShader* shader)
+{
+    if (isContextLost() || !validateWebGLObject("detachShader", program) || !validateWebGLObject("detachShader", shader))
+        return;
+    if (!program->detachShader(shader)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "detachShader", "shader not attached");
+        return;
+    }
+    m_context->detachShader(objectOrZero(program), objectOrZero(shader));
+    shader->onDetached(m_context.get());
+}
+
+void WebGLRenderingContextBase::disable(GLenum cap)
+{
+    if (isContextLost() || !validateCapability("disable", cap))
+        return;
+    if (cap == GL_STENCIL_TEST) {
+        m_stencilEnabled = false;
+        applyStencilTest();
+        return;
+    }
+    if (cap == GL_SCISSOR_TEST) {
+        m_scissorEnabled = false;
+        m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+    }
+    m_context->disable(cap);
+}
+
+void WebGLRenderingContextBase::disableVertexAttribArray(GLuint index)
+{
+    if (isContextLost())
+        return;
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, "disableVertexAttribArray", "index out of range");
+        return;
+    }
+
+    WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+    state.enabled = false;
+
+    // If the disabled index is the current maximum, trace backwards to find the new max enabled attrib index
+    if (m_onePlusMaxEnabledAttribIndex == index + 1) {
+        findNewMaxEnabledAttribIndex();
+    }
+
+    m_context->disableVertexAttribArray(index);
+}
+
+bool WebGLRenderingContextBase::validateRenderingState(const char* functionName)
+{
+    if (!m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no valid shader program in use");
+        return false;
+    }
+
+    // Look in each enabled vertex attrib and check if they've been bound to a buffer.
+    for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
+        const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+        if (state.enabled
+            && (!state.bufferBinding || !state.bufferBinding->object())) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, String::format("attribute %d is enabled but has no buffer bound", i).utf8().data());
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateWebGLObject(const char* functionName, WebGLObject* object)
+{
+    if (!object || !object->object()) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no object or object deleted");
+        return false;
+    }
+    if (!object->validate(contextGroup(), this)) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "object does not belong to this context");
+        return false;
+    }
+    return true;
+}
+
+void WebGLRenderingContextBase::drawArrays(GLenum mode, GLint first, GLsizei count)
+{
+    if (!validateDrawArrays("drawArrays", mode, first, count))
+        return;
+
+    clearIfComposited();
+
+    handleTextureCompleteness("drawArrays", true);
+    m_context->drawArrays(mode, first, count);
+    handleTextureCompleteness("drawArrays", false);
+    markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawElements(GLenum mode, GLsizei count, GLenum type, long long offset)
+{
+    if (!validateDrawElements("drawElements", mode, count, type, offset))
+        return;
+
+    clearIfComposited();
+
+    handleTextureCompleteness("drawElements", true);
+    m_context->drawElements(mode, count, type, static_cast<GLintptr>(offset));
+    handleTextureCompleteness("drawElements", false);
+    markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount)
+{
+    if (!validateDrawArrays("drawArraysInstancedANGLE", mode, first, count))
+        return;
+
+    if (!validateDrawInstanced("drawArraysInstancedANGLE", primcount))
+        return;
+
+    clearIfComposited();
+
+    handleTextureCompleteness("drawArraysInstancedANGLE", true);
+    m_context->drawArraysInstancedANGLE(mode, first, count, primcount);
+    handleTextureCompleteness("drawArraysInstancedANGLE", false);
+    markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount)
+{
+    if (!validateDrawElements("drawElementsInstancedANGLE", mode, count, type, offset))
+        return;
+
+    if (!validateDrawInstanced("drawElementsInstancedANGLE", primcount))
+        return;
+
+    clearIfComposited();
+
+    handleTextureCompleteness("drawElementsInstancedANGLE", true);
+    m_context->drawElementsInstancedANGLE(mode, count, type, static_cast<GLintptr>(offset), primcount);
+    handleTextureCompleteness("drawElementsInstancedANGLE", false);
+    markContextChanged(CanvasChanged);
+}
+
+void WebGLRenderingContextBase::enable(GLenum cap)
+{
+    if (isContextLost() || !validateCapability("enable", cap))
+        return;
+    if (cap == GL_STENCIL_TEST) {
+        m_stencilEnabled = true;
+        applyStencilTest();
+        return;
+    }
+    if (cap == GL_SCISSOR_TEST) {
+        m_scissorEnabled = true;
+        m_drawingBuffer->setScissorEnabled(m_scissorEnabled);
+    }
+    m_context->enable(cap);
+}
+
+void WebGLRenderingContextBase::enableVertexAttribArray(GLuint index)
+{
+    if (isContextLost())
+        return;
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, "enableVertexAttribArray", "index out of range");
+        return;
+    }
+
+    WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+    state.enabled = true;
+
+    m_onePlusMaxEnabledAttribIndex = max(index + 1, m_onePlusMaxEnabledAttribIndex);
+
+    m_context->enableVertexAttribArray(index);
+}
+
+void WebGLRenderingContextBase::finish()
+{
+    if (isContextLost())
+        return;
+    m_context->flush(); // Intentionally a flush, not a finish.
+}
+
+void WebGLRenderingContextBase::flush()
+{
+    if (isContextLost())
+        return;
+    m_context->flush();
+}
+
+void WebGLRenderingContextBase::framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer* buffer)
+{
+    if (isContextLost() || !validateFramebufferFuncParameters("framebufferRenderbuffer", target, attachment))
+        return;
+    if (renderbuffertarget != GL_RENDERBUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, "framebufferRenderbuffer", "invalid target");
+        return;
+    }
+    if (buffer && !buffer->validate(contextGroup(), this)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no buffer or buffer not from this context");
+        return;
+    }
+    // Don't allow the default framebuffer to be mutated; all current
+    // implementations use an FBO internally in place of the default
+    // FBO.
+    if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "framebufferRenderbuffer", "no framebuffer bound");
+        return;
+    }
+    Platform3DObject bufferObject = objectOrZero(buffer);
+    switch (attachment) {
+    case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+        if (isDepthStencilSupported() || !buffer) {
+            m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+            m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, bufferObject);
+        } else {
+            WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(renderbuffertarget, buffer);
+            if (!emulatedStencilBuffer) {
+                synthesizeGLError(GL_OUT_OF_MEMORY, "framebufferRenderbuffer", "out of memory");
+                return;
+            }
+            m_context->framebufferRenderbuffer(target, GL_DEPTH_ATTACHMENT, renderbuffertarget, bufferObject);
+            m_context->framebufferRenderbuffer(target, GL_STENCIL_ATTACHMENT, renderbuffertarget, objectOrZero(emulatedStencilBuffer));
+        }
+        break;
+    default:
+        m_context->framebufferRenderbuffer(target, attachment, renderbuffertarget, bufferObject);
+    }
+    m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, buffer);
+    applyStencilTest();
+}
+
+void WebGLRenderingContextBase::framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture* texture, GLint level)
+{
+    if (isContextLost() || !validateFramebufferFuncParameters("framebufferTexture2D", target, attachment))
+        return;
+    if (level) {
+        synthesizeGLError(GL_INVALID_VALUE, "framebufferTexture2D", "level not 0");
+        return;
+    }
+    if (texture && !texture->validate(contextGroup(), this)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no texture or texture not from this context");
+        return;
+    }
+    // Don't allow the default framebuffer to be mutated; all current
+    // implementations use an FBO internally in place of the default
+    // FBO.
+    if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "framebufferTexture2D", "no framebuffer bound");
+        return;
+    }
+    Platform3DObject textureObject = objectOrZero(texture);
+    switch (attachment) {
+    case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+        m_context->framebufferTexture2D(target, GL_DEPTH_ATTACHMENT, textarget, textureObject, level);
+        m_context->framebufferTexture2D(target, GL_STENCIL_ATTACHMENT, textarget, textureObject, level);
+        break;
+    case GL_DEPTH_ATTACHMENT:
+        m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+        break;
+    case GL_STENCIL_ATTACHMENT:
+        m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+        break;
+    default:
+        m_context->framebufferTexture2D(target, attachment, textarget, textureObject, level);
+    }
+    m_framebufferBinding->setAttachmentForBoundFramebuffer(attachment, textarget, texture, level);
+    applyStencilTest();
+}
+
+void WebGLRenderingContextBase::frontFace(GLenum mode)
+{
+    if (isContextLost())
+        return;
+    switch (mode) {
+    case GL_CW:
+    case GL_CCW:
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "frontFace", "invalid mode");
+        return;
+    }
+    m_context->frontFace(mode);
+}
+
+void WebGLRenderingContextBase::generateMipmap(GLenum target)
+{
+    if (isContextLost())
+        return;
+    WebGLTexture* tex = validateTextureBinding("generateMipmap", target, false);
+    if (!tex)
+        return;
+    if (!tex->canGenerateMipmaps()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "generateMipmap", "level 0 not power of 2 or not all the same size");
+        return;
+    }
+    if (!validateSettableTexFormat("generateMipmap", tex->getInternalFormat(target, 0)))
+        return;
+
+    // generateMipmap won't work properly if minFilter is not NEAREST_MIPMAP_LINEAR
+    // on Mac.  Remove the hack once this driver bug is fixed.
+#if OS(MACOSX)
+    bool needToResetMinFilter = false;
+    if (tex->getMinFilter() != GL_NEAREST_MIPMAP_LINEAR) {
+        m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_LINEAR);
+        needToResetMinFilter = true;
+    }
+#endif
+    m_context->generateMipmap(target);
+#if OS(MACOSX)
+    if (needToResetMinFilter)
+        m_context->texParameteri(target, GL_TEXTURE_MIN_FILTER, tex->getMinFilter());
+#endif
+    tex->generateMipmapLevelInfo();
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveAttrib(WebGLProgram* program, GLuint index)
+{
+    if (isContextLost() || !validateWebGLObject("getActiveAttrib", program))
+        return nullptr;
+    blink::WebGraphicsContext3D::ActiveInfo info;
+    if (!m_context->getActiveAttrib(objectOrZero(program), index, info))
+        return nullptr;
+    return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+PassRefPtr<WebGLActiveInfo> WebGLRenderingContextBase::getActiveUniform(WebGLProgram* program, GLuint index)
+{
+    if (isContextLost() || !validateWebGLObject("getActiveUniform", program))
+        return nullptr;
+    blink::WebGraphicsContext3D::ActiveInfo info;
+    if (!m_context->getActiveUniform(objectOrZero(program), index, info))
+        return nullptr;
+    return WebGLActiveInfo::create(info.name, info.type, info.size);
+}
+
+bool WebGLRenderingContextBase::getAttachedShaders(WebGLProgram* program, Vector<RefPtr<WebGLShader> >& shaderObjects)
+{
+    shaderObjects.clear();
+    if (isContextLost() || !validateWebGLObject("getAttachedShaders", program))
+        return false;
+
+    const GLenum shaderType[] = {
+        GL_VERTEX_SHADER,
+        GL_FRAGMENT_SHADER
+    };
+    for (unsigned i = 0; i < sizeof(shaderType) / sizeof(GLenum); ++i) {
+        WebGLShader* shader = program->getAttachedShader(shaderType[i]);
+        if (shader)
+            shaderObjects.append(shader);
+    }
+    return true;
+}
+
+GLint WebGLRenderingContextBase::getAttribLocation(WebGLProgram* program, const String& name)
+{
+    if (isContextLost() || !validateWebGLObject("getAttribLocation", program))
+        return -1;
+    if (!validateLocationLength("getAttribLocation", name))
+        return -1;
+    if (!validateString("getAttribLocation", name))
+        return -1;
+    if (isPrefixReserved(name))
+        return -1;
+    if (!program->linkStatus()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "getAttribLocation", "program not linked");
+        return 0;
+    }
+    return m_context->getAttribLocation(objectOrZero(program), name.utf8().data());
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBufferParameter(GLenum target, GLenum pname)
+{
+    if (isContextLost())
+        return WebGLGetInfo();
+    if (target != GL_ARRAY_BUFFER && target != GL_ELEMENT_ARRAY_BUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid target");
+        return WebGLGetInfo();
+    }
+
+    if (pname != GL_BUFFER_SIZE && pname != GL_BUFFER_USAGE) {
+        synthesizeGLError(GL_INVALID_ENUM, "getBufferParameter", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+
+    GLint value = 0;
+    m_context->getBufferParameteriv(target, pname, &value);
+    if (pname == GL_BUFFER_SIZE)
+        return WebGLGetInfo(value);
+    return WebGLGetInfo(static_cast<unsigned>(value));
+}
+
+PassRefPtr<WebGLContextAttributes> WebGLRenderingContextBase::getContextAttributes()
+{
+    if (isContextLost())
+        return nullptr;
+    // We always need to return a new WebGLContextAttributes object to
+    // prevent the user from mutating any cached version.
+    blink::WebGraphicsContext3D::Attributes attrs = m_context->getContextAttributes();
+    RefPtr<WebGLContextAttributes> attributes = m_requestedAttributes->clone();
+    // Some requested attributes may not be honored, so we need to query the underlying
+    // context/drawing buffer and adjust accordingly.
+    if (m_requestedAttributes->depth() && !attrs.depth)
+        attributes->setDepth(false);
+    if (m_requestedAttributes->stencil() && !attrs.stencil)
+        attributes->setStencil(false);
+    attributes->setAntialias(m_drawingBuffer->multisample());
+    return attributes.release();
+}
+
+GLenum WebGLRenderingContextBase::getError()
+{
+    if (m_lostContextErrors.size()) {
+        GLenum err = m_lostContextErrors.first();
+        m_lostContextErrors.remove(0);
+        return err;
+    }
+
+    if (isContextLost())
+        return GL_NO_ERROR;
+
+    return m_context->getError();
+}
+
+bool WebGLRenderingContextBase::ExtensionTracker::matchesNameWithPrefixes(const String& name) const
+{
+    static const char* const unprefixed[] = { "", 0, };
+
+    const char* const* prefixes = m_prefixes ? m_prefixes : unprefixed;
+    for (; *prefixes; ++prefixes) {
+        String prefixedName = String(*prefixes) + extensionName();
+        if (equalIgnoringCase(prefixedName, name)) {
+            return true;
+        }
+    }
+    return false;
+}
+
+PassRefPtr<WebGLExtension> WebGLRenderingContextBase::getExtension(const String& name)
+{
+    if (isContextLost())
+        return nullptr;
+
+    for (size_t i = 0; i < m_extensions.size(); ++i) {
+        ExtensionTracker* tracker = m_extensions[i];
+        if (tracker->matchesNameWithPrefixes(name)) {
+            if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
+                return nullptr;
+            if (tracker->privileged() && !allowPrivilegedExtensions())
+                return nullptr;
+            if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
+                return nullptr;
+            if (!tracker->supported(this))
+                return nullptr;
+
+            RefPtr<WebGLExtension> extension = tracker->getExtension(this);
+            if (extension)
+                m_extensionEnabled[extension->name()] = true;
+            return extension.release();
+        }
+    }
+
+    return nullptr;
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname)
+{
+    if (isContextLost() || !validateFramebufferFuncParameters("getFramebufferAttachmentParameter", target, attachment))
+        return WebGLGetInfo();
+
+    if (!m_framebufferBinding || !m_framebufferBinding->object()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "getFramebufferAttachmentParameter", "no framebuffer bound");
+        return WebGLGetInfo();
+    }
+
+    WebGLSharedObject* object = m_framebufferBinding->getAttachmentObject(attachment);
+    if (!object) {
+        if (pname == GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)
+            return WebGLGetInfo(GL_NONE);
+        // OpenGL ES 2.0 specifies INVALID_ENUM in this case, while desktop GL
+        // specifies INVALID_OPERATION.
+        synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+
+    ASSERT(object->isTexture() || object->isRenderbuffer());
+    if (object->isTexture()) {
+        switch (pname) {
+        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+            return WebGLGetInfo(GL_TEXTURE);
+        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+            return WebGLGetInfo(PassRefPtr<WebGLTexture>(static_cast<WebGLTexture*>(object)));
+        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
+        case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
+            {
+                GLint value = 0;
+                m_context->getFramebufferAttachmentParameteriv(target, attachment, pname, &value);
+                return WebGLGetInfo(value);
+            }
+        default:
+            synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for texture attachment");
+            return WebGLGetInfo();
+        }
+    } else {
+        switch (pname) {
+        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
+            return WebGLGetInfo(GL_RENDERBUFFER);
+        case GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
+            return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(static_cast<WebGLRenderbuffer*>(object)));
+        default:
+            synthesizeGLError(GL_INVALID_ENUM, "getFramebufferAttachmentParameter", "invalid parameter name for renderbuffer attachment");
+            return WebGLGetInfo();
+        }
+    }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getParameter(GLenum pname)
+{
+    if (isContextLost())
+        return WebGLGetInfo();
+    const int intZero = 0;
+    switch (pname) {
+    case GL_ACTIVE_TEXTURE:
+        return getUnsignedIntParameter(pname);
+    case GL_ALIASED_LINE_WIDTH_RANGE:
+        return getWebGLFloatArrayParameter(pname);
+    case GL_ALIASED_POINT_SIZE_RANGE:
+        return getWebGLFloatArrayParameter(pname);
+    case GL_ALPHA_BITS:
+        return getIntParameter(pname);
+    case GL_ARRAY_BUFFER_BINDING:
+        return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundArrayBuffer));
+    case GL_BLEND:
+        return getBooleanParameter(pname);
+    case GL_BLEND_COLOR:
+        return getWebGLFloatArrayParameter(pname);
+    case GL_BLEND_DST_ALPHA:
+        return getUnsignedIntParameter(pname);
+    case GL_BLEND_DST_RGB:
+        return getUnsignedIntParameter(pname);
+    case GL_BLEND_EQUATION_ALPHA:
+        return getUnsignedIntParameter(pname);
+    case GL_BLEND_EQUATION_RGB:
+        return getUnsignedIntParameter(pname);
+    case GL_BLEND_SRC_ALPHA:
+        return getUnsignedIntParameter(pname);
+    case GL_BLEND_SRC_RGB:
+        return getUnsignedIntParameter(pname);
+    case GL_BLUE_BITS:
+        return getIntParameter(pname);
+    case GL_COLOR_CLEAR_VALUE:
+        return getWebGLFloatArrayParameter(pname);
+    case GL_COLOR_WRITEMASK:
+        return getBooleanArrayParameter(pname);
+    case GL_COMPRESSED_TEXTURE_FORMATS:
+        return WebGLGetInfo(Uint32Array::create(m_compressedTextureFormats.data(), m_compressedTextureFormats.size()));
+    case GL_CULL_FACE:
+        return getBooleanParameter(pname);
+    case GL_CULL_FACE_MODE:
+        return getUnsignedIntParameter(pname);
+    case GL_CURRENT_PROGRAM:
+        return WebGLGetInfo(PassRefPtr<WebGLProgram>(m_currentProgram));
+    case GL_DEPTH_BITS:
+        if (!m_framebufferBinding && !m_requestedAttributes->depth())
+            return WebGLGetInfo(intZero);
+        return getIntParameter(pname);
+    case GL_DEPTH_CLEAR_VALUE:
+        return getFloatParameter(pname);
+    case GL_DEPTH_FUNC:
+        return getUnsignedIntParameter(pname);
+    case GL_DEPTH_RANGE:
+        return getWebGLFloatArrayParameter(pname);
+    case GL_DEPTH_TEST:
+        return getBooleanParameter(pname);
+    case GL_DEPTH_WRITEMASK:
+        return getBooleanParameter(pname);
+    case GL_DITHER:
+        return getBooleanParameter(pname);
+    case GL_ELEMENT_ARRAY_BUFFER_BINDING:
+        return WebGLGetInfo(PassRefPtr<WebGLBuffer>(m_boundVertexArrayObject->boundElementArrayBuffer()));
+    case GL_FRAMEBUFFER_BINDING:
+        return WebGLGetInfo(PassRefPtr<WebGLFramebuffer>(m_framebufferBinding));
+    case GL_FRONT_FACE:
+        return getUnsignedIntParameter(pname);
+    case GL_GENERATE_MIPMAP_HINT:
+        return getUnsignedIntParameter(pname);
+    case GL_GREEN_BITS:
+        return getIntParameter(pname);
+    case GL_LINE_WIDTH:
+        return getFloatParameter(pname);
+    case GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS:
+        return getIntParameter(pname);
+    case GL_MAX_CUBE_MAP_TEXTURE_SIZE:
+        return getIntParameter(pname);
+    case GL_MAX_FRAGMENT_UNIFORM_VECTORS:
+        return getIntParameter(pname);
+    case GL_MAX_RENDERBUFFER_SIZE:
+        return getIntParameter(pname);
+    case GL_MAX_TEXTURE_IMAGE_UNITS:
+        return getIntParameter(pname);
+    case GL_MAX_TEXTURE_SIZE:
+        return getIntParameter(pname);
+    case GL_MAX_VARYING_VECTORS:
+        return getIntParameter(pname);
+    case GL_MAX_VERTEX_ATTRIBS:
+        return getIntParameter(pname);
+    case GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS:
+        return getIntParameter(pname);
+    case GL_MAX_VERTEX_UNIFORM_VECTORS:
+        return getIntParameter(pname);
+    case GL_MAX_VIEWPORT_DIMS:
+        return getWebGLIntArrayParameter(pname);
+    case GL_NUM_SHADER_BINARY_FORMATS:
+        // FIXME: should we always return 0 for this?
+        return getIntParameter(pname);
+    case GL_PACK_ALIGNMENT:
+        return getIntParameter(pname);
+    case GL_POLYGON_OFFSET_FACTOR:
+        return getFloatParameter(pname);
+    case GL_POLYGON_OFFSET_FILL:
+        return getBooleanParameter(pname);
+    case GL_POLYGON_OFFSET_UNITS:
+        return getFloatParameter(pname);
+    case GL_RED_BITS:
+        return getIntParameter(pname);
+    case GL_RENDERBUFFER_BINDING:
+        return WebGLGetInfo(PassRefPtr<WebGLRenderbuffer>(m_renderbufferBinding));
+    case GL_RENDERER:
+        return WebGLGetInfo(String("WebKit WebGL"));
+    case GL_SAMPLE_BUFFERS:
+        return getIntParameter(pname);
+    case GL_SAMPLE_COVERAGE_INVERT:
+        return getBooleanParameter(pname);
+    case GL_SAMPLE_COVERAGE_VALUE:
+        return getFloatParameter(pname);
+    case GL_SAMPLES:
+        return getIntParameter(pname);
+    case GL_SCISSOR_BOX:
+        return getWebGLIntArrayParameter(pname);
+    case GL_SCISSOR_TEST:
+        return getBooleanParameter(pname);
+    case GL_SHADING_LANGUAGE_VERSION:
+        return WebGLGetInfo("WebGL GLSL ES 1.0 (" + String(m_context->getString(GL_SHADING_LANGUAGE_VERSION)) + ")");
+    case GL_STENCIL_BACK_FAIL:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_BACK_FUNC:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_BACK_PASS_DEPTH_FAIL:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_BACK_PASS_DEPTH_PASS:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_BACK_REF:
+        return getIntParameter(pname);
+    case GL_STENCIL_BACK_VALUE_MASK:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_BACK_WRITEMASK:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_BITS:
+        if (!m_framebufferBinding && !m_requestedAttributes->stencil())
+            return WebGLGetInfo(intZero);
+        return getIntParameter(pname);
+    case GL_STENCIL_CLEAR_VALUE:
+        return getIntParameter(pname);
+    case GL_STENCIL_FAIL:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_FUNC:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_PASS_DEPTH_FAIL:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_PASS_DEPTH_PASS:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_REF:
+        return getIntParameter(pname);
+    case GL_STENCIL_TEST:
+        return getBooleanParameter(pname);
+    case GL_STENCIL_VALUE_MASK:
+        return getUnsignedIntParameter(pname);
+    case GL_STENCIL_WRITEMASK:
+        return getUnsignedIntParameter(pname);
+    case GL_SUBPIXEL_BITS:
+        return getIntParameter(pname);
+    case GL_TEXTURE_BINDING_2D:
+        return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_texture2DBinding));
+    case GL_TEXTURE_BINDING_CUBE_MAP:
+        return WebGLGetInfo(PassRefPtr<WebGLTexture>(m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding));
+    case GL_UNPACK_ALIGNMENT:
+        return getIntParameter(pname);
+    case GC3D_UNPACK_FLIP_Y_WEBGL:
+        return WebGLGetInfo(m_unpackFlipY);
+    case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+        return WebGLGetInfo(m_unpackPremultiplyAlpha);
+    case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
+        return WebGLGetInfo(m_unpackColorspaceConversion);
+    case GL_VENDOR:
+        return WebGLGetInfo(String("WebKit"));
+    case GL_VERSION:
+        return WebGLGetInfo("WebGL 1.0 (" + String(m_context->getString(GL_VERSION)) + ")");
+    case GL_VIEWPORT:
+        return getWebGLIntArrayParameter(pname);
+    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+        if (extensionEnabled(OESStandardDerivativesName))
+            return getUnsignedIntParameter(GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES);
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_standard_derivatives not enabled");
+        return WebGLGetInfo();
+    case WebGLDebugRendererInfo::UNMASKED_RENDERER_WEBGL:
+        if (extensionEnabled(WebGLDebugRendererInfoName))
+            return WebGLGetInfo(m_context->getString(GL_RENDERER));
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+        return WebGLGetInfo();
+    case WebGLDebugRendererInfo::UNMASKED_VENDOR_WEBGL:
+        if (extensionEnabled(WebGLDebugRendererInfoName))
+            return WebGLGetInfo(m_context->getString(GL_VENDOR));
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_debug_renderer_info not enabled");
+        return WebGLGetInfo();
+    case GL_VERTEX_ARRAY_BINDING_OES: // OES_vertex_array_object
+        if (extensionEnabled(OESVertexArrayObjectName)) {
+            if (!m_boundVertexArrayObject->isDefaultObject())
+                return WebGLGetInfo(PassRefPtr<WebGLVertexArrayObjectOES>(m_boundVertexArrayObject));
+            return WebGLGetInfo();
+        }
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, OES_vertex_array_object not enabled");
+        return WebGLGetInfo();
+    case GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+        if (extensionEnabled(EXTTextureFilterAnisotropicName))
+            return getUnsignedIntParameter(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT);
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+        return WebGLGetInfo();
+    case GL_MAX_COLOR_ATTACHMENTS_EXT: // EXT_draw_buffers BEGIN
+        if (extensionEnabled(WebGLDrawBuffersName))
+            return WebGLGetInfo(maxColorAttachments());
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+        return WebGLGetInfo();
+    case GL_MAX_DRAW_BUFFERS_EXT:
+        if (extensionEnabled(WebGLDrawBuffersName))
+            return WebGLGetInfo(maxDrawBuffers());
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name, WEBGL_draw_buffers not enabled");
+        return WebGLGetInfo();
+    default:
+        if (extensionEnabled(WebGLDrawBuffersName)
+            && pname >= GL_DRAW_BUFFER0_EXT
+            && pname < static_cast<GLenum>(GL_DRAW_BUFFER0_EXT + maxDrawBuffers())) {
+            GLint value = GL_NONE;
+            if (m_framebufferBinding)
+                value = m_framebufferBinding->getDrawBuffer(pname);
+            else // emulated backbuffer
+                value = m_backDrawBuffer;
+            return WebGLGetInfo(value);
+        }
+        synthesizeGLError(GL_INVALID_ENUM, "getParameter", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getProgramParameter(WebGLProgram* program, GLenum pname)
+{
+    if (isContextLost() || !validateWebGLObject("getProgramParameter", program))
+        return WebGLGetInfo();
+
+    GLint value = 0;
+    switch (pname) {
+    case GL_DELETE_STATUS:
+        return WebGLGetInfo(program->isDeleted());
+    case GL_VALIDATE_STATUS:
+        m_context->getProgramiv(objectOrZero(program), pname, &value);
+        return WebGLGetInfo(static_cast<bool>(value));
+    case GL_LINK_STATUS:
+        return WebGLGetInfo(program->linkStatus());
+    case GL_ATTACHED_SHADERS:
+    case GL_ACTIVE_ATTRIBUTES:
+    case GL_ACTIVE_UNIFORMS:
+        m_context->getProgramiv(objectOrZero(program), pname, &value);
+        return WebGLGetInfo(value);
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "getProgramParameter", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+}
+
+String WebGLRenderingContextBase::getProgramInfoLog(WebGLProgram* program)
+{
+    if (isContextLost())
+        return String();
+    if (!validateWebGLObject("getProgramInfoLog", program))
+        return "";
+    return ensureNotNull(m_context->getProgramInfoLog(objectOrZero(program)));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getRenderbufferParameter(GLenum target, GLenum pname)
+{
+    if (isContextLost())
+        return WebGLGetInfo();
+    if (target != GL_RENDERBUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid target");
+        return WebGLGetInfo();
+    }
+    if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "getRenderbufferParameter", "no renderbuffer bound");
+        return WebGLGetInfo();
+    }
+
+    GLint value = 0;
+    switch (pname) {
+    case GL_RENDERBUFFER_WIDTH:
+    case GL_RENDERBUFFER_HEIGHT:
+    case GL_RENDERBUFFER_RED_SIZE:
+    case GL_RENDERBUFFER_GREEN_SIZE:
+    case GL_RENDERBUFFER_BLUE_SIZE:
+    case GL_RENDERBUFFER_ALPHA_SIZE:
+    case GL_RENDERBUFFER_DEPTH_SIZE:
+        m_context->getRenderbufferParameteriv(target, pname, &value);
+        return WebGLGetInfo(value);
+    case GL_RENDERBUFFER_STENCIL_SIZE:
+        if (m_renderbufferBinding->emulatedStencilBuffer()) {
+            m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding->emulatedStencilBuffer()));
+            m_context->getRenderbufferParameteriv(target, pname, &value);
+            m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+        } else {
+            m_context->getRenderbufferParameteriv(target, pname, &value);
+        }
+        return WebGLGetInfo(value);
+    case GL_RENDERBUFFER_INTERNAL_FORMAT:
+        return WebGLGetInfo(m_renderbufferBinding->internalFormat());
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "getRenderbufferParameter", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getShaderParameter(WebGLShader* shader, GLenum pname)
+{
+    if (isContextLost() || !validateWebGLObject("getShaderParameter", shader))
+        return WebGLGetInfo();
+    GLint value = 0;
+    switch (pname) {
+    case GL_DELETE_STATUS:
+        return WebGLGetInfo(shader->isDeleted());
+    case GL_COMPILE_STATUS:
+        m_context->getShaderiv(objectOrZero(shader), pname, &value);
+        return WebGLGetInfo(static_cast<bool>(value));
+    case GL_SHADER_TYPE:
+        m_context->getShaderiv(objectOrZero(shader), pname, &value);
+        return WebGLGetInfo(static_cast<unsigned>(value));
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "getShaderParameter", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+}
+
+String WebGLRenderingContextBase::getShaderInfoLog(WebGLShader* shader)
+{
+    if (isContextLost())
+        return String();
+    if (!validateWebGLObject("getShaderInfoLog", shader))
+        return "";
+    return ensureNotNull(m_context->getShaderInfoLog(objectOrZero(shader)));
+}
+
+PassRefPtr<WebGLShaderPrecisionFormat> WebGLRenderingContextBase::getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType)
+{
+    if (isContextLost())
+        return nullptr;
+    switch (shaderType) {
+    case GL_VERTEX_SHADER:
+    case GL_FRAGMENT_SHADER:
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid shader type");
+        return nullptr;
+    }
+    switch (precisionType) {
+    case GL_LOW_FLOAT:
+    case GL_MEDIUM_FLOAT:
+    case GL_HIGH_FLOAT:
+    case GL_LOW_INT:
+    case GL_MEDIUM_INT:
+    case GL_HIGH_INT:
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "getShaderPrecisionFormat", "invalid precision type");
+        return nullptr;
+    }
+
+    GLint range[2] = {0, 0};
+    GLint precision = 0;
+    m_context->getShaderPrecisionFormat(shaderType, precisionType, range, &precision);
+    return WebGLShaderPrecisionFormat::create(range[0], range[1], precision);
+}
+
+String WebGLRenderingContextBase::getShaderSource(WebGLShader* shader)
+{
+    if (isContextLost())
+        return String();
+    if (!validateWebGLObject("getShaderSource", shader))
+        return "";
+    return ensureNotNull(shader->source());
+}
+
+Vector<String> WebGLRenderingContextBase::getSupportedExtensions()
+{
+    Vector<String> result;
+    if (isContextLost())
+        return result;
+
+    for (size_t i = 0; i < m_extensions.size(); ++i) {
+        ExtensionTracker* tracker = m_extensions[i];
+        if (tracker->webglDebugRendererInfo() && !allowWebGLDebugRendererInfo())
+            continue;
+        if (tracker->privileged() && !allowPrivilegedExtensions())
+            continue;
+        if (tracker->draft() && !RuntimeEnabledFeatures::webGLDraftExtensionsEnabled())
+            continue;
+        if (tracker->supported(this))
+            result.append(String(tracker->prefixed()  ? "WEBKIT_" : "") + tracker->extensionName());
+    }
+
+    return result;
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getTexParameter(GLenum target, GLenum pname)
+{
+    if (isContextLost())
+        return WebGLGetInfo();
+    WebGLTexture* tex = validateTextureBinding("getTexParameter", target, false);
+    if (!tex)
+        return WebGLGetInfo();
+    switch (pname) {
+    case GL_TEXTURE_MAG_FILTER:
+    case GL_TEXTURE_MIN_FILTER:
+    case GL_TEXTURE_WRAP_S:
+    case GL_TEXTURE_WRAP_T:
+        {
+            GLint value = 0;
+            m_context->getTexParameteriv(target, pname, &value);
+            return WebGLGetInfo(static_cast<unsigned>(value));
+        }
+    case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+        if (extensionEnabled(EXTTextureFilterAnisotropicName)) {
+            GLfloat value = 0.f;
+            m_context->getTexParameterfv(target, pname, &value);
+            return WebGLGetInfo(value);
+        }
+        synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name, EXT_texture_filter_anisotropic not enabled");
+        return WebGLGetInfo();
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "getTexParameter", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getUniform(WebGLProgram* program, const WebGLUniformLocation* uniformLocation)
+{
+    if (isContextLost() || !validateWebGLObject("getUniform", program))
+        return WebGLGetInfo();
+    if (!uniformLocation || uniformLocation->program() != program) {
+        synthesizeGLError(GL_INVALID_OPERATION, "getUniform", "no uniformlocation or not valid for this program");
+        return WebGLGetInfo();
+    }
+    GLint location = uniformLocation->location();
+
+    // FIXME: make this more efficient using WebGLUniformLocation and caching types in it
+    GLint activeUniforms = 0;
+    m_context->getProgramiv(objectOrZero(program), GL_ACTIVE_UNIFORMS, &activeUniforms);
+    for (GLint i = 0; i < activeUniforms; i++) {
+        blink::WebGraphicsContext3D::ActiveInfo info;
+        if (!m_context->getActiveUniform(objectOrZero(program), i, info))
+            return WebGLGetInfo();
+        String name = info.name;
+        StringBuilder nameBuilder;
+        // Strip "[0]" from the name if it's an array.
+        if (info.size > 1 && name.endsWith("[0]"))
+            info.name = name.left(name.length() - 3);
+        // If it's an array, we need to iterate through each element, appending "[index]" to the name.
+        for (GLint index = 0; index < info.size; ++index) {
+            nameBuilder.clear();
+            nameBuilder.append(info.name);
+            if (info.size > 1 && index >= 1) {
+                nameBuilder.append('[');
+                nameBuilder.append(String::number(index));
+                nameBuilder.append(']');
+            }
+            // Now need to look this up by name again to find its location
+            GLint loc = m_context->getUniformLocation(objectOrZero(program), nameBuilder.toString().utf8().data());
+            if (loc == location) {
+                // Found it. Use the type in the ActiveInfo to determine the return type.
+                GLenum baseType;
+                unsigned length;
+                switch (info.type) {
+                case GL_BOOL:
+                    baseType = GL_BOOL;
+                    length = 1;
+                    break;
+                case GL_BOOL_VEC2:
+                    baseType = GL_BOOL;
+                    length = 2;
+                    break;
+                case GL_BOOL_VEC3:
+                    baseType = GL_BOOL;
+                    length = 3;
+                    break;
+                case GL_BOOL_VEC4:
+                    baseType = GL_BOOL;
+                    length = 4;
+                    break;
+                case GL_INT:
+                    baseType = GL_INT;
+                    length = 1;
+                    break;
+                case GL_INT_VEC2:
+                    baseType = GL_INT;
+                    length = 2;
+                    break;
+                case GL_INT_VEC3:
+                    baseType = GL_INT;
+                    length = 3;
+                    break;
+                case GL_INT_VEC4:
+                    baseType = GL_INT;
+                    length = 4;
+                    break;
+                case GL_FLOAT:
+                    baseType = GL_FLOAT;
+                    length = 1;
+                    break;
+                case GL_FLOAT_VEC2:
+                    baseType = GL_FLOAT;
+                    length = 2;
+                    break;
+                case GL_FLOAT_VEC3:
+                    baseType = GL_FLOAT;
+                    length = 3;
+                    break;
+                case GL_FLOAT_VEC4:
+                    baseType = GL_FLOAT;
+                    length = 4;
+                    break;
+                case GL_FLOAT_MAT2:
+                    baseType = GL_FLOAT;
+                    length = 4;
+                    break;
+                case GL_FLOAT_MAT3:
+                    baseType = GL_FLOAT;
+                    length = 9;
+                    break;
+                case GL_FLOAT_MAT4:
+                    baseType = GL_FLOAT;
+                    length = 16;
+                    break;
+                case GL_SAMPLER_2D:
+                case GL_SAMPLER_CUBE:
+                    baseType = GL_INT;
+                    length = 1;
+                    break;
+                default:
+                    // Can't handle this type
+                    synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unhandled type");
+                    return WebGLGetInfo();
+                }
+                switch (baseType) {
+                case GL_FLOAT: {
+                    GLfloat value[16] = {0};
+                    m_context->getUniformfv(objectOrZero(program), location, value);
+                    if (length == 1)
+                        return WebGLGetInfo(value[0]);
+                    return WebGLGetInfo(Float32Array::create(value, length));
+                }
+                case GL_INT: {
+                    GLint value[4] = {0};
+                    m_context->getUniformiv(objectOrZero(program), location, value);
+                    if (length == 1)
+                        return WebGLGetInfo(value[0]);
+                    return WebGLGetInfo(Int32Array::create(value, length));
+                }
+                case GL_BOOL: {
+                    GLint value[4] = {0};
+                    m_context->getUniformiv(objectOrZero(program), location, value);
+                    if (length > 1) {
+                        bool boolValue[16] = {0};
+                        for (unsigned j = 0; j < length; j++)
+                            boolValue[j] = static_cast<bool>(value[j]);
+                        return WebGLGetInfo(boolValue, length);
+                    }
+                    return WebGLGetInfo(static_cast<bool>(value[0]));
+                }
+                default:
+                    notImplemented();
+                }
+            }
+        }
+    }
+    // If we get here, something went wrong in our unfortunately complex logic above
+    synthesizeGLError(GL_INVALID_VALUE, "getUniform", "unknown error");
+    return WebGLGetInfo();
+}
+
+PassRefPtr<WebGLUniformLocation> WebGLRenderingContextBase::getUniformLocation(WebGLProgram* program, const String& name)
+{
+    if (isContextLost() || !validateWebGLObject("getUniformLocation", program))
+        return nullptr;
+    if (!validateLocationLength("getUniformLocation", name))
+        return nullptr;
+    if (!validateString("getUniformLocation", name))
+        return nullptr;
+    if (isPrefixReserved(name))
+        return nullptr;
+    if (!program->linkStatus()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "getUniformLocation", "program not linked");
+        return nullptr;
+    }
+    GLint uniformLocation = m_context->getUniformLocation(objectOrZero(program), name.utf8().data());
+    if (uniformLocation == -1)
+        return nullptr;
+    return WebGLUniformLocation::create(program, uniformLocation);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getVertexAttrib(GLuint index, GLenum pname)
+{
+    if (isContextLost())
+        return WebGLGetInfo();
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, "getVertexAttrib", "index out of range");
+        return WebGLGetInfo();
+    }
+    const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(index);
+
+    if (extensionEnabled(ANGLEInstancedArraysName) && pname == GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ANGLE)
+        return WebGLGetInfo(state.divisor);
+
+    switch (pname) {
+    case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING:
+        if (!state.bufferBinding || !state.bufferBinding->object())
+            return WebGLGetInfo();
+        return WebGLGetInfo(PassRefPtr<WebGLBuffer>(state.bufferBinding));
+    case GL_VERTEX_ATTRIB_ARRAY_ENABLED:
+        return WebGLGetInfo(state.enabled);
+    case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED:
+        return WebGLGetInfo(state.normalized);
+    case GL_VERTEX_ATTRIB_ARRAY_SIZE:
+        return WebGLGetInfo(state.size);
+    case GL_VERTEX_ATTRIB_ARRAY_STRIDE:
+        return WebGLGetInfo(state.originalStride);
+    case GL_VERTEX_ATTRIB_ARRAY_TYPE:
+        return WebGLGetInfo(state.type);
+    case GL_CURRENT_VERTEX_ATTRIB:
+        return WebGLGetInfo(Float32Array::create(m_vertexAttribValue[index].value, 4));
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "getVertexAttrib", "invalid parameter name");
+        return WebGLGetInfo();
+    }
+}
+
+long long WebGLRenderingContextBase::getVertexAttribOffset(GLuint index, GLenum pname)
+{
+    if (isContextLost())
+        return 0;
+    if (pname != GL_VERTEX_ATTRIB_ARRAY_POINTER) {
+        synthesizeGLError(GL_INVALID_ENUM, "getVertexAttribOffset", "invalid parameter name");
+        return 0;
+    }
+    GLsizeiptr result = m_context->getVertexAttribOffset(index, pname);
+    return static_cast<long long>(result);
+}
+
+void WebGLRenderingContextBase::hint(GLenum target, GLenum mode)
+{
+    if (isContextLost())
+        return;
+    bool isValid = false;
+    switch (target) {
+    case GL_GENERATE_MIPMAP_HINT:
+        isValid = true;
+        break;
+    case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_OES: // OES_standard_derivatives
+        if (extensionEnabled(OESStandardDerivativesName))
+            isValid = true;
+        break;
+    }
+    if (!isValid) {
+        synthesizeGLError(GL_INVALID_ENUM, "hint", "invalid target");
+        return;
+    }
+    m_context->hint(target, mode);
+}
+
+GLboolean WebGLRenderingContextBase::isBuffer(WebGLBuffer* buffer)
+{
+    if (!buffer || isContextLost())
+        return 0;
+
+    if (!buffer->hasEverBeenBound())
+        return 0;
+
+    return m_context->isBuffer(buffer->object());
+}
+
+bool WebGLRenderingContextBase::isContextLost()
+{
+    return m_contextLost;
+}
+
+GLboolean WebGLRenderingContextBase::isEnabled(GLenum cap)
+{
+    if (isContextLost() || !validateCapability("isEnabled", cap))
+        return 0;
+    if (cap == GL_STENCIL_TEST)
+        return m_stencilEnabled;
+    return m_context->isEnabled(cap);
+}
+
+GLboolean WebGLRenderingContextBase::isFramebuffer(WebGLFramebuffer* framebuffer)
+{
+    if (!framebuffer || isContextLost())
+        return 0;
+
+    if (!framebuffer->hasEverBeenBound())
+        return 0;
+
+    return m_context->isFramebuffer(framebuffer->object());
+}
+
+GLboolean WebGLRenderingContextBase::isProgram(WebGLProgram* program)
+{
+    if (!program || isContextLost())
+        return 0;
+
+    return m_context->isProgram(program->object());
+}
+
+GLboolean WebGLRenderingContextBase::isRenderbuffer(WebGLRenderbuffer* renderbuffer)
+{
+    if (!renderbuffer || isContextLost())
+        return 0;
+
+    if (!renderbuffer->hasEverBeenBound())
+        return 0;
+
+    return m_context->isRenderbuffer(renderbuffer->object());
+}
+
+GLboolean WebGLRenderingContextBase::isShader(WebGLShader* shader)
+{
+    if (!shader || isContextLost())
+        return 0;
+
+    return m_context->isShader(shader->object());
+}
+
+GLboolean WebGLRenderingContextBase::isTexture(WebGLTexture* texture)
+{
+    if (!texture || isContextLost())
+        return 0;
+
+    if (!texture->hasEverBeenBound())
+        return 0;
+
+    return m_context->isTexture(texture->object());
+}
+
+void WebGLRenderingContextBase::lineWidth(GLfloat width)
+{
+    if (isContextLost())
+        return;
+    m_context->lineWidth(width);
+}
+
+void WebGLRenderingContextBase::linkProgram(WebGLProgram* program)
+{
+    if (isContextLost() || !validateWebGLObject("linkProgram", program))
+        return;
+
+    m_context->linkProgram(objectOrZero(program));
+    program->increaseLinkCount();
+}
+
+void WebGLRenderingContextBase::pixelStorei(GLenum pname, GLint param)
+{
+    if (isContextLost())
+        return;
+    switch (pname) {
+    case GC3D_UNPACK_FLIP_Y_WEBGL:
+        m_unpackFlipY = param;
+        break;
+    case GC3D_UNPACK_PREMULTIPLY_ALPHA_WEBGL:
+        m_unpackPremultiplyAlpha = param;
+        break;
+    case GC3D_UNPACK_COLORSPACE_CONVERSION_WEBGL:
+        if (static_cast<GLenum>(param) == GC3D_BROWSER_DEFAULT_WEBGL || param == GL_NONE) {
+            m_unpackColorspaceConversion = static_cast<GLenum>(param);
+        } else {
+            synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for UNPACK_COLORSPACE_CONVERSION_WEBGL");
+            return;
+        }
+        break;
+    case GL_PACK_ALIGNMENT:
+    case GL_UNPACK_ALIGNMENT:
+        if (param == 1 || param == 2 || param == 4 || param == 8) {
+            if (pname == GL_PACK_ALIGNMENT) {
+                m_packAlignment = param;
+                m_drawingBuffer->setPackAlignment(param);
+            } else { // GL_UNPACK_ALIGNMENT:
+                m_unpackAlignment = param;
+            }
+            m_context->pixelStorei(pname, param);
+        } else {
+            synthesizeGLError(GL_INVALID_VALUE, "pixelStorei", "invalid parameter for alignment");
+            return;
+        }
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "pixelStorei", "invalid parameter name");
+        return;
+    }
+}
+
+void WebGLRenderingContextBase::polygonOffset(GLfloat factor, GLfloat units)
+{
+    if (isContextLost())
+        return;
+    m_context->polygonOffset(factor, units);
+}
+
+void WebGLRenderingContextBase::readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels)
+{
+    if (isContextLost())
+        return;
+    // Due to WebGL's same-origin restrictions, it is not possible to
+    // taint the origin using the WebGL API.
+    ASSERT(canvas()->originClean());
+    // Validate input parameters.
+    if (!pixels) {
+        synthesizeGLError(GL_INVALID_VALUE, "readPixels", "no destination ArrayBufferView");
+        return;
+    }
+    switch (format) {
+    case GL_ALPHA:
+    case GL_RGB:
+    case GL_RGBA:
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid format");
+        return;
+    }
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_UNSIGNED_SHORT_5_6_5:
+    case GL_UNSIGNED_SHORT_4_4_4_4:
+    case GL_UNSIGNED_SHORT_5_5_5_1:
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "readPixels", "invalid type");
+        return;
+    }
+    if (format != GL_RGBA || type != GL_UNSIGNED_BYTE) {
+        synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "format not RGBA or type not UNSIGNED_BYTE");
+        return;
+    }
+    // Validate array type against pixel type.
+    if (pixels->type() != ArrayBufferView::TypeUint8) {
+        synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not Uint8Array");
+        return;
+    }
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
+        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, "readPixels", reason);
+        return;
+    }
+    // Calculate array size, taking into consideration of PACK_ALIGNMENT.
+    unsigned totalBytesRequired = 0;
+    unsigned padding = 0;
+    GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_packAlignment, &totalBytesRequired, &padding);
+    if (error != GL_NO_ERROR) {
+        synthesizeGLError(error, "readPixels", "invalid dimensions");
+        return;
+    }
+    if (pixels->byteLength() < totalBytesRequired) {
+        synthesizeGLError(GL_INVALID_OPERATION, "readPixels", "ArrayBufferView not large enough for dimensions");
+        return;
+    }
+
+    clearIfComposited();
+    void* data = pixels->baseAddress();
+
+    {
+        ScopedDrawingBufferBinder binder(m_drawingBuffer.get(), m_framebufferBinding.get());
+        m_context->readPixels(x, y, width, height, format, type, data);
+    }
+
+#if OS(MACOSX)
+    // FIXME: remove this section when GL driver bug on Mac is fixed, i.e.,
+    // when alpha is off, readPixels should set alpha to 255 instead of 0.
+    if (!m_framebufferBinding && !m_context->getContextAttributes().alpha) {
+        unsigned char* pixels = reinterpret_cast<unsigned char*>(data);
+        for (GLsizei iy = 0; iy < height; ++iy) {
+            for (GLsizei ix = 0; ix < width; ++ix) {
+                pixels[3] = 255;
+                pixels += 4;
+            }
+            pixels += padding;
+        }
+    }
+#endif
+}
+
+void WebGLRenderingContextBase::renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height)
+{
+    if (isContextLost())
+        return;
+    if (target != GL_RENDERBUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid target");
+        return;
+    }
+    if (!m_renderbufferBinding || !m_renderbufferBinding->object()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "renderbufferStorage", "no bound renderbuffer");
+        return;
+    }
+    if (!validateSize("renderbufferStorage", width, height))
+        return;
+    switch (internalformat) {
+    case GL_DEPTH_COMPONENT16:
+    case GL_RGBA4:
+    case GL_RGB5_A1:
+    case GL_RGB565:
+    case GL_STENCIL_INDEX8:
+        m_context->renderbufferStorage(target, internalformat, width, height);
+        m_renderbufferBinding->setInternalFormat(internalformat);
+        m_renderbufferBinding->setSize(width, height);
+        m_renderbufferBinding->deleteEmulatedStencilBuffer(m_context.get());
+        break;
+    case GL_DEPTH_STENCIL_OES:
+        if (isDepthStencilSupported()) {
+            m_context->renderbufferStorage(target, GL_DEPTH24_STENCIL8_OES, width, height);
+        } else {
+            WebGLRenderbuffer* emulatedStencilBuffer = ensureEmulatedStencilBuffer(target, m_renderbufferBinding.get());
+            if (!emulatedStencilBuffer) {
+                synthesizeGLError(GL_OUT_OF_MEMORY, "renderbufferStorage", "out of memory");
+                return;
+            }
+            m_context->renderbufferStorage(target, GL_DEPTH_COMPONENT16, width, height);
+            m_context->bindRenderbuffer(target, objectOrZero(emulatedStencilBuffer));
+            m_context->renderbufferStorage(target, GL_STENCIL_INDEX8, width, height);
+            m_context->bindRenderbuffer(target, objectOrZero(m_renderbufferBinding.get()));
+            emulatedStencilBuffer->setSize(width, height);
+            emulatedStencilBuffer->setInternalFormat(GL_STENCIL_INDEX8);
+        }
+        m_renderbufferBinding->setSize(width, height);
+        m_renderbufferBinding->setInternalFormat(internalformat);
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "renderbufferStorage", "invalid internalformat");
+        return;
+    }
+    applyStencilTest();
+}
+
+void WebGLRenderingContextBase::sampleCoverage(GLfloat value, GLboolean invert)
+{
+    if (isContextLost())
+        return;
+    m_context->sampleCoverage(value, invert);
+}
+
+void WebGLRenderingContextBase::scissor(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    if (isContextLost())
+        return;
+    if (!validateSize("scissor", width, height))
+        return;
+    m_context->scissor(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::shaderSource(WebGLShader* shader, const String& string)
+{
+    if (isContextLost() || !validateWebGLObject("shaderSource", shader))
+        return;
+    String stringWithoutComments = StripComments(string).result();
+    if (!validateString("shaderSource", stringWithoutComments))
+        return;
+    shader->setSource(string);
+    m_context->shaderSource(objectOrZero(shader), stringWithoutComments.utf8().data());
+}
+
+void WebGLRenderingContextBase::stencilFunc(GLenum func, GLint ref, GLuint mask)
+{
+    if (isContextLost())
+        return;
+    if (!validateStencilOrDepthFunc("stencilFunc", func))
+        return;
+    m_stencilFuncRef = ref;
+    m_stencilFuncRefBack = ref;
+    m_stencilFuncMask = mask;
+    m_stencilFuncMaskBack = mask;
+    m_context->stencilFunc(func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask)
+{
+    if (isContextLost())
+        return;
+    if (!validateStencilOrDepthFunc("stencilFuncSeparate", func))
+        return;
+    switch (face) {
+    case GL_FRONT_AND_BACK:
+        m_stencilFuncRef = ref;
+        m_stencilFuncRefBack = ref;
+        m_stencilFuncMask = mask;
+        m_stencilFuncMaskBack = mask;
+        break;
+    case GL_FRONT:
+        m_stencilFuncRef = ref;
+        m_stencilFuncMask = mask;
+        break;
+    case GL_BACK:
+        m_stencilFuncRefBack = ref;
+        m_stencilFuncMaskBack = mask;
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "stencilFuncSeparate", "invalid face");
+        return;
+    }
+    m_context->stencilFuncSeparate(face, func, ref, mask);
+}
+
+void WebGLRenderingContextBase::stencilMask(GLuint mask)
+{
+    if (isContextLost())
+        return;
+    m_stencilMask = mask;
+    m_stencilMaskBack = mask;
+    m_context->stencilMask(mask);
+}
+
+void WebGLRenderingContextBase::stencilMaskSeparate(GLenum face, GLuint mask)
+{
+    if (isContextLost())
+        return;
+    switch (face) {
+    case GL_FRONT_AND_BACK:
+        m_stencilMask = mask;
+        m_stencilMaskBack = mask;
+        break;
+    case GL_FRONT:
+        m_stencilMask = mask;
+        break;
+    case GL_BACK:
+        m_stencilMaskBack = mask;
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "stencilMaskSeparate", "invalid face");
+        return;
+    }
+    m_context->stencilMaskSeparate(face, mask);
+}
+
+void WebGLRenderingContextBase::stencilOp(GLenum fail, GLenum zfail, GLenum zpass)
+{
+    if (isContextLost())
+        return;
+    m_context->stencilOp(fail, zfail, zpass);
+}
+
+void WebGLRenderingContextBase::stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass)
+{
+    if (isContextLost())
+        return;
+    m_context->stencilOpSeparate(face, fail, zfail, zpass);
+}
+
+GLenum WebGLRenderingContextBase::convertTexInternalFormat(GLenum internalformat, GLenum type)
+{
+    // Convert to sized internal formats that are renderable with GL_CHROMIUM_color_buffer_float_rgb(a).
+    if (type == GL_FLOAT && internalformat == GL_RGBA
+        && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgba"))
+        return GL_RGBA32F_EXT;
+    if (type == GL_FLOAT && internalformat == GL_RGB
+        && extensionsUtil()->isExtensionEnabled("GL_CHROMIUM_color_buffer_float_rgb"))
+        return GL_RGB32F_EXT;
+    return internalformat;
+}
+
+void WebGLRenderingContextBase::texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
+{
+    // All calling functions check isContextLost, so a duplicate check is not needed here.
+    // FIXME: Handle errors.
+    WebGLTexture* tex = validateTextureBinding("texImage2D", target, true);
+    ASSERT(validateTexFuncParameters("texImage2D", NotTexSubImage2D, target, level, internalformat, width, height, border, format, type));
+    ASSERT(tex);
+    ASSERT(!level || !WebGLTexture::isNPOT(width, height));
+    ASSERT(!pixels || validateSettableTexFormat("texImage2D", internalformat));
+    m_context->texImage2D(target, level, convertTexInternalFormat(internalformat, type), width, height, border, format, type, pixels);
+    tex->setLevelInfo(target, level, internalformat, width, height, type);
+}
+
+void WebGLRenderingContextBase::texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
+{
+    // All calling functions check isContextLost, so a duplicate check is not needed here.
+    Vector<uint8_t> data;
+    WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
+    if (!imageExtractor.extractSucceeded()) {
+        synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+        return;
+    }
+    WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+    WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+    const void* imagePixelData = imageExtractor.imagePixelData();
+
+    bool needConversion = true;
+    if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
+        needConversion = false;
+    else {
+        if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+            synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "packImage error");
+            return;
+        }
+    }
+
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    texImage2DBase(target, level, internalformat, image->width(), image->height(), 0, format, type, needConversion ? data.data() : imagePixelData, exceptionState);
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+bool WebGLRenderingContextBase::validateTexFunc(const char* functionName, TexFuncValidationFunctionType functionType, TexFuncValidationSourceType sourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset)
+{
+    if (!validateTexFuncParameters(functionName, functionType, target, level, internalformat, width, height, border, format, type))
+        return false;
+
+    WebGLTexture* texture = validateTextureBinding(functionName, target, true);
+    if (!texture)
+        return false;
+
+    if (functionType == NotTexSubImage2D) {
+        if (level && WebGLTexture::isNPOT(width, height)) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "level > 0 not power of 2");
+            return false;
+        }
+        // For SourceArrayBufferView, function validateTexFuncData() would handle whether to validate the SettableTexFormat
+        // by checking if the ArrayBufferView is null or not.
+        if (sourceType != SourceArrayBufferView) {
+            if (!validateSettableTexFormat(functionName, format))
+                return false;
+        }
+    } else {
+        if (!validateSettableTexFormat(functionName, format))
+            return false;
+        if (!validateSize(functionName, xoffset, yoffset))
+            return false;
+        // Before checking if it is in the range, check if overflow happens first.
+        if (xoffset + width < 0 || yoffset + height < 0) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "bad dimensions");
+            return false;
+        }
+        if (xoffset + width > texture->getWidth(target, level) || yoffset + height > texture->getHeight(target, level)) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "dimensions out of range");
+            return false;
+        }
+        if (texture->getInternalFormat(target, level) != format || texture->getType(target, level) != type) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type and format do not match texture");
+            return false;
+        }
+    }
+
+    return true;
+}
+
+PassRefPtr<Image> WebGLRenderingContextBase::drawImageIntoBuffer(Image* image, int width, int height, const char* functionName)
+{
+    IntSize size(width, height);
+    ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+    if (!buf) {
+        synthesizeGLError(GL_OUT_OF_MEMORY, functionName, "out of memory");
+        return nullptr;
+    }
+
+    IntRect srcRect(IntPoint(), image->size());
+    IntRect destRect(0, 0, size.width(), size.height());
+    buf->context()->drawImage(image, destRect, srcRect);
+    return buf->copyImage(ImageBuffer::fastCopyImageMode());
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+    GLsizei width, GLsizei height, GLint border,
+    GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateTexFuncData("texImage2D", level, width, height, format, type, pixels, NullAllowed)
+        || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceArrayBufferView, target, level, internalformat, width, height, border, format, type, 0, 0))
+        return;
+    void* data = pixels ? pixels->baseAddress() : 0;
+    Vector<uint8_t> tempData;
+    bool changeUnpackAlignment = false;
+    if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+        if (!WebGLImageConversion::extractTextureData(width, height, format, type, m_unpackAlignment, m_unpackFlipY, m_unpackPremultiplyAlpha, data, tempData))
+            return;
+        data = tempData.data();
+        changeUnpackAlignment = true;
+    }
+    if (changeUnpackAlignment)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    texImage2DBase(target, level, internalformat, width, height, border, format, type, data, exceptionState);
+    if (changeUnpackAlignment)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+    GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !pixels || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceImageData, target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, 0, 0))
+        return;
+    Vector<uint8_t> data;
+    bool needConversion = true;
+    // The data from ImageData is always of format RGBA8.
+    // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+    if (!m_unpackFlipY && !m_unpackPremultiplyAlpha && format == GL_RGBA && type == GL_UNSIGNED_BYTE)
+        needConversion = false;
+    else {
+        if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+            synthesizeGLError(GL_INVALID_VALUE, "texImage2D", "bad image data");
+            return;
+        }
+    }
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    texImage2DBase(target, level, internalformat, pixels->width(), pixels->height(), 0, format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+    GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateHTMLImageElement("texImage2D", image, exceptionState))
+        return;
+
+    RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+    if (imageForRender->isSVGImage())
+        imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), "texImage2D");
+
+    if (!imageForRender || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLImageElement, target, level, internalformat, imageForRender->width(), imageForRender->height(), 0, format, type, 0, 0))
+        return;
+
+    texImage2DImpl(target, level, internalformat, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+    GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateHTMLCanvasElement("texImage2D", canvas, exceptionState) || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLCanvasElement, target, level, internalformat, canvas->width(), canvas->height(), 0, format, type, 0, 0))
+        return;
+
+    WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+    // If possible, copy from the canvas element directly to the texture
+    // via the GPU, without a read-back to system memory.
+    if (GL_TEXTURE_2D == target && texture) {
+        if (!canvas->is3D()) {
+            ImageBuffer* buffer = canvas->buffer();
+            if (buffer && buffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
+                level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+                texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+                return;
+            }
+        } else {
+            WebGLRenderingContextBase* gl = toWebGLRenderingContextBase(canvas->renderingContext());
+            if (gl && gl->m_drawingBuffer->copyToPlatformTexture(m_context.get(), texture->object(), internalformat, type,
+                level, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+                texture->setLevelInfo(target, level, internalformat, canvas->width(), canvas->height(), type);
+                return;
+            }
+        }
+    }
+
+    RefPtr<ImageData> imageData = canvas->getImageData();
+    if (imageData)
+        texImage2D(target, level, internalformat, format, type, imageData.get(), exceptionState);
+    else
+        texImage2DImpl(target, level, internalformat, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+PassRefPtr<Image> WebGLRenderingContextBase::videoFrameToImage(HTMLVideoElement* video, BackingStoreCopy backingStoreCopy)
+{
+    IntSize size(video->videoWidth(), video->videoHeight());
+    ImageBuffer* buf = m_generatedImageCache.imageBuffer(size);
+    if (!buf) {
+        synthesizeGLError(GL_OUT_OF_MEMORY, "texImage2D", "out of memory");
+        return nullptr;
+    }
+    IntRect destRect(0, 0, size.width(), size.height());
+    // FIXME: Turn this into a GPU-GPU texture copy instead of CPU readback.
+    video->paintCurrentFrameInContext(buf->context(), destRect);
+    return buf->copyImage(backingStoreCopy);
+}
+
+void WebGLRenderingContextBase::texImage2D(GLenum target, GLint level, GLenum internalformat,
+    GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateHTMLVideoElement("texImage2D", video, exceptionState)
+        || !validateTexFunc("texImage2D", NotTexSubImage2D, SourceHTMLVideoElement, target, level, internalformat, video->videoWidth(), video->videoHeight(), 0, format, type, 0, 0))
+        return;
+
+    // Go through the fast path doing a GPU-GPU textures copy without a readback to system memory if possible.
+    // Otherwise, it will fall back to the normal SW path.
+    WebGLTexture* texture = validateTextureBinding("texImage2D", target, true);
+    if (GL_TEXTURE_2D == target && texture) {
+        if (video->copyVideoTextureToPlatformTexture(m_context.get(), texture->object(), level, type, internalformat, m_unpackPremultiplyAlpha, m_unpackFlipY)) {
+            texture->setLevelInfo(target, level, internalformat, video->videoWidth(), video->videoHeight(), type);
+            return;
+        }
+    }
+
+    // Normal pure SW path.
+    RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
+    if (!image)
+        return;
+    texImage2DImpl(target, level, internalformat, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texParameter(GLenum target, GLenum pname, GLfloat paramf, GLint parami, bool isFloat)
+{
+    if (isContextLost())
+        return;
+    WebGLTexture* tex = validateTextureBinding("texParameter", target, false);
+    if (!tex)
+        return;
+    switch (pname) {
+    case GL_TEXTURE_MIN_FILTER:
+    case GL_TEXTURE_MAG_FILTER:
+        break;
+    case GL_TEXTURE_WRAP_S:
+    case GL_TEXTURE_WRAP_T:
+        if ((isFloat && paramf != GL_CLAMP_TO_EDGE && paramf != GL_MIRRORED_REPEAT && paramf != GL_REPEAT)
+            || (!isFloat && parami != GL_CLAMP_TO_EDGE && parami != GL_MIRRORED_REPEAT && parami != GL_REPEAT)) {
+            synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter");
+            return;
+        }
+        break;
+    case GL_TEXTURE_MAX_ANISOTROPY_EXT: // EXT_texture_filter_anisotropic
+        if (!extensionEnabled(EXTTextureFilterAnisotropicName)) {
+            synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter, EXT_texture_filter_anisotropic not enabled");
+            return;
+        }
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "texParameter", "invalid parameter name");
+        return;
+    }
+    if (isFloat) {
+        tex->setParameterf(pname, paramf);
+        m_context->texParameterf(target, pname, paramf);
+    } else {
+        tex->setParameteri(pname, parami);
+        m_context->texParameteri(target, pname, parami);
+    }
+}
+
+void WebGLRenderingContextBase::texParameterf(GLenum target, GLenum pname, GLfloat param)
+{
+    texParameter(target, pname, param, 0, true);
+}
+
+void WebGLRenderingContextBase::texParameteri(GLenum target, GLenum pname, GLint param)
+{
+    texParameter(target, pname, 0, param, false);
+}
+
+void WebGLRenderingContextBase::texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState& exceptionState)
+{
+    // FIXME: Handle errors.
+    ASSERT(!isContextLost());
+    ASSERT(validateTexFuncParameters("texSubImage2D", TexSubImage2D, target, level, format, width, height, 0, format, type));
+    ASSERT(validateSize("texSubImage2D", xoffset, yoffset));
+    ASSERT(validateSettableTexFormat("texSubImage2D", format));
+    WebGLTexture* tex = validateTextureBinding("texSubImage2D", target, true);
+    if (!tex) {
+        ASSERT_NOT_REACHED();
+        return;
+    }
+    ASSERT((xoffset + width) >= 0);
+    ASSERT((yoffset + height) >= 0);
+    ASSERT(tex->getWidth(target, level) >= (xoffset + width));
+    ASSERT(tex->getHeight(target, level) >= (yoffset + height));
+    ASSERT(tex->getInternalFormat(target, level) == format);
+    ASSERT(tex->getType(target, level) == type);
+    m_context->texSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels);
+}
+
+void WebGLRenderingContextBase::texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image* image, WebGLImageConversion::ImageHtmlDomSource domSource, bool flipY, bool premultiplyAlpha, ExceptionState& exceptionState)
+{
+    // All calling functions check isContextLost, so a duplicate check is not needed here.
+    Vector<uint8_t> data;
+    WebGLImageConversion::ImageExtractor imageExtractor(image, domSource, premultiplyAlpha, m_unpackColorspaceConversion == GL_NONE);
+    if (!imageExtractor.extractSucceeded()) {
+        synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image");
+        return;
+    }
+    WebGLImageConversion::DataFormat sourceDataFormat = imageExtractor.imageSourceFormat();
+    WebGLImageConversion::AlphaOp alphaOp = imageExtractor.imageAlphaOp();
+    const void* imagePixelData = imageExtractor.imagePixelData();
+
+    bool needConversion = true;
+    if (type == GL_UNSIGNED_BYTE && sourceDataFormat == WebGLImageConversion::DataFormatRGBA8 && format == GL_RGBA && alphaOp == WebGLImageConversion::AlphaDoNothing && !flipY)
+        needConversion = false;
+    else {
+        if (!WebGLImageConversion::packImageData(image, imagePixelData, format, type, flipY, alphaOp, sourceDataFormat, imageExtractor.imageWidth(), imageExtractor.imageHeight(), imageExtractor.imageSourceUnpackAlignment(), data)) {
+            synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
+            return;
+        }
+    }
+
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    texSubImage2DBase(target, level, xoffset, yoffset, image->width(), image->height(), format, type,  needConversion ? data.data() : imagePixelData, exceptionState);
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+    GLsizei width, GLsizei height,
+    GLenum format, GLenum type, ArrayBufferView* pixels, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateTexFuncData("texSubImage2D", level, width, height, format, type, pixels, NullNotAllowed)
+        || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceArrayBufferView, target, level, format, width, height, 0, format, type, xoffset, yoffset))
+        return;
+    void* data = pixels->baseAddress();
+    Vector<uint8_t> tempData;
+    bool changeUnpackAlignment = false;
+    if (data && (m_unpackFlipY || m_unpackPremultiplyAlpha)) {
+        if (!WebGLImageConversion::extractTextureData(width, height, format, type,
+                                           m_unpackAlignment,
+                                           m_unpackFlipY, m_unpackPremultiplyAlpha,
+                                           data,
+                                           tempData))
+            return;
+        data = tempData.data();
+        changeUnpackAlignment = true;
+    }
+    if (changeUnpackAlignment)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    texSubImage2DBase(target, level, xoffset, yoffset, width, height, format, type, data, exceptionState);
+    if (changeUnpackAlignment)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+    GLenum format, GLenum type, ImageData* pixels, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !pixels || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceImageData, target, level, format,  pixels->width(), pixels->height(), 0, format, type, xoffset, yoffset))
+        return;
+
+    Vector<uint8_t> data;
+    bool needConversion = true;
+    // The data from ImageData is always of format RGBA8.
+    // No conversion is needed if destination format is RGBA and type is USIGNED_BYTE and no Flip or Premultiply operation is required.
+    if (format == GL_RGBA && type == GL_UNSIGNED_BYTE && !m_unpackFlipY && !m_unpackPremultiplyAlpha)
+        needConversion = false;
+    else {
+        if (!WebGLImageConversion::extractImageData(pixels->data()->data(), pixels->size(), format, type, m_unpackFlipY, m_unpackPremultiplyAlpha, data)) {
+            synthesizeGLError(GL_INVALID_VALUE, "texSubImage2D", "bad image data");
+            return;
+        }
+    }
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, 1);
+    texSubImage2DBase(target, level, xoffset, yoffset, pixels->width(), pixels->height(), format, type, needConversion ? data.data() : pixels->data()->data(), exceptionState);
+    if (m_unpackAlignment != 1)
+        m_context->pixelStorei(GL_UNPACK_ALIGNMENT, m_unpackAlignment);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+    GLenum format, GLenum type, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateHTMLImageElement("texSubImage2D", image, exceptionState))
+        return;
+
+    RefPtr<Image> imageForRender = image->cachedImage()->imageForRenderer(image->renderer());
+    if (imageForRender->isSVGImage())
+        imageForRender = drawImageIntoBuffer(imageForRender.get(), image->width(), image->height(), "texSubImage2D");
+
+    if (!imageForRender || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLImageElement, target, level, format, imageForRender->width(), imageForRender->height(), 0, format, type, xoffset, yoffset))
+        return;
+
+    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, imageForRender.get(), WebGLImageConversion::HtmlDomImage, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+    GLenum format, GLenum type, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateHTMLCanvasElement("texSubImage2D", canvas, exceptionState)
+        || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLCanvasElement, target, level, format, canvas->width(), canvas->height(), 0, format, type, xoffset, yoffset))
+        return;
+
+    RefPtr<ImageData> imageData = canvas->getImageData();
+    if (imageData)
+        texSubImage2D(target, level, xoffset, yoffset, format, type, imageData.get(), exceptionState);
+    else
+        texSubImage2DImpl(target, level, xoffset, yoffset, format, type, canvas->copiedImage(), WebGLImageConversion::HtmlDomCanvas, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+    GLenum format, GLenum type, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+    if (isContextLost() || !validateHTMLVideoElement("texSubImage2D", video, exceptionState)
+        || !validateTexFunc("texSubImage2D", TexSubImage2D, SourceHTMLVideoElement, target, level, format, video->videoWidth(), video->videoHeight(), 0, format, type, xoffset, yoffset))
+        return;
+
+    RefPtr<Image> image = videoFrameToImage(video, ImageBuffer::fastCopyImageMode());
+    if (!image)
+        return;
+    texSubImage2DImpl(target, level, xoffset, yoffset, format, type, image.get(), WebGLImageConversion::HtmlDomVideo, m_unpackFlipY, m_unpackPremultiplyAlpha, exceptionState);
+}
+
+void WebGLRenderingContextBase::uniform1f(const WebGLUniformLocation* location, GLfloat x)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform1f", "location not for current program");
+        return;
+    }
+
+    m_context->uniform1f(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, 1))
+        return;
+
+    m_context->uniform1fv(location->location(), v->length(), v->data());
+}
+
+void WebGLRenderingContextBase::uniform1fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform1fv", location, v, size, 1))
+        return;
+
+    m_context->uniform1fv(location->location(), size, v);
+}
+
+void WebGLRenderingContextBase::uniform1i(const WebGLUniformLocation* location, GLint x)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform1i", "location not for current program");
+        return;
+    }
+
+    m_context->uniform1i(location->location(), x);
+}
+
+void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, 1))
+        return;
+
+    m_context->uniform1iv(location->location(), v->length(), v->data());
+}
+
+void WebGLRenderingContextBase::uniform1iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform1iv", location, v, size, 1))
+        return;
+
+    m_context->uniform1iv(location->location(), size, v);
+}
+
+void WebGLRenderingContextBase::uniform2f(const WebGLUniformLocation* location, GLfloat x, GLfloat y)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform2f", "location not for current program");
+        return;
+    }
+
+    m_context->uniform2f(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, 2))
+        return;
+
+    m_context->uniform2fv(location->location(), v->length() / 2, v->data());
+}
+
+void WebGLRenderingContextBase::uniform2fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform2fv", location, v, size, 2))
+        return;
+
+    m_context->uniform2fv(location->location(), size / 2, v);
+}
+
+void WebGLRenderingContextBase::uniform2i(const WebGLUniformLocation* location, GLint x, GLint y)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform2i", "location not for current program");
+        return;
+    }
+
+    m_context->uniform2i(location->location(), x, y);
+}
+
+void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, 2))
+        return;
+
+    m_context->uniform2iv(location->location(), v->length() / 2, v->data());
+}
+
+void WebGLRenderingContextBase::uniform2iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform2iv", location, v, size, 2))
+        return;
+
+    m_context->uniform2iv(location->location(), size / 2, v);
+}
+
+void WebGLRenderingContextBase::uniform3f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform3f", "location not for current program");
+        return;
+    }
+
+    m_context->uniform3f(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, 3))
+        return;
+
+    m_context->uniform3fv(location->location(), v->length() / 3, v->data());
+}
+
+void WebGLRenderingContextBase::uniform3fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform3fv", location, v, size, 3))
+        return;
+
+    m_context->uniform3fv(location->location(), size / 3, v);
+}
+
+void WebGLRenderingContextBase::uniform3i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform3i", "location not for current program");
+        return;
+    }
+
+    m_context->uniform3i(location->location(), x, y, z);
+}
+
+void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, 3))
+        return;
+
+    m_context->uniform3iv(location->location(), v->length() / 3, v->data());
+}
+
+void WebGLRenderingContextBase::uniform3iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform3iv", location, v, size, 3))
+        return;
+
+    m_context->uniform3iv(location->location(), size / 3, v);
+}
+
+void WebGLRenderingContextBase::uniform4f(const WebGLUniformLocation* location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform4f", "location not for current program");
+        return;
+    }
+
+    m_context->uniform4f(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, Float32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, 4))
+        return;
+
+    m_context->uniform4fv(location->location(), v->length() / 4, v->data());
+}
+
+void WebGLRenderingContextBase::uniform4fv(const WebGLUniformLocation* location, GLfloat* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform4fv", location, v, size, 4))
+        return;
+
+    m_context->uniform4fv(location->location(), size / 4, v);
+}
+
+void WebGLRenderingContextBase::uniform4i(const WebGLUniformLocation* location, GLint x, GLint y, GLint z, GLint w)
+{
+    if (isContextLost() || !location)
+        return;
+
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, "uniform4i", "location not for current program");
+        return;
+    }
+
+    m_context->uniform4i(location->location(), x, y, z, w);
+}
+
+void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, Int32Array* v)
+{
+    if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, 4))
+        return;
+
+    m_context->uniform4iv(location->location(), v->length() / 4, v->data());
+}
+
+void WebGLRenderingContextBase::uniform4iv(const WebGLUniformLocation* location, GLint* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformParameters("uniform4iv", location, v, size, 4))
+        return;
+
+    m_context->uniform4iv(location->location(), size / 4, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, 4))
+        return;
+    m_context->uniformMatrix2fv(location->location(), v->length() / 4, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix2fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix2fv", location, transpose, v, size, 4))
+        return;
+    m_context->uniformMatrix2fv(location->location(), size / 4, transpose, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, 9))
+        return;
+    m_context->uniformMatrix3fv(location->location(), v->length() / 9, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix3fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix3fv", location, transpose, v, size, 9))
+        return;
+    m_context->uniformMatrix3fv(location->location(), size / 9, transpose, v);
+}
+
+void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v)
+{
+    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, 16))
+        return;
+    m_context->uniformMatrix4fv(location->location(), v->length() / 16, transpose, v->data());
+}
+
+void WebGLRenderingContextBase::uniformMatrix4fv(const WebGLUniformLocation* location, GLboolean transpose, GLfloat* v, GLsizei size)
+{
+    if (isContextLost() || !validateUniformMatrixParameters("uniformMatrix4fv", location, transpose, v, size, 16))
+        return;
+    m_context->uniformMatrix4fv(location->location(), size / 16, transpose, v);
+}
+
+void WebGLRenderingContextBase::useProgram(WebGLProgram* program)
+{
+    bool deleted;
+    if (!checkObjectToBeBound("useProgram", program, deleted))
+        return;
+    if (deleted)
+        program = 0;
+    if (program && !program->linkStatus()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "useProgram", "program not valid");
+        return;
+    }
+    if (m_currentProgram != program) {
+        if (m_currentProgram)
+            m_currentProgram->onDetached(m_context.get());
+        m_currentProgram = program;
+        m_context->useProgram(objectOrZero(program));
+        if (program)
+            program->onAttached();
+    }
+}
+
+void WebGLRenderingContextBase::validateProgram(WebGLProgram* program)
+{
+    if (isContextLost() || !validateWebGLObject("validateProgram", program))
+        return;
+    m_context->validateProgram(objectOrZero(program));
+}
+
+void WebGLRenderingContextBase::vertexAttrib1f(GLuint index, GLfloat v0)
+{
+    vertexAttribfImpl("vertexAttrib1f", index, 1, v0, 0.0f, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib1fv(GLuint index, Float32Array* v)
+{
+    vertexAttribfvImpl("vertexAttrib1fv", index, v, 1);
+}
+
+void WebGLRenderingContextBase::vertexAttrib1fv(GLuint index, GLfloat* v, GLsizei size)
+{
+    vertexAttribfvImpl("vertexAttrib1fv", index, v, size, 1);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2f(GLuint index, GLfloat v0, GLfloat v1)
+{
+    vertexAttribfImpl("vertexAttrib2f", index, 2, v0, v1, 0.0f, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2fv(GLuint index, Float32Array* v)
+{
+    vertexAttribfvImpl("vertexAttrib2fv", index, v, 2);
+}
+
+void WebGLRenderingContextBase::vertexAttrib2fv(GLuint index, GLfloat* v, GLsizei size)
+{
+    vertexAttribfvImpl("vertexAttrib2fv", index, v, size, 2);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2)
+{
+    vertexAttribfImpl("vertexAttrib3f", index, 3, v0, v1, v2, 1.0f);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3fv(GLuint index, Float32Array* v)
+{
+    vertexAttribfvImpl("vertexAttrib3fv", index, v, 3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib3fv(GLuint index, GLfloat* v, GLsizei size)
+{
+    vertexAttribfvImpl("vertexAttrib3fv", index, v, size, 3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4f(GLuint index, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+    vertexAttribfImpl("vertexAttrib4f", index, 4, v0, v1, v2, v3);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4fv(GLuint index, Float32Array* v)
+{
+    vertexAttribfvImpl("vertexAttrib4fv", index, v, 4);
+}
+
+void WebGLRenderingContextBase::vertexAttrib4fv(GLuint index, GLfloat* v, GLsizei size)
+{
+    vertexAttribfvImpl("vertexAttrib4fv", index, v, size, 4);
+}
+
+void WebGLRenderingContextBase::vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, long long offset)
+{
+    if (isContextLost())
+        return;
+    switch (type) {
+    case GL_BYTE:
+    case GL_UNSIGNED_BYTE:
+    case GL_SHORT:
+    case GL_UNSIGNED_SHORT:
+    case GL_FLOAT:
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
+        return;
+    }
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "index out of range");
+        return;
+    }
+    if (size < 1 || size > 4 || stride < 0 || stride > 255 || offset < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, "vertexAttribPointer", "bad size, stride or offset");
+        return;
+    }
+    if (!m_boundArrayBuffer) {
+        synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "no bound ARRAY_BUFFER");
+        return;
+    }
+    // Determine the number of elements the bound buffer can hold, given the offset, size, type and stride
+    unsigned typeSize = sizeInBytes(type);
+    if (!typeSize) {
+        synthesizeGLError(GL_INVALID_ENUM, "vertexAttribPointer", "invalid type");
+        return;
+    }
+    if ((stride % typeSize) || (static_cast<GLintptr>(offset) % typeSize)) {
+        synthesizeGLError(GL_INVALID_OPERATION, "vertexAttribPointer", "stride or offset not valid for type");
+        return;
+    }
+    GLsizei bytesPerElement = size * typeSize;
+
+    m_boundVertexArrayObject->setVertexAttribState(index, bytesPerElement, size, type, normalized, stride, static_cast<GLintptr>(offset), m_boundArrayBuffer);
+    m_context->vertexAttribPointer(index, size, type, normalized, stride, static_cast<GLintptr>(offset));
+}
+
+void WebGLRenderingContextBase::vertexAttribDivisorANGLE(GLuint index, GLuint divisor)
+{
+    if (isContextLost())
+        return;
+
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, "vertexAttribDivisorANGLE", "index out of range");
+        return;
+    }
+
+    m_boundVertexArrayObject->setVertexAttribDivisor(index, divisor);
+    m_context->vertexAttribDivisorANGLE(index, divisor);
+}
+
+void WebGLRenderingContextBase::viewport(GLint x, GLint y, GLsizei width, GLsizei height)
+{
+    if (isContextLost())
+        return;
+    if (!validateSize("viewport", width, height))
+        return;
+    m_context->viewport(x, y, width, height);
+}
+
+void WebGLRenderingContextBase::forceLostContext(WebGLRenderingContextBase::LostContextMode mode)
+{
+    if (isContextLost()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "loseContext", "context already lost");
+        return;
+    }
+
+    m_contextGroup->loseContextGroup(mode);
+}
+
+void WebGLRenderingContextBase::loseContextImpl(WebGLRenderingContextBase::LostContextMode mode)
+{
+    if (isContextLost())
+        return;
+
+    m_contextLost = true;
+    m_contextLostMode = mode;
+
+    if (mode == RealLostContext) {
+        // Inform the embedder that a lost context was received. In response, the embedder might
+        // decide to take action such as asking the user for permission to use WebGL again.
+        if (LocalFrame* frame = canvas()->document().frame())
+            frame->loader().client()->didLoseWebGLContext(m_context->getGraphicsResetStatusARB());
+    }
+
+    // Make absolutely sure we do not refer to an already-deleted texture or framebuffer.
+    m_drawingBuffer->setTexture2DBinding(0);
+    m_drawingBuffer->setFramebufferBinding(0);
+
+    detachAndRemoveAllObjects();
+
+    // Lose all the extensions.
+    for (size_t i = 0; i < m_extensions.size(); ++i) {
+        ExtensionTracker* tracker = m_extensions[i];
+        tracker->loseExtension();
+    }
+
+    for (size_t i = 0; i < WebGLExtensionNameCount; ++i)
+        m_extensionEnabled[i] = false;
+
+    removeAllCompressedTextureFormats();
+
+    if (mode != RealLostContext)
+        destroyContext();
+
+    ConsoleDisplayPreference display = (mode == RealLostContext) ? DisplayInConsole: DontDisplayInConsole;
+    synthesizeGLError(GC3D_CONTEXT_LOST_WEBGL, "loseContext", "context lost", display);
+
+    // Don't allow restoration unless the context lost event has both been
+    // dispatched and its default behavior prevented.
+    m_restoreAllowed = false;
+
+    // Always defer the dispatch of the context lost event, to implement
+    // the spec behavior of queueing a task.
+    m_dispatchContextLostEventTimer.startOneShot(0, FROM_HERE);
+}
+
+void WebGLRenderingContextBase::forceRestoreContext()
+{
+    if (!isContextLost()) {
+        synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context not lost");
+        return;
+    }
+
+    if (!m_restoreAllowed) {
+        if (m_contextLostMode == SyntheticLostContext)
+            synthesizeGLError(GL_INVALID_OPERATION, "restoreContext", "context restoration not allowed");
+        return;
+    }
+
+    if (!m_restoreTimer.isActive())
+        m_restoreTimer.startOneShot(0, FROM_HERE);
+}
+
+blink::WebLayer* WebGLRenderingContextBase::platformLayer() const
+{
+    return m_drawingBuffer->platformLayer();
+}
+
+Extensions3DUtil* WebGLRenderingContextBase::extensionsUtil()
+{
+    if (!m_extensionsUtil)
+        m_extensionsUtil = adoptPtr(new Extensions3DUtil(m_context.get()));
+    return m_extensionsUtil.get();
+}
+
+void WebGLRenderingContextBase::removeSharedObject(WebGLSharedObject* object)
+{
+    m_contextGroup->removeObject(object);
+}
+
+void WebGLRenderingContextBase::addSharedObject(WebGLSharedObject* object)
+{
+    ASSERT(!isContextLost());
+    m_contextGroup->addObject(object);
+}
+
+void WebGLRenderingContextBase::removeContextObject(WebGLContextObject* object)
+{
+    m_contextObjects.remove(object);
+}
+
+void WebGLRenderingContextBase::addContextObject(WebGLContextObject* object)
+{
+    ASSERT(!isContextLost());
+    m_contextObjects.add(object);
+}
+
+void WebGLRenderingContextBase::detachAndRemoveAllObjects()
+{
+    while (m_contextObjects.size() > 0) {
+        HashSet<WebGLContextObject*>::iterator it = m_contextObjects.begin();
+        (*it)->detachContext();
+    }
+}
+
+bool WebGLRenderingContextBase::hasPendingActivity() const
+{
+    return false;
+}
+
+void WebGLRenderingContextBase::stop()
+{
+    if (!isContextLost()) {
+        forceLostContext(SyntheticLostContext);
+        destroyContext();
+    }
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBooleanParameter(GLenum pname)
+{
+    GLboolean value = 0;
+    if (!isContextLost())
+        m_context->getBooleanv(pname, &value);
+    return WebGLGetInfo(static_cast<bool>(value));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getBooleanArrayParameter(GLenum pname)
+{
+    if (pname != GL_COLOR_WRITEMASK) {
+        notImplemented();
+        return WebGLGetInfo(0, 0);
+    }
+    GLboolean value[4] = {0};
+    if (!isContextLost())
+        m_context->getBooleanv(pname, value);
+    bool boolValue[4];
+    for (int ii = 0; ii < 4; ++ii)
+        boolValue[ii] = static_cast<bool>(value[ii]);
+    return WebGLGetInfo(boolValue, 4);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getFloatParameter(GLenum pname)
+{
+    GLfloat value = 0;
+    if (!isContextLost())
+        m_context->getFloatv(pname, &value);
+    return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getIntParameter(GLenum pname)
+{
+    GLint value = 0;
+    if (!isContextLost())
+        m_context->getIntegerv(pname, &value);
+    return WebGLGetInfo(value);
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getUnsignedIntParameter(GLenum pname)
+{
+    GLint value = 0;
+    if (!isContextLost())
+        m_context->getIntegerv(pname, &value);
+    return WebGLGetInfo(static_cast<unsigned>(value));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getWebGLFloatArrayParameter(GLenum pname)
+{
+    GLfloat value[4] = {0};
+    if (!isContextLost())
+        m_context->getFloatv(pname, value);
+    unsigned length = 0;
+    switch (pname) {
+    case GL_ALIASED_POINT_SIZE_RANGE:
+    case GL_ALIASED_LINE_WIDTH_RANGE:
+    case GL_DEPTH_RANGE:
+        length = 2;
+        break;
+    case GL_BLEND_COLOR:
+    case GL_COLOR_CLEAR_VALUE:
+        length = 4;
+        break;
+    default:
+        notImplemented();
+    }
+    return WebGLGetInfo(Float32Array::create(value, length));
+}
+
+WebGLGetInfo WebGLRenderingContextBase::getWebGLIntArrayParameter(GLenum pname)
+{
+    GLint value[4] = {0};
+    if (!isContextLost())
+        m_context->getIntegerv(pname, value);
+    unsigned length = 0;
+    switch (pname) {
+    case GL_MAX_VIEWPORT_DIMS:
+        length = 2;
+        break;
+    case GL_SCISSOR_BOX:
+    case GL_VIEWPORT:
+        length = 4;
+        break;
+    default:
+        notImplemented();
+    }
+    return WebGLGetInfo(Int32Array::create(value, length));
+}
+
+void WebGLRenderingContextBase::handleTextureCompleteness(const char* functionName, bool prepareToDraw)
+{
+    // All calling functions check isContextLost, so a duplicate check is not needed here.
+    bool resetActiveUnit = false;
+    WebGLTexture::TextureExtensionFlag flag = static_cast<WebGLTexture::TextureExtensionFlag>((extensionEnabled(OESTextureFloatLinearName) ? WebGLTexture::TextureFloatLinearExtensionEnabled : 0)
+        | (extensionEnabled(OESTextureHalfFloatLinearName) ? WebGLTexture::TextureHalfFloatLinearExtensionEnabled : 0));
+    for (unsigned ii = 0; ii < m_onePlusMaxNonDefaultTextureUnit; ++ii) {
+        if ((m_textureUnits[ii].m_texture2DBinding.get() && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
+            || (m_textureUnits[ii].m_textureCubeMapBinding.get() && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))) {
+            if (ii != m_activeTextureUnit) {
+                m_context->activeTexture(ii);
+                resetActiveUnit = true;
+            } else if (resetActiveUnit) {
+                m_context->activeTexture(ii);
+                resetActiveUnit = false;
+            }
+            WebGLTexture* tex2D;
+            WebGLTexture* texCubeMap;
+            if (prepareToDraw) {
+                String msg(String("texture bound to texture unit ") + String::number(ii)
+                    + " is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'."
+                    + " Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.");
+                emitGLWarning(functionName, msg.utf8().data());
+                tex2D = m_blackTexture2D.get();
+                texCubeMap = m_blackTextureCubeMap.get();
+            } else {
+                tex2D = m_textureUnits[ii].m_texture2DBinding.get();
+                texCubeMap = m_textureUnits[ii].m_textureCubeMapBinding.get();
+            }
+            if (m_textureUnits[ii].m_texture2DBinding && m_textureUnits[ii].m_texture2DBinding->needToUseBlackTexture(flag))
+                m_context->bindTexture(GL_TEXTURE_2D, objectOrZero(tex2D));
+            if (m_textureUnits[ii].m_textureCubeMapBinding && m_textureUnits[ii].m_textureCubeMapBinding->needToUseBlackTexture(flag))
+                m_context->bindTexture(GL_TEXTURE_CUBE_MAP, objectOrZero(texCubeMap));
+        }
+    }
+    if (resetActiveUnit)
+        m_context->activeTexture(m_activeTextureUnit);
+}
+
+void WebGLRenderingContextBase::createFallbackBlackTextures1x1()
+{
+    // All calling functions check isContextLost, so a duplicate check is not needed here.
+    unsigned char black[] = {0, 0, 0, 255};
+    m_blackTexture2D = createTexture();
+    m_context->bindTexture(GL_TEXTURE_2D, m_blackTexture2D->object());
+    m_context->texImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 1, 1,
+        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+    m_context->bindTexture(GL_TEXTURE_2D, 0);
+    m_blackTextureCubeMap = createTexture();
+    m_context->bindTexture(GL_TEXTURE_CUBE_MAP, m_blackTextureCubeMap->object());
+    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA, 1, 1,
+        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA, 1, 1,
+        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA, 1, 1,
+        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA, 1, 1,
+        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA, 1, 1,
+        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+    m_context->texImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA, 1, 1,
+        0, GL_RGBA, GL_UNSIGNED_BYTE, black);
+    m_context->bindTexture(GL_TEXTURE_CUBE_MAP, 0);
+}
+
+bool WebGLRenderingContextBase::isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat)
+{
+    unsigned need = WebGLImageConversion::getChannelBitsByFormat(texInternalFormat);
+    unsigned have = WebGLImageConversion::getChannelBitsByFormat(colorBufferFormat);
+    return (need & have) == need;
+}
+
+GLenum WebGLRenderingContextBase::boundFramebufferColorFormat()
+{
+    if (m_framebufferBinding && m_framebufferBinding->object())
+        return m_framebufferBinding->colorBufferFormat();
+    if (m_requestedAttributes->alpha())
+        return GL_RGBA;
+    return GL_RGB;
+}
+
+WebGLTexture* WebGLRenderingContextBase::validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap)
+{
+    WebGLTexture* tex = 0;
+    switch (target) {
+    case GL_TEXTURE_2D:
+        tex = m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get();
+        break;
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        if (!useSixEnumsForCubeMap) {
+            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+            return 0;
+        }
+        tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+        break;
+    case GL_TEXTURE_CUBE_MAP:
+        if (useSixEnumsForCubeMap) {
+            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+            return 0;
+        }
+        tex = m_textureUnits[m_activeTextureUnit].m_textureCubeMapBinding.get();
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture target");
+        return 0;
+    }
+    if (!tex)
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no texture");
+    return tex;
+}
+
+bool WebGLRenderingContextBase::validateLocationLength(const char* functionName, const String& string)
+{
+    const unsigned maxWebGLLocationLength = 256;
+    if (string.length() > maxWebGLLocationLength) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "location length > 256");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateSize(const char* functionName, GLint x, GLint y)
+{
+    if (x < 0 || y < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "size < 0");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateString(const char* functionName, const String& string)
+{
+    for (size_t i = 0; i < string.length(); ++i) {
+        if (!validateCharacter(string[i])) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "string not ASCII");
+            return false;
+        }
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level)
+{
+    switch (format) {
+    case GL_ALPHA:
+    case GL_LUMINANCE:
+    case GL_LUMINANCE_ALPHA:
+    case GL_RGB:
+    case GL_RGBA:
+        break;
+    case GL_DEPTH_STENCIL_OES:
+    case GL_DEPTH_COMPONENT:
+        if (extensionEnabled(WebGLDepthTextureName))
+            break;
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "depth texture formats not enabled");
+        return false;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture format");
+        return false;
+    }
+
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_UNSIGNED_SHORT_5_6_5:
+    case GL_UNSIGNED_SHORT_4_4_4_4:
+    case GL_UNSIGNED_SHORT_5_5_5_1:
+        break;
+    case GL_FLOAT:
+        if (extensionEnabled(OESTextureFloatName))
+            break;
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+        return false;
+    case GL_HALF_FLOAT_OES:
+        if (extensionEnabled(OESTextureHalfFloatName))
+            break;
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+        return false;
+    case GL_UNSIGNED_INT:
+    case GL_UNSIGNED_INT_24_8_OES:
+    case GL_UNSIGNED_SHORT:
+        if (extensionEnabled(WebGLDepthTextureName))
+            break;
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+        return false;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid texture type");
+        return false;
+    }
+
+    // Verify that the combination of format and type is supported.
+    switch (format) {
+    case GL_ALPHA:
+    case GL_LUMINANCE:
+    case GL_LUMINANCE_ALPHA:
+        if (type != GL_UNSIGNED_BYTE
+            && type != GL_FLOAT
+            && type != GL_HALF_FLOAT_OES) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for format");
+            return false;
+        }
+        break;
+    case GL_RGB:
+        if (type != GL_UNSIGNED_BYTE
+            && type != GL_UNSIGNED_SHORT_5_6_5
+            && type != GL_FLOAT
+            && type != GL_HALF_FLOAT_OES) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGB format");
+            return false;
+        }
+        break;
+    case GL_RGBA:
+        if (type != GL_UNSIGNED_BYTE
+            && type != GL_UNSIGNED_SHORT_4_4_4_4
+            && type != GL_UNSIGNED_SHORT_5_5_5_1
+            && type != GL_FLOAT
+            && type != GL_HALF_FLOAT_OES) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for RGBA format");
+            return false;
+        }
+        break;
+    case GL_DEPTH_COMPONENT:
+        if (!extensionEnabled(WebGLDepthTextureName)) {
+            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_COMPONENT not enabled");
+            return false;
+        }
+        if (type != GL_UNSIGNED_SHORT
+            && type != GL_UNSIGNED_INT) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_COMPONENT format");
+            return false;
+        }
+        if (level > 0) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_COMPONENT format");
+            return false;
+        }
+        break;
+    case GL_DEPTH_STENCIL_OES:
+        if (!extensionEnabled(WebGLDepthTextureName)) {
+            synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format. DEPTH_STENCIL not enabled");
+            return false;
+        }
+        if (type != GL_UNSIGNED_INT_24_8_OES) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "invalid type for DEPTH_STENCIL format");
+            return false;
+        }
+        if (level > 0) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "level must be 0 for DEPTH_STENCIL format");
+            return false;
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncLevel(const char* functionName, GLenum target, GLint level)
+{
+    if (level < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "level < 0");
+        return false;
+    }
+    switch (target) {
+    case GL_TEXTURE_2D:
+        if (level >= m_maxTextureLevel) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
+            return false;
+        }
+        break;
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        if (level >= m_maxCubeMapTextureLevel) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "level out of range");
+            return false;
+        }
+        break;
+    }
+    // This function only checks if level is legal, so we return true and don't
+    // generate INVALID_ENUM if target is illegal.
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType functionType,
+    GLenum target, GLint level, GLsizei width, GLsizei height)
+{
+    if (width < 0 || height < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
+        return false;
+    }
+
+    switch (target) {
+    case GL_TEXTURE_2D:
+        if (width > (m_maxTextureSize >> level) || height > (m_maxTextureSize >> level)) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range");
+            return false;
+        }
+        break;
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_X:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
+    case GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
+    case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
+        if (functionType != TexSubImage2D && width != height) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "width != height for cube map");
+            return false;
+        }
+        // No need to check height here. For texImage width == height.
+        // For texSubImage that will be checked when checking yoffset + height is in range.
+        if (width > (m_maxCubeMapTextureSize >> level)) {
+            synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height out of range for cube map");
+            return false;
+        }
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target,
+    GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type)
+{
+    // We absolutely have to validate the format and type combination.
+    // The texImage2D entry points taking HTMLImage, etc. will produce
+    // temporary data based on this combination, so it must be legal.
+    if (!validateTexFuncFormatAndType(functionName, format, type, level) || !validateTexFuncLevel(functionName, target, level))
+        return false;
+
+    if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
+        return false;
+
+    if (format != internalformat) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "format != internalformat");
+        return false;
+    }
+
+    if (border) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "border != 0");
+        return false;
+    }
+
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition disposition)
+{
+    // All calling functions check isContextLost, so a duplicate check is not needed here.
+    if (!pixels) {
+        if (disposition == NullAllowed)
+            return true;
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
+        return false;
+    }
+
+    if (!validateTexFuncFormatAndType(functionName, format, type, level))
+        return false;
+    if (!validateSettableTexFormat(functionName, format))
+        return false;
+
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+        if (pixels->type() != ArrayBufferView::TypeUint8) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_BYTE but ArrayBufferView not Uint8Array");
+            return false;
+        }
+        break;
+    case GL_UNSIGNED_SHORT_5_6_5:
+    case GL_UNSIGNED_SHORT_4_4_4_4:
+    case GL_UNSIGNED_SHORT_5_5_5_1:
+        if (pixels->type() != ArrayBufferView::TypeUint16) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type UNSIGNED_SHORT but ArrayBufferView not Uint16Array");
+            return false;
+        }
+        break;
+    case GL_FLOAT: // OES_texture_float
+        if (pixels->type() != ArrayBufferView::TypeFloat32) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type FLOAT but ArrayBufferView not Float32Array");
+            return false;
+        }
+        break;
+    case GL_HALF_FLOAT_OES: // OES_texture_half_float
+        // As per the specification, ArrayBufferView should be null when
+        // OES_texture_half_float is enabled.
+        if (pixels) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "type HALF_FLOAT_OES but ArrayBufferView is not NULL");
+            return false;
+        }
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+    }
+
+    unsigned totalBytesRequired;
+    GLenum error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, m_unpackAlignment, &totalBytesRequired, 0);
+    if (error != GL_NO_ERROR) {
+        synthesizeGLError(error, functionName, "invalid texture dimensions");
+        return false;
+    }
+    if (pixels->byteLength() < totalBytesRequired) {
+        if (m_unpackAlignment != 1) {
+            error = WebGLImageConversion::computeImageSizeInBytes(format, type, width, height, 1, &totalBytesRequired, 0);
+            if (pixels->byteLength() == totalBytesRequired) {
+                synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request with UNPACK_ALIGNMENT > 1");
+                return false;
+            }
+        }
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "ArrayBufferView not big enough for request");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFormat(GLenum format)
+{
+    return m_compressedTextureFormats.contains(format);
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels)
+{
+    if (!pixels) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no pixels");
+        return false;
+    }
+    if (width < 0 || height < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "width or height < 0");
+        return false;
+    }
+
+    unsigned bytesRequired = 0;
+
+    switch (format) {
+    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+        {
+            const int kBlockWidth = 4;
+            const int kBlockHeight = 4;
+            const int kBlockSize = 8;
+            int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+            int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+            int numBlocks = numBlocksAcross * numBlocksDown;
+            bytesRequired = numBlocks * kBlockSize;
+        }
+        break;
+    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
+        {
+            const int kBlockWidth = 4;
+            const int kBlockHeight = 4;
+            const int kBlockSize = 16;
+            int numBlocksAcross = (width + kBlockWidth - 1) / kBlockWidth;
+            int numBlocksDown = (height + kBlockHeight - 1) / kBlockHeight;
+            int numBlocks = numBlocksAcross * numBlocksDown;
+            bytesRequired = numBlocks * kBlockSize;
+        }
+        break;
+    case GC3D_COMPRESSED_ATC_RGB_AMD:
+        {
+            bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 8;
+        }
+        break;
+    case GC3D_COMPRESSED_ATC_RGBA_EXPLICIT_ALPHA_AMD:
+    case GC3D_COMPRESSED_ATC_RGBA_INTERPOLATED_ALPHA_AMD:
+        {
+            bytesRequired = floor(static_cast<double>((width + 3) / 4)) * floor(static_cast<double>((height + 3) / 4)) * 16;
+        }
+        break;
+    case GL_COMPRESSED_RGB_PVRTC_4BPPV1_IMG:
+    case GL_COMPRESSED_RGBA_PVRTC_4BPPV1_IMG:
+        {
+            bytesRequired = max(width, 8) * max(height, 8) / 2;
+        }
+        break;
+    case GL_COMPRESSED_RGB_PVRTC_2BPPV1_IMG:
+    case GL_COMPRESSED_RGBA_PVRTC_2BPPV1_IMG:
+        {
+            bytesRequired = max(width, 8) * max(height, 8) / 4;
+        }
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid format");
+        return false;
+    }
+
+    if (pixels->byteLength() != bytesRequired) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "length of ArrayBufferView is not correct for dimensions");
+        return false;
+    }
+
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType functionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format)
+{
+    if (!validateTexFuncDimensions(functionName, functionType, target, level, width, height))
+        return false;
+
+    switch (format) {
+    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+        const int kBlockWidth = 4;
+        const int kBlockHeight = 4;
+        bool widthValid = (level && width == 1) || (level && width == 2) || !(width % kBlockWidth);
+        bool heightValid = (level && height == 1) || (level && height == 2) || !(height % kBlockHeight);
+        if (!widthValid || !heightValid) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "width or height invalid for level");
+            return false;
+        }
+        return true;
+    }
+    default:
+        return false;
+    }
+}
+
+bool WebGLRenderingContextBase::validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture* tex)
+{
+    if (xoffset < 0 || yoffset < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "xoffset or yoffset < 0");
+        return false;
+    }
+
+    switch (format) {
+    case GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
+    case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: {
+        const int kBlockWidth = 4;
+        const int kBlockHeight = 4;
+        if ((xoffset % kBlockWidth) || (yoffset % kBlockHeight)) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "xoffset or yoffset not multiple of 4");
+            return false;
+        }
+        if (width - xoffset > tex->getWidth(target, level)
+            || height - yoffset > tex->getHeight(target, level)) {
+            synthesizeGLError(GL_INVALID_OPERATION, functionName, "dimensions out of range");
+            return false;
+        }
+        return validateCompressedTexDimensions(functionName, TexSubImage2D, target, level, width, height, format);
+    }
+    default:
+        return false;
+    }
+}
+
+bool WebGLRenderingContextBase::validateDrawMode(const char* functionName, GLenum mode)
+{
+    switch (mode) {
+    case GL_POINTS:
+    case GL_LINE_STRIP:
+    case GL_LINE_LOOP:
+    case GL_LINES:
+    case GL_TRIANGLE_STRIP:
+    case GL_TRIANGLE_FAN:
+    case GL_TRIANGLES:
+        return true;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid draw mode");
+        return false;
+    }
+}
+
+bool WebGLRenderingContextBase::validateStencilSettings(const char* functionName)
+{
+    if (m_stencilMask != m_stencilMaskBack || m_stencilFuncRef != m_stencilFuncRefBack || m_stencilFuncMask != m_stencilFuncMaskBack) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "front and back stencils settings do not match");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateStencilOrDepthFunc(const char* functionName, GLenum func)
+{
+    switch (func) {
+    case GL_NEVER:
+    case GL_LESS:
+    case GL_LEQUAL:
+    case GL_GREATER:
+    case GL_GEQUAL:
+    case GL_EQUAL:
+    case GL_NOTEQUAL:
+    case GL_ALWAYS:
+        return true;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid function");
+        return false;
+    }
+}
+
+void WebGLRenderingContextBase::printGLErrorToConsole(const String& message)
+{
+    if (!m_numGLErrorsToConsoleAllowed)
+        return;
+
+    --m_numGLErrorsToConsoleAllowed;
+    printWarningToConsole(message);
+
+    if (!m_numGLErrorsToConsoleAllowed)
+        printWarningToConsole("WebGL: too many errors, no more errors will be reported to the console for this context.");
+
+    return;
+}
+
+void WebGLRenderingContextBase::printWarningToConsole(const String& message)
+{
+    if (!canvas())
+        return;
+    canvas()->document().addConsoleMessage(RenderingMessageSource, WarningMessageLevel, message);
+}
+
+bool WebGLRenderingContextBase::validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment)
+{
+    if (target != GL_FRAMEBUFFER) {
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+        return false;
+    }
+    switch (attachment) {
+    case GL_COLOR_ATTACHMENT0:
+    case GL_DEPTH_ATTACHMENT:
+    case GL_STENCIL_ATTACHMENT:
+    case GC3D_DEPTH_STENCIL_ATTACHMENT_WEBGL:
+        break;
+    default:
+        if (extensionEnabled(WebGLDrawBuffersName)
+            && attachment > GL_COLOR_ATTACHMENT0
+            && attachment < static_cast<GLenum>(GL_COLOR_ATTACHMENT0 + maxColorAttachments()))
+            break;
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid attachment");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateBlendEquation(const char* functionName, GLenum mode)
+{
+    switch (mode) {
+    case GL_FUNC_ADD:
+    case GL_FUNC_SUBTRACT:
+    case GL_FUNC_REVERSE_SUBTRACT:
+        return true;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid mode");
+        return false;
+    }
+}
+
+bool WebGLRenderingContextBase::validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst)
+{
+    if (((src == GL_CONSTANT_COLOR || src == GL_ONE_MINUS_CONSTANT_COLOR)
+        && (dst == GL_CONSTANT_ALPHA || dst == GL_ONE_MINUS_CONSTANT_ALPHA))
+        || ((dst == GL_CONSTANT_COLOR || dst == GL_ONE_MINUS_CONSTANT_COLOR)
+        && (src == GL_CONSTANT_ALPHA || src == GL_ONE_MINUS_CONSTANT_ALPHA))) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "incompatible src and dst");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateCapability(const char* functionName, GLenum cap)
+{
+    switch (cap) {
+    case GL_BLEND:
+    case GL_CULL_FACE:
+    case GL_DEPTH_TEST:
+    case GL_DITHER:
+    case GL_POLYGON_OFFSET_FILL:
+    case GL_SAMPLE_ALPHA_TO_COVERAGE:
+    case GL_SAMPLE_COVERAGE:
+    case GL_SCISSOR_TEST:
+    case GL_STENCIL_TEST:
+        return true;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid capability");
+        return false;
+    }
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Float32Array* v, GLsizei requiredMinSize)
+{
+    if (!v) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+        return false;
+    }
+    return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, Int32Array* v, GLsizei requiredMinSize)
+{
+    if (!v) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+        return false;
+    }
+    return validateUniformMatrixParameters(functionName, location, false, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformParameters(const char* functionName, const WebGLUniformLocation* location, void* v, GLsizei size, GLsizei requiredMinSize)
+{
+    return validateUniformMatrixParameters(functionName, location, false, v, size, requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, Float32Array* v, GLsizei requiredMinSize)
+{
+    if (!v) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+        return false;
+    }
+    return validateUniformMatrixParameters(functionName, location, transpose, v->data(), v->length(), requiredMinSize);
+}
+
+bool WebGLRenderingContextBase::validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation* location, GLboolean transpose, void* v, GLsizei size, GLsizei requiredMinSize)
+{
+    if (!location)
+        return false;
+    if (location->program() != m_currentProgram) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "location is not from current program");
+        return false;
+    }
+    if (!v) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+        return false;
+    }
+    if (transpose) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "transpose not FALSE");
+        return false;
+    }
+    if (size < requiredMinSize || (size % requiredMinSize)) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
+        return false;
+    }
+    return true;
+}
+
+WebGLBuffer* WebGLRenderingContextBase::validateBufferDataParameters(const char* functionName, GLenum target, GLenum usage)
+{
+    WebGLBuffer* buffer = 0;
+    switch (target) {
+    case GL_ELEMENT_ARRAY_BUFFER:
+        buffer = m_boundVertexArrayObject->boundElementArrayBuffer().get();
+        break;
+    case GL_ARRAY_BUFFER:
+        buffer = m_boundArrayBuffer.get();
+        break;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid target");
+        return 0;
+    }
+    if (!buffer) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no buffer");
+        return 0;
+    }
+    switch (usage) {
+    case GL_STREAM_DRAW:
+    case GL_STATIC_DRAW:
+    case GL_DYNAMIC_DRAW:
+        return buffer;
+    }
+    synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid usage");
+    return 0;
+}
+
+bool WebGLRenderingContextBase::validateHTMLImageElement(const char* functionName, HTMLImageElement* image, ExceptionState& exceptionState)
+{
+    if (!image || !image->cachedImage()) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no image");
+        return false;
+    }
+    const KURL& url = image->cachedImage()->response().url();
+    if (url.isNull() || url.isEmpty() || !url.isValid()) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid image");
+        return false;
+    }
+    if (image->wouldTaintOrigin(canvas()->securityOrigin())) {
+        exceptionState.throwSecurityError("The cross-origin image at " + url.elidedString() + " may not be loaded.");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement* canvas, ExceptionState& exceptionState)
+{
+    if (!canvas || !canvas->buffer()) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no canvas");
+        return false;
+    }
+    if (canvas->wouldTaintOrigin(this->canvas()->securityOrigin())) {
+        exceptionState.throwSecurityError("Tainted canvases may not be loaded.");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateHTMLVideoElement(const char* functionName, HTMLVideoElement* video, ExceptionState& exceptionState)
+{
+    if (!video || !video->videoWidth() || !video->videoHeight()) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no video");
+        return false;
+    }
+    if (video->wouldTaintOrigin(canvas()->securityOrigin())) {
+        exceptionState.throwSecurityError("The video element contains cross-origin data, and may not be loaded.");
+        return false;
+    }
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count)
+{
+    if (isContextLost() || !validateDrawMode(functionName, mode))
+        return false;
+
+    if (!validateStencilSettings(functionName))
+        return false;
+
+    if (first < 0 || count < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "first or count < 0");
+        return false;
+    }
+
+    if (!count) {
+        markContextChanged(CanvasChanged);
+        return false;
+    }
+
+    if (!validateRenderingState(functionName)) {
+        return false;
+    }
+
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
+        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+        return false;
+    }
+
+    return true;
+}
+
+bool WebGLRenderingContextBase::validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset)
+{
+    if (isContextLost() || !validateDrawMode(functionName, mode))
+        return false;
+
+    if (!validateStencilSettings(functionName))
+        return false;
+
+    switch (type) {
+    case GL_UNSIGNED_BYTE:
+    case GL_UNSIGNED_SHORT:
+        break;
+    case GL_UNSIGNED_INT:
+        if (extensionEnabled(OESElementIndexUintName))
+            break;
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
+        return false;
+    default:
+        synthesizeGLError(GL_INVALID_ENUM, functionName, "invalid type");
+        return false;
+    }
+
+    if (count < 0 || offset < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "count or offset < 0");
+        return false;
+    }
+
+    if (!count) {
+        markContextChanged(CanvasChanged);
+        return false;
+    }
+
+    if (!m_boundVertexArrayObject->boundElementArrayBuffer()) {
+        synthesizeGLError(GL_INVALID_OPERATION, functionName, "no ELEMENT_ARRAY_BUFFER bound");
+        return false;
+    }
+
+    if (!validateRenderingState(functionName)) {
+        return false;
+    }
+
+    const char* reason = "framebuffer incomplete";
+    if (m_framebufferBinding && !m_framebufferBinding->onAccess(m_context.get(), &reason)) {
+        synthesizeGLError(GL_INVALID_FRAMEBUFFER_OPERATION, functionName, reason);
+        return false;
+    }
+
+    return true;
+}
+
+// Helper function to validate draw*Instanced calls
+bool WebGLRenderingContextBase::validateDrawInstanced(const char* functionName, GLsizei primcount)
+{
+    if (primcount < 0) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "primcount < 0");
+        return false;
+    }
+
+    // Ensure at least one enabled vertex attrib has a divisor of 0.
+    for (unsigned i = 0; i < m_onePlusMaxEnabledAttribIndex; ++i) {
+        const WebGLVertexArrayObjectOES::VertexAttribState& state = m_boundVertexArrayObject->getVertexAttribState(i);
+        if (state.enabled && !state.divisor)
+            return true;
+    }
+
+    synthesizeGLError(GL_INVALID_OPERATION, functionName, "at least one enabled attribute must have a divisor of 0");
+    return false;
+}
+
+void WebGLRenderingContextBase::vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3)
+{
+    if (isContextLost())
+        return;
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
+        return;
+    }
+    // In GL, we skip setting vertexAttrib0 values.
+    switch (expectedSize) {
+    case 1:
+        m_context->vertexAttrib1f(index, v0);
+        break;
+    case 2:
+        m_context->vertexAttrib2f(index, v0, v1);
+        break;
+    case 3:
+        m_context->vertexAttrib3f(index, v0, v1, v2);
+        break;
+    case 4:
+        m_context->vertexAttrib4f(index, v0, v1, v2, v3);
+        break;
+    }
+    VertexAttribValue& attribValue = m_vertexAttribValue[index];
+    attribValue.value[0] = v0;
+    attribValue.value[1] = v1;
+    attribValue.value[2] = v2;
+    attribValue.value[3] = v3;
+}
+
+void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array* v, GLsizei expectedSize)
+{
+    if (isContextLost())
+        return;
+    if (!v) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+        return;
+    }
+    vertexAttribfvImpl(functionName, index, v->data(), v->length(), expectedSize);
+}
+
+void WebGLRenderingContextBase::vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat* v, GLsizei size, GLsizei expectedSize)
+{
+    if (isContextLost())
+        return;
+    if (!v) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "no array");
+        return;
+    }
+    if (size < expectedSize) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "invalid size");
+        return;
+    }
+    if (index >= m_maxVertexAttribs) {
+        synthesizeGLError(GL_INVALID_VALUE, functionName, "index out of range");
+        return;
+    }
+    // In GL, we skip setting vertexAttrib0 values.
+    switch (expectedSize) {
+    case 1:
+        m_context->vertexAttrib1fv(index, v);
+        break;
+    case 2:
+        m_context->vertexAttrib2fv(index, v);
+        break;
+    case 3:
+        m_context->vertexAttrib3fv(index, v);
+        break;
+    case 4:
+        m_context->vertexAttrib4fv(index, v);
+        break;
+    }
+    VertexAttribValue& attribValue = m_vertexAttribValue[index];
+    attribValue.initValue();
+    for (int ii = 0; ii < expectedSize; ++ii)
+        attribValue.value[ii] = v[ii];
+}
+
+void WebGLRenderingContextBase::dispatchContextLostEvent(Timer<WebGLRenderingContextBase>*)
+{
+    RefPtr<WebGLContextEvent> event = WebGLContextEvent::create(EventTypeNames::webglcontextlost, false, true, "");
+    canvas()->dispatchEvent(event);
+    m_restoreAllowed = event->defaultPrevented();
+    deactivateContext(this, m_contextLostMode != RealLostContext && m_restoreAllowed);
+    if ((m_contextLostMode == RealLostContext || m_contextLostMode == AutoRecoverSyntheticLostContext) && m_restoreAllowed)
+        m_restoreTimer.startOneShot(0, FROM_HERE);
+}
+
+void WebGLRenderingContextBase::maybeRestoreContext(Timer<WebGLRenderingContextBase>*)
+{
+    ASSERT(isContextLost());
+
+    // The rendering context is not restored unless the default behavior of the
+    // webglcontextlost event was prevented earlier.
+    //
+    // Because of the way m_restoreTimer is set up for real vs. synthetic lost
+    // context events, we don't have to worry about this test short-circuiting
+    // the retry loop for real context lost events.
+    if (!m_restoreAllowed)
+        return;
+
+    LocalFrame* frame = canvas()->document().frame();
+    if (!frame)
+        return;
+
+    Settings* settings = frame->settings();
+
+    if (!frame->loader().client()->allowWebGL(settings && settings->webGLEnabled()))
+        return;
+
+    blink::WebGraphicsContext3D::Attributes attributes = m_requestedAttributes->attributes(canvas()->document().topDocument().url().string(), settings);
+    OwnPtr<blink::WebGraphicsContext3D> context = adoptPtr(blink::Platform::current()->createOffscreenGraphicsContext3D(attributes));
+    if (!context) {
+        if (m_contextLostMode == RealLostContext) {
+            m_restoreTimer.startOneShot(secondsBetweenRestoreAttempts, FROM_HERE);
+        } else {
+            // This likely shouldn't happen but is the best way to report it to the WebGL app.
+            synthesizeGLError(GL_INVALID_OPERATION, "", "error restoring context");
+        }
+        return;
+    }
+
+    RefPtr<WebGLRenderingContextEvictionManager> contextEvictionManager = adoptRef(new WebGLRenderingContextEvictionManager());
+
+    // Construct a new drawing buffer with the new WebGraphicsContext3D.
+    m_drawingBuffer->releaseResources();
+    DrawingBuffer::PreserveDrawingBuffer preserve = m_requestedAttributes->preserveDrawingBuffer() ? DrawingBuffer::Preserve : DrawingBuffer::Discard;
+    m_drawingBuffer = DrawingBuffer::create(context.get(), clampedCanvasSize(), preserve, contextEvictionManager.release());
+
+    if (m_drawingBuffer->isZeroSized())
+        return;
+
+    m_drawingBuffer->bind();
+
+    m_lostContextErrors.clear();
+
+    m_context = context.release();
+    m_contextLost = false;
+
+    setupFlags();
+    initializeNewContext();
+    markContextChanged(CanvasContextChanged);
+    canvas()->dispatchEvent(WebGLContextEvent::create(EventTypeNames::webglcontextrestored, false, true, ""));
+}
+
+String WebGLRenderingContextBase::ensureNotNull(const String& text) const
+{
+    if (text.isNull())
+        return WTF::emptyString();
+    return text;
+}
+
+WebGLRenderingContextBase::LRUImageBufferCache::LRUImageBufferCache(int capacity)
+    : m_buffers(adoptArrayPtr(new OwnPtr<ImageBuffer>[capacity]))
+    , m_capacity(capacity)
+{
+}
+
+ImageBuffer* WebGLRenderingContextBase::LRUImageBufferCache::imageBuffer(const IntSize& size)
+{
+    int i;
+    for (i = 0; i < m_capacity; ++i) {
+        ImageBuffer* buf = m_buffers[i].get();
+        if (!buf)
+            break;
+        if (buf->size() != size)
+            continue;
+        bubbleToFront(i);
+        return buf;
+    }
+
+    OwnPtr<ImageBuffer> temp(ImageBuffer::create(size));
+    if (!temp)
+        return 0;
+    i = std::min(m_capacity - 1, i);
+    m_buffers[i] = temp.release();
+
+    ImageBuffer* buf = m_buffers[i].get();
+    bubbleToFront(i);
+    return buf;
+}
+
+void WebGLRenderingContextBase::LRUImageBufferCache::bubbleToFront(int idx)
+{
+    for (int i = idx; i > 0; --i)
+        m_buffers[i].swap(m_buffers[i-1]);
+}
+
+namespace {
+
+    String GetErrorString(GLenum error)
+    {
+        switch (error) {
+        case GL_INVALID_ENUM:
+            return "INVALID_ENUM";
+        case GL_INVALID_VALUE:
+            return "INVALID_VALUE";
+        case GL_INVALID_OPERATION:
+            return "INVALID_OPERATION";
+        case GL_OUT_OF_MEMORY:
+            return "OUT_OF_MEMORY";
+        case GL_INVALID_FRAMEBUFFER_OPERATION:
+            return "INVALID_FRAMEBUFFER_OPERATION";
+        case GC3D_CONTEXT_LOST_WEBGL:
+            return "CONTEXT_LOST_WEBGL";
+        default:
+            return String::format("WebGL ERROR(0x%04X)", error);
+        }
+    }
+
+} // namespace anonymous
+
+void WebGLRenderingContextBase::synthesizeGLError(GLenum error, const char* functionName, const char* description, ConsoleDisplayPreference display)
+{
+    String errorType = GetErrorString(error);
+    if (m_synthesizedErrorsToConsole && display == DisplayInConsole) {
+        String message = String("WebGL: ") + errorType +  ": " + String(functionName) + ": " + String(description);
+        printGLErrorToConsole(message);
+    }
+    if (!isContextLost())
+        m_context->synthesizeGLError(error);
+    else {
+        if (m_lostContextErrors.find(error) == WTF::kNotFound)
+            m_lostContextErrors.append(error);
+    }
+    InspectorInstrumentation::didFireWebGLError(canvas(), errorType);
+}
+
+void WebGLRenderingContextBase::emitGLWarning(const char* functionName, const char* description)
+{
+    if (m_synthesizedErrorsToConsole) {
+        String message = String("WebGL: ") + String(functionName) + ": " + String(description);
+        printGLErrorToConsole(message);
+    }
+    InspectorInstrumentation::didFireWebGLWarning(canvas());
+}
+
+void WebGLRenderingContextBase::applyStencilTest()
+{
+    bool haveStencilBuffer = false;
+
+    if (m_framebufferBinding)
+        haveStencilBuffer = m_framebufferBinding->hasStencilBuffer();
+    else {
+        RefPtr<WebGLContextAttributes> attributes = getContextAttributes();
+        haveStencilBuffer = attributes->stencil();
+    }
+    enableOrDisable(GL_STENCIL_TEST,
+                    m_stencilEnabled && haveStencilBuffer);
+}
+
+void WebGLRenderingContextBase::enableOrDisable(GLenum capability, bool enable)
+{
+    if (isContextLost())
+        return;
+    if (enable)
+        m_context->enable(capability);
+    else
+        m_context->disable(capability);
+}
+
+IntSize WebGLRenderingContextBase::clampedCanvasSize()
+{
+    return IntSize(clamp(canvas()->width(), 1, m_maxViewportDims[0]),
+                   clamp(canvas()->height(), 1, m_maxViewportDims[1]));
+}
+
+GLint WebGLRenderingContextBase::maxDrawBuffers()
+{
+    if (isContextLost() || !extensionEnabled(WebGLDrawBuffersName))
+        return 0;
+    if (!m_maxDrawBuffers)
+        m_context->getIntegerv(GL_MAX_DRAW_BUFFERS_EXT, &m_maxDrawBuffers);
+    if (!m_maxColorAttachments)
+        m_context->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+    // WEBGL_draw_buffers requires MAX_COLOR_ATTACHMENTS >= MAX_DRAW_BUFFERS.
+    return std::min(m_maxDrawBuffers, m_maxColorAttachments);
+}
+
+GLint WebGLRenderingContextBase::maxColorAttachments()
+{
+    if (isContextLost() || !extensionEnabled(WebGLDrawBuffersName))
+        return 0;
+    if (!m_maxColorAttachments)
+        m_context->getIntegerv(GL_MAX_COLOR_ATTACHMENTS_EXT, &m_maxColorAttachments);
+    return m_maxColorAttachments;
+}
+
+void WebGLRenderingContextBase::setBackDrawBuffer(GLenum buf)
+{
+    m_backDrawBuffer = buf;
+}
+
+void WebGLRenderingContextBase::restoreCurrentFramebuffer()
+{
+    bindFramebuffer(GL_FRAMEBUFFER, m_framebufferBinding.get());
+}
+
+void WebGLRenderingContextBase::restoreCurrentTexture2D()
+{
+    bindTexture(GL_TEXTURE_2D, m_textureUnits[m_activeTextureUnit].m_texture2DBinding.get());
+}
+
+void WebGLRenderingContextBase::multisamplingChanged(bool enabled)
+{
+    if (m_multisamplingAllowed != enabled) {
+        m_multisamplingAllowed = enabled;
+        forceLostContext(WebGLRenderingContextBase::AutoRecoverSyntheticLostContext);
+    }
+}
+
+void WebGLRenderingContextBase::findNewMaxEnabledAttribIndex()
+{
+    // Trace backwards from the current max to find the new max enabled attrib index
+    int startIndex = m_onePlusMaxEnabledAttribIndex - 1;
+    for (int i = startIndex; i >= 0; --i) {
+        if (m_boundVertexArrayObject->getVertexAttribState(i).enabled) {
+            m_onePlusMaxEnabledAttribIndex = i + 1;
+            return;
+        }
+    }
+    m_onePlusMaxEnabledAttribIndex = 0;
+}
+
+void WebGLRenderingContextBase::findNewMaxNonDefaultTextureUnit()
+{
+    // Trace backwards from the current max to find the new max non-default texture unit
+    int startIndex = m_onePlusMaxNonDefaultTextureUnit - 1;
+    for (int i = startIndex; i >= 0; --i) {
+        if (m_textureUnits[i].m_texture2DBinding
+            || m_textureUnits[i].m_textureCubeMapBinding) {
+            m_onePlusMaxNonDefaultTextureUnit = i + 1;
+            return;
+        }
+    }
+    m_onePlusMaxNonDefaultTextureUnit = 0;
+}
+
+} // namespace WebCore
diff --git a/Source/core/html/canvas/WebGLRenderingContextBase.h b/Source/core/html/canvas/WebGLRenderingContextBase.h
new file mode 100644
index 0000000..41b1d69
--- /dev/null
+++ b/Source/core/html/canvas/WebGLRenderingContextBase.h
@@ -0,0 +1,925 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef WebGLRenderingContextBase_h
+#define WebGLRenderingContextBase_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/dom/ActiveDOMObject.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/html/canvas/WebGLExtensionName.h"
+#include "core/html/canvas/WebGLGetInfo.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderBoxModelObject.h"
+#include "platform/Timer.h"
+#include "platform/graphics/GraphicsTypes3D.h"
+#include "platform/graphics/ImageBuffer.h"
+#include "platform/graphics/gpu/Extensions3DUtil.h"
+#include "platform/graphics/gpu/WebGLImageConversion.h"
+#include "public/platform/WebGraphicsContext3D.h"
+#include "wtf/Float32Array.h"
+#include "wtf/Int32Array.h"
+#include "wtf/OwnPtr.h"
+#include "wtf/text/WTFString.h"
+
+namespace blink {
+class WebLayer;
+}
+
+namespace WebCore {
+
+class ANGLEInstancedArrays;
+class DrawingBuffer;
+class EXTFragDepth;
+class EXTTextureFilterAnisotropic;
+class ExceptionState;
+class HTMLImageElement;
+class HTMLVideoElement;
+class ImageBuffer;
+class ImageData;
+class IntSize;
+class OESElementIndexUint;
+class OESStandardDerivatives;
+class OESTextureFloat;
+class OESTextureFloatLinear;
+class OESTextureHalfFloat;
+class OESTextureHalfFloatLinear;
+class OESVertexArrayObject;
+class WebGLActiveInfo;
+class WebGLBuffer;
+class WebGLCompressedTextureATC;
+class WebGLCompressedTexturePVRTC;
+class WebGLCompressedTextureS3TC;
+class WebGLContextAttributes;
+class WebGLContextGroup;
+class WebGLContextObject;
+class WebGLDebugRendererInfo;
+class WebGLDebugShaders;
+class WebGLDepthTexture;
+class WebGLDrawBuffers;
+class WebGLExtension;
+class WebGLFramebuffer;
+class WebGLLoseContext;
+class WebGLObject;
+class WebGLProgram;
+class WebGLRenderbuffer;
+class WebGLShader;
+class WebGLShaderPrecisionFormat;
+class WebGLSharedObject;
+class WebGLTexture;
+class WebGLUniformLocation;
+class WebGLVertexArrayObjectOES;
+
+class WebGLRenderingContextLostCallback;
+class WebGLRenderingContextErrorMessageCallback;
+
+class WebGLRenderingContextBase: public ScriptWrappable, public CanvasRenderingContext, public ActiveDOMObject, private Page::MultisamplingChangedObserver {
+public:
+    virtual ~WebGLRenderingContextBase();
+
+    virtual bool is3d() const OVERRIDE { return true; }
+    virtual bool isAccelerated() const OVERRIDE { return true; }
+    virtual unsigned version() const = 0;
+    virtual String contextName() const = 0;
+    virtual void registerContextExtensions() = 0;
+
+    static unsigned getWebGLVersion(const CanvasRenderingContext*);
+
+    int drawingBufferWidth() const;
+    int drawingBufferHeight() const;
+
+    void activeTexture(GLenum texture);
+    void attachShader(WebGLProgram*, WebGLShader*);
+    void bindAttribLocation(WebGLProgram*, GLuint index, const String& name);
+    void bindBuffer(GLenum target, WebGLBuffer*);
+    void bindFramebuffer(GLenum target, WebGLFramebuffer*);
+    void bindRenderbuffer(GLenum target, WebGLRenderbuffer*);
+    void bindTexture(GLenum target, WebGLTexture*);
+    void blendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+    void blendEquation(GLenum mode);
+    void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+    void blendFunc(GLenum sfactor, GLenum dfactor);
+    void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+
+    void bufferData(GLenum target, long long size, GLenum usage);
+    void bufferData(GLenum target, ArrayBuffer* data, GLenum usage);
+    void bufferData(GLenum target, ArrayBufferView* data, GLenum usage);
+    void bufferSubData(GLenum target, long long offset, ArrayBuffer* data);
+    void bufferSubData(GLenum target, long long offset, ArrayBufferView* data);
+
+    GLenum checkFramebufferStatus(GLenum target);
+    void clear(GLbitfield mask);
+    void clearColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
+    void clearDepth(GLfloat);
+    void clearStencil(GLint);
+    void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+    void compileShader(WebGLShader*);
+
+    void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, ArrayBufferView* data);
+    void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* data);
+
+    void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+    void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+    PassRefPtr<WebGLBuffer> createBuffer();
+    PassRefPtr<WebGLFramebuffer> createFramebuffer();
+    PassRefPtr<WebGLProgram> createProgram();
+    PassRefPtr<WebGLRenderbuffer> createRenderbuffer();
+    PassRefPtr<WebGLShader> createShader(GLenum type);
+    PassRefPtr<WebGLTexture> createTexture();
+
+    void cullFace(GLenum mode);
+
+    void deleteBuffer(WebGLBuffer*);
+    void deleteFramebuffer(WebGLFramebuffer*);
+    void deleteProgram(WebGLProgram*);
+    void deleteRenderbuffer(WebGLRenderbuffer*);
+    void deleteShader(WebGLShader*);
+    void deleteTexture(WebGLTexture*);
+
+    void depthFunc(GLenum);
+    void depthMask(GLboolean);
+    void depthRange(GLfloat zNear, GLfloat zFar);
+    void detachShader(WebGLProgram*, WebGLShader*);
+    void disable(GLenum cap);
+    void disableVertexAttribArray(GLuint index);
+    void drawArrays(GLenum mode, GLint first, GLsizei count);
+    void drawElements(GLenum mode, GLsizei count, GLenum type, long long offset);
+
+    void drawArraysInstancedANGLE(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
+    void drawElementsInstancedANGLE(GLenum mode, GLsizei count, GLenum type, GLintptr offset, GLsizei primcount);
+
+    void enable(GLenum cap);
+    void enableVertexAttribArray(GLuint index);
+    void finish();
+    void flush();
+    void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer*);
+    void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture*, GLint level);
+    void frontFace(GLenum mode);
+    void generateMipmap(GLenum target);
+
+    PassRefPtr<WebGLActiveInfo> getActiveAttrib(WebGLProgram*, GLuint index);
+    PassRefPtr<WebGLActiveInfo> getActiveUniform(WebGLProgram*, GLuint index);
+    bool getAttachedShaders(WebGLProgram*, Vector<RefPtr<WebGLShader> >&);
+    GLint getAttribLocation(WebGLProgram*, const String& name);
+    WebGLGetInfo getBufferParameter(GLenum target, GLenum pname);
+    PassRefPtr<WebGLContextAttributes> getContextAttributes();
+    GLenum getError();
+    PassRefPtr<WebGLExtension> getExtension(const String& name);
+    WebGLGetInfo getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+    WebGLGetInfo getParameter(GLenum pname);
+    WebGLGetInfo getProgramParameter(WebGLProgram*, GLenum pname);
+    String getProgramInfoLog(WebGLProgram*);
+    WebGLGetInfo getRenderbufferParameter(GLenum target, GLenum pname);
+    WebGLGetInfo getShaderParameter(WebGLShader*, GLenum pname);
+    String getShaderInfoLog(WebGLShader*);
+    PassRefPtr<WebGLShaderPrecisionFormat> getShaderPrecisionFormat(GLenum shaderType, GLenum precisionType);
+    String getShaderSource(WebGLShader*);
+    Vector<String> getSupportedExtensions();
+    WebGLGetInfo getTexParameter(GLenum target, GLenum pname);
+    WebGLGetInfo getUniform(WebGLProgram*, const WebGLUniformLocation*);
+    PassRefPtr<WebGLUniformLocation> getUniformLocation(WebGLProgram*, const String&);
+    WebGLGetInfo getVertexAttrib(GLuint index, GLenum pname);
+    long long getVertexAttribOffset(GLuint index, GLenum pname);
+
+    void hint(GLenum target, GLenum mode);
+    GLboolean isBuffer(WebGLBuffer*);
+    bool isContextLost();
+    GLboolean isEnabled(GLenum cap);
+    GLboolean isFramebuffer(WebGLFramebuffer*);
+    GLboolean isProgram(WebGLProgram*);
+    GLboolean isRenderbuffer(WebGLRenderbuffer*);
+    GLboolean isShader(WebGLShader*);
+    GLboolean isTexture(WebGLTexture*);
+
+    void lineWidth(GLfloat);
+    void linkProgram(WebGLProgram*);
+    void pixelStorei(GLenum pname, GLint param);
+    void polygonOffset(GLfloat factor, GLfloat units);
+    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels);
+    void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+    void sampleCoverage(GLfloat value, GLboolean invert);
+    void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+    void shaderSource(WebGLShader*, const String&);
+    void stencilFunc(GLenum func, GLint ref, GLuint mask);
+    void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+    void stencilMask(GLuint);
+    void stencilMaskSeparate(GLenum face, GLuint mask);
+    void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+    void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border,
+        GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, ImageData*, ExceptionState&);
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
+    void texImage2D(GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
+
+    void texParameterf(GLenum target, GLenum pname, GLfloat param);
+    void texParameteri(GLenum target, GLenum pname, GLint param);
+
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLsizei width, GLsizei height,
+        GLenum format, GLenum type, ArrayBufferView*, ExceptionState&);
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, ImageData*, ExceptionState&);
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, HTMLImageElement*, ExceptionState&);
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, HTMLCanvasElement*, ExceptionState&);
+    void texSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, HTMLVideoElement*, ExceptionState&);
+
+    void uniform1f(const WebGLUniformLocation*, GLfloat x);
+    void uniform1fv(const WebGLUniformLocation*, Float32Array* v);
+    void uniform1fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+    void uniform1i(const WebGLUniformLocation*, GLint x);
+    void uniform1iv(const WebGLUniformLocation*, Int32Array* v);
+    void uniform1iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+    void uniform2f(const WebGLUniformLocation*, GLfloat x, GLfloat y);
+    void uniform2fv(const WebGLUniformLocation*, Float32Array* v);
+    void uniform2fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+    void uniform2i(const WebGLUniformLocation*, GLint x, GLint y);
+    void uniform2iv(const WebGLUniformLocation*, Int32Array* v);
+    void uniform2iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+    void uniform3f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z);
+    void uniform3fv(const WebGLUniformLocation*, Float32Array* v);
+    void uniform3fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+    void uniform3i(const WebGLUniformLocation*, GLint x, GLint y, GLint z);
+    void uniform3iv(const WebGLUniformLocation*, Int32Array* v);
+    void uniform3iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+    void uniform4f(const WebGLUniformLocation*, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+    void uniform4fv(const WebGLUniformLocation*, Float32Array* v);
+    void uniform4fv(const WebGLUniformLocation*, GLfloat* v, GLsizei);
+    void uniform4i(const WebGLUniformLocation*, GLint x, GLint y, GLint z, GLint w);
+    void uniform4iv(const WebGLUniformLocation*, Int32Array* v);
+    void uniform4iv(const WebGLUniformLocation*, GLint* v, GLsizei);
+    void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+    void uniformMatrix2fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+    void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+    void uniformMatrix3fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+    void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, Float32Array* value);
+    void uniformMatrix4fv(const WebGLUniformLocation*, GLboolean transpose, GLfloat* value, GLsizei);
+
+    void useProgram(WebGLProgram*);
+    void validateProgram(WebGLProgram*);
+
+    void vertexAttrib1f(GLuint index, GLfloat x);
+    void vertexAttrib1fv(GLuint index, Float32Array* values);
+    void vertexAttrib1fv(GLuint index, GLfloat* values, GLsizei);
+    void vertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
+    void vertexAttrib2fv(GLuint index, Float32Array* values);
+    void vertexAttrib2fv(GLuint index, GLfloat* values, GLsizei);
+    void vertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
+    void vertexAttrib3fv(GLuint index, Float32Array* values);
+    void vertexAttrib3fv(GLuint index, GLfloat* values, GLsizei);
+    void vertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+    void vertexAttrib4fv(GLuint index, Float32Array* values);
+    void vertexAttrib4fv(GLuint index, GLfloat* values, GLsizei);
+    void vertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized,
+        GLsizei stride, long long offset);
+
+    void vertexAttribDivisorANGLE(GLuint index, GLuint divisor);
+
+    void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+
+    // WEBKIT_lose_context support
+    enum LostContextMode {
+        // Lost context occurred at the graphics system level.
+        RealLostContext,
+
+        // Lost context provoked by WEBKIT_lose_context.
+        SyntheticLostContext,
+
+        // A synthetic lost context that should attempt to recover automatically
+        AutoRecoverSyntheticLostContext
+    };
+    void forceLostContext(LostContextMode);
+    void forceRestoreContext();
+    void loseContextImpl(LostContextMode);
+
+    blink::WebGraphicsContext3D* webGraphicsContext3D() const { return m_context.get(); }
+    WebGLContextGroup* contextGroup() const { return m_contextGroup.get(); }
+    virtual blink::WebLayer* platformLayer() const OVERRIDE;
+    Extensions3DUtil* extensionsUtil();
+
+    void reshape(int width, int height);
+
+    void markLayerComposited();
+    virtual void paintRenderingResultsToCanvas() OVERRIDE;
+    PassRefPtr<ImageData> paintRenderingResultsToImageData();
+
+    void removeSharedObject(WebGLSharedObject*);
+    void removeContextObject(WebGLContextObject*);
+
+    unsigned maxVertexAttribs() const { return m_maxVertexAttribs; }
+
+    // ActiveDOMObject notifications
+    virtual bool hasPendingActivity() const OVERRIDE;
+    virtual void stop() OVERRIDE;
+
+protected:
+    friend class WebGLDrawBuffers;
+    friend class WebGLFramebuffer;
+    friend class WebGLObject;
+    friend class OESVertexArrayObject;
+    friend class WebGLDebugShaders;
+    friend class WebGLCompressedTextureATC;
+    friend class WebGLCompressedTexturePVRTC;
+    friend class WebGLCompressedTextureS3TC;
+    friend class WebGLRenderingContextErrorMessageCallback;
+    friend class WebGLVertexArrayObjectOES;
+
+    WebGLRenderingContextBase(HTMLCanvasElement*, PassOwnPtr<blink::WebGraphicsContext3D>, WebGLContextAttributes*);
+    void initializeNewContext();
+    void setupFlags();
+
+    void addSharedObject(WebGLSharedObject*);
+    void addContextObject(WebGLContextObject*);
+    void detachAndRemoveAllObjects();
+
+    void destroyContext();
+    void markContextChanged(ContentChangeType);
+
+    // Query if the GL implementation is NPOT strict.
+    bool isGLES2NPOTStrict() { return m_isGLES2NPOTStrict; }
+    // Query if depth_stencil buffer is supported.
+    bool isDepthStencilSupported() { return m_isDepthStencilSupported; }
+
+    // Helper to return the size in bytes of OpenGL data types
+    // like GL_FLOAT, GL_INT, etc.
+    unsigned sizeInBytes(GLenum type);
+
+    // Check if each enabled vertex attribute is bound to a buffer.
+    bool validateRenderingState(const char*);
+
+    bool validateWebGLObject(const char*, WebGLObject*);
+
+    // Adds a compressed texture format.
+    void addCompressedTextureFormat(GLenum);
+    void removeAllCompressedTextureFormats();
+
+    PassRefPtr<Image> drawImageIntoBuffer(Image*, int width, int height, const char* functionName);
+
+    PassRefPtr<Image> videoFrameToImage(HTMLVideoElement*, BackingStoreCopy);
+
+    WebGLRenderbuffer* ensureEmulatedStencilBuffer(GLenum target, WebGLRenderbuffer*);
+
+    OwnPtr<blink::WebGraphicsContext3D> m_context;
+    RefPtr<WebGLContextGroup> m_contextGroup;
+
+    // Structure for rendering to a DrawingBuffer, instead of directly
+    // to the back-buffer of m_context.
+    RefPtr<DrawingBuffer> m_drawingBuffer;
+
+    // Dispatches a context lost event once it is determined that one is needed.
+    // This is used both for synthetic and real context losses. For real ones, it's
+    // likely that there's no JavaScript on the stack, but that might be dependent
+    // on how exactly the platform discovers that the context was lost. For better
+    // portability we always defer the dispatch of the event.
+    Timer<WebGLRenderingContextBase> m_dispatchContextLostEventTimer;
+    bool m_restoreAllowed;
+    Timer<WebGLRenderingContextBase> m_restoreTimer;
+
+    bool m_needsUpdate;
+    bool m_markedCanvasDirty;
+    HashSet<WebGLContextObject*> m_contextObjects;
+
+    OwnPtr<WebGLRenderingContextLostCallback> m_contextLostCallbackAdapter;
+    OwnPtr<WebGLRenderingContextErrorMessageCallback> m_errorMessageCallbackAdapter;
+
+    // List of bound VBO's. Used to maintain info about sizes for ARRAY_BUFFER and stored values for ELEMENT_ARRAY_BUFFER
+    RefPtr<WebGLBuffer> m_boundArrayBuffer;
+
+    RefPtr<WebGLVertexArrayObjectOES> m_defaultVertexArrayObject;
+    RefPtr<WebGLVertexArrayObjectOES> m_boundVertexArrayObject;
+    void setBoundVertexArrayObject(PassRefPtr<WebGLVertexArrayObjectOES> arrayObject)
+    {
+        if (arrayObject)
+            m_boundVertexArrayObject = arrayObject;
+        else
+            m_boundVertexArrayObject = m_defaultVertexArrayObject;
+    }
+
+    class VertexAttribValue {
+    public:
+        VertexAttribValue()
+        {
+            initValue();
+        }
+
+        void initValue()
+        {
+            value[0] = 0.0f;
+            value[1] = 0.0f;
+            value[2] = 0.0f;
+            value[3] = 1.0f;
+        }
+
+        GLfloat value[4];
+    };
+    Vector<VertexAttribValue> m_vertexAttribValue;
+    unsigned m_maxVertexAttribs;
+    RefPtr<WebGLBuffer> m_vertexAttrib0Buffer;
+    long m_vertexAttrib0BufferSize;
+    GLfloat m_vertexAttrib0BufferValue[4];
+    bool m_forceAttrib0BufferRefill;
+    bool m_vertexAttrib0UsedBefore;
+
+    RefPtr<WebGLProgram> m_currentProgram;
+    RefPtr<WebGLFramebuffer> m_framebufferBinding;
+    RefPtr<WebGLRenderbuffer> m_renderbufferBinding;
+    class TextureUnitState {
+    public:
+        RefPtr<WebGLTexture> m_texture2DBinding;
+        RefPtr<WebGLTexture> m_textureCubeMapBinding;
+    };
+    Vector<TextureUnitState> m_textureUnits;
+    unsigned long m_activeTextureUnit;
+
+    RefPtr<WebGLTexture> m_blackTexture2D;
+    RefPtr<WebGLTexture> m_blackTextureCubeMap;
+
+    Vector<GLenum> m_compressedTextureFormats;
+
+    // Fixed-size cache of reusable image buffers for video texImage2D calls.
+    class LRUImageBufferCache {
+    public:
+        LRUImageBufferCache(int capacity);
+        // The pointer returned is owned by the image buffer map.
+        ImageBuffer* imageBuffer(const IntSize& size);
+    private:
+        void bubbleToFront(int idx);
+        OwnPtr<OwnPtr<ImageBuffer>[]> m_buffers;
+        int m_capacity;
+    };
+    LRUImageBufferCache m_generatedImageCache;
+
+    GLint m_maxTextureSize;
+    GLint m_maxCubeMapTextureSize;
+    GLint m_maxRenderbufferSize;
+    GLint m_maxViewportDims[2];
+    GLint m_maxTextureLevel;
+    GLint m_maxCubeMapTextureLevel;
+
+    GLint m_maxDrawBuffers;
+    GLint m_maxColorAttachments;
+    GLenum m_backDrawBuffer;
+    bool m_drawBuffersWebGLRequirementsChecked;
+    bool m_drawBuffersSupported;
+
+    GLint m_packAlignment;
+    GLint m_unpackAlignment;
+    bool m_unpackFlipY;
+    bool m_unpackPremultiplyAlpha;
+    GLenum m_unpackColorspaceConversion;
+    bool m_contextLost;
+    LostContextMode m_contextLostMode;
+    RefPtr<WebGLContextAttributes> m_requestedAttributes;
+
+    bool m_layerCleared;
+    GLfloat m_clearColor[4];
+    bool m_scissorEnabled;
+    GLfloat m_clearDepth;
+    GLint m_clearStencil;
+    GLboolean m_colorMask[4];
+    GLboolean m_depthMask;
+
+    bool m_stencilEnabled;
+    GLuint m_stencilMask, m_stencilMaskBack;
+    GLint m_stencilFuncRef, m_stencilFuncRefBack; // Note that these are the user specified values, not the internal clamped value.
+    GLuint m_stencilFuncMask, m_stencilFuncMaskBack;
+
+    bool m_isGLES2NPOTStrict;
+    bool m_isDepthStencilSupported;
+
+    bool m_synthesizedErrorsToConsole;
+    int m_numGLErrorsToConsoleAllowed;
+
+    bool m_multisamplingAllowed;
+    bool m_multisamplingObserverRegistered;
+
+    GLuint m_onePlusMaxEnabledAttribIndex;
+    unsigned long m_onePlusMaxNonDefaultTextureUnit;
+
+    OwnPtr<Extensions3DUtil> m_extensionsUtil;
+
+    enum ExtensionFlags {
+        ApprovedExtension   = 0x00,
+        DraftExtension      = 0x01,
+        PrivilegedExtension = 0x02,
+        PrefixedExtension   = 0x04,
+        WebGLDebugRendererInfoExtension = 0x08,
+    };
+
+    class ExtensionTracker {
+    public:
+        ExtensionTracker(ExtensionFlags flags, const char* const* prefixes)
+            : m_privileged(flags & PrivilegedExtension)
+            , m_draft(flags & DraftExtension)
+            , m_prefixed(flags & PrefixedExtension)
+            , m_webglDebugRendererInfo(flags & WebGLDebugRendererInfoExtension)
+            , m_prefixes(prefixes)
+        {
+        }
+
+        virtual ~ExtensionTracker()
+        {
+        }
+
+        bool prefixed() const
+        {
+            return m_prefixed;
+        }
+
+        bool privileged() const
+        {
+            return m_privileged;
+        }
+
+        bool draft() const
+        {
+            return m_draft;
+        }
+
+        bool webglDebugRendererInfo() const
+        {
+            return m_webglDebugRendererInfo;
+        }
+
+        bool matchesNameWithPrefixes(const String&) const;
+
+        virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContextBase*) = 0;
+        virtual bool supported(WebGLRenderingContextBase*) const = 0;
+        virtual const char* extensionName() const = 0;
+        virtual void loseExtension() = 0;
+
+    private:
+        bool m_privileged;
+        bool m_draft;
+        bool m_prefixed;
+        bool m_webglDebugRendererInfo;
+        const char* const* m_prefixes;
+    };
+
+    template <typename T>
+    class TypedExtensionTracker FINAL : public ExtensionTracker {
+    public:
+        TypedExtensionTracker(RefPtr<T>& extensionField, ExtensionFlags flags, const char* const* prefixes)
+            : ExtensionTracker(flags, prefixes)
+            , m_extensionField(extensionField)
+            , m_extension(nullptr)
+        {
+        }
+
+        virtual ~TypedExtensionTracker()
+        {
+            if (m_extension) {
+                m_extension->lose(true);
+                m_extension = nullptr;
+            }
+        }
+
+        virtual PassRefPtr<WebGLExtension> getExtension(WebGLRenderingContextBase* context) OVERRIDE
+        {
+            if (!m_extension) {
+                m_extension = T::create(context);
+                m_extensionField = m_extension;
+            }
+
+            return m_extension;
+        }
+
+        virtual bool supported(WebGLRenderingContextBase* context) const OVERRIDE
+        {
+            return T::supported(context);
+        }
+
+        virtual const char* extensionName() const OVERRIDE
+        {
+            return T::extensionName();
+        }
+
+        virtual void loseExtension() OVERRIDE
+        {
+            if (m_extension) {
+                m_extension->lose(false);
+                if (m_extension->isLost())
+                    m_extension = nullptr;
+            }
+        }
+
+    private:
+        RefPtr<T>& m_extensionField;
+        // ExtensionTracker holds it's own reference to the extension to ensure
+        // that it is not deleted before this object's destructor is called
+        RefPtr<T> m_extension;
+    };
+
+    bool m_extensionEnabled[WebGLExtensionNameCount];
+    Vector<ExtensionTracker*> m_extensions;
+
+    template <typename T>
+    void registerExtension(RefPtr<T>& extensionPtr, ExtensionFlags flags = ApprovedExtension, const char* const* prefixes = 0)
+    {
+        m_extensions.append(new TypedExtensionTracker<T>(extensionPtr, flags, prefixes));
+    }
+
+    inline bool extensionEnabled(WebGLExtensionName name)
+    {
+        return m_extensionEnabled[name];
+    }
+
+    // Errors raised by synthesizeGLError() while the context is lost.
+    Vector<GLenum> m_lostContextErrors;
+
+    // Helpers for getParameter and others
+    WebGLGetInfo getBooleanParameter(GLenum);
+    WebGLGetInfo getBooleanArrayParameter(GLenum);
+    WebGLGetInfo getFloatParameter(GLenum);
+    WebGLGetInfo getIntParameter(GLenum);
+    WebGLGetInfo getUnsignedIntParameter(GLenum);
+    WebGLGetInfo getWebGLFloatArrayParameter(GLenum);
+    WebGLGetInfo getWebGLIntArrayParameter(GLenum);
+
+    // Clear the backbuffer if it was composited since the last operation.
+    // clearMask is set to the bitfield of any clear that would happen anyway at this time
+    // and the function returns true if that clear is now unnecessary.
+    bool clearIfComposited(GLbitfield clearMask = 0);
+
+    // Helper to restore state that clearing the framebuffer may destroy.
+    void restoreStateAfterClear();
+
+    // Convert texture internal format.
+    GLenum convertTexInternalFormat(GLenum internalformat, GLenum type);
+
+    void texImage2DBase(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void* pixels, ExceptionState&);
+    void texImage2DImpl(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
+    void texSubImage2DBase(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void* pixels, ExceptionState&);
+    void texSubImage2DImpl(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLenum format, GLenum type, Image*, WebGLImageConversion::ImageHtmlDomSource, bool flipY, bool premultiplyAlpha, ExceptionState&);
+
+    void handleTextureCompleteness(const char*, bool);
+    void createFallbackBlackTextures1x1();
+
+    // Helper function for copyTex{Sub}Image, check whether the internalformat
+    // and the color buffer format of the current bound framebuffer combination
+    // is valid.
+    bool isTexInternalFormatColorBufferCombinationValid(GLenum texInternalFormat, GLenum colorBufferFormat);
+
+    // Helper function to get the bound framebuffer's color buffer format.
+    GLenum boundFramebufferColorFormat();
+
+    // Helper function to verify limits on the length of uniform and attribute locations.
+    bool validateLocationLength(const char* functionName, const String&);
+
+    // Helper function to check if size is non-negative.
+    // Generate GL error and return false for negative inputs; otherwise, return true.
+    bool validateSize(const char* functionName, GLint x, GLint y);
+
+    // Helper function to check if all characters in the string belong to the
+    // ASCII subset as defined in GLSL ES 1.0 spec section 3.1.
+    bool validateString(const char* functionName, const String&);
+
+    // Helper function to check target and texture bound to the target.
+    // Generate GL errors and return 0 if target is invalid or texture bound is
+    // null.  Otherwise, return the texture bound to the target.
+    WebGLTexture* validateTextureBinding(const char* functionName, GLenum target, bool useSixEnumsForCubeMap);
+
+    // Helper function to check input format/type for functions {copy}Tex{Sub}Image.
+    // Generates GL error and returns false if parameters are invalid.
+    bool validateTexFuncFormatAndType(const char* functionName, GLenum format, GLenum type, GLint level);
+
+    // Helper function to check input level for functions {copy}Tex{Sub}Image.
+    // Generates GL error and returns false if level is invalid.
+    bool validateTexFuncLevel(const char* functionName, GLenum target, GLint level);
+
+    enum TexFuncValidationFunctionType {
+        NotTexSubImage2D,
+        TexSubImage2D,
+    };
+
+    enum TexFuncValidationSourceType {
+        SourceArrayBufferView,
+        SourceImageData,
+        SourceHTMLImageElement,
+        SourceHTMLCanvasElement,
+        SourceHTMLVideoElement,
+    };
+
+    // Helper function for tex{Sub}Image2D to check if the input format/type/level/target/width/height/border/xoffset/yoffset are valid.
+    // Otherwise, it would return quickly without doing other work.
+    bool validateTexFunc(const char* functionName, TexFuncValidationFunctionType, TexFuncValidationSourceType, GLenum target, GLint level, GLenum internalformat, GLsizei width,
+        GLsizei height, GLint border, GLenum format, GLenum type, GLint xoffset, GLint yoffset);
+
+    // Helper function to check input width and height for functions {copy, compressed}Tex{Sub}Image.
+    // Generates GL error and returns false if width or height is invalid.
+    bool validateTexFuncDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height);
+
+    // Helper function to check input parameters for functions {copy}Tex{Sub}Image.
+    // Generates GL error and returns false if parameters are invalid.
+    bool validateTexFuncParameters(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type);
+
+    enum NullDisposition {
+        NullAllowed,
+        NullNotAllowed
+    };
+
+    // Helper function to validate that the given ArrayBufferView
+    // is of the correct type and contains enough data for the texImage call.
+    // Generates GL error and returns false if parameters are invalid.
+    bool validateTexFuncData(const char* functionName, GLint level, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView* pixels, NullDisposition);
+
+    // Helper function to validate a given texture format is settable as in
+    // you can supply data to texImage2D, or call texImage2D, copyTexImage2D and
+    // copyTexSubImage2D.
+    // Generates GL error and returns false if the format is not settable.
+    bool validateSettableTexFormat(const char* functionName, GLenum format);
+
+    // Helper function to validate compressed texture data is correct size
+    // for the given format and dimensions.
+    bool validateCompressedTexFuncData(const char* functionName, GLsizei width, GLsizei height, GLenum format, ArrayBufferView* pixels);
+
+    // Helper function for validating compressed texture formats.
+    bool validateCompressedTexFormat(GLenum format);
+
+    // Helper function to validate compressed texture dimensions are valid for
+    // the given format.
+    bool validateCompressedTexDimensions(const char* functionName, TexFuncValidationFunctionType, GLenum target, GLint level, GLsizei width, GLsizei height, GLenum format);
+
+    // Helper function to validate compressed texture dimensions are valid for
+    // the given format.
+    bool validateCompressedTexSubDimensions(const char* functionName, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, WebGLTexture*);
+
+    // Helper function to validate mode for draw{Arrays/Elements}.
+    bool validateDrawMode(const char* functionName, GLenum);
+
+    // Helper function to validate if front/back stencilMask and stencilFunc settings are the same.
+    bool validateStencilSettings(const char* functionName);
+
+    // Helper function to validate stencil or depth func.
+    bool validateStencilOrDepthFunc(const char* functionName, GLenum);
+
+    // Helper function for texParameterf and texParameteri.
+    void texParameter(GLenum target, GLenum pname, GLfloat parami, GLint paramf, bool isFloat);
+
+    // Helper function to print GL errors to console.
+    void printGLErrorToConsole(const String&);
+
+    // Helper function to print warnings to console. Currently
+    // used only to warn about use of obsolete functions.
+    void printWarningToConsole(const String&);
+
+    // Helper function to validate input parameters for framebuffer functions.
+    // Generate GL error if parameters are illegal.
+    bool validateFramebufferFuncParameters(const char* functionName, GLenum target, GLenum attachment);
+
+    // Helper function to validate blend equation mode.
+    bool validateBlendEquation(const char* functionName, GLenum);
+
+    // Helper function to validate blend func factors.
+    bool validateBlendFuncFactors(const char* functionName, GLenum src, GLenum dst);
+
+    // Helper function to validate a GL capability.
+    bool validateCapability(const char* functionName, GLenum);
+
+    // Helper function to validate input parameters for uniform functions.
+    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Float32Array*, GLsizei mod);
+    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, Int32Array*, GLsizei mod);
+    bool validateUniformParameters(const char* functionName, const WebGLUniformLocation*, void*, GLsizei, GLsizei mod);
+    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, Float32Array*, GLsizei mod);
+    bool validateUniformMatrixParameters(const char* functionName, const WebGLUniformLocation*, GLboolean transpose, void*, GLsizei, GLsizei mod);
+
+    // Helper function to validate parameters for bufferData.
+    // Return the current bound buffer to target, or 0 if parameters are invalid.
+    WebGLBuffer* validateBufferDataParameters(const char* functionName, GLenum target, GLenum usage);
+
+    // Helper function for tex{Sub}Image2D to make sure image is ready and wouldn't taint Origin.
+    bool validateHTMLImageElement(const char* functionName, HTMLImageElement*, ExceptionState&);
+
+    // Helper function for tex{Sub}Image2D to make sure canvas is ready and wouldn't taint Origin.
+    bool validateHTMLCanvasElement(const char* functionName, HTMLCanvasElement*, ExceptionState&);
+
+    // Helper function for tex{Sub}Image2D to make sure video is ready wouldn't taint Origin.
+    bool validateHTMLVideoElement(const char* functionName, HTMLVideoElement*, ExceptionState&);
+
+    // Helper function to validate drawArrays(Instanced) calls
+    bool validateDrawArrays(const char* functionName, GLenum mode, GLint first, GLsizei count);
+
+    // Helper function to validate drawElements(Instanced) calls
+    bool validateDrawElements(const char* functionName, GLenum mode, GLsizei count, GLenum type, long long offset);
+
+    // Helper function to validate draw*Instanced calls
+    bool validateDrawInstanced(const char* functionName, GLsizei primcount);
+
+    // Helper functions for vertexAttribNf{v}.
+    void vertexAttribfImpl(const char* functionName, GLuint index, GLsizei expectedSize, GLfloat, GLfloat, GLfloat, GLfloat);
+    void vertexAttribfvImpl(const char* functionName, GLuint index, Float32Array*, GLsizei expectedSize);
+    void vertexAttribfvImpl(const char* functionName, GLuint index, GLfloat*, GLsizei, GLsizei expectedSize);
+
+    // Helper function for delete* (deleteBuffer, deleteProgram, etc) functions.
+    // Return false if caller should return without further processing.
+    bool deleteObject(WebGLObject*);
+
+    // Helper function for bind* (bindBuffer, bindTexture, etc) and useProgram.
+    // If the object has already been deleted, set deleted to true upon return.
+    // Return false if caller should return without further processing.
+    bool checkObjectToBeBound(const char* functionName, WebGLObject*, bool& deleted);
+
+    void dispatchContextLostEvent(Timer<WebGLRenderingContextBase>*);
+    // Helper for restoration after context lost.
+    void maybeRestoreContext(Timer<WebGLRenderingContextBase>*);
+
+    // Determine if we are running privileged code in the browser, for example,
+    // a Safari or Chrome extension.
+    bool allowPrivilegedExtensions() const;
+
+    // Determine if WEBGL_debug_renderer_info extension is enabled. For the
+    // moment it can be enabled either through a chromium finch experiment
+    // or for privileged code in the browser.
+    bool allowWebGLDebugRendererInfo() const;
+
+    enum ConsoleDisplayPreference {
+        DisplayInConsole,
+        DontDisplayInConsole
+    };
+
+    // Wrapper for WebGraphicsContext3D::synthesizeGLError that sends a message
+    // to the JavaScript console.
+    void synthesizeGLError(GLenum, const char* functionName, const char* description, ConsoleDisplayPreference = DisplayInConsole);
+    void emitGLWarning(const char* function, const char* reason);
+
+    String ensureNotNull(const String&) const;
+
+    // Enable or disable stencil test based on user setting and
+    // whether the current FBO has a stencil buffer.
+    void applyStencilTest();
+
+    // Helper for enabling or disabling a capability.
+    void enableOrDisable(GLenum capability, bool enable);
+
+    // Clamp the width and height to GL_MAX_VIEWPORT_DIMS.
+    IntSize clampedCanvasSize();
+
+    // First time called, if EXT_draw_buffers is supported, query the value; otherwise return 0.
+    // Later, return the cached value.
+    GLint maxDrawBuffers();
+    GLint maxColorAttachments();
+
+    void setBackDrawBuffer(GLenum);
+
+    void restoreCurrentFramebuffer();
+    void restoreCurrentTexture2D();
+
+    virtual void multisamplingChanged(bool) OVERRIDE;
+
+    void findNewMaxEnabledAttribIndex();
+    void findNewMaxNonDefaultTextureUnit();
+
+    friend class WebGLStateRestorer;
+    friend class WebGLRenderingContextEvictionManager;
+
+    static Vector<WebGLRenderingContextBase*>& activeContexts();
+    static Vector<WebGLRenderingContextBase*>& forciblyEvictedContexts();
+
+    static void activateContext(WebGLRenderingContextBase*);
+    static void deactivateContext(WebGLRenderingContextBase*, bool addToInactiveList);
+    static void willDestroyContext(WebGLRenderingContextBase*);
+    static void forciblyLoseOldestContext(const String& reason);
+    // Return the least recently used context's position in the active context vector.
+    // If the vector is empty, return the maximum allowed active context number.
+    static size_t oldestContextIndex();
+    static IntSize oldestContextSize();
+};
+
+DEFINE_TYPE_CASTS(WebGLRenderingContextBase, CanvasRenderingContext, context, context->is3d(), context.is3d());
+
+} // namespace WebCore
+
+#endif // WebGLRenderingContextBase_h
diff --git a/Source/core/html/canvas/WebGLRenderingContextBase.idl b/Source/core/html/canvas/WebGLRenderingContextBase.idl
new file mode 100644
index 0000000..b41dd90
--- /dev/null
+++ b/Source/core/html/canvas/WebGLRenderingContextBase.idl
@@ -0,0 +1,677 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+typedef unsigned long  GLenum;
+typedef boolean        GLboolean;
+typedef unsigned long  GLbitfield;
+typedef byte           GLbyte;         /* 'byte' should be a signed 8 bit type. */
+typedef short          GLshort;
+typedef long           GLint;
+typedef long           GLsizei;
+typedef long long      GLintptr;
+typedef long long      GLsizeiptr;
+typedef octet          GLubyte;        /* 'octet' should be an unsigned 8 bit type. */
+typedef unsigned short GLushort;
+typedef unsigned long  GLuint;
+typedef /*unrestricted*/ float GLfloat;
+typedef /*unrestricted*/ float GLclampf;
+
+[
+    DoNotCheckConstants,
+    StrictTypeChecking,
+    NoInterfaceObject
+] interface WebGLRenderingContextBase {
+
+    readonly attribute HTMLCanvasElement canvas;
+
+    /* ClearBufferMask */
+    const GLenum DEPTH_BUFFER_BIT               = 0x00000100;
+    const GLenum STENCIL_BUFFER_BIT             = 0x00000400;
+    const GLenum COLOR_BUFFER_BIT               = 0x00004000;
+
+    /* BeginMode */
+    const GLenum POINTS                         = 0x0000;
+    const GLenum LINES                          = 0x0001;
+    const GLenum LINE_LOOP                      = 0x0002;
+    const GLenum LINE_STRIP                     = 0x0003;
+    const GLenum TRIANGLES                      = 0x0004;
+    const GLenum TRIANGLE_STRIP                 = 0x0005;
+    const GLenum TRIANGLE_FAN                   = 0x0006;
+
+    /* AlphaFunction (not supported in ES20) */
+    /*      NEVER */
+    /*      LESS */
+    /*      EQUAL */
+    /*      LEQUAL */
+    /*      GREATER */
+    /*      NOTEQUAL */
+    /*      GEQUAL */
+    /*      ALWAYS */
+
+    /* BlendingFactorDest */
+    const GLenum ZERO                           = 0;
+    const GLenum ONE                            = 1;
+    const GLenum SRC_COLOR                      = 0x0300;
+    const GLenum ONE_MINUS_SRC_COLOR            = 0x0301;
+    const GLenum SRC_ALPHA                      = 0x0302;
+    const GLenum ONE_MINUS_SRC_ALPHA            = 0x0303;
+    const GLenum DST_ALPHA                      = 0x0304;
+    const GLenum ONE_MINUS_DST_ALPHA            = 0x0305;
+
+    /* BlendingFactorSrc */
+    /*      ZERO */
+    /*      ONE */
+    const GLenum DST_COLOR                      = 0x0306;
+    const GLenum ONE_MINUS_DST_COLOR            = 0x0307;
+    const GLenum SRC_ALPHA_SATURATE             = 0x0308;
+    /*      SRC_ALPHA */
+    /*      ONE_MINUS_SRC_ALPHA */
+    /*      DST_ALPHA */
+    /*      ONE_MINUS_DST_ALPHA */
+
+    /* BlendEquationSeparate */
+    const GLenum FUNC_ADD                       = 0x8006;
+    const GLenum BLEND_EQUATION                 = 0x8009;
+    const GLenum BLEND_EQUATION_RGB             = 0x8009;   /* same as BLEND_EQUATION */
+    const GLenum BLEND_EQUATION_ALPHA           = 0x883D;
+
+    /* BlendSubtract */
+    const GLenum FUNC_SUBTRACT                  = 0x800A;
+    const GLenum FUNC_REVERSE_SUBTRACT          = 0x800B;
+
+    /* Separate Blend Functions */
+    const GLenum BLEND_DST_RGB                  = 0x80C8;
+    const GLenum BLEND_SRC_RGB                  = 0x80C9;
+    const GLenum BLEND_DST_ALPHA                = 0x80CA;
+    const GLenum BLEND_SRC_ALPHA                = 0x80CB;
+    const GLenum CONSTANT_COLOR                 = 0x8001;
+    const GLenum ONE_MINUS_CONSTANT_COLOR       = 0x8002;
+    const GLenum CONSTANT_ALPHA                 = 0x8003;
+    const GLenum ONE_MINUS_CONSTANT_ALPHA       = 0x8004;
+    const GLenum BLEND_COLOR                    = 0x8005;
+
+    /* Buffer Objects */
+    const GLenum ARRAY_BUFFER                   = 0x8892;
+    const GLenum ELEMENT_ARRAY_BUFFER           = 0x8893;
+    const GLenum ARRAY_BUFFER_BINDING           = 0x8894;
+    const GLenum ELEMENT_ARRAY_BUFFER_BINDING   = 0x8895;
+
+    const GLenum STREAM_DRAW                    = 0x88E0;
+    const GLenum STATIC_DRAW                    = 0x88E4;
+    const GLenum DYNAMIC_DRAW                   = 0x88E8;
+
+    const GLenum BUFFER_SIZE                    = 0x8764;
+    const GLenum BUFFER_USAGE                   = 0x8765;
+
+    const GLenum CURRENT_VERTEX_ATTRIB          = 0x8626;
+
+    /* CullFaceMode */
+    const GLenum FRONT                          = 0x0404;
+    const GLenum BACK                           = 0x0405;
+    const GLenum FRONT_AND_BACK                 = 0x0408;
+
+    /* DepthFunction */
+    /*      NEVER */
+    /*      LESS */
+    /*      EQUAL */
+    /*      LEQUAL */
+    /*      GREATER */
+    /*      NOTEQUAL */
+    /*      GEQUAL */
+    /*      ALWAYS */
+
+    /* EnableCap */
+    const GLenum TEXTURE_2D                     = 0x0DE1;
+    const GLenum CULL_FACE                      = 0x0B44;
+    const GLenum BLEND                          = 0x0BE2;
+    const GLenum DITHER                         = 0x0BD0;
+    const GLenum STENCIL_TEST                   = 0x0B90;
+    const GLenum DEPTH_TEST                     = 0x0B71;
+    const GLenum SCISSOR_TEST                   = 0x0C11;
+    const GLenum POLYGON_OFFSET_FILL            = 0x8037;
+    const GLenum SAMPLE_ALPHA_TO_COVERAGE       = 0x809E;
+    const GLenum SAMPLE_COVERAGE                = 0x80A0;
+
+    /* ErrorCode */
+    const GLenum NO_ERROR                       = 0;
+    const GLenum INVALID_ENUM                   = 0x0500;
+    const GLenum INVALID_VALUE                  = 0x0501;
+    const GLenum INVALID_OPERATION              = 0x0502;
+    const GLenum OUT_OF_MEMORY                  = 0x0505;
+
+    /* FrontFaceDirection */
+    const GLenum CW                             = 0x0900;
+    const GLenum CCW                            = 0x0901;
+
+    /* GetPName */
+    const GLenum LINE_WIDTH                     = 0x0B21;
+    const GLenum ALIASED_POINT_SIZE_RANGE       = 0x846D;
+    const GLenum ALIASED_LINE_WIDTH_RANGE       = 0x846E;
+    const GLenum CULL_FACE_MODE                 = 0x0B45;
+    const GLenum FRONT_FACE                     = 0x0B46;
+    const GLenum DEPTH_RANGE                    = 0x0B70;
+    const GLenum DEPTH_WRITEMASK                = 0x0B72;
+    const GLenum DEPTH_CLEAR_VALUE              = 0x0B73;
+    const GLenum DEPTH_FUNC                     = 0x0B74;
+    const GLenum STENCIL_CLEAR_VALUE            = 0x0B91;
+    const GLenum STENCIL_FUNC                   = 0x0B92;
+    const GLenum STENCIL_FAIL                   = 0x0B94;
+    const GLenum STENCIL_PASS_DEPTH_FAIL        = 0x0B95;
+    const GLenum STENCIL_PASS_DEPTH_PASS        = 0x0B96;
+    const GLenum STENCIL_REF                    = 0x0B97;
+    const GLenum STENCIL_VALUE_MASK             = 0x0B93;
+    const GLenum STENCIL_WRITEMASK              = 0x0B98;
+    const GLenum STENCIL_BACK_FUNC              = 0x8800;
+    const GLenum STENCIL_BACK_FAIL              = 0x8801;
+    const GLenum STENCIL_BACK_PASS_DEPTH_FAIL   = 0x8802;
+    const GLenum STENCIL_BACK_PASS_DEPTH_PASS   = 0x8803;
+    const GLenum STENCIL_BACK_REF               = 0x8CA3;
+    const GLenum STENCIL_BACK_VALUE_MASK        = 0x8CA4;
+    const GLenum STENCIL_BACK_WRITEMASK         = 0x8CA5;
+    const GLenum VIEWPORT                       = 0x0BA2;
+    const GLenum SCISSOR_BOX                    = 0x0C10;
+    /*      SCISSOR_TEST */
+    const GLenum COLOR_CLEAR_VALUE              = 0x0C22;
+    const GLenum COLOR_WRITEMASK                = 0x0C23;
+    const GLenum UNPACK_ALIGNMENT               = 0x0CF5;
+    const GLenum PACK_ALIGNMENT                 = 0x0D05;
+    const GLenum MAX_TEXTURE_SIZE               = 0x0D33;
+    const GLenum MAX_VIEWPORT_DIMS              = 0x0D3A;
+    const GLenum SUBPIXEL_BITS                  = 0x0D50;
+    const GLenum RED_BITS                       = 0x0D52;
+    const GLenum GREEN_BITS                     = 0x0D53;
+    const GLenum BLUE_BITS                      = 0x0D54;
+    const GLenum ALPHA_BITS                     = 0x0D55;
+    const GLenum DEPTH_BITS                     = 0x0D56;
+    const GLenum STENCIL_BITS                   = 0x0D57;
+    const GLenum POLYGON_OFFSET_UNITS           = 0x2A00;
+    /*      POLYGON_OFFSET_FILL */
+    const GLenum POLYGON_OFFSET_FACTOR          = 0x8038;
+    const GLenum TEXTURE_BINDING_2D             = 0x8069;
+    const GLenum SAMPLE_BUFFERS                 = 0x80A8;
+    const GLenum SAMPLES                        = 0x80A9;
+    const GLenum SAMPLE_COVERAGE_VALUE          = 0x80AA;
+    const GLenum SAMPLE_COVERAGE_INVERT         = 0x80AB;
+
+    /* GetTextureParameter */
+    /*      TEXTURE_MAG_FILTER */
+    /*      TEXTURE_MIN_FILTER */
+    /*      TEXTURE_WRAP_S */
+    /*      TEXTURE_WRAP_T */
+
+    const GLenum COMPRESSED_TEXTURE_FORMATS     = 0x86A3;
+
+    /* HintMode */
+    const GLenum DONT_CARE                      = 0x1100;
+    const GLenum FASTEST                        = 0x1101;
+    const GLenum NICEST                         = 0x1102;
+
+    /* HintTarget */
+    const GLenum GENERATE_MIPMAP_HINT            = 0x8192;
+
+    /* DataType */
+    const GLenum BYTE                           = 0x1400;
+    const GLenum UNSIGNED_BYTE                  = 0x1401;
+    const GLenum SHORT                          = 0x1402;
+    const GLenum UNSIGNED_SHORT                 = 0x1403;
+    const GLenum INT                            = 0x1404;
+    const GLenum UNSIGNED_INT                   = 0x1405;
+    const GLenum FLOAT                          = 0x1406;
+
+    /* PixelFormat */
+    const GLenum DEPTH_COMPONENT                = 0x1902;
+    const GLenum ALPHA                          = 0x1906;
+    const GLenum RGB                            = 0x1907;
+    const GLenum RGBA                           = 0x1908;
+    const GLenum LUMINANCE                      = 0x1909;
+    const GLenum LUMINANCE_ALPHA                = 0x190A;
+
+    /* PixelType */
+    /*      UNSIGNED_BYTE */
+    const GLenum UNSIGNED_SHORT_4_4_4_4         = 0x8033;
+    const GLenum UNSIGNED_SHORT_5_5_5_1         = 0x8034;
+    const GLenum UNSIGNED_SHORT_5_6_5           = 0x8363;
+
+    /* Shaders */
+    const GLenum FRAGMENT_SHADER                  = 0x8B30;
+    const GLenum VERTEX_SHADER                    = 0x8B31;
+    const GLenum MAX_VERTEX_ATTRIBS               = 0x8869;
+    const GLenum MAX_VERTEX_UNIFORM_VECTORS       = 0x8DFB;
+    const GLenum MAX_VARYING_VECTORS              = 0x8DFC;
+    const GLenum MAX_COMBINED_TEXTURE_IMAGE_UNITS = 0x8B4D;
+    const GLenum MAX_VERTEX_TEXTURE_IMAGE_UNITS   = 0x8B4C;
+    const GLenum MAX_TEXTURE_IMAGE_UNITS          = 0x8872;
+    const GLenum MAX_FRAGMENT_UNIFORM_VECTORS     = 0x8DFD;
+    const GLenum SHADER_TYPE                      = 0x8B4F;
+    const GLenum DELETE_STATUS                    = 0x8B80;
+    const GLenum LINK_STATUS                      = 0x8B82;
+    const GLenum VALIDATE_STATUS                  = 0x8B83;
+    const GLenum ATTACHED_SHADERS                 = 0x8B85;
+    const GLenum ACTIVE_UNIFORMS                  = 0x8B86;
+    const GLenum ACTIVE_ATTRIBUTES                = 0x8B89;
+    const GLenum SHADING_LANGUAGE_VERSION         = 0x8B8C;
+    const GLenum CURRENT_PROGRAM                  = 0x8B8D;
+
+    /* StencilFunction */
+    const GLenum NEVER                          = 0x0200;
+    const GLenum LESS                           = 0x0201;
+    const GLenum EQUAL                          = 0x0202;
+    const GLenum LEQUAL                         = 0x0203;
+    const GLenum GREATER                        = 0x0204;
+    const GLenum NOTEQUAL                       = 0x0205;
+    const GLenum GEQUAL                         = 0x0206;
+    const GLenum ALWAYS                         = 0x0207;
+
+    /* StencilOp */
+    /*      ZERO */
+    const GLenum KEEP                           = 0x1E00;
+    const GLenum REPLACE                        = 0x1E01;
+    const GLenum INCR                           = 0x1E02;
+    const GLenum DECR                           = 0x1E03;
+    const GLenum INVERT                         = 0x150A;
+    const GLenum INCR_WRAP                      = 0x8507;
+    const GLenum DECR_WRAP                      = 0x8508;
+
+    /* StringName */
+    const GLenum VENDOR                         = 0x1F00;
+    const GLenum RENDERER                       = 0x1F01;
+    const GLenum VERSION                        = 0x1F02;
+
+    /* TextureMagFilter */
+    const GLenum NEAREST                        = 0x2600;
+    const GLenum LINEAR                         = 0x2601;
+
+    /* TextureMinFilter */
+    /*      NEAREST */
+    /*      LINEAR */
+    const GLenum NEAREST_MIPMAP_NEAREST         = 0x2700;
+    const GLenum LINEAR_MIPMAP_NEAREST          = 0x2701;
+    const GLenum NEAREST_MIPMAP_LINEAR          = 0x2702;
+    const GLenum LINEAR_MIPMAP_LINEAR           = 0x2703;
+
+    /* TextureParameterName */
+    const GLenum TEXTURE_MAG_FILTER             = 0x2800;
+    const GLenum TEXTURE_MIN_FILTER             = 0x2801;
+    const GLenum TEXTURE_WRAP_S                 = 0x2802;
+    const GLenum TEXTURE_WRAP_T                 = 0x2803;
+
+    /* TextureTarget */
+    /*      TEXTURE_2D */
+    const GLenum TEXTURE                        = 0x1702;
+
+    const GLenum TEXTURE_CUBE_MAP               = 0x8513;
+    const GLenum TEXTURE_BINDING_CUBE_MAP       = 0x8514;
+    const GLenum TEXTURE_CUBE_MAP_POSITIVE_X    = 0x8515;
+    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_X    = 0x8516;
+    const GLenum TEXTURE_CUBE_MAP_POSITIVE_Y    = 0x8517;
+    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Y    = 0x8518;
+    const GLenum TEXTURE_CUBE_MAP_POSITIVE_Z    = 0x8519;
+    const GLenum TEXTURE_CUBE_MAP_NEGATIVE_Z    = 0x851A;
+    const GLenum MAX_CUBE_MAP_TEXTURE_SIZE      = 0x851C;
+
+    /* TextureUnit */
+    const GLenum TEXTURE0                       = 0x84C0;
+    const GLenum TEXTURE1                       = 0x84C1;
+    const GLenum TEXTURE2                       = 0x84C2;
+    const GLenum TEXTURE3                       = 0x84C3;
+    const GLenum TEXTURE4                       = 0x84C4;
+    const GLenum TEXTURE5                       = 0x84C5;
+    const GLenum TEXTURE6                       = 0x84C6;
+    const GLenum TEXTURE7                       = 0x84C7;
+    const GLenum TEXTURE8                       = 0x84C8;
+    const GLenum TEXTURE9                       = 0x84C9;
+    const GLenum TEXTURE10                      = 0x84CA;
+    const GLenum TEXTURE11                      = 0x84CB;
+    const GLenum TEXTURE12                      = 0x84CC;
+    const GLenum TEXTURE13                      = 0x84CD;
+    const GLenum TEXTURE14                      = 0x84CE;
+    const GLenum TEXTURE15                      = 0x84CF;
+    const GLenum TEXTURE16                      = 0x84D0;
+    const GLenum TEXTURE17                      = 0x84D1;
+    const GLenum TEXTURE18                      = 0x84D2;
+    const GLenum TEXTURE19                      = 0x84D3;
+    const GLenum TEXTURE20                      = 0x84D4;
+    const GLenum TEXTURE21                      = 0x84D5;
+    const GLenum TEXTURE22                      = 0x84D6;
+    const GLenum TEXTURE23                      = 0x84D7;
+    const GLenum TEXTURE24                      = 0x84D8;
+    const GLenum TEXTURE25                      = 0x84D9;
+    const GLenum TEXTURE26                      = 0x84DA;
+    const GLenum TEXTURE27                      = 0x84DB;
+    const GLenum TEXTURE28                      = 0x84DC;
+    const GLenum TEXTURE29                      = 0x84DD;
+    const GLenum TEXTURE30                      = 0x84DE;
+    const GLenum TEXTURE31                      = 0x84DF;
+    const GLenum ACTIVE_TEXTURE                 = 0x84E0;
+
+    /* TextureWrapMode */
+    const GLenum REPEAT                         = 0x2901;
+    const GLenum CLAMP_TO_EDGE                  = 0x812F;
+    const GLenum MIRRORED_REPEAT                = 0x8370;
+
+    /* Uniform Types */
+    const GLenum FLOAT_VEC2                     = 0x8B50;
+    const GLenum FLOAT_VEC3                     = 0x8B51;
+    const GLenum FLOAT_VEC4                     = 0x8B52;
+    const GLenum INT_VEC2                       = 0x8B53;
+    const GLenum INT_VEC3                       = 0x8B54;
+    const GLenum INT_VEC4                       = 0x8B55;
+    const GLenum BOOL                           = 0x8B56;
+    const GLenum BOOL_VEC2                      = 0x8B57;
+    const GLenum BOOL_VEC3                      = 0x8B58;
+    const GLenum BOOL_VEC4                      = 0x8B59;
+    const GLenum FLOAT_MAT2                     = 0x8B5A;
+    const GLenum FLOAT_MAT3                     = 0x8B5B;
+    const GLenum FLOAT_MAT4                     = 0x8B5C;
+    const GLenum SAMPLER_2D                     = 0x8B5E;
+    const GLenum SAMPLER_CUBE                   = 0x8B60;
+
+    /* Vertex Arrays */
+    const GLenum VERTEX_ATTRIB_ARRAY_ENABLED        = 0x8622;
+    const GLenum VERTEX_ATTRIB_ARRAY_SIZE           = 0x8623;
+    const GLenum VERTEX_ATTRIB_ARRAY_STRIDE         = 0x8624;
+    const GLenum VERTEX_ATTRIB_ARRAY_TYPE           = 0x8625;
+    const GLenum VERTEX_ATTRIB_ARRAY_NORMALIZED     = 0x886A;
+    const GLenum VERTEX_ATTRIB_ARRAY_POINTER        = 0x8645;
+    const GLenum VERTEX_ATTRIB_ARRAY_BUFFER_BINDING = 0x889F;
+
+    /* Shader Source */
+    const GLenum COMPILE_STATUS                 = 0x8B81;
+
+    /* Shader Precision-Specified Types */
+    const GLenum LOW_FLOAT                      = 0x8DF0;
+    const GLenum MEDIUM_FLOAT                   = 0x8DF1;
+    const GLenum HIGH_FLOAT                     = 0x8DF2;
+    const GLenum LOW_INT                        = 0x8DF3;
+    const GLenum MEDIUM_INT                     = 0x8DF4;
+    const GLenum HIGH_INT                       = 0x8DF5;
+
+    /* Framebuffer Object. */
+    const GLenum FRAMEBUFFER                    = 0x8D40;
+    const GLenum RENDERBUFFER                   = 0x8D41;
+
+    const GLenum RGBA4                          = 0x8056;
+    const GLenum RGB5_A1                        = 0x8057;
+    const GLenum RGB565                         = 0x8D62;
+    const GLenum DEPTH_COMPONENT16              = 0x81A5;
+    const GLenum STENCIL_INDEX                  = 0x1901;
+    const GLenum STENCIL_INDEX8                 = 0x8D48;
+    const GLenum DEPTH_STENCIL                  = 0x84F9;
+
+    const GLenum RENDERBUFFER_WIDTH             = 0x8D42;
+    const GLenum RENDERBUFFER_HEIGHT            = 0x8D43;
+    const GLenum RENDERBUFFER_INTERNAL_FORMAT   = 0x8D44;
+    const GLenum RENDERBUFFER_RED_SIZE          = 0x8D50;
+    const GLenum RENDERBUFFER_GREEN_SIZE        = 0x8D51;
+    const GLenum RENDERBUFFER_BLUE_SIZE         = 0x8D52;
+    const GLenum RENDERBUFFER_ALPHA_SIZE        = 0x8D53;
+    const GLenum RENDERBUFFER_DEPTH_SIZE        = 0x8D54;
+    const GLenum RENDERBUFFER_STENCIL_SIZE      = 0x8D55;
+
+    const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE           = 0x8CD0;
+    const GLenum FRAMEBUFFER_ATTACHMENT_OBJECT_NAME           = 0x8CD1;
+    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL         = 0x8CD2;
+    const GLenum FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE = 0x8CD3;
+
+    const GLenum COLOR_ATTACHMENT0              = 0x8CE0;
+    const GLenum DEPTH_ATTACHMENT               = 0x8D00;
+    const GLenum STENCIL_ATTACHMENT             = 0x8D20;
+    const GLenum DEPTH_STENCIL_ATTACHMENT       = 0x821A;
+
+    const GLenum NONE                           = 0;
+
+    const GLenum FRAMEBUFFER_COMPLETE                      = 0x8CD5;
+    const GLenum FRAMEBUFFER_INCOMPLETE_ATTACHMENT         = 0x8CD6;
+    const GLenum FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT = 0x8CD7;
+    const GLenum FRAMEBUFFER_INCOMPLETE_DIMENSIONS         = 0x8CD9;
+    const GLenum FRAMEBUFFER_UNSUPPORTED                   = 0x8CDD;
+
+    const GLenum FRAMEBUFFER_BINDING            = 0x8CA6;
+    const GLenum RENDERBUFFER_BINDING           = 0x8CA7;
+    const GLenum MAX_RENDERBUFFER_SIZE          = 0x84E8;
+
+    const GLenum INVALID_FRAMEBUFFER_OPERATION  = 0x0506;
+
+    /* WebGL-specific enums */
+    const GLenum UNPACK_FLIP_Y_WEBGL                = 0x9240;
+    const GLenum UNPACK_PREMULTIPLY_ALPHA_WEBGL     = 0x9241;
+    const GLenum CONTEXT_LOST_WEBGL                 = 0x9242;
+    const GLenum UNPACK_COLORSPACE_CONVERSION_WEBGL = 0x9243;
+    const GLenum BROWSER_DEFAULT_WEBGL              = 0x9244;
+
+    readonly attribute GLsizei drawingBufferWidth;
+    readonly attribute GLsizei drawingBufferHeight;
+
+    void activeTexture(GLenum texture);
+    void attachShader(WebGLProgram? program, WebGLShader? shader);
+    void bindAttribLocation(WebGLProgram? program, GLuint index, DOMString name);
+    void bindBuffer(GLenum target, WebGLBuffer? buffer);
+    void bindFramebuffer(GLenum target, WebGLFramebuffer? framebuffer);
+    void bindRenderbuffer(GLenum target, WebGLRenderbuffer? renderbuffer);
+    void bindTexture(GLenum target, WebGLTexture? texture);
+    void blendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+    void blendEquation(GLenum mode);
+    void blendEquationSeparate(GLenum modeRGB, GLenum modeAlpha);
+    void blendFunc(GLenum sfactor, GLenum dfactor);
+    void blendFuncSeparate(GLenum srcRGB, GLenum dstRGB, GLenum srcAlpha, GLenum dstAlpha);
+    void bufferData(GLenum target, ArrayBuffer? data, GLenum usage);
+    void bufferData(GLenum target, ArrayBufferView? data, GLenum usage);
+    void bufferData(GLenum target, GLsizeiptr size, GLenum usage);
+    void bufferSubData(GLenum target, GLintptr offset, ArrayBuffer? data);
+    void bufferSubData(GLenum target, GLintptr offset, ArrayBufferView? data);
+
+    GLenum checkFramebufferStatus(GLenum target);
+    void clear(GLbitfield mask);
+    void clearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
+    void clearDepth(GLclampf depth);
+    void clearStencil(GLint s);
+    void colorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha);
+    void compileShader(WebGLShader? shader);
+
+    void compressedTexImage2D(GLenum target, GLint level, GLenum internalformat,
+                              GLsizei width, GLsizei height, GLint border, ArrayBufferView? data);
+    void compressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset,
+                                 GLsizei width, GLsizei height, GLenum format, ArrayBufferView? data);
+
+    void copyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border);
+    void copyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height);
+
+    WebGLBuffer createBuffer();
+    WebGLFramebuffer createFramebuffer();
+    WebGLProgram createProgram();
+    WebGLRenderbuffer createRenderbuffer();
+    WebGLShader createShader(GLenum type);
+    WebGLTexture createTexture();
+
+    void cullFace(GLenum mode);
+
+    void deleteBuffer(WebGLBuffer? buffer);
+    void deleteFramebuffer(WebGLFramebuffer? framebuffer);
+    void deleteProgram(WebGLProgram? program);
+    void deleteRenderbuffer(WebGLRenderbuffer? renderbuffer);
+    void deleteShader(WebGLShader? shader);
+    void deleteTexture(WebGLTexture? texture);
+
+    void depthFunc(GLenum func);
+    void depthMask(GLboolean flag);
+    void depthRange(GLclampf zNear, GLclampf zFar);
+    void detachShader(WebGLProgram? program, WebGLShader? shader);
+    void disable(GLenum cap);
+    void disableVertexAttribArray(GLuint index);
+    void drawArrays(GLenum mode, GLint first, GLsizei count);
+    void drawElements(GLenum mode, GLsizei count, GLenum type, GLintptr offset);
+
+    void enable(GLenum cap);
+    void enableVertexAttribArray(GLuint index);
+    void finish();
+    void flush();
+    void framebufferRenderbuffer(GLenum target, GLenum attachment, GLenum renderbuffertarget, WebGLRenderbuffer? renderbuffer);
+    void framebufferTexture2D(GLenum target, GLenum attachment, GLenum textarget, WebGLTexture? texture, GLint level);
+    void frontFace(GLenum mode);
+    void generateMipmap(GLenum target);
+
+    WebGLActiveInfo getActiveAttrib(WebGLProgram? program, GLuint index);
+    WebGLActiveInfo getActiveUniform(WebGLProgram? program, GLuint index);
+
+    [Custom] void getAttachedShaders(WebGLProgram? program);
+
+    GLint getAttribLocation(WebGLProgram? program, DOMString name);
+
+    [Custom] any getBufferParameter(GLenum target, GLenum pname);
+
+    WebGLContextAttributes getContextAttributes();
+
+    GLenum getError();
+
+    // object getExtension(DOMString name);
+    [Custom] any getExtension(DOMString name);
+
+    [Custom] any getFramebufferAttachmentParameter(GLenum target, GLenum attachment, GLenum pname);
+    [Custom] any getParameter(GLenum pname);
+    [Custom] any getProgramParameter(WebGLProgram? program, GLenum pname);
+    [TreatReturnedNullStringAs=Null] DOMString getProgramInfoLog(WebGLProgram? program);
+    [Custom] any getRenderbufferParameter(GLenum target, GLenum pname);
+    [Custom] any getShaderParameter(WebGLShader? shader, GLenum pname);
+
+    [TreatReturnedNullStringAs=Null] DOMString    getShaderInfoLog(WebGLShader? shader);
+
+    WebGLShaderPrecisionFormat getShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype);
+
+    [TreatReturnedNullStringAs=Null] DOMString    getShaderSource(WebGLShader? shader);
+
+    [Custom] sequence<DOMString> getSupportedExtensions();
+
+    [Custom] any getTexParameter(GLenum target, GLenum pname);
+
+    [Custom] any getUniform(WebGLProgram? program, WebGLUniformLocation location);
+
+    WebGLUniformLocation getUniformLocation(WebGLProgram? program, DOMString name);
+
+    [Custom] any getVertexAttrib(GLuint index, GLenum pname);
+
+    GLsizeiptr getVertexAttribOffset(GLuint index, GLenum pname);
+
+    void hint(GLenum target, GLenum mode);
+    GLboolean isBuffer(WebGLBuffer? buffer);
+    GLboolean isContextLost();
+    GLboolean isEnabled(GLenum cap);
+    GLboolean isFramebuffer(WebGLFramebuffer? framebuffer);
+    GLboolean isProgram(WebGLProgram? program);
+    GLboolean isRenderbuffer(WebGLRenderbuffer? renderbuffer);
+    GLboolean isShader(WebGLShader? shader);
+    GLboolean isTexture(WebGLTexture? texture);
+    void lineWidth(GLfloat width);
+    void linkProgram(WebGLProgram? program);
+    void pixelStorei(GLenum pname, GLint param);
+    void polygonOffset(GLfloat factor, GLfloat units);
+
+    void readPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, ArrayBufferView? pixels);
+
+    void renderbufferStorage(GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+    void sampleCoverage(GLclampf value, GLboolean invert);
+    void scissor(GLint x, GLint y, GLsizei width, GLsizei height);
+    void shaderSource(WebGLShader? shader, DOMString string);
+    void stencilFunc(GLenum func, GLint ref, GLuint mask);
+    void stencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask);
+    void stencilMask(GLuint mask);
+    void stencilMaskSeparate(GLenum face, GLuint mask);
+    void stencilOp(GLenum fail, GLenum zfail, GLenum zpass);
+    void stencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass);
+
+    void texParameterf(GLenum target, GLenum pname, GLfloat param);
+    void texParameteri(GLenum target, GLenum pname, GLint param);
+
+    // Supported forms:
+    [RaisesException] void texImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLsizei width, GLsizei height, GLint border,
+        GLenum format, GLenum type, ArrayBufferView? pixels);
+    [RaisesException] void texImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, ImageData? pixels);
+    [RaisesException] void texImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, HTMLImageElement? image);
+    [RaisesException] void texImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, HTMLCanvasElement? canvas);
+    [RaisesException] void texImage2D(
+        GLenum target, GLint level, GLenum internalformat,
+        GLenum format, GLenum type, HTMLVideoElement? video);
+
+    [RaisesException] void texSubImage2D(
+        GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLsizei width, GLsizei height,
+        GLenum format, GLenum type, ArrayBufferView? pixels);
+    [RaisesException] void texSubImage2D(
+        GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, ImageData? pixels);
+    [RaisesException] void texSubImage2D(
+        GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, HTMLImageElement? image);
+    [RaisesException] void texSubImage2D(
+        GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, HTMLCanvasElement? canvas);
+    [RaisesException] void texSubImage2D(
+        GLenum target, GLint level, GLint xoffset, GLint yoffset,
+        GLenum format, GLenum type, HTMLVideoElement? video);
+
+    void uniform1f(WebGLUniformLocation? location, GLfloat x);
+    [Custom] void uniform1fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform1i(WebGLUniformLocation? location, GLint x);
+    [Custom] void uniform1iv(WebGLUniformLocation? location, Int32Array v);
+    void uniform2f(WebGLUniformLocation? location, GLfloat x, GLfloat y);
+    [Custom] void uniform2fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform2i(WebGLUniformLocation? location, GLint x, GLint y);
+    [Custom] void uniform2iv(WebGLUniformLocation? location, Int32Array v);
+    void uniform3f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z);
+    [Custom] void uniform3fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform3i(WebGLUniformLocation? location, GLint x, GLint y, GLint z);
+    [Custom] void uniform3iv(WebGLUniformLocation? location, Int32Array v);
+    void uniform4f(WebGLUniformLocation? location, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+    [Custom] void uniform4fv(WebGLUniformLocation? location, Float32Array v);
+    void uniform4i(WebGLUniformLocation? location, GLint x, GLint y, GLint z, GLint w);
+    [Custom] void uniform4iv(WebGLUniformLocation? location, Int32Array v);
+
+    [Custom] void uniformMatrix2fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+    [Custom] void uniformMatrix3fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+    [Custom] void uniformMatrix4fv(WebGLUniformLocation? location, GLboolean transpose, Float32Array array);
+
+    void useProgram(WebGLProgram? program);
+    void validateProgram(WebGLProgram? program);
+
+    void vertexAttrib1f(GLuint indx, GLfloat x);
+    [Custom] void vertexAttrib1fv(GLuint indx, Float32Array values);
+    void vertexAttrib2f(GLuint indx, GLfloat x, GLfloat y);
+    [Custom] void vertexAttrib2fv(GLuint indx, Float32Array values);
+    void vertexAttrib3f(GLuint indx, GLfloat x, GLfloat y, GLfloat z);
+    [Custom] void vertexAttrib3fv(GLuint indx, Float32Array values);
+    void vertexAttrib4f(GLuint indx, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+    [Custom] void vertexAttrib4fv(GLuint indx, Float32Array values);
+    void vertexAttribPointer(GLuint indx, GLint size, GLenum type, GLboolean normalized,
+                             GLsizei stride, GLintptr offset);
+
+    void viewport(GLint x, GLint y, GLsizei width, GLsizei height);
+};
diff --git a/Source/core/html/canvas/WebGLShader.cpp b/Source/core/html/canvas/WebGLShader.cpp
index 009347d..d306a81 100644
--- a/Source/core/html/canvas/WebGLShader.cpp
+++ b/Source/core/html/canvas/WebGLShader.cpp
@@ -27,16 +27,16 @@
 
 #include "core/html/canvas/WebGLShader.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContext* ctx, GLenum type)
+PassRefPtr<WebGLShader> WebGLShader::create(WebGLRenderingContextBase* ctx, GLenum type)
 {
     return adoptRef(new WebGLShader(ctx, type));
 }
 
-WebGLShader::WebGLShader(WebGLRenderingContext* ctx, GLenum type)
+WebGLShader::WebGLShader(WebGLRenderingContextBase* ctx, GLenum type)
     : WebGLSharedObject(ctx)
     , m_type(type)
     , m_source("")
diff --git a/Source/core/html/canvas/WebGLShader.h b/Source/core/html/canvas/WebGLShader.h
index 940231f..2d2fc23 100644
--- a/Source/core/html/canvas/WebGLShader.h
+++ b/Source/core/html/canvas/WebGLShader.h
@@ -37,7 +37,7 @@
 public:
     virtual ~WebGLShader();
 
-    static PassRefPtr<WebGLShader> create(WebGLRenderingContext*, GLenum);
+    static PassRefPtr<WebGLShader> create(WebGLRenderingContextBase*, GLenum);
 
     GLenum type() const { return m_type; }
     const String& source() const { return m_source; }
@@ -45,7 +45,7 @@
     void setSource(const String& source) { m_source = source; }
 
 private:
-    WebGLShader(WebGLRenderingContext*, GLenum);
+    WebGLShader(WebGLRenderingContextBase*, GLenum);
 
     virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
 
diff --git a/Source/core/html/canvas/WebGLSharedObject.cpp b/Source/core/html/canvas/WebGLSharedObject.cpp
index 42cc599..94f1db8 100644
--- a/Source/core/html/canvas/WebGLSharedObject.cpp
+++ b/Source/core/html/canvas/WebGLSharedObject.cpp
@@ -28,11 +28,11 @@
 #include "core/html/canvas/WebGLSharedObject.h"
 
 #include "core/html/canvas/WebGLContextGroup.h"
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-WebGLSharedObject::WebGLSharedObject(WebGLRenderingContext* context)
+WebGLSharedObject::WebGLSharedObject(WebGLRenderingContextBase* context)
     : WebGLObject(context),
       m_contextGroup(context->contextGroup())
 {
diff --git a/Source/core/html/canvas/WebGLSharedObject.h b/Source/core/html/canvas/WebGLSharedObject.h
index 025b960..990c8ae 100644
--- a/Source/core/html/canvas/WebGLSharedObject.h
+++ b/Source/core/html/canvas/WebGLSharedObject.h
@@ -31,7 +31,7 @@
 namespace WebCore {
 
 class WebGLContextGroup;
-class WebGLRenderingContext;
+class WebGLRenderingContextBase;
 
 // WebGLSharedObject the base class for objects that can be shared by multiple
 // WebGLRenderingContexts.
@@ -47,7 +47,7 @@
     virtual bool isShader() const { return false; }
     virtual bool isTexture() const { return false; }
 
-    virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContext*) const OVERRIDE FINAL
+    virtual bool validate(const WebGLContextGroup* contextGroup, const WebGLRenderingContextBase*) const OVERRIDE FINAL
     {
         return contextGroup == m_contextGroup;
     }
@@ -55,7 +55,7 @@
     void detachContextGroup();
 
 protected:
-    WebGLSharedObject(WebGLRenderingContext*);
+    WebGLSharedObject(WebGLRenderingContextBase*);
 
     virtual bool hasGroupOrContext() const OVERRIDE FINAL
     {
diff --git a/Source/core/html/canvas/WebGLTexture.cpp b/Source/core/html/canvas/WebGLTexture.cpp
index c9b3d6c..1cf21aa 100644
--- a/Source/core/html/canvas/WebGLTexture.cpp
+++ b/Source/core/html/canvas/WebGLTexture.cpp
@@ -27,16 +27,16 @@
 
 #include "core/html/canvas/WebGLTexture.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContext* ctx)
+PassRefPtr<WebGLTexture> WebGLTexture::create(WebGLRenderingContextBase* ctx)
 {
     return adoptRef(new WebGLTexture(ctx));
 }
 
-WebGLTexture::WebGLTexture(WebGLRenderingContext* ctx)
+WebGLTexture::WebGLTexture(WebGLRenderingContextBase* ctx)
     : WebGLSharedObject(ctx)
     , m_target(0)
     , m_minFilter(GL_NEAREST_MIPMAP_LINEAR)
diff --git a/Source/core/html/canvas/WebGLTexture.h b/Source/core/html/canvas/WebGLTexture.h
index a23ab4c..bb086c0 100644
--- a/Source/core/html/canvas/WebGLTexture.h
+++ b/Source/core/html/canvas/WebGLTexture.h
@@ -42,7 +42,7 @@
     };
     virtual ~WebGLTexture();
 
-    static PassRefPtr<WebGLTexture> create(WebGLRenderingContext*);
+    static PassRefPtr<WebGLTexture> create(WebGLRenderingContextBase*);
 
     void setTarget(GLenum target, GLint maxLevel);
     void setParameteri(GLenum pname, GLint param);
@@ -76,7 +76,7 @@
     static GLint computeLevelCount(GLsizei width, GLsizei height);
 
 protected:
-    WebGLTexture(WebGLRenderingContext*);
+    WebGLTexture(WebGLRenderingContextBase*);
 
     virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
 
diff --git a/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp b/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
index dcb7e53..9492147 100644
--- a/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
+++ b/Source/core/html/canvas/WebGLVertexArrayObjectOES.cpp
@@ -27,20 +27,20 @@
 
 #include "core/html/canvas/WebGLVertexArrayObjectOES.h"
 
-#include "core/html/canvas/WebGLRenderingContext.h"
+#include "core/html/canvas/WebGLRenderingContextBase.h"
 
 namespace WebCore {
 
-PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContext* ctx, VaoType type)
+PassRefPtr<WebGLVertexArrayObjectOES> WebGLVertexArrayObjectOES::create(WebGLRenderingContextBase* ctx, VaoType type)
 {
     return adoptRef(new WebGLVertexArrayObjectOES(ctx, type));
 }
 
-WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContext* ctx, VaoType type)
+WebGLVertexArrayObjectOES::WebGLVertexArrayObjectOES(WebGLRenderingContextBase* ctx, VaoType type)
     : WebGLContextObject(ctx)
     , m_type(type)
     , m_hasEverBeenBound(false)
-    , m_boundElementArrayBuffer(0)
+    , m_boundElementArrayBuffer(nullptr)
 {
     ScriptWrappable::init(this);
     m_vertexAttribState.resize(ctx->maxVertexAttribs());
@@ -115,14 +115,14 @@
 {
     if (m_boundElementArrayBuffer == buffer) {
         m_boundElementArrayBuffer->onDetached(context()->webGraphicsContext3D());
-        m_boundElementArrayBuffer = 0;
+        m_boundElementArrayBuffer = nullptr;
     }
 
     for (size_t i = 0; i < m_vertexAttribState.size(); ++i) {
         VertexAttribState& state = m_vertexAttribState[i];
         if (state.bufferBinding == buffer) {
             buffer->onDetached(context()->webGraphicsContext3D());
-            state.bufferBinding = 0;
+            state.bufferBinding = nullptr;
         }
     }
 }
diff --git a/Source/core/html/canvas/WebGLVertexArrayObjectOES.h b/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
index 8b1c11d..e54ef0a 100644
--- a/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
+++ b/Source/core/html/canvas/WebGLVertexArrayObjectOES.h
@@ -42,7 +42,7 @@
 
     virtual ~WebGLVertexArrayObjectOES();
 
-    static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContext*, VaoType);
+    static PassRefPtr<WebGLVertexArrayObjectOES> create(WebGLRenderingContextBase*, VaoType);
 
     // Cached values for vertex attrib range checks
     struct VertexAttribState {
@@ -85,7 +85,7 @@
     void setVertexAttribDivisor(GLuint index, GLuint divisor);
 
 private:
-    WebGLVertexArrayObjectOES(WebGLRenderingContext*, VaoType);
+    WebGLVertexArrayObjectOES(WebGLRenderingContextBase*, VaoType);
 
     virtual void deleteObjectImpl(blink::WebGraphicsContext3D*, Platform3DObject) OVERRIDE;
 
diff --git a/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp b/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
index 4fbb511..a678dbe 100644
--- a/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
+++ b/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.cpp
@@ -64,15 +64,19 @@
     RefPtr<HTMLDivElement> valueContainer = HTMLDivElement::create(element().document());
     valueContainer->setShadowPseudoId(valueContainerPseudo);
     element().userAgentShadowRoot()->appendChild(valueContainer.get());
-    updateAppearance();
+    updateView();
 }
 
-void BaseChooserOnlyDateAndTimeInputType::updateAppearance()
+void BaseChooserOnlyDateAndTimeInputType::updateView()
 {
     Node* node = element().userAgentShadowRoot()->firstChild();
     if (!node || !node->isHTMLElement())
         return;
-    String displayValue = visibleValue();
+    String displayValue;
+    if (!element().suggestedValue().isNull())
+        displayValue = element().suggestedValue();
+    else
+        displayValue = visibleValue();
     if (displayValue.isEmpty()) {
         // Need to put something to keep text baseline.
         displayValue = " ";
@@ -84,7 +88,7 @@
 {
     BaseDateAndTimeInputType::setValue(value, valueChanged, eventBehavior);
     if (valueChanged)
-        updateAppearance();
+        updateView();
 }
 
 void BaseChooserOnlyDateAndTimeInputType::closePopupView()
diff --git a/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h b/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
index 4ba1f87..7b4af2f 100644
--- a/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
+++ b/Source/core/html/forms/BaseChooserOnlyDateAndTimeInputType.h
@@ -40,7 +40,6 @@
     virtual ~BaseChooserOnlyDateAndTimeInputType();
 
 private:
-    void updateAppearance();
     void closeDateTimeChooser();
 
     // InputType functions:
@@ -52,6 +51,7 @@
     virtual void handleKeypressEvent(KeyboardEvent*) OVERRIDE;
     virtual void handleKeyupEvent(KeyboardEvent*) OVERRIDE;
     virtual void accessKeyAction(bool sendMouseEvents) OVERRIDE;
+    virtual void updateView() OVERRIDE;
 
     // DateTimeChooserClient functions:
     virtual void didChooseValue(const String&) OVERRIDE;
diff --git a/Source/core/html/forms/BaseDateAndTimeInputType.cpp b/Source/core/html/forms/BaseDateAndTimeInputType.cpp
index 6868f8a..df92c91 100644
--- a/Source/core/html/forms/BaseDateAndTimeInputType.cpp
+++ b/Source/core/html/forms/BaseDateAndTimeInputType.cpp
@@ -177,7 +177,7 @@
 
 bool BaseDateAndTimeInputType::shouldRespectListAttribute()
 {
-    return InputType::themeSupportsDataListUI(this);
+    return true;
 }
 
 bool BaseDateAndTimeInputType::valueMissing(const String& value) const
diff --git a/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp b/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
index 447ae22..4db5923 100644
--- a/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
+++ b/Source/core/html/forms/BaseMultipleFieldsDateAndTimeInputType.cpp
@@ -339,22 +339,15 @@
     ContainerNode* container = element().userAgentShadowRoot();
 
     container->appendChild(DateTimeEditElement::create(document, *this));
-    updateView();
+    element().updateView();
     container->appendChild(ClearButtonElement::create(document, *this));
     container->appendChild(SpinButtonElement::create(document, *this));
 
-    bool shouldAddPickerIndicator = false;
-    if (InputType::themeSupportsDataListUI(this))
-        shouldAddPickerIndicator = true;
-    if (RenderTheme::theme().supportsCalendarPicker(formControlType())) {
-        shouldAddPickerIndicator = true;
+    if (RenderTheme::theme().supportsCalendarPicker(formControlType()))
         m_pickerIndicatorIsAlwaysVisible = true;
-    }
-    if (shouldAddPickerIndicator) {
-        container->appendChild(PickerIndicatorElement::create(document, *this));
-        m_pickerIndicatorIsVisible = true;
-        updatePickerIndicatorVisibility();
-    }
+    container->appendChild(PickerIndicatorElement::create(document, *this));
+    m_pickerIndicatorIsVisible = true;
+    updatePickerIndicatorVisibility();
 }
 
 void BaseMultipleFieldsDateAndTimeInputType::destroyShadowSubtree()
@@ -479,7 +472,7 @@
     InputType::setValue(sanitizedValue, valueChanged, eventBehavior);
     DateTimeEditElement* edit = dateTimeEditElement();
     if (valueChanged || (sanitizedValue.isEmpty() && edit && edit->anyEditableFieldsHaveValues())) {
-        updateView();
+        element().updateView();
         element().setNeedsValidityCheck();
     }
 }
@@ -503,7 +496,11 @@
     DateTimeEditElement::LayoutParameters layoutParameters(element().locale(), createStepRange(AnyIsDefaultStep));
 
     DateComponents date;
-    const bool hasValue = parseToDateComponents(element().value(), &date);
+    bool hasValue = false;
+    if (!element().suggestedValue().isNull())
+        hasValue = parseToDateComponents(element().suggestedValue(), &date);
+    else
+        hasValue = parseToDateComponents(element().value(), &date);
     if (!hasValue)
         setMillisecondToDateComponents(layoutParameters.stepRange.minimum().toDouble(), &date);
 
diff --git a/Source/core/html/forms/ColorInputType.cpp b/Source/core/html/forms/ColorInputType.cpp
index 9adbc54..569c635 100644
--- a/Source/core/html/forms/ColorInputType.cpp
+++ b/Source/core/html/forms/ColorInputType.cpp
@@ -135,7 +135,7 @@
     wrapperElement->appendChild(colorSwatch.release());
     element().userAgentShadowRoot()->appendChild(wrapperElement.release());
 
-    updateColorSwatch();
+    element().updateView();
 }
 
 void ColorInputType::setValue(const String& value, bool valueChanged, TextFieldEventBehavior eventBehavior)
@@ -145,7 +145,7 @@
     if (!valueChanged)
         return;
 
-    updateColorSwatch();
+    element().updateView();
     if (m_chooser)
         m_chooser->setSelectedColor(valueAsColor());
 }
@@ -172,7 +172,7 @@
 
 bool ColorInputType::shouldRespectListAttribute()
 {
-    return InputType::themeSupportsDataListUI(this);
+    return true;
 }
 
 bool ColorInputType::typeMismatchFor(const String& value) const
@@ -185,7 +185,7 @@
     if (element().isDisabledFormControl() || color == valueAsColor())
         return;
     element().setValueFromRenderer(color.serialized());
-    updateColorSwatch();
+    element().updateView();
     element().dispatchFormControlChangeEvent();
 }
 
@@ -200,7 +200,7 @@
         m_chooser->endChooser();
 }
 
-void ColorInputType::updateColorSwatch()
+void ColorInputType::updateView()
 {
     HTMLElement* colorSwatch = shadowColorSwatch();
     if (!colorSwatch)
diff --git a/Source/core/html/forms/ColorInputType.h b/Source/core/html/forms/ColorInputType.h
index b28246a..a35abd2 100644
--- a/Source/core/html/forms/ColorInputType.h
+++ b/Source/core/html/forms/ColorInputType.h
@@ -63,10 +63,10 @@
     virtual void closePopupView() OVERRIDE;
     virtual bool shouldRespectListAttribute() OVERRIDE;
     virtual bool typeMismatchFor(const String&) const OVERRIDE;
+    virtual void updateView() OVERRIDE;
 
     Color valueAsColor() const;
     void endColorChooser();
-    void updateColorSwatch();
     HTMLElement* shadowColorSwatch() const;
 
     OwnPtr<ColorChooser> m_chooser;
diff --git a/Source/core/html/forms/FileInputType.cpp b/Source/core/html/forms/FileInputType.cpp
index e0ceace..a2ebe75 100644
--- a/Source/core/html/forms/FileInputType.cpp
+++ b/Source/core/html/forms/FileInputType.cpp
@@ -210,9 +210,9 @@
     element().setNeedsValidityCheck();
 }
 
-PassRefPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files) const
+PassRefPtrWillBeRawPtr<FileList> FileInputType::createFileList(const Vector<FileChooserFileInfo>& files) const
 {
-    RefPtr<FileList> fileList(FileList::create());
+    RefPtrWillBeRawPtr<FileList> fileList(FileList::create());
     size_t size = files.size();
 
     // If a directory is being selected, the UI allows a directory to be chosen
@@ -272,7 +272,7 @@
         button->setAttribute(valueAttr, AtomicString(locale().queryString(element().multiple() ? WebLocalizedString::FileButtonChooseMultipleFilesLabel : WebLocalizedString::FileButtonChooseFileLabel)));
 }
 
-void FileInputType::setFiles(PassRefPtr<FileList> files)
+void FileInputType::setFiles(PassRefPtrWillBeRawPtr<FileList> files)
 {
     if (!files)
         return;
diff --git a/Source/core/html/forms/FileInputType.h b/Source/core/html/forms/FileInputType.h
index a675ec9..79b7709 100644
--- a/Source/core/html/forms/FileInputType.h
+++ b/Source/core/html/forms/FileInputType.h
@@ -33,6 +33,7 @@
 #define FileInputType_h
 
 #include "core/html/forms/BaseClickableWithKeyInputType.h"
+#include "heap/Handle.h"
 #include "platform/FileChooser.h"
 #include "wtf/RefPtr.h"
 
@@ -58,7 +59,7 @@
     virtual RenderObject* createRenderer(RenderStyle*) const OVERRIDE;
     virtual bool canSetStringValue() const OVERRIDE;
     virtual FileList* files() OVERRIDE;
-    virtual void setFiles(PassRefPtr<FileList>) OVERRIDE;
+    virtual void setFiles(PassRefPtrWillBeRawPtr<FileList>) OVERRIDE;
     virtual bool canSetValue(const String&) OVERRIDE;
     virtual bool getTypeSpecificValue(String&) OVERRIDE; // Checked first, before internal storage or the value attribute.
     virtual void setValue(const String&, bool valueChanged, TextFieldEventBehavior) OVERRIDE;
@@ -73,10 +74,10 @@
     // FileChooserClient implementation.
     virtual void filesChosen(const Vector<FileChooserFileInfo>&) OVERRIDE;
 
-    PassRefPtr<FileList> createFileList(const Vector<FileChooserFileInfo>& files) const;
+    PassRefPtrWillBeRawPtr<FileList> createFileList(const Vector<FileChooserFileInfo>& files) const;
     void receiveDropForDirectoryUpload(const Vector<String>&);
 
-    RefPtr<FileList> m_fileList;
+    RefPtrWillBePersistent<FileList> m_fileList;
 
     String m_droppedFileSystemId;
 };
diff --git a/Source/core/html/forms/FormController.cpp b/Source/core/html/forms/FormController.cpp
index 09f2b0e..df0d2ab 100644
--- a/Source/core/html/forms/FormController.cpp
+++ b/Source/core/html/forms/FormController.cpp
@@ -508,7 +508,7 @@
     SavedFormStateMap map;
     formStatesFromStateVector(stateVector, map);
     for (SavedFormStateMap::const_iterator it = map.begin(); it != map.end(); ++it)
-        toReturn.append(it->value->getReferencedFilePaths());
+        toReturn.appendVector(it->value->getReferencedFilePaths());
     return toReturn;
 }
 
diff --git a/Source/core/html/forms/InputType.cpp b/Source/core/html/forms/InputType.cpp
index 53ad643..58dfc09 100644
--- a/Source/core/html/forms/InputType.cpp
+++ b/Source/core/html/forms/InputType.cpp
@@ -40,6 +40,7 @@
 #include "core/frame/FrameHost.h"
 #include "core/html/FormDataList.h"
 #include "core/html/HTMLInputElement.h"
+#include "core/html/HTMLShadowElement.h"
 #include "core/html/forms/ButtonInputType.h"
 #include "core/html/forms/CheckboxInputType.h"
 #include "core/html/forms/ColorInputType.h"
@@ -64,7 +65,6 @@
 #include "core/html/forms/URLInputType.h"
 #include "core/html/forms/WeekInputType.h"
 #include "core/html/parser/HTMLParserIdioms.h"
-#include "core/html/shadow/HTMLShadowElement.h"
 #include "core/rendering/RenderTheme.h"
 #include "platform/text/PlatformLocale.h"
 #include "platform/text/TextBreakIterator.h"
@@ -147,11 +147,6 @@
 {
 }
 
-bool InputType::themeSupportsDataListUI(InputType* type)
-{
-    return RenderTheme::theme().supportsDataListUI(type->formControlType());
-}
-
 bool InputType::isTextField() const
 {
     return false;
@@ -528,7 +523,7 @@
     return 0;
 }
 
-void InputType::setFiles(PassRefPtr<FileList>)
+void InputType::setFiles(PassRefPtrWillBeRawPtr<FileList>)
 {
 }
 
@@ -748,10 +743,6 @@
     return false;
 }
 
-void InputType::updatePlaceholderText()
-{
-}
-
 String InputType::defaultToolTip() const
 {
     return String();
diff --git a/Source/core/html/forms/InputType.h b/Source/core/html/forms/InputType.h
index 1e83ecd..e636319 100644
--- a/Source/core/html/forms/InputType.h
+++ b/Source/core/html/forms/InputType.h
@@ -64,7 +64,6 @@
     virtual ~InputType();
 
     static bool canChangeFromAnotherType(const AtomicString& normalizedTypeName);
-    static bool themeSupportsDataListUI(InputType*);
 
     virtual const AtomicString& formControlType() const = 0;
 
@@ -171,7 +170,7 @@
     virtual void sanitizeValueInResponseToMinOrMaxAttributeChange();
     virtual bool shouldRespectAlignAttribute();
     virtual FileList* files();
-    virtual void setFiles(PassRefPtr<FileList>);
+    virtual void setFiles(PassRefPtrWillBeRawPtr<FileList>);
     // Should return true if the given DragData has more than one dropped files.
     virtual bool receiveDroppedFiles(const DragData*);
     virtual String droppedFileSystemId();
@@ -189,7 +188,6 @@
     virtual bool shouldRespectHeightAndWidthAttributes();
     virtual bool supportsPlaceholder() const;
     virtual bool supportsReadOnly() const;
-    virtual void updatePlaceholderText();
     virtual String defaultToolTip() const;
     virtual Decimal findClosestTickMarkValue(const Decimal&);
     virtual void handleDOMActivateEvent(Event*);
diff --git a/Source/core/html/forms/InputTypeView.cpp b/Source/core/html/forms/InputTypeView.cpp
index 1ae57e2..c87c062 100644
--- a/Source/core/html/forms/InputTypeView.cpp
+++ b/Source/core/html/forms/InputTypeView.cpp
@@ -209,4 +209,8 @@
 {
 }
 
+void InputTypeView::updatePlaceholderText()
+{
+}
+
 } // namespace WebCore
diff --git a/Source/core/html/forms/InputTypeView.h b/Source/core/html/forms/InputTypeView.h
index 20b7210..408a3d2 100644
--- a/Source/core/html/forms/InputTypeView.h
+++ b/Source/core/html/forms/InputTypeView.h
@@ -111,6 +111,7 @@
     virtual void valueAttributeChanged();
     virtual void listAttributeTargetChanged();
     virtual void updateClearButtonVisibility();
+    virtual void updatePlaceholderText();
 
 protected:
     InputTypeView(HTMLInputElement& element) : m_element(element) { }
diff --git a/Source/core/html/forms/MonthInputType.cpp b/Source/core/html/forms/MonthInputType.cpp
index 647ac35..02de23c 100644
--- a/Source/core/html/forms/MonthInputType.cpp
+++ b/Source/core/html/forms/MonthInputType.cpp
@@ -134,6 +134,11 @@
     return true;
 }
 
+bool MonthInputType::canSetSuggestedValue()
+{
+    return true;
+}
+
 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
 String MonthInputType::formatDateTimeFieldsState(const DateTimeFieldsState& dateTimeFieldsState) const
 {
diff --git a/Source/core/html/forms/MonthInputType.h b/Source/core/html/forms/MonthInputType.h
index 9baf95c..a671044 100644
--- a/Source/core/html/forms/MonthInputType.h
+++ b/Source/core/html/forms/MonthInputType.h
@@ -58,6 +58,7 @@
     virtual bool parseToDateComponentsInternal(const String&, DateComponents*) const OVERRIDE;
     virtual bool setMillisecondToDateComponents(double, DateComponents*) const OVERRIDE;
     virtual bool isMonthField() const OVERRIDE;
+    virtual bool canSetSuggestedValue() OVERRIDE;
 
 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
     // BaseMultipleFieldsDateAndTimeInputType functions
diff --git a/Source/core/html/forms/NumberInputType.cpp b/Source/core/html/forms/NumberInputType.cpp
index 53cc2b5..6ad66bb 100644
--- a/Source/core/html/forms/NumberInputType.cpp
+++ b/Source/core/html/forms/NumberInputType.cpp
@@ -112,7 +112,7 @@
 void NumberInputType::setValue(const String& sanitizedValue, bool valueChanged, TextFieldEventBehavior eventBehavior)
 {
     if (!valueChanged && sanitizedValue.isEmpty() && !element().innerTextValue().isEmpty())
-        updateView();
+        element().updateView();
     TextFieldInputType::setValue(sanitizedValue, valueChanged, eventBehavior);
 }
 
@@ -123,24 +123,11 @@
 
 void NumberInputType::setValueAsDouble(double newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
 {
-    // FIXME: We should use numeric_limits<double>::max for number input type.
-    // (NOTE: the range check will not be true for NaN.)
-    const double floatMax = numeric_limits<float>::max();
-    if (newValue < -floatMax || newValue > floatMax) {
-        exceptionState.throwDOMException(InvalidStateError, "The value provided (" + String::number(newValue) + ") is outside the range (" + String::number(-floatMax) + ", " + String::number(floatMax) + ").");
-        return;
-    }
     element().setValue(serializeForNumberType(newValue), eventBehavior);
 }
 
 void NumberInputType::setValueAsDecimal(const Decimal& newValue, TextFieldEventBehavior eventBehavior, ExceptionState& exceptionState) const
 {
-    // FIXME: We should use numeric_limits<double>::max for number input type.
-    const Decimal floatMax = Decimal::fromDouble(numeric_limits<float>::max());
-    if (newValue < -floatMax || newValue > floatMax) {
-        exceptionState.throwDOMException(InvalidStateError, "The value provided (" + newValue.toString() + ") is outside the range (-" + floatMax.toString() + ", " + floatMax.toString() + ").");
-        return;
-    }
     element().setValue(serializeForNumberType(newValue), eventBehavior);
 }
 
@@ -158,10 +145,8 @@
 StepRange NumberInputType::createStepRange(AnyStepHandling anyStepHandling) const
 {
     DEFINE_STATIC_LOCAL(const StepRange::StepDescription, stepDescription, (numberDefaultStep, numberDefaultStepBase, numberStepScaleFactor));
-
-    // FIXME: We should use numeric_limits<double>::max for number input type.
-    const Decimal floatMax = Decimal::fromDouble(numeric_limits<float>::max());
-    return InputType::createStepRange(anyStepHandling, numberDefaultStepBase, -floatMax, floatMax, stepDescription);
+    const Decimal doubleMax = Decimal::fromDouble(numeric_limits<double>::max());
+    return InputType::createStepRange(anyStepHandling, numberDefaultStepBase, -doubleMax, doubleMax, stepDescription);
 }
 
 bool NumberInputType::sizeShouldIncludeDecoration(int defaultSize, int& preferredSize) const
diff --git a/Source/core/html/forms/RadioInputType.cpp b/Source/core/html/forms/RadioInputType.cpp
index fc6da49..7a90d2f 100644
--- a/Source/core/html/forms/RadioInputType.cpp
+++ b/Source/core/html/forms/RadioInputType.cpp
@@ -24,7 +24,7 @@
 
 #include "HTMLNames.h"
 #include "InputTypeNames.h"
-#include "core/dom/NodeTraversal.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/events/KeyboardEvent.h"
 #include "core/events/MouseEvent.h"
 #include "core/html/HTMLInputElement.h"
@@ -83,15 +83,15 @@
 
     // We can only stay within the form's children if the form hasn't been demoted to a leaf because
     // of malformed HTML.
-    Node* node = &element();
-    while ((node = (forward ? NodeTraversal::next(*node) : NodeTraversal::previous(*node)))) {
+    HTMLElement* htmlElement = &element();
+    while ((htmlElement = (forward ? Traversal<HTMLElement>::next(*htmlElement) : Traversal<HTMLElement>::previous(*htmlElement)))) {
         // Once we encounter a form element, we know we're through.
-        if (node->hasTagName(formTag))
+        if (isHTMLFormElement(*htmlElement))
             break;
         // Look for more radio buttons.
-        if (!node->hasTagName(inputTag))
+        if (!isHTMLInputElement(*htmlElement))
             continue;
-        HTMLInputElement* inputElement = toHTMLInputElement(node);
+        HTMLInputElement* inputElement = toHTMLInputElement(htmlElement);
         if (inputElement->form() != element().form())
             break;
         if (inputElement->isRadioButton() && inputElement->name() == element().name() && inputElement->isFocusable()) {
@@ -128,9 +128,9 @@
     // Never allow keyboard tabbing to leave you in the same radio group. Always
     // skip any other elements in the group.
     Element* currentFocusedElement = element().document().focusedElement();
-    if (currentFocusedElement && currentFocusedElement->hasTagName(inputTag)) {
-        HTMLInputElement* focusedInput = toHTMLInputElement(currentFocusedElement);
-        if (focusedInput->isRadioButton() && focusedInput->form() == element().form() && focusedInput->name() == element().name())
+    if (isHTMLInputElement(currentFocusedElement)) {
+        HTMLInputElement& focusedInput = toHTMLInputElement(*currentFocusedElement);
+        if (focusedInput.isRadioButton() && focusedInput.form() == element().form() && focusedInput.name() == element().name())
             return false;
     }
 
diff --git a/Source/core/html/forms/RangeInputType.cpp b/Source/core/html/forms/RangeInputType.cpp
index 55a9915..557fb82 100644
--- a/Source/core/html/forms/RangeInputType.cpp
+++ b/Source/core/html/forms/RangeInputType.cpp
@@ -230,12 +230,11 @@
 
     if (newValue != current) {
         EventQueueScope scope;
-        TextFieldEventBehavior eventBehavior = DispatchChangeEvent;
+        TextFieldEventBehavior eventBehavior = DispatchInputAndChangeEvent;
         setValueAsDecimal(newValue, eventBehavior, IGNORE_EXCEPTION);
 
         if (AXObjectCache* cache = element().document().existingAXObjectCache())
             cache->postNotification(&element(), AXObjectCache::AXValueChanged, true);
-        element().dispatchFormControlChangeEvent();
     }
 
     event->setDefaultHandled();
@@ -318,7 +317,7 @@
 
 bool RangeInputType::shouldRespectListAttribute()
 {
-    return InputType::themeSupportsDataListUI(this);
+    return true;
 }
 
 inline SliderThumbElement* RangeInputType::sliderThumbElement() const
diff --git a/Source/core/html/forms/SearchInputType.cpp b/Source/core/html/forms/SearchInputType.cpp
index ba6e85a..16f40b1 100644
--- a/Source/core/html/forms/SearchInputType.cpp
+++ b/Source/core/html/forms/SearchInputType.cpp
@@ -130,7 +130,7 @@
 
     // After typing the first key, we wait 0.5 seconds.
     // After the second key, 0.4 seconds, then 0.3, then 0.2 from then on.
-    m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length));
+    m_searchEventTimer.startOneShot(max(0.2, 0.6 - 0.1 * length), FROM_HERE);
 }
 
 void SearchInputType::stopSearchEventTimer()
diff --git a/Source/core/html/forms/TextFieldInputType.cpp b/Source/core/html/forms/TextFieldInputType.cpp
index c89f07c..041d030 100644
--- a/Source/core/html/forms/TextFieldInputType.cpp
+++ b/Source/core/html/forms/TextFieldInputType.cpp
@@ -41,8 +41,8 @@
 #include "core/events/BeforeTextInsertedEvent.h"
 #include "core/events/KeyboardEvent.h"
 #include "core/events/TextEvent.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/FormDataList.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/shadow/ShadowElementNames.h"
@@ -155,7 +155,7 @@
     InputType::setValue(sanitizedValue, valueChanged, DispatchNoEvent);
 
     if (valueChanged)
-        updateView();
+        input->updateView();
 
     unsigned max = visibleValue().length();
     if (input->focused())
@@ -284,7 +284,7 @@
 {
     ASSERT(element().shadow());
     ShadowRoot* shadowRoot = element().userAgentShadowRoot();
-    ASSERT(!shadowRoot->hasChildNodes());
+    ASSERT(!shadowRoot->hasChildren());
 
     Document& document = element().document();
     bool shouldHaveSpinButton = this->shouldHaveSpinButton();
@@ -356,6 +356,8 @@
             editingViewPort->appendChild(innerEditor.release());
             rpContainer->appendChild(editingViewPort.release());
             rpContainer->appendChild(DataListIndicatorElement::create(document));
+            if (element().document().focusedElement() == element())
+                element().updateFocusAppearance(true /* restore selection */);
         }
     } else {
         picker->remove(ASSERT_NO_EXCEPTION);
@@ -399,15 +401,6 @@
 static String limitLength(const String& string, unsigned maxLength)
 {
     unsigned newLength = std::min(maxLength, string.length());
-    // FIXME: We should not truncate the string at a control character. It's not
-    // compatible with IE and Firefox.
-    for (unsigned i = 0; i < newLength; ++i) {
-        const UChar current = string[i];
-        if (current < ' ' && current != '\t') {
-            newLength = i;
-            break;
-        }
-    }
     if (newLength == string.length())
         return string;
     if (newLength > 0 && U16_IS_LEAD(string[newLength - 1]))
@@ -457,7 +450,7 @@
 
 bool TextFieldInputType::shouldRespectListAttribute()
 {
-    return InputType::themeSupportsDataListUI(this);
+    return true;
 }
 
 void TextFieldInputType::updatePlaceholderText()
diff --git a/Source/core/html/ime/InputMethodContext.cpp b/Source/core/html/ime/InputMethodContext.cpp
index 40f2aab..5f1e053 100644
--- a/Source/core/html/ime/InputMethodContext.cpp
+++ b/Source/core/html/ime/InputMethodContext.cpp
@@ -33,7 +33,7 @@
 
 #include "core/dom/Text.h"
 #include "core/editing/InputMethodController.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 namespace WebCore {
 
@@ -85,7 +85,7 @@
 
 bool InputMethodContext::hasFocus() const
 {
-    Frame* frame = m_element->document().frame();
+    LocalFrame* frame = m_element->document().frame();
     if (!frame)
         return false;
 
diff --git a/Source/core/html/HTMLImport.cpp b/Source/core/html/imports/HTMLImport.cpp
similarity index 96%
rename from Source/core/html/HTMLImport.cpp
rename to Source/core/html/imports/HTMLImport.cpp
index 154ef04..5cde318 100644
--- a/Source/core/html/HTMLImport.cpp
+++ b/Source/core/html/imports/HTMLImport.cpp
@@ -29,14 +29,14 @@
  */
 
 #include "config.h"
-#include "core/html/HTMLImport.h"
+#include "core/html/imports/HTMLImport.h"
 
 #include "core/dom/Document.h"
-#include "core/html/HTMLImportStateResolver.h"
+#include "core/html/imports/HTMLImportStateResolver.h"
 
 namespace WebCore {
 
-Frame* HTMLImport::frame()
+LocalFrame* HTMLImport::frame()
 {
     return master()->frame();
 }
@@ -57,7 +57,7 @@
 
     // This prevents HTML parser from going beyond the
     // blockage line before the precise state is computed by recalcState().
-    if (child->isCreatedByParser())
+    if (child->isSync())
         m_state = HTMLImportState::blockedState();
 
     stateWillChange();
diff --git a/Source/core/html/HTMLImport.h b/Source/core/html/imports/HTMLImport.h
similarity index 95%
rename from Source/core/html/HTMLImport.h
rename to Source/core/html/imports/HTMLImport.h
index 0e4f5c1..8c463aa 100644
--- a/Source/core/html/HTMLImport.h
+++ b/Source/core/html/imports/HTMLImport.h
@@ -31,7 +31,7 @@
 #ifndef HTMLImport_h
 #define HTMLImport_h
 
-#include "core/html/HTMLImportState.h"
+#include "core/html/imports/HTMLImportState.h"
 #include "wtf/TreeNode.h"
 #include "wtf/Vector.h"
 
@@ -39,7 +39,7 @@
 
 class CustomElementMicrotaskImportStep;
 class Document;
-class Frame;
+class LocalFrame;
 class HTMLImportChild;
 class HTMLImportRoot;
 class HTMLImportsController;
@@ -105,11 +105,11 @@
 
     virtual ~HTMLImport() { }
 
-    Frame* frame();
+    LocalFrame* frame();
     Document* master();
     HTMLImportsController* controller();
     bool isRoot() const { return !isChild(); }
-    bool isCreatedByParser() const { return m_createdByParser; }
+    bool isSync() const { return m_sync; }
     const HTMLImportState& state() const { return m_state; }
 
     void appendChild(HTMLImport*);
@@ -119,6 +119,7 @@
     virtual Document* document() const = 0;
     virtual void wasDetachedFromDocument() = 0;
     virtual void didFinishParsing() { };
+    virtual void didRemoveAllPendingStylesheet() { }
     virtual bool isDone() const = 0; // FIXME: Should be renamed to haveFinishedLoading()
     virtual bool hasLoader() const = 0;
     virtual bool ownsLoader() const { return false; }
@@ -128,8 +129,8 @@
 protected:
     // Stating from most conservative state.
     // It will be corrected through state update flow.
-    explicit HTMLImport(bool createdByParser = false)
-        : m_createdByParser(createdByParser)
+    explicit HTMLImport(bool sync = false)
+        : m_sync(sync)
     { }
 
     void stateWillChange();
@@ -143,7 +144,7 @@
 
 private:
     HTMLImportState m_state;
-    bool m_createdByParser : 1;
+    bool m_sync : 1;
 };
 
 // An abstract class to decouple its sublcass HTMLImportsController.
diff --git a/Source/core/html/HTMLImportChild.cpp b/Source/core/html/imports/HTMLImportChild.cpp
similarity index 92%
rename from Source/core/html/HTMLImportChild.cpp
rename to Source/core/html/imports/HTMLImportChild.cpp
index 3a80baf..a812644 100644
--- a/Source/core/html/HTMLImportChild.cpp
+++ b/Source/core/html/imports/HTMLImportChild.cpp
@@ -29,22 +29,24 @@
  */
 
 #include "config.h"
-#include "core/html/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportChild.h"
 
 #include "core/dom/Document.h"
 #include "core/dom/custom/CustomElement.h"
 #include "core/dom/custom/CustomElementMicrotaskImportStep.h"
-#include "core/html/HTMLImportChildClient.h"
-#include "core/html/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportChildClient.h"
+#include "core/html/imports/HTMLImportLoader.h"
 
 namespace WebCore {
 
-HTMLImportChild::HTMLImportChild(const KURL& url, bool createdByParser)
-    : HTMLImport(createdByParser)
+HTMLImportChild::HTMLImportChild(Document& master, const KURL& url, bool sync)
+    : HTMLImport(sync)
+    , m_master(master)
     , m_url(url)
     , m_customElementMicrotaskStep(0)
     , m_client(0)
 {
+    m_master.guardRef();
 }
 
 HTMLImportChild::~HTMLImportChild()
@@ -60,6 +62,8 @@
 
     if (m_client)
         m_client->importChildWasDestroyed(this);
+
+    m_master.guardDeref();
 }
 
 void HTMLImportChild::wasAlreadyLoaded()
@@ -74,7 +78,7 @@
     ASSERT(!this->resource());
     ASSERT(!m_loader);
 
-    if (isCreatedByParser()) {
+    if (isSync()) {
         ASSERT(!m_customElementMicrotaskStep);
         m_customElementMicrotaskStep = CustomElement::didCreateImport(this);
     }
@@ -149,6 +153,12 @@
     m_loader->didFinishParsing();
 }
 
+void HTMLImportChild::didRemoveAllPendingStylesheet()
+{
+    ASSERT(m_loader->isOwnedBy(this));
+    m_loader->didRemoveAllPendingStylesheet();
+}
+
 void HTMLImportChild::stateDidChange()
 {
     HTMLImport::stateDidChange();
@@ -239,7 +249,7 @@
     fprintf(stderr, " loader=%p own=%s async=%s url=%s",
         m_loader.get(),
         hasLoader() && ownsLoader() ? "Y" : "N",
-        isCreatedByParser() ? "Y" : "N",
+        isSync() ? "Y" : "N",
         url().string().utf8().data());
 }
 #endif
diff --git a/Source/core/html/HTMLImportChild.h b/Source/core/html/imports/HTMLImportChild.h
similarity index 94%
rename from Source/core/html/HTMLImportChild.h
rename to Source/core/html/imports/HTMLImportChild.h
index 6a1a19b..ae4bb32 100644
--- a/Source/core/html/HTMLImportChild.h
+++ b/Source/core/html/imports/HTMLImportChild.h
@@ -33,8 +33,8 @@
 
 #include "core/fetch/RawResource.h"
 #include "core/fetch/ResourceOwner.h"
-#include "core/html/HTMLImport.h"
-#include "core/html/HTMLImportLoaderClient.h"
+#include "core/html/imports/HTMLImport.h"
+#include "core/html/imports/HTMLImportLoaderClient.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/Vector.h"
 
@@ -56,7 +56,7 @@
 //
 class HTMLImportChild FINAL : public HTMLImport, public HTMLImportLoaderClient, public ResourceOwner<RawResource> {
 public:
-    HTMLImportChild(const KURL&, bool createdByParser);
+    HTMLImportChild(Document&, const KURL&, bool sync);
     virtual ~HTMLImportChild();
 
     HTMLLinkElement* link() const;
@@ -73,6 +73,7 @@
     virtual Document* document() const OVERRIDE;
     virtual void wasDetachedFromDocument() OVERRIDE;
     virtual void didFinishParsing() OVERRIDE;
+    virtual void didRemoveAllPendingStylesheet() OVERRIDE;
     virtual bool isDone() const OVERRIDE;
     virtual bool hasLoader() const OVERRIDE;
     virtual bool ownsLoader() const OVERRIDE;
@@ -102,6 +103,7 @@
     void shareLoader(HTMLImportChild*);
     void ensureLoader();
 
+    Document& m_master;
     KURL m_url;
     CustomElementMicrotaskImportStep* m_customElementMicrotaskStep;
     RefPtr<HTMLImportLoader> m_loader;
diff --git a/Source/core/html/HTMLImportChildClient.h b/Source/core/html/imports/HTMLImportChildClient.h
similarity index 97%
rename from Source/core/html/HTMLImportChildClient.h
rename to Source/core/html/imports/HTMLImportChildClient.h
index be3177d..362a2c1 100644
--- a/Source/core/html/HTMLImportChildClient.h
+++ b/Source/core/html/imports/HTMLImportChildClient.h
@@ -41,7 +41,7 @@
     virtual ~HTMLImportChildClient() { }
     virtual void didFinish() = 0;
     virtual void importChildWasDestroyed(HTMLImportChild*) = 0;
-    virtual bool isCreatedByParser() const = 0;
+    virtual bool isSync() const = 0;
     virtual HTMLLinkElement* link() = 0;
 };
 
diff --git a/Source/core/html/HTMLImportLoader.cpp b/Source/core/html/imports/HTMLImportLoader.cpp
similarity index 84%
rename from Source/core/html/HTMLImportLoader.cpp
rename to Source/core/html/imports/HTMLImportLoader.cpp
index e0a0c00..d745721 100644
--- a/Source/core/html/HTMLImportLoader.cpp
+++ b/Source/core/html/imports/HTMLImportLoader.cpp
@@ -29,15 +29,15 @@
  */
 
 #include "config.h"
-#include "core/html/HTMLImportLoader.h"
+#include "core/html/imports/HTMLImportLoader.h"
 
 #include "core/dom/Document.h"
-#include "core/fetch/ResourceFetcher.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
+#include "core/dom/StyleEngine.h"
 #include "core/html/HTMLDocument.h"
-#include "core/html/HTMLImport.h"
-#include "core/html/HTMLImportLoaderClient.h"
+#include "core/html/imports/HTMLImport.h"
+#include "core/html/imports/HTMLImportLoaderClient.h"
 #include "core/loader/DocumentWriter.h"
+#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
 
 
 namespace WebCore {
@@ -93,7 +93,6 @@
     DocumentInit init = DocumentInit(response.url(), 0, m_import->master()->contextDocument(), m_import)
         .withRegistrationContext(m_import->master()->registrationContext());
     m_importedDocument = HTMLDocument::create(init);
-    m_importedDocument->initContentSecurityPolicy(ContentSecurityPolicyResponseHeaders(response));
     m_writer = DocumentWriter::create(m_importedDocument.get(), response.mimeType(), response.textEncodingName());
 
     return StateLoading;
@@ -106,7 +105,12 @@
 
 HTMLImportLoader::State HTMLImportLoader::finishParsing()
 {
-    return StateReady;
+    return StateParsed;
+}
+
+HTMLImportLoader::State HTMLImportLoader::finishLoading()
+{
+    return StateLoaded;
 }
 
 void HTMLImportLoader::setState(State state)
@@ -116,19 +120,32 @@
 
     m_state = state;
 
-    if (m_state == StateReady || m_state == StateError || m_state == StateWritten) {
+    if (m_state == StateParsed || m_state == StateError || m_state == StateWritten) {
         if (RefPtr<DocumentWriter> writer = m_writer.release())
             writer->end();
     }
 
     // Since DocumentWriter::end() can let setState() reenter, we shouldn't refer to m_state here.
-    if (state == StateReady || state == StateError)
-        didFinish();
+    if (state == StateLoaded || state == StateError)
+        didFinishLoading();
 }
 
 void HTMLImportLoader::didFinishParsing()
 {
     setState(finishParsing());
+    if (!hasPendingResources())
+        setState(finishLoading());
+}
+
+void HTMLImportLoader::didRemoveAllPendingStylesheet()
+{
+    if (m_state == StateParsed)
+        setState(finishLoading());
+}
+
+bool HTMLImportLoader::hasPendingResources() const
+{
+    return m_importedDocument && m_importedDocument->styleEngine()->hasPendingSheets();
 }
 
 Document* HTMLImportLoader::importedDocument() const
@@ -138,7 +155,7 @@
     return m_importedDocument.get();
 }
 
-void HTMLImportLoader::didFinish()
+void HTMLImportLoader::didFinishLoading()
 {
     for (size_t i = 0; i < m_clients.size(); ++i)
         m_clients[i]->didFinishLoading();
diff --git a/Source/core/html/HTMLImportLoader.h b/Source/core/html/imports/HTMLImportLoader.h
similarity index 92%
rename from Source/core/html/HTMLImportLoader.h
rename to Source/core/html/imports/HTMLImportLoader.h
index a09f658..e48305b 100644
--- a/Source/core/html/HTMLImportLoader.h
+++ b/Source/core/html/imports/HTMLImportLoader.h
@@ -53,8 +53,9 @@
     enum State {
         StateLoading,
         StateWritten,
-        StateError,
-        StateReady
+        StateParsed,
+        StateLoaded,
+        StateError
     };
 
     static PassRefPtr<HTMLImportLoader> create(HTMLImport* import)
@@ -69,11 +70,12 @@
     void addClient(HTMLImportLoaderClient*);
     void removeClient(HTMLImportLoaderClient*);
 
-    bool isDone() const { return m_state == StateReady || m_state == StateError; }
+    bool isDone() const { return m_state == StateLoaded || m_state == StateError; }
     bool hasError() const { return m_state == StateError; }
 
     void startLoading(const ResourcePtr<RawResource>&);
     void didFinishParsing();
+    void didRemoveAllPendingStylesheet();
     bool isOwnedBy(const HTMLImport* import) const { return m_import == import; }
 
 private:
@@ -87,9 +89,11 @@
     State startWritingAndParsing(const ResourceResponse&);
     State finishWriting();
     State finishParsing();
+    State finishLoading();
 
     void setState(State);
-    void didFinish();
+    void didFinishLoading();
+    bool hasPendingResources() const;
 
     HTMLImport* m_import;
     Vector<HTMLImportLoaderClient*> m_clients;
diff --git a/Source/core/html/HTMLImportLoaderClient.h b/Source/core/html/imports/HTMLImportLoaderClient.h
similarity index 100%
rename from Source/core/html/HTMLImportLoaderClient.h
rename to Source/core/html/imports/HTMLImportLoaderClient.h
diff --git a/Source/core/html/HTMLImportState.h b/Source/core/html/imports/HTMLImportState.h
similarity index 100%
rename from Source/core/html/HTMLImportState.h
rename to Source/core/html/imports/HTMLImportState.h
diff --git a/Source/core/html/HTMLImportStateResolver.cpp b/Source/core/html/imports/HTMLImportStateResolver.cpp
similarity index 94%
rename from Source/core/html/HTMLImportStateResolver.cpp
rename to Source/core/html/imports/HTMLImportStateResolver.cpp
index 90650e8..e83449c 100644
--- a/Source/core/html/HTMLImportStateResolver.cpp
+++ b/Source/core/html/imports/HTMLImportStateResolver.cpp
@@ -29,9 +29,9 @@
  */
 
 #include "config.h"
-#include "core/html/HTMLImportStateResolver.h"
+#include "core/html/imports/HTMLImportStateResolver.h"
 
-#include "core/html/HTMLImport.h"
+#include "core/html/imports/HTMLImport.h"
 
 namespace WebCore {
 
@@ -60,7 +60,7 @@
 inline bool HTMLImportStateResolver::shouldBlockScriptExecution() const
 {
     for (HTMLImport* child = m_import->firstChild(); child; child = child->next()) {
-        if (child->isCreatedByParser() && isBlockingFollowers(child))
+        if (child->isSync() && isBlockingFollowers(child))
             return true;
     }
 
diff --git a/Source/core/html/HTMLImportStateResolver.h b/Source/core/html/imports/HTMLImportStateResolver.h
similarity index 97%
rename from Source/core/html/HTMLImportStateResolver.h
rename to Source/core/html/imports/HTMLImportStateResolver.h
index 417680c..f68ac99 100644
--- a/Source/core/html/HTMLImportStateResolver.h
+++ b/Source/core/html/imports/HTMLImportStateResolver.h
@@ -31,7 +31,7 @@
 #ifndef HTMLImportStateResolver_h
 #define HTMLImportStateResolver_h
 
-#include "core/html/HTMLImportState.h"
+#include "core/html/imports/HTMLImportState.h"
 
 namespace WebCore {
 
diff --git a/Source/core/html/HTMLImportsController.cpp b/Source/core/html/imports/HTMLImportsController.cpp
similarity index 87%
rename from Source/core/html/HTMLImportsController.cpp
rename to Source/core/html/imports/HTMLImportsController.cpp
index 7baf599..b7d0f26 100644
--- a/Source/core/html/HTMLImportsController.cpp
+++ b/Source/core/html/imports/HTMLImportsController.cpp
@@ -29,25 +29,26 @@
  */
 
 #include "config.h"
-#include "core/html/HTMLImportsController.h"
+#include "core/html/imports/HTMLImportsController.h"
 
 #include "core/dom/Document.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/html/HTMLImportChild.h"
-#include "core/html/HTMLImportChildClient.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportChildClient.h"
 
 namespace WebCore {
 
-void HTMLImportsController::provideTo(Document* master)
+void HTMLImportsController::provideTo(Document& master)
 {
     DEFINE_STATIC_LOCAL(const char*, name, ("HTMLImportsController"));
     OwnPtr<HTMLImportsController> controller = adoptPtr(new HTMLImportsController(master));
-    master->setImport(controller.get());
+    master.setImport(controller.get());
     DocumentSupplement::provideTo(master, name, controller.release());
 }
 
-HTMLImportsController::HTMLImportsController(Document* master)
-    : m_master(master)
+HTMLImportsController::HTMLImportsController(Document& master)
+    : m_master(&master)
     , m_recalcTimer(this, &HTMLImportsController::recalcTimerFired)
 {
     recalcTreeState(this); // This recomputes initial state.
@@ -69,7 +70,7 @@
 
 HTMLImportChild* HTMLImportsController::createChild(const KURL& url, HTMLImport* parent, HTMLImportChildClient* client)
 {
-    OwnPtr<HTMLImportChild> loader = adoptPtr(new HTMLImportChild(url, client->isCreatedByParser()));
+    OwnPtr<HTMLImportChild> loader = adoptPtr(new HTMLImportChild(*m_master, url, client->isSync()));
     loader->setClient(client);
     parent->appendChild(loader.get());
     m_imports.append(loader.release());
@@ -150,11 +151,21 @@
     return !m_master->parsing();
 }
 
+void HTMLImportsController::stateDidChange()
+{
+    HTMLImport::stateDidChange();
+
+    if (!state().isReady())
+        return;
+    if (LocalFrame* frame = m_master->frame())
+        frame->loader().checkCompleted();
+}
+
 void HTMLImportsController::scheduleRecalcState()
 {
     if (m_recalcTimer.isActive())
         return;
-    m_recalcTimer.startOneShot(0);
+    m_recalcTimer.startOneShot(0, FROM_HERE);
 }
 
 void HTMLImportsController::recalcTimerFired(Timer<HTMLImportsController>*)
diff --git a/Source/core/html/HTMLImportsController.h b/Source/core/html/imports/HTMLImportsController.h
similarity index 94%
rename from Source/core/html/HTMLImportsController.h
rename to Source/core/html/imports/HTMLImportsController.h
index 1d62bde..a52482c 100644
--- a/Source/core/html/HTMLImportsController.h
+++ b/Source/core/html/imports/HTMLImportsController.h
@@ -32,8 +32,8 @@
 #define HTMLImportsController_h
 
 #include "core/fetch/RawResource.h"
-#include "core/html/HTMLImport.h"
 #include "core/html/LinkResource.h"
+#include "core/html/imports/HTMLImport.h"
 #include "platform/Supplementable.h"
 #include "platform/Timer.h"
 #include "wtf/FastAllocBase.h"
@@ -51,9 +51,9 @@
 class HTMLImportsController FINAL : public HTMLImportRoot, public DocumentSupplement {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    static void provideTo(Document*);
+    static void provideTo(Document&);
 
-    explicit HTMLImportsController(Document*);
+    explicit HTMLImportsController(Document&);
     virtual ~HTMLImportsController();
 
     // HTMLImport
@@ -62,6 +62,7 @@
     virtual void wasDetachedFromDocument() OVERRIDE;
     virtual bool isDone() const OVERRIDE;
     virtual bool hasLoader() const OVERRIDE;
+    virtual void stateDidChange() OVERRIDE;
 
     // HTMLImportRoot
     virtual void scheduleRecalcState() OVERRIDE;
diff --git a/Source/core/html/LinkImport.cpp b/Source/core/html/imports/LinkImport.cpp
similarity index 89%
rename from Source/core/html/LinkImport.cpp
rename to Source/core/html/imports/LinkImport.cpp
index dd61de4..18751a4 100644
--- a/Source/core/html/LinkImport.cpp
+++ b/Source/core/html/imports/LinkImport.cpp
@@ -29,13 +29,13 @@
  */
 
 #include "config.h"
-#include "core/html/LinkImport.h"
+#include "core/html/imports/LinkImport.h"
 
 #include "core/dom/Document.h"
 #include "core/fetch/CrossOriginAccessControl.h"
-#include "core/html/HTMLImportChild.h"
-#include "core/html/HTMLImportsController.h"
 #include "core/html/HTMLLinkElement.h"
+#include "core/html/imports/HTMLImportChild.h"
+#include "core/html/imports/HTMLImportsController.h"
 
 
 namespace WebCore {
@@ -58,7 +58,7 @@
 
 Document* LinkImport::importedDocument() const
 {
-    if (!m_child)
+    if (!m_child || !m_owner || !m_owner->inDocument())
         return 0;
     return m_child->importedDocument();
 }
@@ -74,7 +74,7 @@
 
     if (!m_owner->document().import()) {
         ASSERT(m_owner->document().frame()); // The document should be the master.
-        HTMLImportsController::provideTo(&m_owner->document());
+        HTMLImportsController::provideTo(m_owner->document());
     }
 
     LinkRequestBuilder builder(m_owner);
@@ -101,14 +101,9 @@
     }
 }
 
-void LinkImport::ownerRemoved()
-{
-    clear();
-}
-
 void LinkImport::didFinish()
 {
-    if (!m_owner)
+    if (!m_owner || !m_owner->inDocument())
         return;
     // Because didFinish() is called from import's own scheduler in HTMLImportsController,
     // we don't need to scheduleEvent() here.
@@ -122,9 +117,9 @@
     clear();
 }
 
-bool LinkImport::isCreatedByParser() const
+bool LinkImport::isSync() const
 {
-    return m_owner && m_owner->isCreatedByParser();
+    return m_owner && m_owner->isCreatedByParser() && !m_owner->async();
 }
 
 HTMLLinkElement* LinkImport::link()
diff --git a/Source/core/html/LinkImport.h b/Source/core/html/imports/LinkImport.h
similarity index 94%
rename from Source/core/html/LinkImport.h
rename to Source/core/html/imports/LinkImport.h
index 5d84870..ab46aff 100644
--- a/Source/core/html/LinkImport.h
+++ b/Source/core/html/imports/LinkImport.h
@@ -31,8 +31,8 @@
 #ifndef LinkImport_h
 #define LinkImport_h
 
-#include "core/html/HTMLImportChildClient.h"
 #include "core/html/LinkResource.h"
+#include "core/html/imports/HTMLImportChildClient.h"
 #include "wtf/FastAllocBase.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/RefPtr.h"
@@ -57,13 +57,12 @@
     // LinkResource
     virtual void process() OVERRIDE;
     virtual Type type() const OVERRIDE { return Import; }
-    virtual void ownerRemoved() OVERRIDE;
     virtual bool hasLoaded() const OVERRIDE;
 
     // HTMLImportChildClient
     virtual void didFinish() OVERRIDE;
     virtual void importChildWasDestroyed(HTMLImportChild*) OVERRIDE;
-    virtual bool isCreatedByParser() const OVERRIDE;
+    virtual bool isSync() const OVERRIDE;
     virtual HTMLLinkElement* link() OVERRIDE;
 
     Document* importedDocument() const;
diff --git a/Source/core/html/parser/HTMLConstructionSite.cpp b/Source/core/html/parser/HTMLConstructionSite.cpp
index 84f1d38..79feebf 100644
--- a/Source/core/html/parser/HTMLConstructionSite.cpp
+++ b/Source/core/html/parser/HTMLConstructionSite.cpp
@@ -35,6 +35,7 @@
 #include "core/dom/Element.h"
 #include "core/dom/ScriptLoader.h"
 #include "core/dom/Text.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLHtmlElement.h"
 #include "core/html/HTMLScriptElement.h"
@@ -45,7 +46,7 @@
 #include "core/html/parser/HTMLToken.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
+#include "core/svg/SVGScriptElement.h"
 #include "platform/NotImplemented.h"
 #include "platform/text/TextBreakIterator.h"
 #include <limits>
@@ -75,14 +76,14 @@
         || item->hasTagName(rtTag);
 }
 
-static bool shouldUseLengthLimit(const ContainerNode* node)
+static bool shouldUseLengthLimit(const ContainerNode& node)
 {
-    return !node->hasTagName(scriptTag)
-        && !node->hasTagName(styleTag)
-        && !node->hasTagName(SVGNames::scriptTag);
+    return !isHTMLScriptElement(node)
+        && !isHTMLStyleElement(node)
+        && !isSVGScriptElement(node);
 }
 
-static unsigned textLengthLimitForContainer(const ContainerNode* node)
+static unsigned textLengthLimitForContainer(const ContainerNode& node)
 {
     return shouldUseLengthLimit(node) ? Text::defaultLengthLimit : std::numeric_limits<unsigned>::max();
 }
@@ -94,7 +95,7 @@
 
 static inline void insert(HTMLConstructionSiteTask& task)
 {
-    if (task.parent->hasTagName(templateTag))
+    if (isHTMLTemplateElement(*task.parent))
         task.parent = toHTMLTemplateElement(task.parent.get())->content();
 
     if (ContainerNode* parent = task.child->parentNode())
@@ -131,7 +132,7 @@
     Node* previousChild = task.nextChild ? task.nextChild->previousSibling() : task.parent->lastChild();
     if (previousChild && previousChild->isTextNode()) {
         Text* previousText = toText(previousChild);
-        unsigned lengthLimit = textLengthLimitForContainer(task.parent.get());
+        unsigned lengthLimit = textLengthLimitForContainer(*task.parent);
         if (previousText->length() + newText->length() < lengthLimit) {
             previousText->parserAppendData(newText->data());
             return;
@@ -239,7 +240,7 @@
 
     // Splitting text nodes into smaller chunks contradicts HTML5 spec, but is necessary
     // for performance, see: https://bugs.webkit.org/show_bug.cgi?id=55898
-    unsigned lengthLimit = textLengthLimitForContainer(pendingText.parent.get());
+    unsigned lengthLimit = textLengthLimitForContainer(*pendingText.parent);
 
     unsigned currentPosition = 0;
     const StringBuilder& string = pendingText.stringBuilder;
@@ -590,14 +591,14 @@
     RefPtr<Element> body = createHTMLElement(token);
     attachLater(currentNode(), body);
     m_openElements.pushHTMLBodyElement(HTMLStackItem::create(body.release(), token));
-    if (Frame* frame = m_document->frame())
+    if (LocalFrame* frame = m_document->frame())
         frame->loader().client()->dispatchWillInsertBody();
 }
 
 void HTMLConstructionSite::insertHTMLFormElement(AtomicHTMLToken* token, bool isDemoted)
 {
     RefPtr<Element> element = createHTMLElement(token);
-    ASSERT(element->hasTagName(formTag));
+    ASSERT(isHTMLFormElement(element));
     m_form = static_pointer_cast<HTMLFormElement>(element.release());
     m_form->setDemoted(isDemoted);
     attachLater(currentNode(), m_form);
@@ -668,7 +669,7 @@
         findFosterSite(dummyTask);
 
     // FIXME: This probably doesn't need to be done both here and in insert(Task).
-    if (dummyTask.parent->hasTagName(templateTag))
+    if (isHTMLTemplateElement(*dummyTask.parent))
         dummyTask.parent = toHTMLTemplateElement(dummyTask.parent.get())->content();
 
     // Unclear when parent != case occurs. Somehow we insert text into two separate nodes while processing the same Token.
@@ -726,7 +727,7 @@
 
 inline Document& HTMLConstructionSite::ownerDocumentForCurrentNode()
 {
-    if (currentNode()->hasTagName(templateTag))
+    if (isHTMLTemplateElement(*currentNode()))
         return toHTMLTemplateElement(currentElement())->content()->document();
     return currentNode()->document();
 }
diff --git a/Source/core/html/parser/HTMLDocumentParser.cpp b/Source/core/html/parser/HTMLDocumentParser.cpp
index 84c9197..210185e 100644
--- a/Source/core/html/parser/HTMLDocumentParser.cpp
+++ b/Source/core/html/parser/HTMLDocumentParser.cpp
@@ -29,6 +29,7 @@
 #include "HTMLNames.h"
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/Element.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLDocument.h"
 #include "core/html/parser/AtomicHTMLToken.h"
 #include "core/html/parser/BackgroundHTMLParser.h"
@@ -37,7 +38,6 @@
 #include "core/html/parser/HTMLScriptRunner.h"
 #include "core/html/parser/HTMLTreeBuilder.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
 #include "platform/SharedBuffer.h"
 #include "platform/TraceEvent.h"
 #include "wtf/Functional.h"
@@ -279,7 +279,7 @@
     }
 
     // FIXME: It's wrong for the HTMLDocumentParser to reach back to the
-    //        Frame, but this approach is how the old parser handled
+    //        LocalFrame, but this approach is how the old parser handled
     //        stopping when the page assigns window.location.  What really
     //        should happen is that assigning window.location causes the
     //        parser to stop parsing cleanly.  The problem is we're not
diff --git a/Source/core/html/parser/HTMLElementStack.cpp b/Source/core/html/parser/HTMLElementStack.cpp
index 5bf3a14..ccbbdd8 100644
--- a/Source/core/html/parser/HTMLElementStack.cpp
+++ b/Source/core/html/parser/HTMLElementStack.cpp
@@ -31,6 +31,7 @@
 #include "MathMLNames.h"
 #include "SVGNames.h"
 #include "core/dom/Element.h"
+#include "core/html/HTMLElement.h"
 
 namespace WebCore {
 
@@ -400,7 +401,7 @@
 
 void HTMLElementStack::remove(Element* element)
 {
-    ASSERT(!element->hasTagName(HTMLNames::headTag));
+    ASSERT(!isHTMLHeadElement(element));
     if (m_top->element() == element) {
         pop();
         return;
@@ -576,8 +577,8 @@
 
 void HTMLElementStack::removeNonTopCommon(Element* element)
 {
-    ASSERT(!element->hasTagName(htmlTag));
-    ASSERT(!element->hasTagName(bodyTag));
+    ASSERT(!isHTMLHtmlElement(element));
+    ASSERT(!isHTMLBodyElement(element));
     ASSERT(top() != element);
     for (ElementRecord* pos = m_top.get(); pos; pos = pos->next()) {
         if (pos->next()->element() == element) {
diff --git a/Source/core/html/parser/HTMLFormattingElementList.cpp b/Source/core/html/parser/HTMLFormattingElementList.cpp
index 34215d7..08128d7 100644
--- a/Source/core/html/parser/HTMLFormattingElementList.cpp
+++ b/Source/core/html/parser/HTMLFormattingElementList.cpp
@@ -155,7 +155,7 @@
     if (candidates.size() < kNoahsArkCapacity)
         return; // There's room for the new element in the ark. There's no need to copy out the remainingCandidates.
 
-    remainingCandidates.append(candidates);
+    remainingCandidates.appendVector(candidates);
 }
 
 void HTMLFormattingElementList::ensureNoahsArkCondition(HTMLStackItem* newItem)
diff --git a/Source/core/html/parser/HTMLFormattingElementList.h b/Source/core/html/parser/HTMLFormattingElementList.h
index 745dba1..507ac84 100644
--- a/Source/core/html/parser/HTMLFormattingElementList.h
+++ b/Source/core/html/parser/HTMLFormattingElementList.h
@@ -54,7 +54,7 @@
         }
         enum MarkerEntryType { MarkerEntry };
         explicit Entry(MarkerEntryType)
-            : m_item(0)
+            : m_item(nullptr)
         {
         }
         ~Entry() {}
diff --git a/Source/core/html/parser/HTMLParserIdioms.cpp b/Source/core/html/parser/HTMLParserIdioms.cpp
index e3b143a..a71d9a5 100644
--- a/Source/core/html/parser/HTMLParserIdioms.cpp
+++ b/Source/core/html/parser/HTMLParserIdioms.cpp
@@ -95,8 +95,7 @@
 
 Decimal parseToDecimalForNumberType(const String& string, const Decimal& fallbackValue)
 {
-    // See HTML5 2.5.4.3 `Real numbers.' and parseToDoubleForNumberType
-
+    // http://www.whatwg.org/specs/web-apps/current-work/#floating-point-numbers and parseToDoubleForNumberType
     // String::toDouble() accepts leading + and whitespace characters, which are not valid here.
     const UChar firstCharacter = string[0];
     if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
@@ -106,11 +105,9 @@
     if (!value.isFinite())
         return fallbackValue;
 
-    // Numbers are considered finite IEEE 754 single-precision floating point values.
-    // See HTML5 2.5.4.3 `Real numbers.'
-    // FIXME: We should use numeric_limits<double>::max for number input type.
-    const Decimal floatMax = Decimal::fromDouble(std::numeric_limits<float>::max());
-    if (value < -floatMax || value > floatMax)
+    // Numbers are considered finite IEEE 754 Double-precision floating point values.
+    const Decimal doubleMax = Decimal::fromDouble(std::numeric_limits<double>::max());
+    if (value < -doubleMax || value > doubleMax)
         return fallbackValue;
 
     // We return +0 for -0 case.
@@ -119,8 +116,7 @@
 
 double parseToDoubleForNumberType(const String& string, double fallbackValue)
 {
-    // See HTML5 2.5.4.3 `Real numbers.'
-
+    // http://www.whatwg.org/specs/web-apps/current-work/#floating-point-numbers
     // String::toDouble() accepts leading + and whitespace characters, which are not valid here.
     UChar firstCharacter = string[0];
     if (firstCharacter != '-' && firstCharacter != '.' && !isASCIIDigit(firstCharacter))
@@ -135,9 +131,8 @@
     if (!std::isfinite(value))
         return fallbackValue;
 
-    // Numbers are considered finite IEEE 754 single-precision floating point values.
-    // See HTML5 2.5.4.3 `Real numbers.'
-    if (-std::numeric_limits<float>::max() > value || value > std::numeric_limits<float>::max())
+    // Numbers are considered finite IEEE 754 Double-precision floating point values.
+    if (-std::numeric_limits<double>::max() > value || value > std::numeric_limits<double>::max())
         return fallbackValue;
 
     // The following expression converts -0 to +0.
@@ -374,7 +369,8 @@
     return threadSafeEqual(localName.impl(), qName.localName().impl());
 }
 
-StringImpl* findStringIfStatic(const UChar* characters, unsigned length)
+template<typename CharType>
+inline StringImpl* findStringIfStatic(const CharType* characters, unsigned length)
 {
     // We don't need to try hashing if we know the string is too long.
     if (length > StringImpl::highestStaticStringLength())
@@ -396,4 +392,27 @@
     return it->value;
 }
 
+String attemptStaticStringCreation(const LChar* characters, size_t size)
+{
+    String string(findStringIfStatic(characters, size));
+    if (string.impl())
+        return string;
+    return String(characters, size);
+}
+
+String attemptStaticStringCreation(const UChar* characters, size_t size, CharacterWidth width)
+{
+    String string(findStringIfStatic(characters, size));
+    if (string.impl())
+        return string;
+    if (width == Likely8Bit)
+        string = StringImpl::create8BitIfPossible(characters, size);
+    else if (width == Force8Bit)
+        string = String::make8BitFrom16BitSource(characters, size);
+    else
+        string = String(characters, size);
+
+    return string;
+}
+
 }
diff --git a/Source/core/html/parser/HTMLParserIdioms.h b/Source/core/html/parser/HTMLParserIdioms.h
index 49dbed3..4cfb3d4 100644
--- a/Source/core/html/parser/HTMLParserIdioms.h
+++ b/Source/core/html/parser/HTMLParserIdioms.h
@@ -107,29 +107,29 @@
 bool threadSafeMatch(const QualifiedName&, const QualifiedName&);
 bool threadSafeMatch(const String&, const QualifiedName&);
 
-StringImpl* findStringIfStatic(const UChar* characters, unsigned length);
-
 enum CharacterWidth {
     Likely8Bit,
     Force8Bit,
     Force16Bit
 };
 
-template<size_t inlineCapacity>
-static String attemptStaticStringCreation(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
-{
-    String string(findStringIfStatic(vector.data(), vector.size()));
-    if (string.impl())
-        return string;
-    if (width == Likely8Bit)
-        string = StringImpl::create8BitIfPossible(vector);
-    else if (width == Force8Bit)
-        string = String::make8BitFrom16BitSource(vector);
-    else
-        string = String(vector);
+String attemptStaticStringCreation(const LChar*, size_t);
 
-    return string;
+String attemptStaticStringCreation(const UChar*, size_t, CharacterWidth);
+
+template<size_t inlineCapacity>
+inline static String attemptStaticStringCreation(const Vector<UChar, inlineCapacity>& vector, CharacterWidth width)
+{
+    return attemptStaticStringCreation(vector.data(), vector.size(), width);
 }
 
+inline static String attemptStaticStringCreation(const String str)
+{
+    if (!str.is8Bit())
+        return attemptStaticStringCreation(str.characters16(), str.length(), Force16Bit);
+    return attemptStaticStringCreation(str.characters8(), str.length());
+}
+
+
 }
 #endif
diff --git a/Source/core/html/parser/HTMLParserOptions.cpp b/Source/core/html/parser/HTMLParserOptions.cpp
index 98ceb68..150eed2 100644
--- a/Source/core/html/parser/HTMLParserOptions.cpp
+++ b/Source/core/html/parser/HTMLParserOptions.cpp
@@ -28,15 +28,15 @@
 
 #include "bindings/v8/ScriptController.h"
 #include "core/dom/Document.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
+#include "core/loader/FrameLoader.h"
 
 namespace WebCore {
 
 HTMLParserOptions::HTMLParserOptions(Document* document)
 {
-    Frame* frame = document ? document->frame() : 0;
+    LocalFrame* frame = document ? document->frame() : 0;
     scriptEnabled = frame && frame->script().canExecuteScripts(NotAboutToExecuteScript);
     pluginsEnabled = frame && frame->loader().allowPlugins(NotAboutToInstantiatePlugin);
 
diff --git a/Source/core/html/parser/HTMLParserScheduler.cpp b/Source/core/html/parser/HTMLParserScheduler.cpp
index c746284..7825c9c 100644
--- a/Source/core/html/parser/HTMLParserScheduler.cpp
+++ b/Source/core/html/parser/HTMLParserScheduler.cpp
@@ -93,7 +93,7 @@
     // FIXME: We should fix this by reducing the max-parse-time instead of
     // artificially forcing the parser to yield agressively before first layout.
     if (m_parser->document()->shouldParserYieldAgressivelyBeforeScriptExecution()) {
-        m_continueNextChunkTimer.startOneShot(0);
+        m_continueNextChunkTimer.startOneShot(0, FROM_HERE);
         return;
     }
     m_parser->resumeParsingAfterYield();
@@ -112,7 +112,7 @@
 
 void HTMLParserScheduler::scheduleForResume()
 {
-    m_continueNextChunkTimer.startOneShot(0);
+    m_continueNextChunkTimer.startOneShot(0, FROM_HERE);
 }
 
 
@@ -131,7 +131,7 @@
     if (!m_isSuspendedWithActiveTimer)
         return;
     m_isSuspendedWithActiveTimer = false;
-    m_continueNextChunkTimer.startOneShot(0);
+    m_continueNextChunkTimer.startOneShot(0, FROM_HERE);
 }
 
 }
diff --git a/Source/core/html/parser/HTMLPreloadScanner.cpp b/Source/core/html/parser/HTMLPreloadScanner.cpp
index f9199cc..5f55827 100644
--- a/Source/core/html/parser/HTMLPreloadScanner.cpp
+++ b/Source/core/html/parser/HTMLPreloadScanner.cpp
@@ -142,7 +142,7 @@
         TextPosition position = TextPosition(source.currentLine(), source.currentColumn());
         OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagImpl), position, m_urlToLoad, predictedBaseURL, resourceType(), m_mediaAttribute);
         if (isCORSEnabled())
-            request->setCrossOriginEnabled(allowCredentials());
+            request->setCrossOriginEnabled(allowStoredCredentials());
         request->setCharset(charset());
         return request.release();
     }
@@ -242,7 +242,7 @@
         return m_isCORSEnabled;
     }
 
-    StoredCredentials allowCredentials() const
+    StoredCredentials allowStoredCredentials() const
     {
         return m_allowCredentials;
     }
diff --git a/Source/core/html/parser/HTMLResourcePreloader.cpp b/Source/core/html/parser/HTMLResourcePreloader.cpp
index b023fa9..68e7217 100644
--- a/Source/core/html/parser/HTMLResourcePreloader.cpp
+++ b/Source/core/html/parser/HTMLResourcePreloader.cpp
@@ -29,9 +29,9 @@
 #include "core/dom/Document.h"
 #include "core/fetch/FetchInitiatorInfo.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/html/HTMLImport.h"
 #include "core/css/MediaList.h"
 #include "core/css/MediaQueryEvaluator.h"
+#include "core/html/imports/HTMLImport.h"
 #include "core/rendering/RenderObject.h"
 #include "public/platform/Platform.h"
 
@@ -73,9 +73,9 @@
         preload(it->release());
 }
 
-static bool mediaAttributeMatches(Frame* frame, RenderStyle* renderStyle, const String& attributeValue)
+static bool mediaAttributeMatches(LocalFrame* frame, RenderStyle* renderStyle, const String& attributeValue)
 {
-    RefPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(attributeValue);
+    RefPtrWillBeRawPtr<MediaQuerySet> mediaQueries = MediaQuerySet::create(attributeValue);
     MediaQueryEvaluator mediaQueryEvaluator("screen", frame, renderStyle);
     return mediaQueryEvaluator.eval(mediaQueries.get());
 }
diff --git a/Source/core/html/parser/HTMLScriptRunner.cpp b/Source/core/html/parser/HTMLScriptRunner.cpp
index 2d73cce..c16d06a 100644
--- a/Source/core/html/parser/HTMLScriptRunner.cpp
+++ b/Source/core/html/parser/HTMLScriptRunner.cpp
@@ -33,10 +33,10 @@
 #include "core/dom/Microtask.h"
 #include "core/dom/ScriptLoader.h"
 #include "core/fetch/ScriptResource.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/parser/HTMLInputStream.h"
 #include "core/html/parser/HTMLScriptRunnerHost.h"
 #include "core/html/parser/NestingLevelIncrementer.h"
-#include "core/frame/Frame.h"
 #include "platform/NotImplemented.h"
 
 namespace WebCore {
diff --git a/Source/core/html/parser/HTMLScriptRunner.h b/Source/core/html/parser/HTMLScriptRunner.h
index 82d8bc2..aae39e2 100644
--- a/Source/core/html/parser/HTMLScriptRunner.h
+++ b/Source/core/html/parser/HTMLScriptRunner.h
@@ -37,7 +37,7 @@
 class ScriptResource;
 class Document;
 class Element;
-class Frame;
+class LocalFrame;
 class HTMLScriptRunnerHost;
 class ScriptSourceCode;
 
@@ -66,7 +66,7 @@
 private:
     HTMLScriptRunner(Document*, HTMLScriptRunnerHost*);
 
-    Frame* frame() const;
+    LocalFrame* frame() const;
 
     void executeParsingBlockingScript();
     void executePendingScriptAndDispatchEvent(PendingScript&);
diff --git a/Source/core/html/parser/HTMLSrcsetParser.cpp b/Source/core/html/parser/HTMLSrcsetParser.cpp
index 7002dff..1002d8a 100644
--- a/Source/core/html/parser/HTMLSrcsetParser.cpp
+++ b/Source/core/html/parser/HTMLSrcsetParser.cpp
@@ -51,8 +51,9 @@
 static bool parseDescriptors(const CharType* descriptorsStart, const CharType* descriptorsEnd, float& imgScaleFactor)
 {
     const CharType* position = descriptorsStart;
-    bool isValid = true;
-    bool isScaleFactorFound = false;
+    bool isValid = false;
+    bool isFoundScaleFactor = false;
+    bool isEmptyDescriptor = !(descriptorsEnd > descriptorsStart);
     while (position < descriptorsEnd) {
         // 13.1. Let descriptor list be the result of splitting unparsed descriptors on spaces.
         skipWhile<CharType, isHTMLSpace<CharType> >(position, descriptorsEnd);
@@ -65,15 +66,15 @@
         --currentDescriptorEnd;
         unsigned descriptorLength = currentDescriptorEnd - currentDescriptorStart;
         if (*currentDescriptorEnd == 'x') {
-            if (isScaleFactorFound)
+            if (isFoundScaleFactor)
                 return false;
             imgScaleFactor = charactersToFloat(currentDescriptorStart, descriptorLength, &isValid);
-            isScaleFactorFound = true;
+            isFoundScaleFactor = true;
         } else {
             continue;
         }
     }
-    return isValid;
+    return isEmptyDescriptor || isValid;
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/embedded-content-1.html#processing-the-image-candidates
@@ -138,11 +139,18 @@
     std::stable_sort(imageCandidates.begin(), imageCandidates.end(), compareByScaleFactor);
 
     unsigned i;
-    for (i = 0; i < imageCandidates.size() - 1; ++i) {
+    for (i = 0; i < imageCandidates.size() - 1; ++i)
         if (imageCandidates[i].scaleFactor() >= deviceScaleFactor)
             break;
-    }
-    return imageCandidates[i];
+
+    float winningScaleFactor = imageCandidates[i].scaleFactor();
+    unsigned winner = i;
+    // 16. If an entry b in candidates has the same associated ... pixel density as an earlier entry a in candidates,
+    // then remove entry b
+    while ((i > 0) && (imageCandidates[--i].scaleFactor() == winningScaleFactor))
+        winner = i;
+
+    return imageCandidates[winner];
 }
 
 ImageCandidate bestFitSourceForSrcsetAttribute(float deviceScaleFactor, const String& srcsetAttribute)
diff --git a/Source/core/html/parser/HTMLStackItem.h b/Source/core/html/parser/HTMLStackItem.h
index d3dd15c..038e7f0 100644
--- a/Source/core/html/parser/HTMLStackItem.h
+++ b/Source/core/html/parser/HTMLStackItem.h
@@ -172,7 +172,6 @@
             || tagName == HTMLNames::iframeTag
             || tagName == HTMLNames::imgTag
             || tagName == HTMLNames::inputTag
-            || tagName == HTMLNames::isindexTag
             || tagName == HTMLNames::liTag
             || tagName == HTMLNames::linkTag
             || tagName == HTMLNames::listingTag
diff --git a/Source/core/html/parser/HTMLTreeBuilder.cpp b/Source/core/html/parser/HTMLTreeBuilder.cpp
index 5997b21..d75d7a3 100644
--- a/Source/core/html/parser/HTMLTreeBuilder.cpp
+++ b/Source/core/html/parser/HTMLTreeBuilder.cpp
@@ -137,7 +137,7 @@
 {
     ASSERT(isMainThread());
     while (element) {
-        if (element->hasTagName(formTag))
+        if (isHTMLFormElement(*element))
             return toHTMLFormElement(element);
         ContainerNode* parent = element->parentNode();
         if (!parent || !parent->isElementNode())
@@ -311,7 +311,7 @@
         // and instead use the DocumentFragment as a root node.
         m_tree.openElements()->pushRootNode(HTMLStackItem::create(fragment, HTMLStackItem::ItemForDocumentFragmentNode));
 
-        if (contextElement->hasTagName(templateTag))
+        if (isHTMLTemplateElement(*contextElement))
             m_templateInsertionModes.append(TemplateContentsMode);
 
         resetInsertionModeAppropriately();
@@ -343,7 +343,7 @@
 HTMLTreeBuilder::FragmentParsingContext::FragmentParsingContext(DocumentFragment* fragment, Element* contextElement)
     : m_fragment(fragment)
 {
-    ASSERT(!fragment->hasChildNodes());
+    ASSERT(!fragment->hasChildren());
     m_contextElementStackItem = HTMLStackItem::create(contextElement, HTMLStackItem::ItemForContextElement);
 }
 
@@ -458,13 +458,6 @@
     processFakeEndTag(tagName.localName());
 }
 
-void HTMLTreeBuilder::processFakeCharacters(const String& characters)
-{
-    ASSERT(!characters.isEmpty());
-    CharacterTokenBuffer buffer(characters);
-    processCharacterBuffer(buffer);
-}
-
 void HTMLTreeBuilder::processFakePEndTagIfPInButtonScope()
 {
     if (!m_tree.openElements()->inButtonScope(pTag.localName()))
@@ -473,49 +466,6 @@
     processEndTag(&endP);
 }
 
-Vector<Attribute> HTMLTreeBuilder::attributesForIsindexInput(AtomicHTMLToken* token)
-{
-    Vector<Attribute> attributes = token->attributes();
-    for (int i = attributes.size() - 1; i >= 0; --i) {
-        const QualifiedName& name = attributes.at(i).name();
-        if (name.matches(nameAttr) || name.matches(actionAttr) || name.matches(promptAttr))
-            attributes.remove(i);
-    }
-
-    attributes.append(Attribute(nameAttr, isindexTag.localName()));
-    return attributes;
-}
-
-void HTMLTreeBuilder::processIsindexStartTagForInBody(AtomicHTMLToken* token)
-{
-    ASSERT(token->type() == HTMLToken::StartTag);
-    ASSERT(token->name() == isindexTag);
-
-    if (m_parser->useCounter())
-        m_parser->useCounter()->count(UseCounter::IsIndexElement);
-
-    parseError(token);
-    if (m_tree.form())
-        return;
-    notImplemented(); // Acknowledge self-closing flag
-    processFakeStartTag(formTag);
-    Attribute* actionAttribute = token->getAttributeItem(actionAttr);
-    if (actionAttribute)
-        m_tree.form()->setAttribute(actionAttr, actionAttribute->value());
-    processFakeStartTag(hrTag);
-    processFakeStartTag(labelTag);
-    Attribute* promptAttribute = token->getAttributeItem(promptAttr);
-    if (promptAttribute)
-        processFakeCharacters(promptAttribute->value());
-    else
-        processFakeCharacters(Locale::defaultLocale().queryString(blink::WebLocalizedString::SearchableIndexIntroduction));
-    processFakeStartTag(inputTag, attributesForIsindexInput(token));
-    notImplemented(); // This second set of characters may be needed by non-english locales.
-    processFakeEndTag(labelTag);
-    processFakeStartTag(hrTag);
-    processFakeEndTag(formTag);
-}
-
 namespace {
 
 bool isLi(const HTMLStackItem* item)
@@ -856,10 +806,6 @@
         m_framesetOk = false;
         return;
     }
-    if (token->name() == isindexTag) {
-        processIsindexStartTagForInBody(token);
-        return;
-    }
     if (token->name() == textareaTag) {
         m_tree.insertHTMLElement(token);
         m_shouldSkipLeadingNewline = true;
@@ -966,7 +912,7 @@
 {
     ASSERT(token->name() == templateTag.localName());
     if (!m_tree.openElements()->hasTemplateInHTMLScope()) {
-        ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && m_fragmentContext.contextElement()->hasTagName(templateTag)));
+        ASSERT(m_templateInsertionModes.isEmpty() || (m_templateInsertionModes.size() == 1 && isHTMLTemplateElement(m_fragmentContext.contextElement())));
         parseError(token);
         return false;
     }
@@ -992,7 +938,7 @@
 
 bool HTMLTreeBuilder::processColgroupEndTagForInColumnGroup()
 {
-    if (m_tree.currentIsRootNode() || m_tree.currentNode()->hasTagName(templateTag)) {
+    if (m_tree.currentIsRootNode() || isHTMLTemplateElement(*m_tree.currentNode())) {
         ASSERT(isParsingFragmentOrTemplateContents());
         // FIXME: parse error
         return false;
@@ -2509,7 +2455,7 @@
             ASSERT(isParsingFragment());
             return; // FIXME: Should we break here instead of returning?
         }
-        ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || m_tree.currentNode()->hasTagName(templateTag));
+        ASSERT(m_tree.currentNode()->hasTagName(colgroupTag) || isHTMLTemplateElement(m_tree.currentNode()));
         processColgroupEndTagForInColumnGroup();
         // Fall through
     case InFramesetMode:
diff --git a/Source/core/html/parser/HTMLTreeBuilder.h b/Source/core/html/parser/HTMLTreeBuilder.h
index 60ead95..124ae9a 100644
--- a/Source/core/html/parser/HTMLTreeBuilder.h
+++ b/Source/core/html/parser/HTMLTreeBuilder.h
@@ -44,7 +44,7 @@
 class Document;
 class DocumentFragment;
 class Element;
-class Frame;
+class LocalFrame;
 class HTMLToken;
 class HTMLDocument;
 class Node;
@@ -153,7 +153,6 @@
     void processFakeStartTag(const QualifiedName&, const Vector<Attribute>& attributes = Vector<Attribute>());
     void processFakeEndTag(const QualifiedName&);
     void processFakeEndTag(const AtomicString&);
-    void processFakeCharacters(const String&);
     void processFakePEndTagIfPInButtonScope();
 
     void processGenericRCDATAStartTag(AtomicHTMLToken*);
diff --git a/Source/core/html/parser/TextResourceDecoder.cpp b/Source/core/html/parser/TextResourceDecoder.cpp
index 1f650d4..3daddfe 100644
--- a/Source/core/html/parser/TextResourceDecoder.cpp
+++ b/Source/core/html/parser/TextResourceDecoder.cpp
@@ -406,7 +406,7 @@
     if (!m_codec)
         m_codec = newTextCodec(m_encoding);
 
-    String result = m_codec->decode(dataForDecode, lengthForDecode, false, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
+    String result = m_codec->decode(dataForDecode, lengthForDecode, DoNotFlush, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
 
     m_buffer.clear();
     return result;
@@ -427,7 +427,7 @@
     if (!m_codec)
         m_codec = newTextCodec(m_encoding);
 
-    String result = m_codec->decode(m_buffer.data(), m_buffer.size(), true, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
+    String result = m_codec->decode(m_buffer.data(), m_buffer.size(), FetchEOF, m_contentType == XMLContent && !m_useLenientXMLDecoding, m_sawError);
     m_buffer.clear();
     m_codec.clear();
     m_checkedForBOM = false; // Skip BOM again when re-decoding.
diff --git a/Source/core/html/parser/XSSAuditor.cpp b/Source/core/html/parser/XSSAuditor.cpp
index 2e07967..7adae45 100644
--- a/Source/core/html/parser/XSSAuditor.cpp
+++ b/Source/core/html/parser/XSSAuditor.cpp
@@ -31,8 +31,8 @@
 #include "SVGNames.h"
 #include "XLinkNames.h"
 #include "core/dom/Document.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/HTMLParamElement.h"
 #include "core/html/parser/HTMLDocumentParser.h"
 #include "core/html/parser/HTMLParserIdioms.h"
@@ -63,9 +63,11 @@
     // Note, we don't remove backslashes like PHP stripslashes(), which among other things converts "\\0" to the \0 character.
     // Instead, we remove backslashes and zeros (since the string "\\0" =(remove backslashes)=> "0"). However, this has the
     // adverse effect that we remove any legitimate zeros from a string.
+    // We also remove forward-slash, because it is common for some servers to collapse successive path components, eg,
+    // a//b becomes a/b.
     //
-    // For instance: new String("http://localhost:8000") => new String("http://localhost:8").
-    return (c == '\\' || c == '0' || c == '\0' || c >= 127);
+    // For instance: new String("http://localhost:8000") => new String("http:localhost:8").
+    return (c == '\\' || c == '0' || c == '\0' || c == '/' || c >= 127);
 }
 
 static String canonicalize(const String& string)
@@ -171,7 +173,6 @@
         workingString = decode16BitUnicodeEscapeSequences(decodeStandardURLEscapeSequences(workingString, encoding));
     } while (workingString.length() < oldWorkingStringLength);
     workingString.replace('+', ' ');
-    workingString = canonicalize(workingString);
     return workingString;
 }
 
@@ -240,7 +241,7 @@
 
     m_documentURL = document->url().copy();
 
-    // In theory, the Document could have detached from the Frame after the
+    // In theory, the Document could have detached from the LocalFrame after the
     // XSSAuditor was constructed.
     if (!document->frame()) {
         m_isEnabled = false;
@@ -309,12 +310,12 @@
 
     m_encoding = encoding;
 
-    m_decodedURL = fullyDecodeString(m_documentURL.string(), m_encoding);
+    m_decodedURL = canonicalize(fullyDecodeString(m_documentURL.string(), m_encoding));
     if (m_decodedURL.find(isRequiredForInjection) == kNotFound)
         m_decodedURL = String();
 
     if (!m_httpBodyAsString.isEmpty()) {
-        m_decodedHTTPBody = fullyDecodeString(m_httpBodyAsString, m_encoding);
+        m_decodedHTTPBody = canonicalize(fullyDecodeString(m_httpBodyAsString, m_encoding));
         m_httpBodyAsString = String();
         if (m_decodedHTTPBody.find(isRequiredForInjection) == kNotFound)
             m_decodedHTTPBody = String();
@@ -580,7 +581,7 @@
 String XSSAuditor::decodedSnippetForName(const FilterTokenRequest& request)
 {
     // Grab a fixed number of characters equal to the length of the token's name plus one (to account for the "<").
-    return fullyDecodeString(request.sourceTracker.sourceForToken(request.token), m_encoding).substring(0, request.token.name().size() + 1);
+    return canonicalize(fullyDecodeString(request.sourceTracker.sourceForToken(request.token), m_encoding).substring(0, request.token.name().size() + 1));
 }
 
 String XSSAuditor::decodedSnippetForAttribute(const FilterTokenRequest& request, const HTMLToken::Attribute& attribute, AttributeKind treatment)
@@ -639,7 +640,7 @@
             decodedSnippet.truncate(position);
         }
     }
-    return decodedSnippet;
+    return canonicalize(decodedSnippet);
 }
 
 String XSSAuditor::decodedSnippetForJavaScript(const FilterTokenRequest& request)
@@ -699,7 +700,7 @@
             }
         }
 
-        result = fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_encoding);
+        result = canonicalize(fullyDecodeString(string.substring(startPosition, foundPosition - startPosition), m_encoding));
         startPosition = foundPosition + 1;
     }
     return result;
diff --git a/Source/core/html/parser/XSSAuditorDelegate.cpp b/Source/core/html/parser/XSSAuditorDelegate.cpp
index 8e3e0b9..9b329e8 100644
--- a/Source/core/html/parser/XSSAuditorDelegate.cpp
+++ b/Source/core/html/parser/XSSAuditorDelegate.cpp
@@ -27,7 +27,7 @@
 #include "core/html/parser/XSSAuditorDelegate.h"
 
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
@@ -100,8 +100,8 @@
 
     m_document->addConsoleMessage(JSMessageSource, ErrorMessageLevel, xssInfo.buildConsoleError());
 
-    // stopAllLoaders can detach the Frame, so protect it.
-    RefPtr<Frame> protect(m_document->frame());
+    // stopAllLoaders can detach the LocalFrame, so protect it.
+    RefPtr<LocalFrame> protect(m_document->frame());
     FrameLoader& frameLoader = m_document->frame()->loader();
     if (xssInfo.m_didBlockEntirePage)
         frameLoader.stopAllLoaders();
diff --git a/Source/core/html/shadow/ClearButtonElement.cpp b/Source/core/html/shadow/ClearButtonElement.cpp
index f3e0d1d..c67e02d 100644
--- a/Source/core/html/shadow/ClearButtonElement.cpp
+++ b/Source/core/html/shadow/ClearButtonElement.cpp
@@ -27,9 +27,9 @@
 #include "core/html/shadow/ClearButtonElement.h"
 
 #include "core/events/MouseEvent.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderView.h"
 
 namespace WebCore {
@@ -54,8 +54,8 @@
 void ClearButtonElement::detach(const AttachContext& context)
 {
     if (m_capturing) {
-        if (Frame* frame = document().frame())
-            frame->eventHandler().setCapturingMouseEventsNode(0);
+        if (LocalFrame* frame = document().frame())
+            frame->eventHandler().setCapturingMouseEventsNode(nullptr);
     }
     HTMLDivElement::detach(context);
 }
@@ -65,8 +65,8 @@
     if (!m_capturing)
         return;
 
-    if (Frame* frame = document().frame()) {
-        frame->eventHandler().setCapturingMouseEventsNode(0);
+    if (LocalFrame* frame = document().frame()) {
+        frame->eventHandler().setCapturingMouseEventsNode(nullptr);
         m_capturing = false;
     }
 }
@@ -87,7 +87,7 @@
 
     if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
         if (renderer() && renderer()->visibleToHitTesting()) {
-            if (Frame* frame = document().frame()) {
+            if (LocalFrame* frame = document().frame()) {
                 frame->eventHandler().setCapturingMouseEventsNode(this);
                 m_capturing = true;
             }
@@ -97,8 +97,8 @@
     }
     if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
         if (m_capturing) {
-            if (Frame* frame = document().frame()) {
-                frame->eventHandler().setCapturingMouseEventsNode(0);
+            if (LocalFrame* frame = document().frame()) {
+                frame->eventHandler().setCapturingMouseEventsNode(nullptr);
                 m_capturing = false;
             }
             if (hovered()) {
diff --git a/Source/core/html/shadow/HTMLContentElement.h b/Source/core/html/shadow/HTMLContentElement.h
deleted file mode 100644
index 2b60b19..0000000
--- a/Source/core/html/shadow/HTMLContentElement.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Copyright (C) 2011 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLContentElement_h
-#define HTMLContentElement_h
-
-#include "core/css/CSSSelectorList.h"
-#include "core/dom/shadow/InsertionPoint.h"
-
-namespace WebCore {
-
-class HTMLContentElement FINAL : public InsertionPoint {
-public:
-    static PassRefPtr<HTMLContentElement> create(Document&);
-
-    virtual ~HTMLContentElement();
-
-    virtual bool canAffectSelector() const OVERRIDE { return true; }
-
-    bool canSelectNode(const Vector<Node*, 32>& siblings, int nth) const;
-
-    const CSSSelectorList& selectorList() const;
-    bool isSelectValid() const;
-
-private:
-    explicit HTMLContentElement(Document&);
-
-    virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
-
-    bool validateSelect() const;
-    void parseSelect();
-
-    bool matchSelector(const Vector<Node*, 32>& siblings, int nth) const;
-
-    bool m_shouldParseSelect;
-    bool m_isValidSelector;
-    AtomicString m_select;
-    CSSSelectorList m_selectorList;
-};
-
-inline const CSSSelectorList& HTMLContentElement::selectorList() const
-{
-    if (m_shouldParseSelect)
-        const_cast<HTMLContentElement*>(this)->parseSelect();
-    return m_selectorList;
-}
-
-inline bool HTMLContentElement::isSelectValid() const
-{
-    if (m_shouldParseSelect)
-        const_cast<HTMLContentElement*>(this)->parseSelect();
-    return m_isValidSelector;
-}
-
-inline bool HTMLContentElement::canSelectNode(const Vector<Node*, 32>& siblings, int nth) const
-{
-    if (m_select.isNull() || m_select.isEmpty())
-        return true;
-    if (!isSelectValid())
-        return false;
-    if (!siblings[nth]->isElementNode())
-        return false;
-    return matchSelector(siblings, nth);
-}
-
-DEFINE_NODE_TYPE_CASTS(HTMLContentElement, hasTagName(HTMLNames::contentTag));
-
-}
-
-#endif
diff --git a/Source/core/html/shadow/HTMLShadowElement.h b/Source/core/html/shadow/HTMLShadowElement.h
deleted file mode 100644
index 435a057..0000000
--- a/Source/core/html/shadow/HTMLShadowElement.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef HTMLShadowElement_h
-#define HTMLShadowElement_h
-
-#include "core/dom/shadow/InsertionPoint.h"
-#include "wtf/Forward.h"
-
-namespace WebCore {
-
-class HTMLShadowElement FINAL : public InsertionPoint {
-public:
-    static PassRefPtr<HTMLShadowElement> create(Document&);
-
-    virtual ~HTMLShadowElement();
-
-    ShadowRoot* olderShadowRoot();
-
-private:
-    explicit HTMLShadowElement(Document&);
-    virtual InsertionNotificationRequest insertedInto(ContainerNode* insertionPoint) OVERRIDE;
-};
-
-DEFINE_NODE_TYPE_CASTS(HTMLShadowElement, hasTagName(HTMLNames::shadowTag));
-
-} // namespace WebCore
-
-#endif // HTMLShadowElement_h
diff --git a/Source/core/html/shadow/MediaControlElementTypes.cpp b/Source/core/html/shadow/MediaControlElementTypes.cpp
index f8e0d5f..1090eb0 100644
--- a/Source/core/html/shadow/MediaControlElementTypes.cpp
+++ b/Source/core/html/shadow/MediaControlElementTypes.cpp
@@ -36,6 +36,8 @@
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/css/StylePropertySet.h"
 #include "core/events/MouseEvent.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/shadow/MediaControls.h"
 
 namespace WebCore {
 
@@ -50,7 +52,7 @@
     Node* mediaNode = node->shadowHost();
     if (!mediaNode)
         mediaNode = node;
-    if (!mediaNode || !mediaNode->isElementNode() || !toElement(mediaNode)->isMediaElement())
+    if (!isHTMLMediaElement(mediaNode))
         return 0;
 
     return toHTMLMediaElement(mediaNode);
@@ -60,18 +62,28 @@
 {
     ASSERT_WITH_SECURITY_IMPLICATION(node->isMediaControlElement());
     HTMLElement* element = toHTMLElement(node);
-    if (element->hasTagName(inputTag))
+    if (isHTMLInputElement(*element))
         return static_cast<MediaControlInputElement*>(element)->displayType();
     return static_cast<MediaControlDivElement*>(element)->displayType();
 }
 
-MediaControlElement::MediaControlElement(MediaControlElementType displayType, HTMLElement* element)
-    : m_mediaController(0)
+MediaControlElement::MediaControlElement(MediaControls& mediaControls, MediaControlElementType displayType, HTMLElement* element)
+    : m_mediaControls(mediaControls)
     , m_displayType(displayType)
     , m_element(element)
 {
 }
 
+HTMLMediaElement& MediaControlElement::mediaElement() const
+{
+    return mediaControls().mediaElement();
+}
+
+MediaControllerInterface& MediaControlElement::mediaControllerInterface() const
+{
+    return mediaControls().mediaControllerInterface();
+}
+
 void MediaControlElement::hide()
 {
     m_element->setInlineStyleProperty(CSSPropertyDisplay, CSSValueNone);
@@ -94,17 +106,17 @@
 
 // ----------------------------
 
-MediaControlDivElement::MediaControlDivElement(Document& document, MediaControlElementType displayType)
-    : HTMLDivElement(document)
-    , MediaControlElement(displayType, this)
+MediaControlDivElement::MediaControlDivElement(MediaControls& mediaControls, MediaControlElementType displayType)
+    : HTMLDivElement(mediaControls.document())
+    , MediaControlElement(mediaControls, displayType, this)
 {
 }
 
 // ----------------------------
 
-MediaControlInputElement::MediaControlInputElement(Document& document, MediaControlElementType displayType)
-    : HTMLInputElement(document, 0, false)
-    , MediaControlElement(displayType, this)
+MediaControlInputElement::MediaControlInputElement(MediaControls& mediaControls, MediaControlElementType displayType)
+    : HTMLInputElement(mediaControls.document(), 0, false)
+    , MediaControlElement(mediaControls, displayType, this)
 {
 }
 
@@ -115,8 +127,8 @@
 
 // ----------------------------
 
-MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(Document& document, MediaControlElementType displayType)
-    : MediaControlDivElement(document, displayType)
+MediaControlTimeDisplayElement::MediaControlTimeDisplayElement(MediaControls& mediaControls, MediaControlElementType displayType)
+    : MediaControlDivElement(mediaControls, displayType)
     , m_currentValue(0)
 {
 }
@@ -126,87 +138,4 @@
     m_currentValue = time;
 }
 
-// ----------------------------
-
-MediaControlMuteButtonElement::MediaControlMuteButtonElement(Document& document, MediaControlElementType displayType)
-    : MediaControlInputElement(document, displayType)
-{
-}
-
-void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
-{
-    if (event->type() == EventTypeNames::click) {
-        mediaController()->setMuted(!mediaController()->muted());
-        event->setDefaultHandled();
-    }
-
-    HTMLInputElement::defaultEventHandler(event);
-}
-
-void MediaControlMuteButtonElement::changedMute()
-{
-    updateDisplayType();
-}
-
-void MediaControlMuteButtonElement::updateDisplayType()
-{
-    setDisplayType(mediaController()->muted() ? MediaUnMuteButton : MediaMuteButton);
-}
-
-// ----------------------------
-
-MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(Document& document)
-    : MediaControlInputElement(document, MediaVolumeSlider)
-    , m_clearMutedOnUserInteraction(false)
-{
-}
-
-void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
-{
-    // Left button is 0. Rejects mouse events not from left button.
-    if (event->isMouseEvent() && toMouseEvent(event)->button())
-        return;
-
-    if (!inDocument() || !document().isActive())
-        return;
-
-    MediaControlInputElement::defaultEventHandler(event);
-
-    if (event->type() == EventTypeNames::mouseover || event->type() == EventTypeNames::mouseout || event->type() == EventTypeNames::mousemove)
-        return;
-
-    double volume = value().toDouble();
-    if (volume != mediaController()->volume())
-        mediaController()->setVolume(volume, ASSERT_NO_EXCEPTION);
-    if (m_clearMutedOnUserInteraction)
-        mediaController()->setMuted(false);
-}
-
-bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
-{
-    if (!inDocument() || !document().isActive())
-        return false;
-
-    return MediaControlInputElement::willRespondToMouseMoveEvents();
-}
-
-bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
-{
-    if (!inDocument() || !document().isActive())
-        return false;
-
-    return MediaControlInputElement::willRespondToMouseClickEvents();
-}
-
-void MediaControlVolumeSliderElement::setVolume(double volume)
-{
-    if (value().toDouble() != volume)
-        setValue(String::number(volume));
-}
-
-void MediaControlVolumeSliderElement::setClearMutedOnUserInteraction(bool clearMute)
-{
-    m_clearMutedOnUserInteraction = clearMute;
-}
-
 } // namespace WebCore
diff --git a/Source/core/html/shadow/MediaControlElementTypes.h b/Source/core/html/shadow/MediaControlElementTypes.h
index e80ee79..511b768 100644
--- a/Source/core/html/shadow/MediaControlElementTypes.h
+++ b/Source/core/html/shadow/MediaControlElementTypes.h
@@ -32,12 +32,14 @@
 
 #include "core/html/HTMLDivElement.h"
 #include "core/html/HTMLInputElement.h"
-#include "core/html/HTMLMediaElement.h"
-#include "core/html/MediaControllerInterface.h"
 #include "core/rendering/RenderBlock.h"
 
 namespace WebCore {
 
+class HTMLMediaElement;
+class MediaControllerInterface;
+class MediaControls;
+
 enum MediaControlElementType {
     MediaEnterFullscreenButton = 0,
     MediaMuteButton,
@@ -78,17 +80,17 @@
 
     MediaControlElementType displayType() { return m_displayType; }
 
-    void setMediaController(MediaControllerInterface* controller) { m_mediaController = controller; }
-    MediaControllerInterface* mediaController() const { return m_mediaController; }
-
 protected:
-    explicit MediaControlElement(MediaControlElementType, HTMLElement*);
-    ~MediaControlElement() { }
+    MediaControlElement(MediaControls&, MediaControlElementType, HTMLElement*);
+
+    MediaControls& mediaControls() const { return m_mediaControls; }
+    HTMLMediaElement& mediaElement() const;
+    MediaControllerInterface& mediaControllerInterface() const;
 
     void setDisplayType(MediaControlElementType);
 
 private:
-    MediaControllerInterface* m_mediaController;
+    MediaControls& m_mediaControls;
     MediaControlElementType m_displayType;
     HTMLElement* m_element;
 };
@@ -98,7 +100,7 @@
 class MediaControlDivElement : public HTMLDivElement, public MediaControlElement {
 protected:
     virtual bool isMediaControlElement() const OVERRIDE FINAL { return true; }
-    explicit MediaControlDivElement(Document&, MediaControlElementType);
+    MediaControlDivElement(MediaControls&, MediaControlElementType);
 };
 
 // ----------------------------
@@ -106,7 +108,7 @@
 class MediaControlInputElement : public HTMLInputElement, public MediaControlElement {
 protected:
     virtual bool isMediaControlElement() const OVERRIDE FINAL { return true; }
-    explicit MediaControlInputElement(Document&, MediaControlElementType);
+    MediaControlInputElement(MediaControls&, MediaControlElementType);
 
 private:
     virtual void updateDisplayType() { }
@@ -121,47 +123,12 @@
     double currentValue() const { return m_currentValue; }
 
 protected:
-    explicit MediaControlTimeDisplayElement(Document&, MediaControlElementType);
+    MediaControlTimeDisplayElement(MediaControls&, MediaControlElementType);
 
 private:
     double m_currentValue;
 };
 
-// ----------------------------
-
-class MediaControlMuteButtonElement : public MediaControlInputElement {
-public:
-    void changedMute();
-
-    virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
-
-protected:
-    explicit MediaControlMuteButtonElement(Document&, MediaControlElementType);
-
-    virtual void defaultEventHandler(Event*) OVERRIDE;
-
-private:
-    virtual void updateDisplayType() OVERRIDE;
-};
-
-// ----------------------------
-
-class MediaControlVolumeSliderElement : public MediaControlInputElement {
-public:
-    virtual bool willRespondToMouseMoveEvents() OVERRIDE;
-    virtual bool willRespondToMouseClickEvents() OVERRIDE;
-    void setVolume(double);
-    void setClearMutedOnUserInteraction(bool);
-
-protected:
-    explicit MediaControlVolumeSliderElement(Document&);
-
-    virtual void defaultEventHandler(Event*) OVERRIDE;
-
-private:
-    bool m_clearMutedOnUserInteraction;
-};
-
 } // namespace WebCore
 
 #endif // MediaControlElementTypes_h
diff --git a/Source/core/html/shadow/MediaControlElements.cpp b/Source/core/html/shadow/MediaControlElements.cpp
index 2c1ad6e..5e04376 100644
--- a/Source/core/html/shadow/MediaControlElements.cpp
+++ b/Source/core/html/shadow/MediaControlElements.cpp
@@ -37,13 +37,13 @@
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
 #include "core/html/HTMLVideoElement.h"
 #include "core/html/shadow/MediaControls.h"
 #include "core/html/track/TextTrack.h"
 #include "core/html/track/vtt/VTTRegionList.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
 #include "core/rendering/RenderMediaControlElements.h"
 #include "core/rendering/RenderSlider.h"
 #include "core/rendering/RenderTheme.h"
@@ -59,8 +59,8 @@
 static const double fadeInDuration = 0.1;
 static const double fadeOutDuration = 0.3;
 
-MediaControlPanelElement::MediaControlPanelElement(Document& document)
-    : MediaControlDivElement(document, MediaControlsPanel)
+MediaControlPanelElement::MediaControlPanelElement(MediaControls& mediaControls)
+    : MediaControlDivElement(mediaControls, MediaControlsPanel)
     , m_canBeDragged(false)
     , m_isBeingDragged(false)
     , m_isDisplayed(false)
@@ -69,9 +69,9 @@
 {
 }
 
-PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(Document& document)
+PassRefPtr<MediaControlPanelElement> MediaControlPanelElement::create(MediaControls& mediaControls)
 {
-    return adoptRef(new MediaControlPanelElement(document));
+    return adoptRef(new MediaControlPanelElement(mediaControls));
 }
 
 const AtomicString& MediaControlPanelElement::shadowPseudoId() const
@@ -92,7 +92,7 @@
     if (!renderer || !renderer->isBox())
         return;
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
@@ -121,11 +121,11 @@
 
     m_isBeingDragged = false;
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
-    frame->eventHandler().setCapturingMouseEventsNode(0);
+    frame->eventHandler().setCapturingMouseEventsNode(nullptr);
 }
 
 void MediaControlPanelElement::startTimer()
@@ -136,7 +136,7 @@
     // such that captions are correctly displayed at the bottom of the video
     // at the end of the fadeout transition.
     // FIXME: Racing a transition with a setTimeout like this is wrong.
-    m_transitionTimer.startOneShot(fadeOutDuration);
+    m_transitionTimer.startOneShot(fadeOutDuration, FROM_HERE);
 }
 
 void MediaControlPanelElement::stopTimer()
@@ -155,8 +155,9 @@
 
 void MediaControlPanelElement::setPosition(const LayoutPoint& position)
 {
-    double left = position.x();
-    double top = position.y();
+    // FIXME: Do we really want to up-convert these to doubles and not round? crbug.com/350474
+    double left = position.x().toFloat();
+    double top = position.y().toFloat();
 
     // Set the left and top to control the panel's position; this depends on it being absolute positioned.
     // Set the margin to zero since the position passed in will already include the effect of the margin.
@@ -165,7 +166,7 @@
     setInlineStyleProperty(CSSPropertyMarginLeft, 0.0, CSSPrimitiveValue::CSS_PX);
     setInlineStyleProperty(CSSPropertyMarginTop, 0.0, CSSPrimitiveValue::CSS_PX);
 
-    classList()->add("dragged", IGNORE_EXCEPTION);
+    classList().add("dragged", IGNORE_EXCEPTION);
 }
 
 void MediaControlPanelElement::resetPosition()
@@ -175,7 +176,7 @@
     removeInlineStyleProperty(CSSPropertyMarginLeft);
     removeInlineStyleProperty(CSSPropertyMarginTop);
 
-    classList()->remove("dragged", IGNORE_EXCEPTION);
+    classList().remove("dragged", IGNORE_EXCEPTION);
 
     m_cumulativeDragOffset.setX(0);
     m_cumulativeDragOffset.setY(0);
@@ -246,15 +247,15 @@
 
 // ----------------------------
 
-MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(Document& document)
+MediaControlPanelEnclosureElement::MediaControlPanelEnclosureElement(MediaControls& mediaControls)
     // Mapping onto same MediaControlElementType as panel element, since it has similar properties.
-    : MediaControlDivElement(document, MediaControlsPanel)
+    : MediaControlDivElement(mediaControls, MediaControlsPanel)
 {
 }
 
-PassRefPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(Document& document)
+PassRefPtr<MediaControlPanelEnclosureElement> MediaControlPanelEnclosureElement::create(MediaControls& mediaControls)
 {
-    return adoptRef(new MediaControlPanelEnclosureElement(document));
+    return adoptRef(new MediaControlPanelEnclosureElement(mediaControls));
 }
 
 const AtomicString& MediaControlPanelEnclosureElement::shadowPseudoId() const
@@ -265,15 +266,15 @@
 
 // ----------------------------
 
-MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(Document& document)
+MediaControlOverlayEnclosureElement::MediaControlOverlayEnclosureElement(MediaControls& mediaControls)
     // Mapping onto same MediaControlElementType as panel element, since it has similar properties.
-    : MediaControlDivElement(document, MediaControlsPanel)
+    : MediaControlDivElement(mediaControls, MediaControlsPanel)
 {
 }
 
-PassRefPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(Document& document)
+PassRefPtr<MediaControlOverlayEnclosureElement> MediaControlOverlayEnclosureElement::create(MediaControls& mediaControls)
 {
-    return adoptRef(new MediaControlOverlayEnclosureElement(document));
+    return adoptRef(new MediaControlOverlayEnclosureElement(mediaControls));
 }
 
 const AtomicString& MediaControlOverlayEnclosureElement::shadowPseudoId() const
@@ -284,31 +285,35 @@
 
 // ----------------------------
 
-MediaControlPanelMuteButtonElement::MediaControlPanelMuteButtonElement(Document& document, MediaControls* controls)
-    : MediaControlMuteButtonElement(document, MediaMuteButton)
-    , m_controls(controls)
+MediaControlMuteButtonElement::MediaControlMuteButtonElement(MediaControls& mediaControls)
+    : MediaControlInputElement(mediaControls, MediaMuteButton)
 {
 }
 
-PassRefPtr<MediaControlPanelMuteButtonElement> MediaControlPanelMuteButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtr<MediaControlMuteButtonElement> MediaControlMuteButtonElement::create(MediaControls& mediaControls)
 {
-    ASSERT(controls);
-
-    RefPtr<MediaControlPanelMuteButtonElement> button = adoptRef(new MediaControlPanelMuteButtonElement(document, controls));
+    RefPtr<MediaControlMuteButtonElement> button = adoptRef(new MediaControlMuteButtonElement(mediaControls));
     button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
 }
 
-void MediaControlPanelMuteButtonElement::defaultEventHandler(Event* event)
+void MediaControlMuteButtonElement::defaultEventHandler(Event* event)
 {
-    if (event->type() == EventTypeNames::mouseover)
-        m_controls->showVolumeSlider();
+    if (event->type() == EventTypeNames::click) {
+        mediaControllerInterface().setMuted(!mediaControllerInterface().muted());
+        event->setDefaultHandled();
+    }
 
-    MediaControlMuteButtonElement::defaultEventHandler(event);
+    HTMLInputElement::defaultEventHandler(event);
 }
 
-const AtomicString& MediaControlPanelMuteButtonElement::shadowPseudoId() const
+void MediaControlMuteButtonElement::updateDisplayType()
+{
+    setDisplayType(mediaControllerInterface().muted() ? MediaUnMuteButton : MediaMuteButton);
+}
+
+const AtomicString& MediaControlMuteButtonElement::shadowPseudoId() const
 {
     DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-mute-button", AtomicString::ConstructFromLiteral));
     return id;
@@ -316,14 +321,14 @@
 
 // ----------------------------
 
-MediaControlPlayButtonElement::MediaControlPlayButtonElement(Document& document)
-    : MediaControlInputElement(document, MediaPlayButton)
+MediaControlPlayButtonElement::MediaControlPlayButtonElement(MediaControls& mediaControls)
+    : MediaControlInputElement(mediaControls, MediaPlayButton)
 {
 }
 
-PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(Document& document)
+PassRefPtr<MediaControlPlayButtonElement> MediaControlPlayButtonElement::create(MediaControls& mediaControls)
 {
-    RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(document));
+    RefPtr<MediaControlPlayButtonElement> button = adoptRef(new MediaControlPlayButtonElement(mediaControls));
     button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
@@ -332,10 +337,10 @@
 void MediaControlPlayButtonElement::defaultEventHandler(Event* event)
 {
     if (event->type() == EventTypeNames::click) {
-        if (mediaController()->canPlay())
-            mediaController()->play();
+        if (mediaControllerInterface().canPlay())
+            mediaControllerInterface().play();
         else
-            mediaController()->pause();
+            mediaControllerInterface().pause();
         updateDisplayType();
         event->setDefaultHandled();
     }
@@ -344,7 +349,7 @@
 
 void MediaControlPlayButtonElement::updateDisplayType()
 {
-    setDisplayType(mediaController()->canPlay() ? MediaPlayButton : MediaPauseButton);
+    setDisplayType(mediaControllerInterface().canPlay() ? MediaPlayButton : MediaPauseButton);
 }
 
 const AtomicString& MediaControlPlayButtonElement::shadowPseudoId() const
@@ -355,14 +360,14 @@
 
 // ----------------------------
 
-MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(Document& document)
-    : MediaControlInputElement(document, MediaOverlayPlayButton)
+MediaControlOverlayPlayButtonElement::MediaControlOverlayPlayButtonElement(MediaControls& mediaControls)
+    : MediaControlInputElement(mediaControls, MediaOverlayPlayButton)
 {
 }
 
-PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(Document& document)
+PassRefPtr<MediaControlOverlayPlayButtonElement> MediaControlOverlayPlayButtonElement::create(MediaControls& mediaControls)
 {
-    RefPtr<MediaControlOverlayPlayButtonElement> button = adoptRef(new MediaControlOverlayPlayButtonElement(document));
+    RefPtr<MediaControlOverlayPlayButtonElement> button = adoptRef(new MediaControlOverlayPlayButtonElement(mediaControls));
     button->ensureUserAgentShadowRoot();
     button->setType("button");
     return button.release();
@@ -370,8 +375,8 @@
 
 void MediaControlOverlayPlayButtonElement::defaultEventHandler(Event* event)
 {
-    if (event->type() == EventTypeNames::click && mediaController()->canPlay()) {
-        mediaController()->play();
+    if (event->type() == EventTypeNames::click && mediaControllerInterface().canPlay()) {
+        mediaControllerInterface().play();
         updateDisplayType();
         event->setDefaultHandled();
     }
@@ -380,7 +385,7 @@
 
 void MediaControlOverlayPlayButtonElement::updateDisplayType()
 {
-    if (mediaController()->canPlay()) {
+    if (mediaControllerInterface().canPlay()) {
         show();
     } else
         hide();
@@ -395,16 +400,14 @@
 
 // ----------------------------
 
-MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(Document& document, MediaControls*)
-    : MediaControlInputElement(document, MediaShowClosedCaptionsButton)
+MediaControlToggleClosedCaptionsButtonElement::MediaControlToggleClosedCaptionsButtonElement(MediaControls& mediaControls)
+    : MediaControlInputElement(mediaControls, MediaShowClosedCaptionsButton)
 {
 }
 
-PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(Document& document, MediaControls* controls)
+PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> MediaControlToggleClosedCaptionsButtonElement::create(MediaControls& mediaControls)
 {
-    ASSERT(controls);
-
-    RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(document, controls));
+    RefPtr<MediaControlToggleClosedCaptionsButtonElement> button = adoptRef(new MediaControlToggleClosedCaptionsButtonElement(mediaControls));
     button->ensureUserAgentShadowRoot();
     button->setType("button");
     button->hide();
@@ -413,7 +416,7 @@
 
 void MediaControlToggleClosedCaptionsButtonElement::updateDisplayType()
 {
-    bool captionsVisible = mediaController()->closedCaptionsVisible();
+    bool captionsVisible = mediaControllerInterface().closedCaptionsVisible();
     setDisplayType(captionsVisible ? MediaHideClosedCaptionsButton : MediaShowClosedCaptionsButton);
     setChecked(captionsVisible);
 }
@@ -421,8 +424,8 @@
 void MediaControlToggleClosedCaptionsButtonElement::defaultEventHandler(Event* event)
 {
     if (event->type() == EventTypeNames::click) {
-        mediaController()->setClosedCaptionsVisible(!mediaController()->closedCaptionsVisible());
-        setChecked(mediaController()->closedCaptionsVisible());
+        mediaControllerInterface().setClosedCaptionsVisible(!mediaControllerInterface().closedCaptionsVisible());
+        setChecked(mediaControllerInterface().closedCaptionsVisible());
         updateDisplayType();
         event->setDefaultHandled();
     }
@@ -438,17 +441,14 @@
 
 // ----------------------------
 
-MediaControlTimelineElement::MediaControlTimelineElement(Document& document, MediaControls* controls)
-    : MediaControlInputElement(document, MediaSlider)
-    , m_controls(controls)
+MediaControlTimelineElement::MediaControlTimelineElement(MediaControls& mediaControls)
+    : MediaControlInputElement(mediaControls, MediaSlider)
 {
 }
 
-PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(Document& document, MediaControls* controls)
+PassRefPtr<MediaControlTimelineElement> MediaControlTimelineElement::create(MediaControls& mediaControls)
 {
-    ASSERT(controls);
-
-    RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(document, controls));
+    RefPtr<MediaControlTimelineElement> timeline = adoptRef(new MediaControlTimelineElement(mediaControls));
     timeline->ensureUserAgentShadowRoot();
     timeline->setType("range");
     timeline->setAttribute(stepAttr, "any");
@@ -465,10 +465,10 @@
         return;
 
     if (event->type() == EventTypeNames::mousedown)
-        mediaController()->beginScrubbing();
+        mediaControllerInterface().beginScrubbing();
 
     if (event->type() == EventTypeNames::mouseup)
-        mediaController()->endScrubbing();
+        mediaControllerInterface().endScrubbing();
 
     MediaControlInputElement::defaultEventHandler(event);
 
@@ -476,12 +476,12 @@
         return;
 
     double time = value().toDouble();
-    if (event->type() == EventTypeNames::input && time != mediaController()->currentTime())
-        mediaController()->setCurrentTime(time, IGNORE_EXCEPTION);
+    if (event->type() == EventTypeNames::input && time != mediaControllerInterface().currentTime())
+        mediaControllerInterface().setCurrentTime(time, IGNORE_EXCEPTION);
 
     RenderSlider* slider = toRenderSlider(renderer());
     if (slider && slider->inDragMode())
-        m_controls->updateCurrentTimeDisplay();
+        mediaControls().updateCurrentTimeDisplay();
 }
 
 bool MediaControlTimelineElement::willRespondToMouseClickEvents()
@@ -508,14 +508,14 @@
 
 // ----------------------------
 
-MediaControlPanelVolumeSliderElement::MediaControlPanelVolumeSliderElement(Document& document)
-    : MediaControlVolumeSliderElement(document)
+MediaControlVolumeSliderElement::MediaControlVolumeSliderElement(MediaControls& mediaControls)
+    : MediaControlInputElement(mediaControls, MediaVolumeSlider)
 {
 }
 
-PassRefPtr<MediaControlPanelVolumeSliderElement> MediaControlPanelVolumeSliderElement::create(Document& document)
+PassRefPtr<MediaControlVolumeSliderElement> MediaControlVolumeSliderElement::create(MediaControls& mediaControls)
 {
-    RefPtr<MediaControlPanelVolumeSliderElement> slider = adoptRef(new MediaControlPanelVolumeSliderElement(document));
+    RefPtr<MediaControlVolumeSliderElement> slider = adoptRef(new MediaControlVolumeSliderElement(mediaControls));
     slider->ensureUserAgentShadowRoot();
     slider->setType("range");
     slider->setAttribute(stepAttr, "any");
@@ -523,7 +523,47 @@
     return slider.release();
 }
 
-const AtomicString& MediaControlPanelVolumeSliderElement::shadowPseudoId() const
+void MediaControlVolumeSliderElement::defaultEventHandler(Event* event)
+{
+    if (event->isMouseEvent() && toMouseEvent(event)->button() != LeftButton)
+        return;
+
+    if (!inDocument() || !document().isActive())
+        return;
+
+    MediaControlInputElement::defaultEventHandler(event);
+
+    if (event->type() == EventTypeNames::mouseover || event->type() == EventTypeNames::mouseout || event->type() == EventTypeNames::mousemove)
+        return;
+
+    double volume = value().toDouble();
+    mediaControllerInterface().setVolume(volume, ASSERT_NO_EXCEPTION);
+    mediaControllerInterface().setMuted(false);
+}
+
+bool MediaControlVolumeSliderElement::willRespondToMouseMoveEvents()
+{
+    if (!inDocument() || !document().isActive())
+        return false;
+
+    return MediaControlInputElement::willRespondToMouseMoveEvents();
+}
+
+bool MediaControlVolumeSliderElement::willRespondToMouseClickEvents()
+{
+    if (!inDocument() || !document().isActive())
+        return false;
+
+    return MediaControlInputElement::willRespondToMouseClickEvents();
+}
+
+void MediaControlVolumeSliderElement::setVolume(double volume)
+{
+    if (value().toDouble() != volume)
+        setValue(String::number(volume));
+}
+
+const AtomicString& MediaControlVolumeSliderElement::shadowPseudoId() const
 {
     DEFINE_STATIC_LOCAL(AtomicString, id, ("-webkit-media-controls-volume-slider", AtomicString::ConstructFromLiteral));
     return id;
@@ -531,14 +571,14 @@
 
 // ----------------------------
 
-MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(Document& document)
-    : MediaControlInputElement(document, MediaEnterFullscreenButton)
+MediaControlFullscreenButtonElement::MediaControlFullscreenButtonElement(MediaControls& mediaControls)
+    : MediaControlInputElement(mediaControls, MediaEnterFullscreenButton)
 {
 }
 
-PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(Document& document)
+PassRefPtr<MediaControlFullscreenButtonElement> MediaControlFullscreenButtonElement::create(MediaControls& mediaControls)
 {
-    RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(document));
+    RefPtr<MediaControlFullscreenButtonElement> button = adoptRef(new MediaControlFullscreenButtonElement(mediaControls));
     button->ensureUserAgentShadowRoot();
     button->setType("button");
     button->hide();
@@ -554,12 +594,13 @@
         // video implementation without requiring them to implement their own full
         // screen behavior.
         if (document().settings() && document().settings()->fullScreenEnabled()) {
-            if (FullscreenElementStack::isActiveFullScreenElement(toParentMediaElement(this)))
-                FullscreenElementStack::from(&document())->webkitCancelFullScreen();
+            if (FullscreenElementStack::isActiveFullScreenElement(&mediaElement()))
+                FullscreenElementStack::from(document()).webkitCancelFullScreen();
             else
-                FullscreenElementStack::from(&document())->requestFullScreenForElement(toParentMediaElement(this), 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
-        } else
-            mediaController()->enterFullscreen();
+                FullscreenElementStack::from(document()).requestFullScreenForElement(&mediaElement(), 0, FullscreenElementStack::ExemptIFrameAllowFullScreenRequirement);
+        } else {
+            mediaControllerInterface().enterFullscreen();
+        }
         event->setDefaultHandled();
     }
     HTMLInputElement::defaultEventHandler(event);
@@ -578,14 +619,14 @@
 
 // ----------------------------
 
-MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(Document& document)
-    : MediaControlTimeDisplayElement(document, MediaTimeRemainingDisplay)
+MediaControlTimeRemainingDisplayElement::MediaControlTimeRemainingDisplayElement(MediaControls& mediaControls)
+    : MediaControlTimeDisplayElement(mediaControls, MediaTimeRemainingDisplay)
 {
 }
 
-PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(Document& document)
+PassRefPtr<MediaControlTimeRemainingDisplayElement> MediaControlTimeRemainingDisplayElement::create(MediaControls& mediaControls)
 {
-    return adoptRef(new MediaControlTimeRemainingDisplayElement(document));
+    return adoptRef(new MediaControlTimeRemainingDisplayElement(mediaControls));
 }
 
 static const AtomicString& getMediaControlTimeRemainingDisplayElementShadowPseudoId()
@@ -601,14 +642,14 @@
 
 // ----------------------------
 
-MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(Document& document)
-    : MediaControlTimeDisplayElement(document, MediaCurrentTimeDisplay)
+MediaControlCurrentTimeDisplayElement::MediaControlCurrentTimeDisplayElement(MediaControls& mediaControls)
+    : MediaControlTimeDisplayElement(mediaControls, MediaCurrentTimeDisplay)
 {
 }
 
-PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(Document& document)
+PassRefPtr<MediaControlCurrentTimeDisplayElement> MediaControlCurrentTimeDisplayElement::create(MediaControls& mediaControls)
 {
-    return adoptRef(new MediaControlCurrentTimeDisplayElement(document));
+    return adoptRef(new MediaControlCurrentTimeDisplayElement(mediaControls));
 }
 
 static const AtomicString& getMediaControlCurrentTimeDisplayElementShadowPseudoId()
@@ -624,15 +665,15 @@
 
 // ----------------------------
 
-MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(Document& document)
-    : MediaControlDivElement(document, MediaTextTrackDisplayContainer)
+MediaControlTextTrackContainerElement::MediaControlTextTrackContainerElement(MediaControls& mediaControls)
+    : MediaControlDivElement(mediaControls, MediaTextTrackDisplayContainer)
     , m_fontSize(0)
 {
 }
 
-PassRefPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(Document& document)
+PassRefPtr<MediaControlTextTrackContainerElement> MediaControlTextTrackContainerElement::create(MediaControls& mediaControls)
 {
-    RefPtr<MediaControlTextTrackContainerElement> element = adoptRef(new MediaControlTextTrackContainerElement(document));
+    RefPtr<MediaControlTextTrackContainerElement> element = adoptRef(new MediaControlTextTrackContainerElement(mediaControls));
     element->hide();
     return element.release();
 }
@@ -655,20 +696,19 @@
 
 void MediaControlTextTrackContainerElement::updateDisplay()
 {
-    if (!mediaController()->closedCaptionsVisible()) {
+    if (!mediaControllerInterface().closedCaptionsVisible()) {
         removeChildren();
         return;
     }
 
-    HTMLMediaElement* mediaElement = toParentMediaElement(this);
     // 1. If the media element is an audio element, or is another playback
     // mechanism with no rendering area, abort these steps. There is nothing to
     // render.
-    if (!mediaElement || !mediaElement->isVideo())
+    if (!mediaElement().isVideo())
         return;
 
     // 2. Let video be the media element or other playback mechanism.
-    HTMLVideoElement* video = toHTMLVideoElement(mediaElement);
+    HTMLVideoElement& video = toHTMLVideoElement(mediaElement());
 
     // 3. Let output be an empty list of absolutely positioned CSS block boxes.
     Vector<RefPtr<HTMLDivElement> > output;
@@ -692,7 +732,7 @@
     // 7. Let cues be an empty list of text track cues.
     // 8. For each track track in tracks, append to cues all the cues from
     // track's list of cues that have their text track cue active flag set.
-    CueList activeCues = video->currentlyActiveCues();
+    CueList activeCues = video.currentlyActiveCues();
 
     // 9. If reset is false, then, for each text track cue cue in cues: if cue's
     // text track cue display state has a set of CSS boxes, then add those boxes
@@ -716,7 +756,7 @@
     }
 
     // 11. Return output.
-    if (hasChildNodes())
+    if (hasChildren())
         show();
     else
         hide();
@@ -724,18 +764,14 @@
 
 void MediaControlTextTrackContainerElement::updateSizes()
 {
-    HTMLMediaElement* mediaElement = toParentMediaElement(this);
-    if (!mediaElement)
-        return;
-
     if (!document().isActive())
         return;
 
     IntRect videoBox;
 
-    if (!mediaElement->renderer() || !mediaElement->renderer()->isVideo())
+    if (!mediaElement().renderer() || !mediaElement().renderer()->isVideo())
         return;
-    videoBox = toRenderVideo(mediaElement->renderer())->videoBox();
+    videoBox = toRenderVideo(mediaElement().renderer())->videoBox();
 
     if (m_videoDisplaySize == videoBox)
         return;
diff --git a/Source/core/html/shadow/MediaControlElements.h b/Source/core/html/shadow/MediaControlElements.h
index 85d2bac..4b1a3fd 100644
--- a/Source/core/html/shadow/MediaControlElements.h
+++ b/Source/core/html/shadow/MediaControlElements.h
@@ -38,7 +38,7 @@
 
 class MediaControlPanelElement FINAL : public MediaControlDivElement {
 public:
-    static PassRefPtr<MediaControlPanelElement> create(Document&);
+    static PassRefPtr<MediaControlPanelElement> create(MediaControls&);
 
     void setCanBeDragged(bool);
     void setIsDisplayed(bool);
@@ -51,7 +51,7 @@
     virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
 
 private:
-    explicit MediaControlPanelElement(Document&);
+    explicit MediaControlPanelElement(MediaControls&);
 
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
     virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -80,10 +80,10 @@
 
 class MediaControlPanelEnclosureElement FINAL : public MediaControlDivElement {
 public:
-    static PassRefPtr<MediaControlPanelEnclosureElement> create(Document&);
+    static PassRefPtr<MediaControlPanelEnclosureElement> create(MediaControls&);
 
 private:
-    explicit MediaControlPanelEnclosureElement(Document&);
+    explicit MediaControlPanelEnclosureElement(MediaControls&);
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
 };
 
@@ -91,41 +91,40 @@
 
 class MediaControlOverlayEnclosureElement FINAL : public MediaControlDivElement {
 public:
-    static PassRefPtr<MediaControlOverlayEnclosureElement> create(Document&);
+    static PassRefPtr<MediaControlOverlayEnclosureElement> create(MediaControls&);
 
 private:
-    explicit MediaControlOverlayEnclosureElement(Document&);
+    explicit MediaControlOverlayEnclosureElement(MediaControls&);
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
 };
 
 // ----------------------------
 
-class MediaControlPanelMuteButtonElement FINAL : public MediaControlMuteButtonElement {
+class MediaControlMuteButtonElement FINAL : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlPanelMuteButtonElement> create(Document&, MediaControls*);
+    static PassRefPtr<MediaControlMuteButtonElement> create(MediaControls&);
 
-    virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
+    virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
+    virtual void updateDisplayType() OVERRIDE;
 
 private:
-    explicit MediaControlPanelMuteButtonElement(Document&, MediaControls*);
+    explicit MediaControlMuteButtonElement(MediaControls&);
 
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
     virtual void defaultEventHandler(Event*) OVERRIDE;
-
-    MediaControls* m_controls;
 };
 
 // ----------------------------
 
 class MediaControlPlayButtonElement FINAL : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlPlayButtonElement> create(Document&);
+    static PassRefPtr<MediaControlPlayButtonElement> create(MediaControls&);
 
     virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
     virtual void updateDisplayType() OVERRIDE;
 
 private:
-    explicit MediaControlPlayButtonElement(Document&);
+    explicit MediaControlPlayButtonElement(MediaControls&);
 
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
     virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -135,12 +134,12 @@
 
 class MediaControlOverlayPlayButtonElement FINAL : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlOverlayPlayButtonElement> create(Document&);
+    static PassRefPtr<MediaControlOverlayPlayButtonElement> create(MediaControls&);
 
     virtual void updateDisplayType() OVERRIDE;
 
 private:
-    explicit MediaControlOverlayPlayButtonElement(Document&);
+    explicit MediaControlOverlayPlayButtonElement(MediaControls&);
 
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
     virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -150,14 +149,14 @@
 
 class MediaControlToggleClosedCaptionsButtonElement FINAL : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(Document&, MediaControls*);
+    static PassRefPtr<MediaControlToggleClosedCaptionsButtonElement> create(MediaControls&);
 
     virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
 
     virtual void updateDisplayType() OVERRIDE;
 
 private:
-    explicit MediaControlToggleClosedCaptionsButtonElement(Document&, MediaControls*);
+    explicit MediaControlToggleClosedCaptionsButtonElement(MediaControls&);
 
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
     virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -167,7 +166,7 @@
 
 class MediaControlTimelineElement FINAL : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlTimelineElement> create(Document&, MediaControls*);
+    static PassRefPtr<MediaControlTimelineElement> create(MediaControls&);
 
     virtual bool willRespondToMouseClickEvents() OVERRIDE;
 
@@ -175,26 +174,24 @@
     void setDuration(double);
 
 private:
-    explicit MediaControlTimelineElement(Document&, MediaControls*);
+    explicit MediaControlTimelineElement(MediaControls&);
 
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
     virtual void defaultEventHandler(Event*) OVERRIDE;
-
-    MediaControls* m_controls;
 };
 
 // ----------------------------
 
 class MediaControlFullscreenButtonElement FINAL : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlFullscreenButtonElement> create(Document&);
+    static PassRefPtr<MediaControlFullscreenButtonElement> create(MediaControls&);
 
     virtual bool willRespondToMouseClickEvents() OVERRIDE { return true; }
 
     void setIsFullscreen(bool);
 
 private:
-    explicit MediaControlFullscreenButtonElement(Document&);
+    explicit MediaControlFullscreenButtonElement(MediaControls&);
 
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
     virtual void defaultEventHandler(Event*) OVERRIDE;
@@ -202,23 +199,29 @@
 
 // ----------------------------
 
-class MediaControlPanelVolumeSliderElement FINAL : public MediaControlVolumeSliderElement {
+class MediaControlVolumeSliderElement FINAL : public MediaControlInputElement {
 public:
-    static PassRefPtr<MediaControlPanelVolumeSliderElement> create(Document&);
+    static PassRefPtr<MediaControlVolumeSliderElement> create(MediaControls&);
+
+    virtual bool willRespondToMouseMoveEvents() OVERRIDE;
+    virtual bool willRespondToMouseClickEvents() OVERRIDE;
+    void setVolume(double);
 
 private:
-    explicit MediaControlPanelVolumeSliderElement(Document&);
+    explicit MediaControlVolumeSliderElement(MediaControls&);
+
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
+    virtual void defaultEventHandler(Event*) OVERRIDE;
 };
 
 // ----------------------------
 
 class MediaControlTimeRemainingDisplayElement FINAL : public MediaControlTimeDisplayElement {
 public:
-    static PassRefPtr<MediaControlTimeRemainingDisplayElement> create(Document&);
+    static PassRefPtr<MediaControlTimeRemainingDisplayElement> create(MediaControls&);
 
 private:
-    explicit MediaControlTimeRemainingDisplayElement(Document&);
+    explicit MediaControlTimeRemainingDisplayElement(MediaControls&);
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
 };
 
@@ -226,10 +229,10 @@
 
 class MediaControlCurrentTimeDisplayElement FINAL : public MediaControlTimeDisplayElement {
 public:
-    static PassRefPtr<MediaControlCurrentTimeDisplayElement> create(Document&);
+    static PassRefPtr<MediaControlCurrentTimeDisplayElement> create(MediaControls&);
 
 private:
-    explicit MediaControlCurrentTimeDisplayElement(Document&);
+    explicit MediaControlCurrentTimeDisplayElement(MediaControls&);
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
 };
 
@@ -237,14 +240,14 @@
 
 class MediaControlTextTrackContainerElement FINAL : public MediaControlDivElement {
 public:
-    static PassRefPtr<MediaControlTextTrackContainerElement> create(Document&);
+    static PassRefPtr<MediaControlTextTrackContainerElement> create(MediaControls&);
 
     void updateDisplay();
     void updateSizes();
     static const AtomicString& textTrackContainerElementShadowPseudoId();
 
 private:
-    explicit MediaControlTextTrackContainerElement(Document&);
+    explicit MediaControlTextTrackContainerElement(MediaControls&);
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
 
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
diff --git a/Source/core/html/shadow/MediaControls.cpp b/Source/core/html/shadow/MediaControls.cpp
index bb3c8c2..2af3e93 100644
--- a/Source/core/html/shadow/MediaControls.cpp
+++ b/Source/core/html/shadow/MediaControls.cpp
@@ -28,23 +28,34 @@
 #include "core/html/shadow/MediaControls.h"
 
 #include "bindings/v8/ExceptionStatePlaceholder.h"
-#if OS(ANDROID)
-#include "core/html/shadow/MediaControlsAndroid.h"
-#endif
+#include "core/events/MouseEvent.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/MediaController.h"
+#include "core/rendering/RenderTheme.h"
 
 namespace WebCore {
 
+#if OS(ANDROID)
+static const bool alwaysHideFullscreenControls = true;
+static const bool needOverlayPlayButton = true;
+#else
+static const bool alwaysHideFullscreenControls = false;
+static const bool needOverlayPlayButton = false;
+#endif
+
 static const double timeWithoutMouseMovementBeforeHidingFullscreenControls = 3;
 
-MediaControls::MediaControls(Document& document)
-    : HTMLDivElement(document)
-    , m_mediaController(0)
+MediaControls::MediaControls(HTMLMediaElement& mediaElement)
+    : HTMLDivElement(mediaElement.document())
+    , m_mediaElement(mediaElement)
     , m_panel(0)
     , m_textDisplayContainer(0)
+    , m_overlayPlayButton(0)
+    , m_overlayEnclosure(0)
     , m_playButton(0)
     , m_currentTimeDisplay(0)
     , m_timeline(0)
-    , m_panelMuteButton(0)
+    , m_muteButton(0)
     , m_volumeSlider(0)
     , m_toggleClosedCaptionsButton(0)
     , m_fullScreenButton(0)
@@ -56,78 +67,83 @@
 {
 }
 
-PassRefPtr<MediaControls> MediaControls::create(Document& document)
+PassRefPtr<MediaControls> MediaControls::create(HTMLMediaElement& mediaElement)
 {
-    if (!document.page())
-        return 0;
+    RefPtr<MediaControls> controls = adoptRef(new MediaControls(mediaElement));
 
-    RefPtr<MediaControls> controls;
-#if OS(ANDROID)
-    controls = adoptRef(new MediaControlsAndroid(document));
-#else
-    controls = adoptRef(new MediaControls(document));
-#endif
-
-    if (controls->initializeControls(document))
+    if (controls->initializeControls())
         return controls.release();
 
-    return 0;
+    return nullptr;
 }
 
-bool MediaControls::initializeControls(Document& document)
+bool MediaControls::initializeControls()
 {
-    // Create an enclosing element for the panel so we can visually offset the controls correctly.
-    RefPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(document);
-
-    RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(document);
-
     TrackExceptionState exceptionState;
 
-    RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(document);
+    if (needOverlayPlayButton) {
+        RefPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(*this);
+        RefPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(*this);
+        m_overlayPlayButton = overlayPlayButton.get();
+        overlayEnclosure->appendChild(overlayPlayButton.release(), exceptionState);
+        if (exceptionState.hadException())
+            return false;
+
+        m_overlayEnclosure = overlayEnclosure.get();
+        appendChild(overlayEnclosure.release(), exceptionState);
+        if (exceptionState.hadException())
+            return false;
+    }
+
+    // Create an enclosing element for the panel so we can visually offset the controls correctly.
+    RefPtr<MediaControlPanelEnclosureElement> enclosure = MediaControlPanelEnclosureElement::create(*this);
+
+    RefPtr<MediaControlPanelElement> panel = MediaControlPanelElement::create(*this);
+
+    RefPtr<MediaControlPlayButtonElement> playButton = MediaControlPlayButtonElement::create(*this);
     m_playButton = playButton.get();
     panel->appendChild(playButton.release(), exceptionState);
     if (exceptionState.hadException())
         return false;
 
-    RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(document, this);
+    RefPtr<MediaControlTimelineElement> timeline = MediaControlTimelineElement::create(*this);
     m_timeline = timeline.get();
     panel->appendChild(timeline.release(), exceptionState);
     if (exceptionState.hadException())
         return false;
 
-    RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(document);
+    RefPtr<MediaControlCurrentTimeDisplayElement> currentTimeDisplay = MediaControlCurrentTimeDisplayElement::create(*this);
     m_currentTimeDisplay = currentTimeDisplay.get();
     m_currentTimeDisplay->hide();
     panel->appendChild(currentTimeDisplay.release(), exceptionState);
     if (exceptionState.hadException())
         return false;
 
-    RefPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(document);
+    RefPtr<MediaControlTimeRemainingDisplayElement> durationDisplay = MediaControlTimeRemainingDisplayElement::create(*this);
     m_durationDisplay = durationDisplay.get();
     panel->appendChild(durationDisplay.release(), exceptionState);
     if (exceptionState.hadException())
         return false;
 
-    RefPtr<MediaControlPanelMuteButtonElement> panelMuteButton = MediaControlPanelMuteButtonElement::create(document, this);
-    m_panelMuteButton = panelMuteButton.get();
-    panel->appendChild(panelMuteButton.release(), exceptionState);
+    RefPtr<MediaControlMuteButtonElement> muteButton = MediaControlMuteButtonElement::create(*this);
+    m_muteButton = muteButton.get();
+    panel->appendChild(muteButton.release(), exceptionState);
     if (exceptionState.hadException())
         return false;
 
-    RefPtr<MediaControlPanelVolumeSliderElement> slider = MediaControlPanelVolumeSliderElement::create(document);
+    RefPtr<MediaControlVolumeSliderElement> slider = MediaControlVolumeSliderElement::create(*this);
     m_volumeSlider = slider.get();
-    m_volumeSlider->setClearMutedOnUserInteraction(true);
     panel->appendChild(slider.release(), exceptionState);
     if (exceptionState.hadException())
         return false;
 
-    RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(document, this);
+    RefPtr<MediaControlToggleClosedCaptionsButtonElement> toggleClosedCaptionsButton = MediaControlToggleClosedCaptionsButtonElement::create(*this);
     m_toggleClosedCaptionsButton = toggleClosedCaptionsButton.get();
     panel->appendChild(toggleClosedCaptionsButton.release(), exceptionState);
     if (exceptionState.hadException())
         return false;
 
-    RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(document);
+    RefPtr<MediaControlFullscreenButtonElement> fullscreenButton = MediaControlFullscreenButtonElement::create(*this);
     m_fullScreenButton = fullscreenButton.get();
     panel->appendChild(fullscreenButton.release(), exceptionState);
     if (exceptionState.hadException())
@@ -146,43 +162,16 @@
     return true;
 }
 
-void MediaControls::setMediaController(MediaControllerInterface* controller)
+MediaControllerInterface& MediaControls::mediaControllerInterface() const
 {
-    if (m_mediaController == controller)
-        return;
-    m_mediaController = controller;
-
-    if (m_panel)
-        m_panel->setMediaController(controller);
-    if (m_textDisplayContainer)
-        m_textDisplayContainer->setMediaController(controller);
-    if (m_playButton)
-        m_playButton->setMediaController(controller);
-    if (m_currentTimeDisplay)
-        m_currentTimeDisplay->setMediaController(controller);
-    if (m_timeline)
-        m_timeline->setMediaController(controller);
-    if (m_panelMuteButton)
-        m_panelMuteButton->setMediaController(controller);
-    if (m_volumeSlider)
-        m_volumeSlider->setMediaController(controller);
-    if (m_toggleClosedCaptionsButton)
-        m_toggleClosedCaptionsButton->setMediaController(controller);
-    if (m_fullScreenButton)
-        m_fullScreenButton->setMediaController(controller);
-    if (m_durationDisplay)
-        m_durationDisplay->setMediaController(controller);
-    if (m_enclosure)
-        m_enclosure->setMediaController(controller);
+    if (m_mediaElement.controller())
+        return *m_mediaElement.controller();
+    return m_mediaElement;
 }
 
 void MediaControls::reset()
 {
-    Page* page = document().page();
-    if (!page)
-        return;
-
-    double duration = m_mediaController->duration();
+    double duration = mediaControllerInterface().duration();
     m_durationDisplay->setInnerText(RenderTheme::theme().formatMediaControlsTime(duration), ASSERT_NO_EXCEPTION);
     m_durationDisplay->setCurrentValue(duration);
 
@@ -190,28 +179,22 @@
 
     updateCurrentTimeDisplay();
 
-    m_timeline->setDuration(m_mediaController->duration());
-    m_timeline->setPosition(m_mediaController->currentTime());
+    m_timeline->setDuration(mediaControllerInterface().duration());
+    m_timeline->setPosition(mediaControllerInterface().currentTime());
 
-    m_panelMuteButton->show();
-
-    if (m_volumeSlider) {
-        if (!m_mediaController->hasAudio())
-            m_volumeSlider->hide();
-        else {
-            m_volumeSlider->show();
-            m_volumeSlider->setVolume(m_mediaController->volume());
-        }
+    if (!mediaControllerInterface().hasAudio()) {
+        m_volumeSlider->hide();
+    } else {
+        m_volumeSlider->show();
+        m_volumeSlider->setVolume(mediaControllerInterface().volume());
     }
 
     refreshClosedCaptionsButtonVisibility();
 
-    if (m_fullScreenButton) {
-        if (m_mediaController->hasVideo())
-            m_fullScreenButton->show();
-        else
-            m_fullScreenButton->hide();
-    }
+    if (mediaControllerInterface().hasVideo())
+        m_fullScreenButton->show();
+    else
+        m_fullScreenButton->hide();
 
     makeOpaque();
 }
@@ -239,17 +222,9 @@
     m_panel->makeTransparent();
 }
 
-bool MediaControls::shouldHideControls()
+bool MediaControls::shouldHideFullscreenControls()
 {
-    return !m_panel->hovered();
-}
-
-void MediaControls::bufferingProgressed()
-{
-    // We only need to update buffering progress when paused, during normal
-    // playback playbackProgressed() will take care of it.
-    if (m_mediaController->paused())
-        m_timeline->setPosition(m_mediaController->currentTime());
+    return alwaysHideFullscreenControls || !m_panel->hovered();
 }
 
 void MediaControls::playbackStarted()
@@ -257,8 +232,10 @@
     m_currentTimeDisplay->show();
     m_durationDisplay->hide();
 
+    if (m_overlayPlayButton)
+        m_overlayPlayButton->updateDisplayType();
     m_playButton->updateDisplayType();
-    m_timeline->setPosition(m_mediaController->currentTime());
+    m_timeline->setPosition(mediaControllerInterface().currentTime());
     updateCurrentTimeDisplay();
 
     if (m_isFullscreen)
@@ -267,17 +244,19 @@
 
 void MediaControls::playbackProgressed()
 {
-    m_timeline->setPosition(m_mediaController->currentTime());
+    m_timeline->setPosition(mediaControllerInterface().currentTime());
     updateCurrentTimeDisplay();
 
-    if (!m_isMouseOverControls && m_mediaController->hasVideo())
+    if (!m_isMouseOverControls && mediaControllerInterface().hasVideo())
         makeTransparent();
 }
 
 void MediaControls::playbackStopped()
 {
+    if (m_overlayPlayButton)
+        m_overlayPlayButton->updateDisplayType();
     m_playButton->updateDisplayType();
-    m_timeline->setPosition(m_mediaController->currentTime());
+    m_timeline->setPosition(mediaControllerInterface().currentTime());
     updateCurrentTimeDisplay();
     makeOpaque();
 
@@ -286,12 +265,8 @@
 
 void MediaControls::updateCurrentTimeDisplay()
 {
-    double now = m_mediaController->currentTime();
-    double duration = m_mediaController->duration();
-
-    Page* page = document().page();
-    if (!page)
-        return;
+    double now = mediaControllerInterface().currentTime();
+    double duration = mediaControllerInterface().duration();
 
     // After seek, hide duration display and show current time.
     if (now > 0) {
@@ -304,44 +279,31 @@
     m_currentTimeDisplay->setCurrentValue(now);
 }
 
-void MediaControls::showVolumeSlider()
-{
-    if (!m_mediaController->hasAudio())
-        return;
-
-    m_volumeSlider->show();
-}
-
 void MediaControls::changedMute()
 {
-    m_panelMuteButton->changedMute();
+    m_muteButton->updateDisplayType();
 
-    if (m_mediaController->muted())
+    if (mediaControllerInterface().muted())
         m_volumeSlider->setVolume(0);
     else
-        m_volumeSlider->setVolume(m_mediaController->volume());
+        m_volumeSlider->setVolume(mediaControllerInterface().volume());
 }
 
 void MediaControls::changedVolume()
 {
-    if (m_volumeSlider)
-        m_volumeSlider->setVolume(m_mediaController->volume());
-    if (m_panelMuteButton && m_panelMuteButton->renderer())
-        m_panelMuteButton->renderer()->repaint();
+    m_volumeSlider->setVolume(mediaControllerInterface().volume());
+    if (m_muteButton->renderer())
+        m_muteButton->renderer()->repaint();
 }
 
 void MediaControls::changedClosedCaptionsVisibility()
 {
-    if (m_toggleClosedCaptionsButton)
-        m_toggleClosedCaptionsButton->updateDisplayType();
+    m_toggleClosedCaptionsButton->updateDisplayType();
 }
 
 void MediaControls::refreshClosedCaptionsButtonVisibility()
 {
-    if (!m_toggleClosedCaptionsButton)
-        return;
-
-    if (m_mediaController->hasClosedCaptions())
+    if (mediaControllerInterface().hasClosedCaptions())
         m_toggleClosedCaptionsButton->show();
     else
         m_toggleClosedCaptionsButton->hide();
@@ -373,9 +335,9 @@
     if (event->type() == EventTypeNames::mouseover) {
         if (!containsRelatedTarget(event)) {
             m_isMouseOverControls = true;
-            if (!m_mediaController->canPlay()) {
+            if (!mediaControllerInterface().canPlay()) {
                 makeOpaque();
-                if (shouldHideControls())
+                if (shouldHideFullscreenControls())
                     startHideFullscreenControlsTimer();
             }
         }
@@ -395,7 +357,7 @@
             // When we get a mouse move in fullscreen mode, show the media controls, and start a timer
             // that will hide the media controls after a 3 seconds without a mouse move.
             makeOpaque();
-            if (shouldHideControls())
+            if (shouldHideFullscreenControls())
                 startHideFullscreenControlsTimer();
         }
         return;
@@ -404,13 +366,13 @@
 
 void MediaControls::hideFullscreenControlsTimerFired(Timer<MediaControls>*)
 {
-    if (m_mediaController->paused())
+    if (mediaControllerInterface().paused())
         return;
 
     if (!m_isFullscreen)
         return;
 
-    if (!shouldHideControls())
+    if (!shouldHideFullscreenControls())
         return;
 
     makeTransparent();
@@ -421,11 +383,7 @@
     if (!m_isFullscreen)
         return;
 
-    Page* page = document().page();
-    if (!page)
-        return;
-
-    m_hideFullscreenControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingFullscreenControls);
+    m_hideFullscreenControlsTimer.startOneShot(timeWithoutMouseMovementBeforeHidingFullscreenControls, FROM_HERE);
 }
 
 void MediaControls::stopHideFullscreenControlsTimer()
@@ -454,13 +412,14 @@
     if (m_textDisplayContainer)
         return;
 
-    RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(document());
+    RefPtr<MediaControlTextTrackContainerElement> textDisplayContainer = MediaControlTextTrackContainerElement::create(*this);
     m_textDisplayContainer = textDisplayContainer.get();
 
-    if (m_mediaController)
-        m_textDisplayContainer->setMediaController(m_mediaController);
-
-    insertTextTrackContainer(textDisplayContainer.release());
+    // Insert it before (behind) all other control elements.
+    if (m_overlayEnclosure && m_overlayPlayButton)
+        m_overlayEnclosure->insertBefore(textDisplayContainer.release(), m_overlayPlayButton);
+    else
+        insertBefore(textDisplayContainer.release(), m_enclosure);
 }
 
 void MediaControls::showTextTrackDisplay()
@@ -485,10 +444,4 @@
     m_textDisplayContainer->updateDisplay();
 }
 
-void MediaControls::insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement> textTrackContainer)
-{
-    // Insert it before the first controller element so it always displays behind the controls.
-    insertBefore(textTrackContainer, m_enclosure);
-}
-
 }
diff --git a/Source/core/html/shadow/MediaControls.h b/Source/core/html/shadow/MediaControls.h
index c5e86af..669b295 100644
--- a/Source/core/html/shadow/MediaControls.h
+++ b/Source/core/html/shadow/MediaControls.h
@@ -27,40 +27,31 @@
 #ifndef MediaControls_h
 #define MediaControls_h
 
-#include "core/events/MouseEvent.h"
 #include "core/html/HTMLDivElement.h"
 #include "core/html/shadow/MediaControlElements.h"
-#include "core/rendering/RenderTheme.h"
 
 namespace WebCore {
 
 class Document;
 class Event;
-class MediaPlayer;
 
-class RenderBox;
-class RenderMedia;
-
-class MediaControls : public HTMLDivElement {
+class MediaControls FINAL : public HTMLDivElement {
 public:
-    virtual ~MediaControls() {}
+    static PassRefPtr<MediaControls> create(HTMLMediaElement&);
 
-    static PassRefPtr<MediaControls> create(Document&);
-
-    virtual void setMediaController(MediaControllerInterface*);
+    HTMLMediaElement& mediaElement() const { return m_mediaElement; }
+    MediaControllerInterface& mediaControllerInterface() const;
 
     void reset();
 
     void show();
     void hide();
 
-    void bufferingProgressed();
-    virtual void playbackStarted();
+    void playbackStarted();
     void playbackProgressed();
-    virtual void playbackStopped();
+    void playbackStopped();
 
     void updateCurrentTimeDisplay();
-    void showVolumeSlider();
 
     void changedMute();
     void changedVolume();
@@ -74,19 +65,15 @@
 
     void updateTextTrackDisplay();
 
-protected:
-    explicit MediaControls(Document&);
-
-    virtual bool initializeControls(Document&);
-
-    virtual bool shouldHideControls();
-
-    virtual void insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement>);
-
 private:
+    explicit MediaControls(HTMLMediaElement&);
+
+    bool initializeControls();
+
     void makeOpaque();
     void makeTransparent();
 
+    bool shouldHideFullscreenControls();
     void hideFullscreenControlsTimerFired(Timer<MediaControls>*);
     void startHideFullscreenControlsTimer();
     void stopHideFullscreenControlsTimer();
@@ -96,7 +83,7 @@
     void hideTextTrackDisplay();
 
     // Node
-    virtual bool isMediaControls() const OVERRIDE FINAL { return true; }
+    virtual bool isMediaControls() const OVERRIDE { return true; }
     virtual bool willRespondToMouseMoveEvents() OVERRIDE { return true; }
     virtual void defaultEventHandler(Event*) OVERRIDE;
     bool containsRelatedTarget(Event*);
@@ -104,7 +91,7 @@
     // Element
     virtual const AtomicString& shadowPseudoId() const OVERRIDE;
 
-    MediaControllerInterface* m_mediaController;
+    HTMLMediaElement& m_mediaElement;
 
     // Container for the media control elements.
     MediaControlPanelElement* m_panel;
@@ -113,11 +100,13 @@
     MediaControlTextTrackContainerElement* m_textDisplayContainer;
 
     // Media control elements.
+    MediaControlOverlayPlayButtonElement* m_overlayPlayButton;
+    MediaControlOverlayEnclosureElement* m_overlayEnclosure;
     MediaControlPlayButtonElement* m_playButton;
     MediaControlCurrentTimeDisplayElement* m_currentTimeDisplay;
     MediaControlTimelineElement* m_timeline;
-    MediaControlPanelMuteButtonElement* m_panelMuteButton;
-    MediaControlPanelVolumeSliderElement* m_volumeSlider;
+    MediaControlMuteButtonElement* m_muteButton;
+    MediaControlVolumeSliderElement* m_volumeSlider;
     MediaControlToggleClosedCaptionsButtonElement* m_toggleClosedCaptionsButton;
     MediaControlFullscreenButtonElement* m_fullScreenButton;
     MediaControlTimeRemainingDisplayElement* m_durationDisplay;
@@ -128,7 +117,7 @@
     bool m_isMouseOverControls;
 };
 
-DEFINE_NODE_TYPE_CASTS(MediaControls, isMediaControls());
+DEFINE_ELEMENT_TYPE_CASTS(MediaControls, isMediaControls());
 
 }
 
diff --git a/Source/core/html/shadow/MediaControlsAndroid.cpp b/Source/core/html/shadow/MediaControlsAndroid.cpp
deleted file mode 100644
index 6943ae5..0000000
--- a/Source/core/html/shadow/MediaControlsAndroid.cpp
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/html/shadow/MediaControlsAndroid.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-
-namespace WebCore {
-
-MediaControlsAndroid::MediaControlsAndroid(Document& document)
-    : MediaControls(document)
-    , m_overlayPlayButton(0)
-    , m_overlayEnclosure(0)
-{
-}
-
-bool MediaControlsAndroid::initializeControls(Document& document)
-{
-    TrackExceptionState exceptionState;
-
-    RefPtr<MediaControlOverlayEnclosureElement> overlayEnclosure = MediaControlOverlayEnclosureElement::create(document);
-    RefPtr<MediaControlOverlayPlayButtonElement> overlayPlayButton = MediaControlOverlayPlayButtonElement::create(document);
-    m_overlayPlayButton = overlayPlayButton.get();
-    overlayEnclosure->appendChild(overlayPlayButton.release(), exceptionState);
-    if (exceptionState.hadException())
-        return false;
-
-    m_overlayEnclosure = overlayEnclosure.get();
-    appendChild(overlayEnclosure.release(), exceptionState);
-    if (exceptionState.hadException())
-        return false;
-
-    return MediaControls::initializeControls(document);
-}
-
-void MediaControlsAndroid::setMediaController(MediaControllerInterface* controller)
-{
-    if (m_overlayPlayButton)
-        m_overlayPlayButton->setMediaController(controller);
-    if (m_overlayEnclosure)
-        m_overlayEnclosure->setMediaController(controller);
-    MediaControls::setMediaController(controller);
-}
-
-void MediaControlsAndroid::playbackStarted()
-{
-    m_overlayPlayButton->updateDisplayType();
-    MediaControls::playbackStarted();
-}
-
-void MediaControlsAndroid::playbackStopped()
-{
-    m_overlayPlayButton->updateDisplayType();
-    MediaControls::playbackStopped();
-}
-
-void MediaControlsAndroid::insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement> textTrackContainer)
-{
-    // Insert it before the overlay play button so it always displays behind it.
-    m_overlayEnclosure->insertBefore(textTrackContainer, m_overlayPlayButton);
-}
-}
diff --git a/Source/core/html/shadow/MediaControlsAndroid.h b/Source/core/html/shadow/MediaControlsAndroid.h
deleted file mode 100644
index 34240bc..0000000
--- a/Source/core/html/shadow/MediaControlsAndroid.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef MediaControlsAndroid_h
-#define MediaControlsAndroid_h
-
-#include "core/html/shadow/MediaControls.h"
-
-namespace WebCore {
-
-class MediaControlsAndroid FINAL : public MediaControls {
-public:
-    explicit MediaControlsAndroid(Document&);
-
-    virtual void setMediaController(MediaControllerInterface*) OVERRIDE;
-    virtual void playbackStarted() OVERRIDE;
-    virtual void playbackStopped() OVERRIDE;
-    virtual bool shouldHideControls() OVERRIDE { return true; }
-
-    virtual void insertTextTrackContainer(PassRefPtr<MediaControlTextTrackContainerElement>) OVERRIDE;
-
-private:
-    virtual bool initializeControls(Document&) OVERRIDE;
-
-    MediaControlOverlayPlayButtonElement* m_overlayPlayButton;
-    MediaControlOverlayEnclosureElement* m_overlayEnclosure;
-};
-
-}
-
-#endif
diff --git a/Source/core/html/shadow/SliderThumbElement.cpp b/Source/core/html/shadow/SliderThumbElement.cpp
index 94dae01..e34c2c0 100644
--- a/Source/core/html/shadow/SliderThumbElement.cpp
+++ b/Source/core/html/shadow/SliderThumbElement.cpp
@@ -36,12 +36,12 @@
 #include "core/events/Event.h"
 #include "core/events/MouseEvent.h"
 #include "core/dom/shadow/ShadowRoot.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/forms/StepRange.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderFlexibleBox.h"
 #include "core/rendering/RenderSlider.h"
 #include "core/rendering/RenderTheme.h"
@@ -306,7 +306,7 @@
 
 void SliderThumbElement::startDragging()
 {
-    if (Frame* frame = document().frame()) {
+    if (LocalFrame* frame = document().frame()) {
         frame->eventHandler().setCapturingMouseEventsNode(this);
         m_inDragMode = true;
     }
@@ -317,8 +317,8 @@
     if (!m_inDragMode)
         return;
 
-    if (Frame* frame = document().frame())
-        frame->eventHandler().setCapturingMouseEventsNode(0);
+    if (LocalFrame* frame = document().frame())
+        frame->eventHandler().setCapturingMouseEventsNode(nullptr);
     m_inDragMode = false;
     if (renderer())
         renderer()->setNeedsLayout();
@@ -384,8 +384,8 @@
 void SliderThumbElement::detach(const AttachContext& context)
 {
     if (m_inDragMode) {
-        if (Frame* frame = document().frame())
-            frame->eventHandler().setCapturingMouseEventsNode(0);
+        if (LocalFrame* frame = document().frame())
+            frame->eventHandler().setCapturingMouseEventsNode(nullptr);
     }
     HTMLDivElement::detach(context);
 }
@@ -412,7 +412,7 @@
 const AtomicString& SliderThumbElement::shadowPseudoId() const
 {
     HTMLInputElement* input = hostInput();
-    if (!input)
+    if (!input || !input->renderer())
         return sliderThumbShadowPartId();
 
     RenderStyle* sliderStyle = input->renderer()->style();
@@ -451,10 +451,10 @@
     DEFINE_STATIC_LOCAL(const AtomicString, mediaSliderContainer, ("-webkit-media-slider-container", AtomicString::ConstructFromLiteral));
     DEFINE_STATIC_LOCAL(const AtomicString, sliderContainer, ("-webkit-slider-container", AtomicString::ConstructFromLiteral));
 
-    if (!shadowHost()->hasTagName(inputTag))
+    if (!shadowHost() || !shadowHost()->renderer())
         return sliderContainer;
 
-    RenderStyle* sliderStyle = toHTMLInputElement(shadowHost())->renderer()->style();
+    RenderStyle* sliderStyle = shadowHost()->renderer()->style();
     switch (sliderStyle->appearance()) {
     case MediaSliderPart:
     case MediaSliderThumbPart:
diff --git a/Source/core/html/shadow/SliderThumbElement.h b/Source/core/html/shadow/SliderThumbElement.h
index 39bbe01..255d58a 100644
--- a/Source/core/html/shadow/SliderThumbElement.h
+++ b/Source/core/html/shadow/SliderThumbElement.h
@@ -79,7 +79,7 @@
 }
 
 // FIXME: There are no ways to check if a node is a SliderThumbElement.
-DEFINE_NODE_TYPE_CASTS(SliderThumbElement, isHTMLElement());
+DEFINE_ELEMENT_TYPE_CASTS(SliderThumbElement, isHTMLElement());
 
 // --------------------------------
 
@@ -90,7 +90,6 @@
 
 private:
     virtual bool isSliderThumb() const OVERRIDE;
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
 };
 
 // --------------------------------
diff --git a/Source/core/html/shadow/SpinButtonElement.cpp b/Source/core/html/shadow/SpinButtonElement.cpp
index e9cefa5..a9ec4fa 100644
--- a/Source/core/html/shadow/SpinButtonElement.cpp
+++ b/Source/core/html/shadow/SpinButtonElement.cpp
@@ -31,10 +31,10 @@
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/events/WheelEvent.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/page/Chrome.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/rendering/RenderBox.h"
 #include "platform/scroll/ScrollbarTheme.h"
@@ -116,7 +116,7 @@
     } else if (event->type() == EventTypeNames::mousemove) {
         if (box->pixelSnappedBorderBoxRect().contains(local)) {
             if (!m_capturing) {
-                if (Frame* frame = document().frame()) {
+                if (LocalFrame* frame = document().frame()) {
                     frame->eventHandler().setCapturingMouseEventsNode(this);
                     m_capturing = true;
                     if (Page* page = document().page())
@@ -192,8 +192,8 @@
 {
     stopRepeatingTimer();
     if (m_capturing) {
-        if (Frame* frame = document().frame()) {
-            frame->eventHandler().setCapturingMouseEventsNode(0);
+        if (LocalFrame* frame = document().frame()) {
+            frame->eventHandler().setCapturingMouseEventsNode(nullptr);
             m_capturing = false;
             if (Page* page = document().page())
                 page->chrome().unregisterPopupOpeningObserver(this);
@@ -215,7 +215,7 @@
 {
     m_pressStartingState = m_upDownState;
     ScrollbarTheme* theme = ScrollbarTheme::theme();
-    m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay());
+    m_repeatingTimer.start(theme->initialAutoscrollTimerDelay(), theme->autoscrollTimerDelay(), FROM_HERE);
 }
 
 void SpinButtonElement::stopRepeatingTimer()
diff --git a/Source/core/html/shadow/TextControlInnerElements.cpp b/Source/core/html/shadow/TextControlInnerElements.cpp
index 5570359..b1fa3e6 100644
--- a/Source/core/html/shadow/TextControlInnerElements.cpp
+++ b/Source/core/html/shadow/TextControlInnerElements.cpp
@@ -34,10 +34,10 @@
 #include "core/events/TextEvent.h"
 #include "core/events/TextEventInputType.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/shadow/ShadowElementNames.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/RenderTextControlSingleLine.h"
 #include "core/rendering/RenderView.h"
 #include "core/speech/SpeechInput.h"
@@ -88,9 +88,6 @@
     style->inheritFrom(shadowHost()->renderStyle());
 
     style->setFlexGrow(1);
-    // min-width: 0; is needed for correct shrinking.
-    // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed.
-    style->setMinWidth(Length(0, Fixed));
     style->setDisplay(BLOCK);
     style->setDirection(LTR);
 
@@ -171,7 +168,7 @@
     Element* host = shadowHost();
     if (!host)
         return resultsDecorationId;
-    if (host->hasTagName(inputTag)) {
+    if (isHTMLInputElement(*host)) {
         if (toHTMLInputElement(host)->maxResults() < 0)
             return decorationId;
         return resultsDecorationId;
@@ -217,8 +214,8 @@
 void SearchFieldCancelButtonElement::detach(const AttachContext& context)
 {
     if (m_capturing) {
-        if (Frame* frame = document().frame())
-            frame->eventHandler().setCapturingMouseEventsNode(0);
+        if (LocalFrame* frame = document().frame())
+            frame->eventHandler().setCapturingMouseEventsNode(nullptr);
     }
     HTMLDivElement::detach(context);
 }
@@ -236,7 +233,7 @@
 
     if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
         if (renderer() && renderer()->visibleToHitTesting()) {
-            if (Frame* frame = document().frame()) {
+            if (LocalFrame* frame = document().frame()) {
                 frame->eventHandler().setCapturingMouseEventsNode(this);
                 m_capturing = true;
             }
@@ -247,8 +244,8 @@
     }
     if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
         if (m_capturing) {
-            if (Frame* frame = document().frame()) {
-                frame->eventHandler().setCapturingMouseEventsNode(0);
+            if (LocalFrame* frame = document().frame()) {
+                frame->eventHandler().setCapturingMouseEventsNode(nullptr);
                 m_capturing = false;
             }
             if (hovered()) {
@@ -325,7 +322,7 @@
     // On mouse down, select the text and set focus.
     if (event->type() == EventTypeNames::mousedown && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
         if (renderer() && renderer()->visibleToHitTesting()) {
-            if (Frame* frame = document().frame()) {
+            if (LocalFrame* frame = document().frame()) {
                 frame->eventHandler().setCapturingMouseEventsNode(this);
                 m_capturing = true;
             }
@@ -338,8 +335,8 @@
     // On mouse up, release capture cleanly.
     if (event->type() == EventTypeNames::mouseup && event->isMouseEvent() && toMouseEvent(event)->button() == LeftButton) {
         if (m_capturing && renderer() && renderer()->visibleToHitTesting()) {
-            if (Frame* frame = document().frame()) {
-                frame->eventHandler().setCapturingMouseEventsNode(0);
+            if (LocalFrame* frame = document().frame()) {
+                frame->eventHandler().setCapturingMouseEventsNode(nullptr);
                 m_capturing = false;
             }
         }
@@ -437,8 +434,8 @@
 void InputFieldSpeechButtonElement::detach(const AttachContext& context)
 {
     if (m_capturing) {
-        if (Frame* frame = document().frame())
-            frame->eventHandler().setCapturingMouseEventsNode(0);
+        if (LocalFrame* frame = document().frame())
+            frame->eventHandler().setCapturingMouseEventsNode(nullptr);
     }
 
     if (m_listenerId) {
diff --git a/Source/core/html/shadow/TextControlInnerElements.h b/Source/core/html/shadow/TextControlInnerElements.h
index d18fd8c..48e6894 100644
--- a/Source/core/html/shadow/TextControlInnerElements.h
+++ b/Source/core/html/shadow/TextControlInnerElements.h
@@ -134,7 +134,7 @@
     bool m_capturing;
     SpeechInputState m_state;
     int m_listenerId;
-    SpeechInputResultArray m_results;
+    WillBePersistentSpeechInputResultArray m_results;
 };
 
 DEFINE_TYPE_CASTS(InputFieldSpeechButtonElement, Element, element, element->isInputFieldSpeechButtonElement(), element.isInputFieldSpeechButtonElement());
diff --git a/Source/core/html/track/InbandTextTrack.cpp b/Source/core/html/track/InbandTextTrack.cpp
index 925f84e..1d5cbe3 100644
--- a/Source/core/html/track/InbandTextTrack.cpp
+++ b/Source/core/html/track/InbandTextTrack.cpp
@@ -38,13 +38,13 @@
 
 namespace WebCore {
 
-PassRefPtr<InbandTextTrack> InbandTextTrack::create(Document& document, TextTrackClient* client, WebInbandTextTrack* webTrack)
+PassRefPtr<InbandTextTrack> InbandTextTrack::create(Document& document, WebInbandTextTrack* webTrack)
 {
-    return adoptRef(new InbandTextTrack(document, client, webTrack));
+    return adoptRef(new InbandTextTrack(document, webTrack));
 }
 
-InbandTextTrack::InbandTextTrack(Document& document, TextTrackClient* client, WebInbandTextTrack* webTrack)
-    : TextTrack(document, client, emptyAtom, webTrack->label(), webTrack->language(), webTrack->id(), InBand)
+InbandTextTrack::InbandTextTrack(Document& document, WebInbandTextTrack* webTrack)
+    : TextTrack(document, emptyAtom, webTrack->label(), webTrack->language(), webTrack->id(), InBand)
     , m_webTrack(webTrack)
 {
     m_webTrack->setClient(this);
@@ -84,12 +84,15 @@
     return m_webTrack->textTrackIndex();
 }
 
-void InbandTextTrack::trackRemoved()
+void InbandTextTrack::setTrackList(TextTrackList* trackList)
 {
+    TextTrack::setTrackList(trackList);
+    if (trackList)
+        return;
+
     ASSERT(m_webTrack);
     m_webTrack->setClient(0);
     m_webTrack = 0;
-    clearClient();
 }
 
 void InbandTextTrack::addWebVTTCue(double start, double end, const WebString& id, const WebString& content, const WebString& settings)
diff --git a/Source/core/html/track/InbandTextTrack.h b/Source/core/html/track/InbandTextTrack.h
index 70c1ada..268340a 100644
--- a/Source/core/html/track/InbandTextTrack.h
+++ b/Source/core/html/track/InbandTextTrack.h
@@ -43,14 +43,14 @@
 
 class InbandTextTrack FINAL : public TextTrack, public blink::WebInbandTextTrackClient {
 public:
-    static PassRefPtr<InbandTextTrack> create(Document&, TextTrackClient*, blink::WebInbandTextTrack*);
+    static PassRefPtr<InbandTextTrack> create(Document&, blink::WebInbandTextTrack*);
     virtual ~InbandTextTrack();
 
     size_t inbandTrackIndex();
-    void trackRemoved();
+    virtual void setTrackList(TextTrackList*) OVERRIDE FINAL;
 
 private:
-    InbandTextTrack(Document&, TextTrackClient*, blink::WebInbandTextTrack*);
+    InbandTextTrack(Document&, blink::WebInbandTextTrack*);
 
     virtual void addWebVTTCue(double, double, const blink::WebString&, const blink::WebString&, const blink::WebString&) OVERRIDE;
 
diff --git a/Source/core/html/track/LoadableTextTrack.cpp b/Source/core/html/track/LoadableTextTrack.cpp
index 012b360..66e6b8d 100644
--- a/Source/core/html/track/LoadableTextTrack.cpp
+++ b/Source/core/html/track/LoadableTextTrack.cpp
@@ -26,6 +26,8 @@
 #include "config.h"
 #include "core/html/track/LoadableTextTrack.h"
 
+#include "core/dom/ElementTraversal.h"
+#include "core/html/HTMLMediaElement.h"
 #include "core/html/HTMLTrackElement.h"
 #include "core/html/track/TextTrackCueList.h"
 #include "core/html/track/vtt/VTTRegionList.h"
@@ -35,7 +37,7 @@
 using namespace HTMLNames;
 
 LoadableTextTrack::LoadableTextTrack(HTMLTrackElement* track)
-    : TextTrack(track->document(), track, emptyAtom, emptyAtom, emptyAtom, emptyAtom, TrackElement)
+    : TextTrack(track->document(), emptyAtom, emptyAtom, emptyAtom, emptyAtom, TrackElement)
     , m_trackElement(track)
     , m_loadTimer(this, &LoadableTextTrack::loadTimerFired)
     , m_isDefault(false)
@@ -44,12 +46,22 @@
 
 LoadableTextTrack::~LoadableTextTrack()
 {
+    ASSERT(!m_trackElement);
 }
 
-void LoadableTextTrack::clearClient()
+void LoadableTextTrack::clearTrackElement()
 {
     m_trackElement = 0;
-    TextTrack::clearClient();
+}
+
+void LoadableTextTrack::setMode(const AtomicString& mode)
+{
+    TextTrack::setMode(mode);
+    if (!m_trackElement)
+        return;
+
+    if (m_trackElement->readyState() == HTMLTrackElement::NONE)
+        m_trackElement->scheduleLoad();
 }
 
 void LoadableTextTrack::scheduleLoad(const KURL& url)
@@ -74,7 +86,7 @@
     // 3. Asynchronously run the remaining steps, while continuing with whatever task
     // was responsible for creating the text track or changing the text track mode.
     if (!m_loadTimer.isActive())
-        m_loadTimer.startOneShot(0);
+        m_loadTimer.startOneShot(0, FROM_HERE);
 }
 
 void LoadableTextTrack::loadTimerFired(Timer<LoadableTextTrack>*)
@@ -110,8 +122,8 @@
         m_cues->add(newCues[i]);
     }
 
-    if (client())
-        client()->textTrackAddCues(this, m_cues.get());
+    if (mediaElement())
+        mediaElement()->textTrackAddCues(this, m_cues.get());
 }
 
 void LoadableTextTrack::cueLoadingCompleted(TextTrackLoader* loader, bool loadingFailed)
@@ -143,10 +155,10 @@
     ASSERT(m_trackElement->parentNode());
 
     size_t index = 0;
-    for (Node* node = m_trackElement->parentNode()->firstChild(); node; node = node->nextSibling()) {
-        if (!node->hasTagName(trackTag) || !node->parentNode())
+    for (HTMLTrackElement* track = Traversal<HTMLTrackElement>::firstChild(*m_trackElement->parentNode()); track; track = Traversal<HTMLTrackElement>::nextSibling(*track)) {
+        if (!track->parentNode())
             continue;
-        if (node == m_trackElement)
+        if (track == m_trackElement)
             return index;
         ++index;
     }
@@ -156,4 +168,3 @@
 }
 
 } // namespace WebCore
-
diff --git a/Source/core/html/track/LoadableTextTrack.h b/Source/core/html/track/LoadableTextTrack.h
index b557645..9447220 100644
--- a/Source/core/html/track/LoadableTextTrack.h
+++ b/Source/core/html/track/LoadableTextTrack.h
@@ -45,11 +45,12 @@
 
     void scheduleLoad(const KURL&);
 
-    // This shadows TextTrack::clearClient, but need not be virtual.
-    void clearClient();
+    // TextTrack method.
+    virtual void setMode(const AtomicString&) OVERRIDE;
 
     size_t trackElementIndex();
     HTMLTrackElement* trackElement() { return m_trackElement; }
+    void clearTrackElement();
 
     virtual bool isDefault() const OVERRIDE { return m_isDefault; }
     virtual void setIsDefault(bool isDefault) OVERRIDE  { m_isDefault = isDefault; }
diff --git a/Source/core/html/track/TextTrack.cpp b/Source/core/html/track/TextTrack.cpp
index 02b8753..5789476 100644
--- a/Source/core/html/track/TextTrack.cpp
+++ b/Source/core/html/track/TextTrack.cpp
@@ -95,14 +95,13 @@
     return ended;
 }
 
-TextTrack::TextTrack(Document& document, TextTrackClient* client, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType type)
+TextTrack::TextTrack(Document& document, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType type)
     : TrackBase(TrackBase::TextTrack, label, language, id)
-    , m_cues(0)
-    , m_regions(0)
+    , m_cues(nullptr)
+    , m_regions(nullptr)
     , m_document(&document)
     , m_trackList(0)
     , m_mode(disabledKeyword())
-    , m_client(client)
     , m_trackType(type)
     , m_readinessState(NotLoaded)
     , m_trackIndex(invalidTrackIndex)
@@ -115,10 +114,9 @@
 
 TextTrack::~TextTrack()
 {
-    if (m_cues) {
-        if (m_client)
-            m_client->textTrackRemoveCues(this, m_cues.get());
+    ASSERT(!m_trackList);
 
+    if (m_cues) {
         for (size_t i = 0; i < m_cues->length(); ++i)
             m_cues->item(i)->setTrack(0);
     }
@@ -127,7 +125,6 @@
         for (size_t i = 0; i < m_regions->length(); ++i)
             m_regions->item(i)->setTrack(0);
     }
-    clearClient();
 }
 
 bool TextTrack::isValidKindKeyword(const AtomicString& value)
@@ -146,13 +143,22 @@
     return false;
 }
 
+void TextTrack::setTrackList(TextTrackList* trackList)
+{
+    if (!trackList && mediaElement() && m_cues)
+        mediaElement()->textTrackRemoveCues(this, m_cues.get());
+
+    m_trackList = trackList;
+    invalidateTrackIndex();
+}
+
 void TextTrack::setKind(const AtomicString& newKind)
 {
     AtomicString oldKind = kind();
     TrackBase::setKind(newKind);
 
-    if (m_client && oldKind != kind())
-        m_client->textTrackKindChanged(this);
+    if (mediaElement() && oldKind != kind())
+        mediaElement()->textTrackKindChanged(this);
 }
 
 void TextTrack::setMode(const AtomicString& mode)
@@ -166,8 +172,8 @@
 
     // If mode changes to disabled, remove this track's cues from the client
     // because they will no longer be accessible from the cues() function.
-    if (mode == disabledKeyword() && m_client && m_cues)
-        m_client->textTrackRemoveCues(this, m_cues.get());
+    if (mode == disabledKeyword() && mediaElement() && m_cues)
+        mediaElement()->textTrackRemoveCues(this, m_cues.get());
 
     if (mode != showingKeyword() && m_cues)
         for (size_t i = 0; i < m_cues->length(); ++i)
@@ -175,8 +181,8 @@
 
     m_mode = mode;
 
-    if (m_client)
-        m_client->textTrackModeChanged(this);
+    if (mediaElement())
+        mediaElement()->textTrackModeChanged(this);
 }
 
 TextTrackCueList* TextTrack::cues()
@@ -196,13 +202,13 @@
     if (!m_cues)
         return;
 
-    if (m_client)
-        m_client->textTrackRemoveCues(this, m_cues.get());
+    if (mediaElement())
+        mediaElement()->textTrackRemoveCues(this, m_cues.get());
 
     for (size_t i = 0; i < m_cues->length(); ++i)
         m_cues->item(i)->setTrack(0);
 
-    m_cues = 0;
+    m_cues = nullptr;
 }
 
 TextTrackCueList* TextTrack::activeCues() const
@@ -243,8 +249,8 @@
     cue->setTrack(this);
     ensureTextTrackCueList()->add(cue);
 
-    if (m_client)
-        m_client->textTrackAddCue(this, cue.get());
+    if (mediaElement())
+        mediaElement()->textTrackAddCue(this, cue.get());
 }
 
 void TextTrack::removeCue(TextTrackCue* cue, ExceptionState& exceptionState)
@@ -270,8 +276,8 @@
     }
 
     cue->setTrack(0);
-    if (m_client)
-        m_client->textTrackRemoveCue(this, cue);
+    if (mediaElement())
+        mediaElement()->textTrackRemoveCue(this, cue);
 }
 
 VTTRegionList* TextTrack::ensureVTTRegionList()
@@ -347,24 +353,24 @@
 
 void TextTrack::cueWillChange(TextTrackCue* cue)
 {
-    if (!m_client)
+    if (!mediaElement())
         return;
 
     // The cue may need to be repositioned in the media element's interval tree, may need to
     // be re-rendered, etc, so remove it before the modification...
-    m_client->textTrackRemoveCue(this, cue);
+    mediaElement()->textTrackRemoveCue(this, cue);
 }
 
 void TextTrack::cueDidChange(TextTrackCue* cue)
 {
-    if (!m_client)
+    if (!mediaElement())
         return;
 
     // Make sure the TextTrackCueList order is up-to-date.
     ensureTextTrackCueList()->updateCueIndex(cue);
 
     // ... and add it back again.
-    m_client->textTrackAddCue(this, cue);
+    mediaElement()->textTrackAddCue(this, cue);
 }
 
 int TextTrack::trackIndex()
@@ -422,5 +428,9 @@
     return m_document;
 }
 
-} // namespace WebCore
+HTMLMediaElement* TextTrack::mediaElement()
+{
+    return m_trackList ? m_trackList->owner() : 0;
+}
 
+} // namespace WebCore
diff --git a/Source/core/html/track/TextTrack.h b/Source/core/html/track/TextTrack.h
index c430c83..6e9d743 100644
--- a/Source/core/html/track/TextTrack.h
+++ b/Source/core/html/track/TextTrack.h
@@ -44,27 +44,16 @@
 class VTTRegion;
 class VTTRegionList;
 
-class TextTrackClient {
-public:
-    virtual ~TextTrackClient() { }
-    virtual void textTrackKindChanged(TextTrack*) = 0;
-    virtual void textTrackModeChanged(TextTrack*) = 0;
-    virtual void textTrackAddCues(TextTrack*, const TextTrackCueList*) = 0;
-    virtual void textTrackRemoveCues(TextTrack*, const TextTrackCueList*) = 0;
-    virtual void textTrackAddCue(TextTrack*, PassRefPtr<TextTrackCue>) = 0;
-    virtual void textTrackRemoveCue(TextTrack*, PassRefPtr<TextTrackCue>) = 0;
-};
-
 class TextTrack : public TrackBase, public ScriptWrappable, public EventTargetWithInlineData {
     REFCOUNTED_EVENT_TARGET(TrackBase);
 public:
-    static PassRefPtr<TextTrack> create(Document& document, TextTrackClient* client, const AtomicString& kind, const AtomicString& label, const AtomicString& language)
+    static PassRefPtr<TextTrack> create(Document& document, const AtomicString& kind, const AtomicString& label, const AtomicString& language)
     {
-        return adoptRef(new TextTrack(document, client, kind, label, language, emptyAtom, AddTrack));
+        return adoptRef(new TextTrack(document, kind, label, language, emptyAtom, AddTrack));
     }
     virtual ~TextTrack();
 
-    void setTrackList(TextTrackList* trackList) { m_trackList = trackList; }
+    virtual void setTrackList(TextTrackList*);
     TextTrackList* trackList() { return m_trackList; }
 
     virtual void setKind(const AtomicString&) OVERRIDE;
@@ -81,7 +70,7 @@
     static const AtomicString& showingKeyword();
 
     AtomicString mode() const { return m_mode; }
-    void setMode(const AtomicString&);
+    virtual void setMode(const AtomicString&);
 
     enum ReadinessState { NotLoaded = 0, Loading = 1, Loaded = 2, FailedToLoad = 3 };
     ReadinessState readinessState() const { return m_readinessState; }
@@ -90,8 +79,7 @@
     TextTrackCueList* cues();
     TextTrackCueList* activeCues() const;
 
-    void clearClient() { m_client = 0; }
-    TextTrackClient* client() { return m_client; }
+    HTMLMediaElement* mediaElement();
 
     void addCue(PassRefPtr<TextTrackCue>);
     void removeCue(TextTrackCue*, ExceptionState&);
@@ -129,7 +117,7 @@
     virtual ExecutionContext* executionContext() const OVERRIDE;
 
 protected:
-    TextTrack(Document&, TextTrackClient*, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType);
+    TextTrack(Document&, const AtomicString& kind, const AtomicString& label, const AtomicString& language, const AtomicString& id, TextTrackType);
 
     virtual bool isValidKind(const AtomicString& kind) const OVERRIDE { return isValidKindKeyword(kind); }
     virtual AtomicString defaultKind() const OVERRIDE { return subtitlesKeyword(); }
@@ -147,7 +135,6 @@
 
     TextTrackList* m_trackList;
     AtomicString m_mode;
-    TextTrackClient* m_client;
     TextTrackType m_trackType;
     ReadinessState m_readinessState;
     int m_trackIndex;
diff --git a/Source/core/html/track/TextTrackCue.idl b/Source/core/html/track/TextTrackCue.idl
index efc18e3..d762c40 100644
--- a/Source/core/html/track/TextTrackCue.idl
+++ b/Source/core/html/track/TextTrackCue.idl
@@ -25,7 +25,6 @@
 
 [
     Custom=ToV8,
-    CustomConstructor(double startTime, double endTime, DOMString text),
     RuntimeEnabled=VideoTrack,
 ] interface TextTrackCue : EventTarget {
     readonly attribute TextTrack track;
diff --git a/Source/core/html/track/TextTrackList.cpp b/Source/core/html/track/TextTrackList.cpp
index ba8ca1a..847ef25 100644
--- a/Source/core/html/track/TextTrackList.cpp
+++ b/Source/core/html/track/TextTrackList.cpp
@@ -46,7 +46,13 @@
 
 TextTrackList::~TextTrackList()
 {
+    ASSERT(!m_owner);
+
     m_asyncEventQueue->close();
+
+    for (unsigned i = 0; i < length(); ++i) {
+        item(i)->setTrackList(0);
+    }
 }
 
 unsigned TextTrackList::length() const
@@ -201,7 +207,6 @@
 void TextTrackList::remove(TextTrack* track)
 {
     Vector<RefPtr<TextTrack> >* tracks = 0;
-    RefPtr<InbandTextTrack> inbandTrack;
 
     if (track->trackType() == TextTrack::TrackElement) {
         tracks = &m_elementTracks;
@@ -209,7 +214,6 @@
         tracks = &m_addTrackTracks;
     } else if (track->trackType() == TextTrack::InBand) {
         tracks = &m_inbandTracks;
-        inbandTrack = static_cast<InbandTextTrack*>(track);
     } else {
         ASSERT_NOT_REACHED();
     }
@@ -225,12 +229,17 @@
 
     tracks->remove(index);
 
-    if (inbandTrack)
-        inbandTrack->trackRemoved();
-
     scheduleRemoveTrackEvent(track);
 }
 
+void TextTrackList::removeAllInbandTracks()
+{
+    for (unsigned i = 0; i < m_inbandTracks.size(); ++i) {
+        m_inbandTracks[i]->setTrackList(0);
+    }
+    m_inbandTracks.clear();
+}
+
 bool TextTrackList::contains(TextTrack* track) const
 {
     const Vector<RefPtr<TextTrack> >* tracks = 0;
@@ -258,6 +267,11 @@
     return m_owner->executionContext();
 }
 
+void TextTrackList::clearOwner()
+{
+    m_owner = 0;
+}
+
 void TextTrackList::scheduleTrackEvent(const AtomicString& eventName, PassRefPtr<TextTrack> track)
 {
     TrackEventInit initializer;
@@ -310,7 +324,7 @@
     scheduleTrackEvent(EventTypeNames::removetrack, track);
 }
 
-Node* TextTrackList::owner() const
+HTMLMediaElement* TextTrackList::owner() const
 {
     return m_owner;
 }
diff --git a/Source/core/html/track/TextTrackList.h b/Source/core/html/track/TextTrackList.h
index 0d4c883..bc70584 100644
--- a/Source/core/html/track/TextTrackList.h
+++ b/Source/core/html/track/TextTrackList.h
@@ -29,6 +29,7 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/events/EventListener.h"
 #include "core/events/EventTarget.h"
+#include "core/html/HTMLMediaElement.h"
 #include "platform/Timer.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -37,9 +38,7 @@
 namespace WebCore {
 
 class GenericEventQueue;
-class HTMLMediaElement;
 class TextTrack;
-class TextTrackList;
 
 class TextTrackList FINAL : public RefCounted<TextTrackList>, public ScriptWrappable, public EventTargetWithInlineData {
     REFCOUNTED_EVENT_TARGET(TextTrackList);
@@ -68,10 +67,11 @@
     DEFINE_ATTRIBUTE_EVENT_LISTENER(change);
     DEFINE_ATTRIBUTE_EVENT_LISTENER(removetrack);
 
-    void clearOwner() { m_owner = 0; }
-    Node* owner() const;
+    void clearOwner();
+    HTMLMediaElement* owner() const;
 
     void scheduleChangeEvent();
+    void removeAllInbandTracks();
 
 private:
     explicit TextTrackList(HTMLMediaElement*);
diff --git a/Source/core/html/track/TrackEvent.cpp b/Source/core/html/track/TrackEvent.cpp
index 39d70bd..6cc6e1c 100644
--- a/Source/core/html/track/TrackEvent.cpp
+++ b/Source/core/html/track/TrackEvent.cpp
@@ -57,5 +57,10 @@
     return EventNames::TrackEvent;
 }
 
+void TrackEvent::trace(Visitor* visitor)
+{
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
 
diff --git a/Source/core/html/track/TrackEvent.h b/Source/core/html/track/TrackEvent.h
index 17fbf09..15dc425 100644
--- a/Source/core/html/track/TrackEvent.h
+++ b/Source/core/html/track/TrackEvent.h
@@ -55,6 +55,8 @@
 
     TrackBase* track() const { return m_track.get(); }
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     TrackEvent();
     TrackEvent(const AtomicString& type, const TrackEventInit& initializer);
diff --git a/Source/core/html/track/vtt/VTTCue.cpp b/Source/core/html/track/vtt/VTTCue.cpp
index f5a4c8c..e3ae747 100644
--- a/Source/core/html/track/vtt/VTTCue.cpp
+++ b/Source/core/html/track/vtt/VTTCue.cpp
@@ -120,7 +120,7 @@
     if (TextTrackCue::isInfiniteOrNonNumber(value, exceptionState))
         return true;
     if (value < 0 || value > 100) {
-        exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(value) + ") is not between 0 and 100.");
+        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0.0, ExceptionMessages::InclusiveBound, 100.0, ExceptionMessages::InclusiveBound));
         return true;
     }
     return false;
@@ -210,7 +210,7 @@
     , m_cueSize(100)
     , m_writingDirection(Horizontal)
     , m_cueAlignment(Middle)
-    , m_vttNodeTree(0)
+    , m_vttNodeTree(nullptr)
     , m_cueBackgroundBox(HTMLDivElement::create(document))
     , m_displayDirection(CSSValueLtr)
     , m_displaySize(undefinedSize)
@@ -277,7 +277,7 @@
     else if (value == verticalGrowingRightKeyword())
         direction = VerticalGrowingRight;
     else
-        exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("vertical", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'rl', 'lr', and the empty string are accepted."));
+        exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid. Only 'rl', 'lr', and the empty string are accepted.");
 
     if (direction == m_writingDirection)
         return;
@@ -303,7 +303,7 @@
     // On setting, if the text track cue snap-to-lines flag is not set, and the new
     // value is negative or greater than 100, then throw an IndexSizeError exception.
     if (!m_snapToLines && (position < 0 || position > 100)) {
-        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::failedToSet("line", "TextTrackCue", "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100."));
+        exceptionState.throwDOMException(IndexSizeError, "The snap-to-lines flag is not set, and the value provided (" + String::number(position) + ") is not between 0 and 100.");
         return;
     }
 
@@ -390,7 +390,7 @@
     else if (value == rightKeyword())
         alignment = Right;
     else
-        exceptionState.throwDOMException(SyntaxError, ExceptionMessages::failedToSet("align", "TextTrackCue", "The value provided ('" + value + "') is invalid. Only 'start', 'middle', 'end', 'left', and 'right' are accepted."));
+        exceptionState.throwDOMException(SyntaxError, "The value provided ('" + value + "') is invalid. Only 'start', 'middle', 'end', 'left', and 'right' are accepted.");
 
     if (alignment == m_cueAlignment)
         return;
@@ -408,7 +408,7 @@
     cueWillChange();
     // Clear the document fragment but don't bother to create it again just yet as we can do that
     // when it is requested.
-    m_vttNodeTree = 0;
+    m_vttNodeTree = nullptr;
     m_text = text;
     cueDidChange();
 }
@@ -779,7 +779,7 @@
         // If cue has an empty text track cue region identifier or there is no
         // WebVTT region whose region identifier is identical to cue's text
         // track cue region identifier, run the following substeps:
-        if (displayBox->hasChildNodes() && !container.contains(displayBox.get())) {
+        if (displayBox->hasChildren() && !container.contains(displayBox.get())) {
             // Note: the display tree of a cue is removed when the active flag of the cue is unset.
             container.appendChild(displayBox);
         }
diff --git a/Source/core/html/track/vtt/VTTElement.h b/Source/core/html/track/vtt/VTTElement.h
index 2fe08c7..f0181ad 100644
--- a/Source/core/html/track/vtt/VTTElement.h
+++ b/Source/core/html/track/vtt/VTTElement.h
@@ -79,7 +79,7 @@
     AtomicString m_language;
 };
 
-DEFINE_NODE_TYPE_CASTS(VTTElement, isVTTElement());
+DEFINE_ELEMENT_TYPE_CASTS(VTTElement, isVTTElement());
 
 } // namespace WebCore
 
diff --git a/Source/core/html/track/vtt/VTTRegion.cpp b/Source/core/html/track/vtt/VTTRegion.cpp
index dd7613e..bea2d79 100644
--- a/Source/core/html/track/vtt/VTTRegion.cpp
+++ b/Source/core/html/track/vtt/VTTRegion.cpp
@@ -75,7 +75,7 @@
         return true;
     }
     if (value < 0 || value > 100) {
-        exceptionState.throwDOMException(IndexSizeError, "The value provided (" + String::number(value) + ") is not between 0 and 100.");
+        exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexOutsideRange("value", value, 0.0, ExceptionMessages::InclusiveBound, 100.0, ExceptionMessages::InclusiveBound));
         return true;
     }
     return false;
@@ -339,7 +339,7 @@
 
     double boxHeight = box->getBoundingClientRect()->bottom() - box->getBoundingClientRect()->top();
 
-    m_cueContainer->classList()->remove(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
+    m_cueContainer->classList().remove(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
 
     m_currentTop += boxHeight;
     m_cueContainer->setInlineStyleProperty(CSSPropertyTop, m_currentTop, CSSPrimitiveValue::CSS_PX);
@@ -370,14 +370,14 @@
 
     // If it's a scrolling region, add the scrolling class.
     if (isScrollingRegion())
-        m_cueContainer->classList()->add(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
+        m_cueContainer->classList().add(textTrackCueContainerScrollingClass(), ASSERT_NO_EXCEPTION);
 
     float regionBottom = m_regionDisplayTree->getBoundingClientRect()->bottom();
 
     // Find first cue that is not entirely displayed and scroll it upwards.
-    for (size_t i = 0; i < m_cueContainer->childNodeCount() && !m_scrollTimer.isActive(); ++i) {
-        float childTop = toHTMLDivElement(m_cueContainer->childNode(i))->getBoundingClientRect()->top();
-        float childBottom = toHTMLDivElement(m_cueContainer->childNode(i))->getBoundingClientRect()->bottom();
+    for (Element* child = ElementTraversal::firstWithin(*m_cueContainer); child && !m_scrollTimer.isActive(); child = ElementTraversal::nextSibling(*child)) {
+        float childTop = toHTMLDivElement(child)->getBoundingClientRect()->top();
+        float childBottom = toHTMLDivElement(child)->getBoundingClientRect()->bottom();
 
         if (regionBottom >= childBottom)
             continue;
@@ -452,7 +452,7 @@
         return;
 
     double duration = isScrollingRegion() ? scrollTime : 0;
-    m_scrollTimer.startOneShot(duration);
+    m_scrollTimer.startOneShot(duration, FROM_HERE);
 }
 
 void VTTRegion::stopTimer()
diff --git a/Source/core/inspector/AsyncCallStackTracker.cpp b/Source/core/inspector/AsyncCallStackTracker.cpp
index a8761a9..66bf28b 100644
--- a/Source/core/inspector/AsyncCallStackTracker.cpp
+++ b/Source/core/inspector/AsyncCallStackTracker.cpp
@@ -102,11 +102,11 @@
     {
         HashMap<EventTarget*, EventListenerAsyncCallChainVectorHashMap>::iterator it = m_eventTargetCallChains.find(eventTarget);
         if (it == m_eventTargetCallChains.end())
-            return 0;
+            return nullptr;
         EventListenerAsyncCallChainVectorHashMap& map = it->value;
         EventListenerAsyncCallChainVectorHashMap::iterator it2 = map.find(eventType);
         if (it2 == map.end())
-            return 0;
+            return nullptr;
         RefPtr<AsyncCallChain> result;
         EventListenerAsyncCallChainVector& vector = it2->value;
         for (size_t i = 0; i < vector.size(); ++i) {
@@ -216,7 +216,7 @@
         else
             setCurrentAsyncCallChain(data->m_timerCallChains.take(timerId));
     } else {
-        setCurrentAsyncCallChain(0);
+        setCurrentAsyncCallChain(nullptr);
     }
 }
 
@@ -250,7 +250,7 @@
     if (ExecutionContextData* data = m_executionContextDataMap.get(context))
         setCurrentAsyncCallChain(data->m_animationFrameCallChains.take(callbackId));
     else
-        setCurrentAsyncCallChain(0);
+        setCurrentAsyncCallChain(nullptr);
 }
 
 void AsyncCallStackTracker::didAddEventListener(EventTarget* eventTarget, const AtomicString& eventType, EventListener* listener, bool useCapture, const ScriptValue& callFrames)
@@ -304,7 +304,7 @@
     if (ExecutionContextData* data = m_executionContextDataMap.get(eventTarget->executionContext()))
         setCurrentAsyncCallChain(data->findEventListenerData(eventTarget, eventType, RegisteredEventListener(listener, useCapture)));
     else
-        setCurrentAsyncCallChain(0);
+        setCurrentAsyncCallChain(nullptr);
 }
 
 void AsyncCallStackTracker::willLoadXHR(XMLHttpRequest* xhr, const ScriptValue& callFrames)
@@ -328,7 +328,7 @@
         else
             setCurrentAsyncCallChain(data->m_xhrCallChains.get(xhr));
     } else {
-        setCurrentAsyncCallChain(0);
+        setCurrentAsyncCallChain(nullptr);
     }
 }
 
@@ -366,7 +366,7 @@
     if (ExecutionContextData* data = m_executionContextDataMap.get(context))
         setCurrentAsyncCallChain(data->m_mutationObserverCallChains.take(observer));
     else
-        setCurrentAsyncCallChain(0);
+        setCurrentAsyncCallChain(nullptr);
 }
 
 void AsyncCallStackTracker::didPostPromiseTask(ExecutionContext* context, ExecutionContextTask* task, bool isResolved, const ScriptValue& callFrames)
@@ -390,7 +390,7 @@
     if (ExecutionContextData* data = m_executionContextDataMap.get(context))
         setCurrentAsyncCallChain(data->m_promiseTaskCallChains.take(task));
     else
-        setCurrentAsyncCallChain(0);
+        setCurrentAsyncCallChain(nullptr);
 }
 
 void AsyncCallStackTracker::didFireAsyncCall()
diff --git a/Source/core/inspector/CodeGeneratorInspector.py b/Source/core/inspector/CodeGeneratorInspector.py
index 342b5a2..506b321 100755
--- a/Source/core/inspector/CodeGeneratorInspector.py
+++ b/Source/core/inspector/CodeGeneratorInspector.py
@@ -1849,6 +1849,9 @@
 
     @staticmethod
     def process_event(json_event, domain_name, frontend_method_declaration_lines):
+        if (("handlers" in json_event) and (not ("renderer" in json_event["handlers"]))):
+            return
+
         event_name = json_event["name"]
 
         ad_hoc_type_output = []
@@ -1879,6 +1882,9 @@
 
     @staticmethod
     def process_command(json_command, domain_name, agent_field_name, agent_interface_name):
+        if (("handlers" in json_command) and (not ("renderer" in json_command["handlers"]))):
+            return
+
         json_command_name = json_command["name"]
 
         cmd_enum_name = "k%s_%sCmd" % (domain_name, json_command["name"])
diff --git a/Source/core/inspector/CodeGeneratorInspectorStrings.py b/Source/core/inspector/CodeGeneratorInspectorStrings.py
index 94416e7..4b91530 100644
--- a/Source/core/inspector/CodeGeneratorInspectorStrings.py
+++ b/Source/core/inspector/CodeGeneratorInspectorStrings.py
@@ -33,8 +33,8 @@
 """    class $domainClassName {
     public:
         $domainClassName(InspectorFrontendChannel* inspectorFrontendChannel) : m_inspectorFrontendChannel(inspectorFrontendChannel) { }
-${frontendDomainMethodDeclarations}        void setInspectorFrontendChannel(InspectorFrontendChannel* inspectorFrontendChannel) { m_inspectorFrontendChannel = inspectorFrontendChannel; }
-        InspectorFrontendChannel* getInspectorFrontendChannel() { return m_inspectorFrontendChannel; }
+${frontendDomainMethodDeclarations}
+        void flush() { m_inspectorFrontendChannel->flush(); }
     private:
         InspectorFrontendChannel* m_inspectorFrontendChannel;
     };
@@ -69,7 +69,7 @@
     RefPtr<JSONObject> jsonMessage = JSONObject::create();
     jsonMessage->setString("method", "$domainName.$eventName");
 $code    if (m_inspectorFrontendChannel)
-        m_inspectorFrontendChannel->sendMessageToFrontend(jsonMessage->toJSONString());
+        m_inspectorFrontendChannel->sendMessageToFrontend(jsonMessage.release());
 }
 """)
 
@@ -91,7 +91,7 @@
     if (error) {
         errorDataValue = $argument;
     }
-    sendIfActive(0, error, errorDataValue.release());
+    sendIfActive(nullptr, error, errorDataValue.release());
 }
 """)
 
@@ -101,23 +101,23 @@
 #define InspectorFrontend_h
 
 #include "InspectorTypeBuilder.h"
+#include "core/inspector/InspectorFrontendChannel.h"
 #include "platform/JSONValues.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-class InspectorFrontendChannel;
-
 typedef String ErrorString;
 
 class InspectorFrontend {
 public:
     InspectorFrontend(InspectorFrontendChannel*);
-
+    InspectorFrontendChannel* channel() { return m_inspectorFrontendChannel; }
 
 $domainClassList
 private:
+    InspectorFrontendChannel* m_inspectorFrontendChannel;
 ${fieldDeclarations}};
 
 } // namespace WebCore
@@ -360,7 +360,7 @@
     responseMessage->setObject("result", result);
     responseMessage->setNumber("id", callId);
     if (m_inspectorFrontendChannel)
-        m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage->toJSONString());
+        m_inspectorFrontendChannel->sendMessageToFrontend(responseMessage.release());
 }
 
 void InspectorBackendDispatcher::reportProtocolError(const long* const callId, CommonErrorCode code, const String& errorMessage) const
@@ -395,7 +395,7 @@
     else
         message->setValue("id", JSONValue::null());
     if (m_inspectorFrontendChannel)
-        m_inspectorFrontendChannel->sendMessageToFrontend(message->toJSONString());
+        m_inspectorFrontendChannel->sendMessageToFrontend(message.release());
 }
 
 template<typename R, typename V, typename V0>
@@ -496,7 +496,7 @@
 void InspectorBackendDispatcher::CallbackBase::sendFailure(const ErrorString& error)
 {
     ASSERT(error.length());
-    sendIfActive(0, error, PassRefPtr<JSONValue>());
+    sendIfActive(nullptr, error, PassRefPtr<JSONValue>());
 }
 
 bool InspectorBackendDispatcher::CallbackBase::isActive()
@@ -530,7 +530,9 @@
 namespace WebCore {
 
 InspectorFrontend::InspectorFrontend(InspectorFrontendChannel* inspectorFrontendChannel)
-    : $constructorInit{
+    : m_inspectorFrontendChannel(inspectorFrontendChannel)
+    , $constructorInit
+{
 }
 
 $methods
@@ -661,6 +663,11 @@
         return static_cast<Array<T>*>(static_cast<JSONArrayBase*>(array.get()));
     }
 
+    void concat(PassRefPtr<Array<T> > array)
+    {
+        return ArrayItemHelper<T>::Traits::concat(this->openAccessors(), array->openAccessors());
+    }
+
 #if $validatorIfdefName
     static void assertCorrectValue(JSONValue* value)
     {
@@ -680,6 +687,12 @@
         array->pushValue(value);
     }
 
+    static void concat(JSONArray* array, JSONArray* anotherArray)
+    {
+        for (JSONArray::iterator it = anotherArray->begin(); it != anotherArray->end(); ++it)
+            array->pushValue(*it);
+    }
+
 #if $validatorIfdefName
     template<typename T>
     static void assertCorrectValue(JSONValue* value) {
diff --git a/Source/core/inspector/ConsoleMessage.cpp b/Source/core/inspector/ConsoleMessage.cpp
index 4e1dabc..4c33b18 100644
--- a/Source/core/inspector/ConsoleMessage.cpp
+++ b/Source/core/inspector/ConsoleMessage.cpp
@@ -80,7 +80,7 @@
     , m_type(type)
     , m_level(level)
     , m_message(message)
-    , m_arguments(0)
+    , m_arguments(nullptr)
     , m_line(0)
     , m_column(0)
     , m_repeatCount(1)
diff --git a/Source/core/inspector/ContentSearchUtils.cpp b/Source/core/inspector/ContentSearchUtils.cpp
index 9ed8568..af65fb6 100644
--- a/Source/core/inspector/ContentSearchUtils.cpp
+++ b/Source/core/inspector/ContentSearchUtils.cpp
@@ -132,51 +132,63 @@
     ASSERT(name.find("=") == kNotFound);
     if (deprecated)
         *deprecated = false;
-    String pattern;
-    String deprecatedPattern;
-    switch (commentType) {
-    case JavaScriptMagicComment:
-        pattern = "//#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$";
-        deprecatedPattern = "//@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s\'\"]*)[\040\t]*$";
+
+    unsigned length = content.length();
+    unsigned nameLength = name.length();
+
+    size_t pos = length;
+    size_t equalSignPos = 0;
+    size_t closingCommentPos = 0;
+    while (true) {
+        pos = content.reverseFind(name, pos);
+        if (pos == kNotFound)
+            return String();
+
+        // Check for a /\/[\/*][@#][ \t]/ regexp (length of 4) before found name.
+        if (pos < 4)
+            return String();
+        pos -= 4;
+        if (content[pos] != '/')
+            continue;
+        if ((content[pos + 1] != '/' || commentType != JavaScriptMagicComment)
+            && (content[pos + 1] != '*' || commentType != CSSMagicComment))
+            continue;
+        if (content[pos + 2] != '#' && content[pos + 2] != '@')
+            continue;
+        if (content[pos + 3] != ' ' && content[pos + 3] != '\t')
+            continue;
+        equalSignPos = pos + 4 + nameLength;
+        if (equalSignPos < length && content[equalSignPos] != '=')
+            continue;
+        if (commentType == CSSMagicComment) {
+            closingCommentPos = content.find("*/", equalSignPos + 1);
+            if (closingCommentPos == kNotFound)
+                return String();
+            if (!content.substring(closingCommentPos + 2).containsOnlyWhitespace())
+                return String();
+        }
+
         break;
-    case CSSMagicComment:
-        pattern = "/\\*#[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$";
-        deprecatedPattern = "/\\*@[\040\t]" + createSearchRegexSource(name) + "=[\040\t]*([^\\s]*)[\040\t]*\\*/[\040\t]*$";
-        break;
-    default:
-        ASSERT_NOT_REACHED();
-        return String();
     }
-    ScriptRegexp regex(pattern, TextCaseSensitive, MultilineEnabled);
-    ScriptRegexp deprecatedRegex(deprecatedPattern, TextCaseSensitive, MultilineEnabled);
 
-    int matchLength;
-    int offset = regex.match(content, 0, &matchLength);
-    if (offset == -1) {
-        offset = deprecatedRegex.match(content, 0, &matchLength);
-        if (offset != -1 && deprecated)
-            *deprecated = true;
-    }
-    if (offset == -1)
-        return String();
+    if (deprecated && content[pos + 2] == '@')
+        *deprecated = true;
 
-    String match = content.substring(offset, matchLength);
-    size_t separator = match.find("=");
-    ASSERT(separator != kNotFound);
-    match = match.substring(separator + 1);
+    ASSERT(equalSignPos);
+    ASSERT(commentType != CSSMagicComment || closingCommentPos);
+    size_t urlPos = equalSignPos + 1;
+    String match = commentType == CSSMagicComment
+        ? content.substring(urlPos, closingCommentPos - urlPos)
+        : content.substring(urlPos);
+    match = match.stripWhiteSpace();
 
-    switch (commentType) {
-    case JavaScriptMagicComment:
-        return match.stripWhiteSpace();
-    case CSSMagicComment: {
-        size_t lastStarIndex = match.reverseFind('*');
-        ASSERT(lastStarIndex != kNotFound);
-        return match.substring(0, lastStarIndex).stripWhiteSpace();
+    String disallowedChars("\"' \t\n\r");
+    for (unsigned i = 0; i < match.length(); ++i) {
+        if (disallowedChars.find(match[i]) != kNotFound)
+            return String();
     }
-    default:
-        ASSERT_NOT_REACHED();
-        return String();
-    }
+
+    return match;
 }
 
 String findSourceURL(const String& content, MagicCommentType commentType, bool* deprecated)
diff --git a/Source/core/inspector/DOMEditor.cpp b/Source/core/inspector/DOMEditor.cpp
index 1f8956b..734077f 100644
--- a/Source/core/inspector/DOMEditor.cpp
+++ b/Source/core/inspector/DOMEditor.cpp
@@ -175,9 +175,10 @@
 
     virtual bool perform(ExceptionState& exceptionState) OVERRIDE
     {
-        m_hadAttribute = m_element->hasAttribute(m_name);
+        const AtomicString& value = m_element->getAttribute(m_name);
+        m_hadAttribute = !value.isNull();
         if (m_hadAttribute)
-            m_oldValue = m_element->getAttribute(m_name);
+            m_oldValue = value;
         return redo(exceptionState);
     }
 
diff --git a/Source/core/inspector/DOMPatchSupport.cpp b/Source/core/inspector/DOMPatchSupport.cpp
index 67c9718..be9f2a3 100644
--- a/Source/core/inspector/DOMPatchSupport.cpp
+++ b/Source/core/inspector/DOMPatchSupport.cpp
@@ -31,7 +31,6 @@
 #include "config.h"
 #include "core/inspector/DOMPatchSupport.h"
 
-#include "HTMLNames.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/Attribute.h"
@@ -40,7 +39,9 @@
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/Node.h"
 #include "core/dom/XMLDocument.h"
+#include "core/html/HTMLBodyElement.h"
 #include "core/html/HTMLDocument.h"
+#include "core/html/HTMLHeadElement.h"
 #include "core/html/parser/HTMLDocumentParser.h"
 #include "core/inspector/DOMEditor.h"
 #include "core/inspector/InspectorHistory.h"
@@ -56,10 +57,6 @@
 
 namespace WebCore {
 
-using HTMLNames::bodyTag;
-using HTMLNames::headTag;
-using HTMLNames::htmlTag;
-
 struct DOMPatchSupport::Digest {
     explicit Digest(Node* node) : m_node(node) { }
 
@@ -123,12 +120,20 @@
     }
 
     Node* previousSibling = node->previousSibling();
-    // FIXME: This code should use one of createFragment* in markup.h
     RefPtr<DocumentFragment> fragment = DocumentFragment::create(m_document);
+    Node* targetNode = node->parentElementOrShadowRoot() ? node->parentElementOrShadowRoot() : m_document.documentElement();
+
+    // Use the document BODY as the context element when editing immediate shadow root children,
+    // as it provides an equivalent parsing context.
+    if (targetNode->isShadowRoot())
+        targetNode = m_document.body();
+    Element* targetElement = toElement(targetNode);
+
+    // FIXME: This code should use one of createFragment* in markup.h
     if (m_document.isHTMLDocument())
-        fragment->parseHTML(markup, node->parentElement() ? node->parentElement() : m_document.documentElement());
+        fragment->parseHTML(markup, targetElement);
     else
-        fragment->parseXML(markup, node->parentElement() ? node->parentElement() : m_document.documentElement());
+        fragment->parseXML(markup, targetElement);
 
     // Compose the old list.
     ContainerNode* parentNode = node->parentNode();
@@ -142,9 +147,9 @@
     for (Node* child = parentNode->firstChild(); child != node; child = child->nextSibling())
         newList.append(createDigest(child, 0));
     for (Node* child = fragment->firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(headTag) && !child->firstChild() && markupCopy.find("</head>") == kNotFound)
+        if (isHTMLHeadElement(*child) && !child->firstChild() && markupCopy.find("</head>") == kNotFound)
             continue; // HTML5 parser inserts empty <head> tag whenever it parses <body>
-        if (child->hasTagName(bodyTag) && !child->firstChild() && markupCopy.find("</body>") == kNotFound)
+        if (isHTMLBodyElement(*child) && !child->firstChild() && markupCopy.find("</body>") == kNotFound)
             continue; // HTML5 parser inserts empty <body> tag whenever it parses </head>
         newList.append(createDigest(child, &m_unusedNodesMap));
     }
@@ -185,8 +190,8 @@
         // FIXME: Create a function in Element for removing all properties. Take in account whether did/willModifyAttribute are important.
         if (oldElement->hasAttributesWithoutUpdate()) {
             while (oldElement->attributeCount()) {
-                const Attribute* attribute = oldElement->attributeItem(0);
-                if (!m_domEditor->removeAttribute(oldElement, attribute->localName(), exceptionState))
+                const Attribute& attribute = oldElement->attributeItem(0);
+                if (!m_domEditor->removeAttribute(oldElement, attribute.localName(), exceptionState))
                     return false;
             }
         }
@@ -195,8 +200,8 @@
         if (newElement->hasAttributesWithoutUpdate()) {
             size_t numAttrs = newElement->attributeCount();
             for (size_t i = 0; i < numAttrs; ++i) {
-                const Attribute* attribute = newElement->attributeItem(i);
-                if (!m_domEditor->setAttribute(oldElement, attribute->name().localName(), attribute->value(), exceptionState))
+                const Attribute& attribute = newElement->attributeItem(i);
+                if (!m_domEditor->setAttribute(oldElement, attribute.name().localName(), attribute.value(), exceptionState))
                     return false;
             }
         }
@@ -315,11 +320,11 @@
 
         // Always match <head> and <body> tags with each other - we can't remove them from the DOM
         // upon patching.
-        if (oldList[i]->m_node->hasTagName(headTag)) {
+        if (isHTMLHeadElement(*oldList[i]->m_node)) {
             oldHead = oldList[i].get();
             continue;
         }
-        if (oldList[i]->m_node->hasTagName(bodyTag)) {
+        if (isHTMLBodyElement(*oldList[i]->m_node)) {
             oldBody = oldList[i].get();
             continue;
         }
@@ -359,9 +364,9 @@
     // Mark <head> and <body> nodes for merge.
     if (oldHead || oldBody) {
         for (size_t i = 0; i < newList.size(); ++i) {
-            if (oldHead && newList[i]->m_node->hasTagName(headTag))
+            if (oldHead && isHTMLHeadElement(*newList[i]->m_node))
                 merges.set(newList[i].get(), oldHead);
-            if (oldBody && newList[i]->m_node->hasTagName(bodyTag))
+            if (oldBody && isHTMLBodyElement(*newList[i]->m_node))
                 merges.set(newList[i].get(), oldBody);
         }
     }
@@ -376,7 +381,7 @@
     for (size_t i = 0; i < newMap.size(); ++i) {
         if (newMap[i].first || merges.contains(newList[i].get()))
             continue;
-        if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode->childNode(i), exceptionState))
+        if (!insertBeforeAndMarkAsUsed(parentNode, newList[i].get(), parentNode->traverseToChildAt(i), exceptionState))
             return false;
     }
 
@@ -385,10 +390,10 @@
         if (!oldMap[i].first)
             continue;
         RefPtr<Node> node = oldMap[i].first->m_node;
-        Node* anchorNode = parentNode->childNode(oldMap[i].second);
-        if (node.get() == anchorNode)
+        Node* anchorNode = parentNode->traverseToChildAt(oldMap[i].second);
+        if (node == anchorNode)
             continue;
-        if (node->hasTagName(bodyTag) || node->hasTagName(headTag))
+        if (isHTMLBodyElement(*node) || isHTMLHeadElement(*node))
             continue; // Never move head or body, move the rest of the nodes around them.
 
         if (!m_domEditor->insertBefore(parentNode, node.release(), anchorNode, exceptionState))
@@ -428,9 +433,9 @@
             size_t numAttrs = element->attributeCount();
             SHA1 attrsSHA1;
             for (size_t i = 0; i < numAttrs; ++i) {
-                const Attribute* attribute = element->attributeItem(i);
-                addStringToSHA1(attrsSHA1, attribute->name().toString());
-                addStringToSHA1(attrsSHA1, attribute->value());
+                const Attribute& attribute = element->attributeItem(i);
+                addStringToSHA1(attrsSHA1, attribute.name().toString());
+                addStringToSHA1(attrsSHA1, attribute.value());
             }
             Vector<uint8_t, 20> attrsHash;
             attrsSHA1.computeHash(attrsHash);
diff --git a/Source/core/inspector/InjectedScript.cpp b/Source/core/inspector/InjectedScript.cpp
index d746427..cfe7b56 100644
--- a/Source/core/inspector/InjectedScript.cpp
+++ b/Source/core/inspector/InjectedScript.cpp
@@ -258,7 +258,7 @@
     bool hadException = false;
     ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException);
     if (hadException)
-        return 0;
+        return nullptr;
     RefPtr<JSONObject> rawResult = r.toJSONValue(scriptState())->asObject();
     return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult);
 }
@@ -276,7 +276,7 @@
     bool hadException = false;
     ScriptValue r = callFunctionWithEvalEnabled(wrapFunction, hadException);
     if (hadException)
-        return 0;
+        return nullptr;
     RefPtr<JSONObject> rawResult = r.toJSONValue(scriptState())->asObject();
     return TypeBuilder::Runtime::RemoteObject::runtimeCast(rawResult);
 }
diff --git a/Source/core/inspector/InjectedScriptCanvasModuleSource.js b/Source/core/inspector/InjectedScriptCanvasModuleSource.js
index c82ab23..7c0a223 100644
--- a/Source/core/inspector/InjectedScriptCanvasModuleSource.js
+++ b/Source/core/inspector/InjectedScriptCanvasModuleSource.js
@@ -40,7 +40,7 @@
     /**
      * http://www.khronos.org/registry/typedarray/specs/latest/#7
      * @const
-     * @type {!Array.<function(new:ArrayBufferView, ArrayBufferView)>}
+     * @type {!Array.<function(new:ArrayBufferView, (ArrayBuffer|ArrayBufferView), number=, number=)>}
      */
     _typedArrayClasses: (function(typeNames) {
         var result = [];
@@ -59,7 +59,7 @@
 
     /**
      * @param {*} array
-     * @return {function(new:ArrayBufferView, ArrayBufferView)|null}
+     * @return {function(new:ArrayBufferView, (ArrayBuffer|ArrayBufferView), number=, number=)|null}
      */
     typedArrayClass: function(array)
     {
@@ -1864,6 +1864,73 @@
     },
 
     /**
+     * @return {?ArrayBufferView}
+     */
+    cachedBufferData: function()
+    {
+        /**
+         * Creates a view to a given buffer, does NOT copy the buffer.
+         * @param {!ArrayBuffer|!ArrayBufferView} buffer
+         * @return {!Uint8Array}
+         */
+        function createUint8ArrayBufferView(buffer)
+        {
+            return buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
+        }
+
+        if (!this._cachedBufferData) {
+            for (var i = this._calls.length - 1; i >= 0; --i) {
+                var call = this._calls[i];
+                if (call.functionName() === "bufferData") {
+                    var sizeOrData = /** @type {number|ArrayBuffer|ArrayBufferView} */ (call.args()[1]);
+                    if (typeof sizeOrData === "number")
+                        this._cachedBufferData = new ArrayBuffer(sizeOrData);
+                    else
+                        this._cachedBufferData = sizeOrData;
+                    this._lastBufferSubDataIndex = i + 1;
+                    break;
+                }
+            }
+            if (!this._cachedBufferData)
+                return null;
+        }
+
+        // Apply any "bufferSubData" calls that have not been applied yet.
+        var bufferDataView;
+        while (this._lastBufferSubDataIndex < this._calls.length) {
+            var call = this._calls[this._lastBufferSubDataIndex++];
+            if (call.functionName() !== "bufferSubData")
+                continue;
+            var offset = /** @type {number} */ (call.args()[1]);
+            var data = /** @type {!ArrayBuffer|!ArrayBufferView} */ (call.args()[2]);
+            var view = createUint8ArrayBufferView(data);
+            if (!bufferDataView)
+                bufferDataView = createUint8ArrayBufferView(this._cachedBufferData);
+            bufferDataView.set(view, offset);
+
+            var isFullReplacement = (offset === 0 && bufferDataView.length === view.length);
+            if (this._cachedBufferData instanceof ArrayBuffer) {
+                // The buffer data has no type yet. Try to guess from the "bufferSubData" call.
+                var typedArrayClass = TypeUtils.typedArrayClass(data);
+                if (typedArrayClass)
+                    this._cachedBufferData = new typedArrayClass(this._cachedBufferData); // Does not copy the buffer.
+            } else if (isFullReplacement) {
+                var typedArrayClass = TypeUtils.typedArrayClass(data);
+                if (typedArrayClass) {
+                    var typedArrayData = /** @type {!ArrayBufferView} */ (data);
+                    this._cachedBufferData = new typedArrayClass(this._cachedBufferData.buffer, this._cachedBufferData.byteOffset, typedArrayData.length); // Does not copy the buffer.
+                }
+            }
+        }
+
+        if (this._cachedBufferData instanceof ArrayBuffer) {
+            // If we failed to guess the data type yet, use Uint8Array.
+            return new Uint8Array(this._cachedBufferData);
+        }
+        return this._cachedBufferData;
+    },
+
+    /**
      * @override
      * @return {!Array.<TypeUtils.InternalResourceStateDescriptor>}
      */
@@ -1905,16 +1972,34 @@
 
         if (oldBuffer !== buffer)
             gl.bindBuffer(target, oldBuffer);
+
+        try {
+            var data = this.cachedBufferData();
+            if (data)
+                result.push({ name: "bufferData", value: data });
+        } catch (e) {
+            console.error("Exception while restoring bufferData", e);
+        }
+
         return result;
     },
 
     /**
-     * @override
      * @param {!Call} call
      */
-    pushCall: function(call)
+    pushCall_bufferData: function(call)
     {
         // FIXME: remove any older calls that no longer contribute to the resource state.
+        delete this._cachedBufferData;
+        delete this._lastBufferSubDataIndex;
+        WebGLBoundResource.prototype.pushCall.call(this, call);
+    },
+
+    /**
+     * @param {!Call} call
+     */
+    pushCall_bufferSubData: function(call)
+    {
         // FIXME: Optimize memory for bufferSubData.
         WebGLBoundResource.prototype.pushCall.call(this, call);
     },
@@ -2818,6 +2903,16 @@
         case "getExtension":
             this.registerWebGLExtension(args[0], /** @type {Object} */ (call.result()));
             break;
+        case "bufferData":
+            var resource = /** @type {WebGLBufferResource} */ (this.currentBinding(args[0]));
+            if (resource)
+                resource.pushCall_bufferData(call);
+            break;
+        case "bufferSubData":
+            var resource = /** @type {WebGLBufferResource} */ (this.currentBinding(args[0]));
+            if (resource)
+                resource.pushCall_bufferSubData(call);
+            break;
         }
     },
 
@@ -2844,8 +2939,8 @@
             stateModifyingWrapFunction("detachShader");
             stateModifyingWrapFunction("linkProgram");
             stateModifyingWrapFunction("shaderSource");
-            stateModifyingWrapFunction("bufferData");
-            stateModifyingWrapFunction("bufferSubData");
+            stateModifyingWrapFunction("bufferData", WebGLBufferResource.prototype.pushCall_bufferData);
+            stateModifyingWrapFunction("bufferSubData", WebGLBufferResource.prototype.pushCall_bufferSubData);
             stateModifyingWrapFunction("compressedTexImage2D");
             stateModifyingWrapFunction("compressedTexSubImage2D");
             stateModifyingWrapFunction("copyTexImage2D", WebGLTextureResource.prototype.pushCall_copyTexImage2D);
diff --git a/Source/core/inspector/InjectedScriptExterns.js b/Source/core/inspector/InjectedScriptExterns.js
index 59c7d56..55dce74 100644
--- a/Source/core/inspector/InjectedScriptExterns.js
+++ b/Source/core/inspector/InjectedScriptExterns.js
@@ -39,6 +39,12 @@
  */
 InjectedScriptHostClass.prototype.functionDetails = function(func) { }
 /**
+ * @param {!Object} receiver
+ * @param {!Function} func
+ * @param {...*} args
+ */
+InjectedScriptHostClass.prototype.suppressWarningsAndCall = function(receiver, func, args) { }
+/**
  * @param {*} object
  */
 InjectedScriptHostClass.prototype.isHTMLAllCollection = function(object) { }
@@ -46,10 +52,7 @@
  * @param {*} object
  */
 InjectedScriptHostClass.prototype.internalConstructorName = function(object) { }
-/**
- * @param {*} object
- */
-InjectedScriptHostClass.prototype.copyText = function(object) { }
+
 InjectedScriptHostClass.prototype.clearConsoleMessages = function() { }
 /**
  * @param {number} index
diff --git a/Source/core/inspector/InjectedScriptHost.h b/Source/core/inspector/InjectedScriptHost.h
index 046fe3b..b6068bf 100644
--- a/Source/core/inspector/InjectedScriptHost.h
+++ b/Source/core/inspector/InjectedScriptHost.h
@@ -32,8 +32,10 @@
 
 #include "bindings/v8/ScriptState.h"
 #include "bindings/v8/ScriptWrappable.h"
+#include "wtf/PassOwnPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/inspector/InjectedScriptHost.idl b/Source/core/inspector/InjectedScriptHost.idl
index da13730..5dec0fc 100644
--- a/Source/core/inspector/InjectedScriptHost.idl
+++ b/Source/core/inspector/InjectedScriptHost.idl
@@ -48,6 +48,7 @@
     [Custom] void undebugFunction(any fn);
     [Custom] void monitorFunction(any fn);
     [Custom] void unmonitorFunction(any fn);
+    [Custom] any suppressWarningsAndCall(any receiver, any fn, any param1, any param2);
 
     // Only declarative scope (local, with and catch) is accepted. Returns undefined.
     [Custom] any setFunctionVariableValue(any functionObject, long scopeIndex, DOMString variableName, any newValue);
diff --git a/Source/core/inspector/InjectedScriptSource.js b/Source/core/inspector/InjectedScriptSource.js
index efb9451..3d761ae 100644
--- a/Source/core/inspector/InjectedScriptSource.js
+++ b/Source/core/inspector/InjectedScriptSource.js
@@ -111,6 +111,30 @@
 }
 
 /**
+ * FireBug's array detection.
+ * @param {*} obj
+ * @return {boolean}
+ */
+function isArrayLike(obj)
+{
+    try {
+        if (typeof obj !== "object")
+            return false;
+        if (typeof obj.splice === "function")
+            return isFinite(obj.length);
+        var str = Object.prototype.toString.call(obj);
+        if (str === "[object Array]" ||
+            str === "[object Arguments]" ||
+            str === "[object HTMLCollection]" ||
+            str === "[object NodeList]" ||
+            str === "[object DOMTokenList]")
+            return isFinite(obj.length);
+    } catch (e) {
+    }
+    return false;
+}
+
+/**
  * @constructor
  */
 var InjectedScript = function()
@@ -434,7 +458,7 @@
 
                 try {
                     nameProcessed[name] = true;
-                    var descriptor = nullifyObjectProto(Object.getOwnPropertyDescriptor(/** @type {!Object} */ (o), name));
+                    var descriptor = nullifyObjectProto(InjectedScriptHost.suppressWarningsAndCall(Object, Object.getOwnPropertyDescriptor, o, name));
                     if (descriptor) {
                         if (accessorPropertiesOnly && !("get" in descriptor || "set" in descriptor))
                             continue;
@@ -557,7 +581,10 @@
 
             return resolvedArg;
         } else if ("value" in callArgumentJson) {
-            return callArgumentJson.value;
+            var value = callArgumentJson.value;
+            if (callArgumentJson.type === "number" && typeof value !== "number")
+                value = Number(value);
+            return value;
         }
         return undefined;
     },
@@ -614,20 +641,21 @@
         // Surround the expression in with statements to inject our command line API so that
         // the window object properties still take more precedent than our API functions.
 
-        var injectScopeChain = scopeChain && scopeChain.length;
+        injectCommandLineAPI = injectCommandLineAPI && !("__commandLineAPI" in inspectedWindow);
+        var injectScopeChain = scopeChain && scopeChain.length && !("__scopeChainForEval" in inspectedWindow);
 
         try {
             var prefix = "";
             var suffix = "";
-            if (injectCommandLineAPI && inspectedWindow.console) {
-                inspectedWindow.console._commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
-                prefix = "with ((console && console._commandLineAPI) || { __proto__: null }) {";
+            if (injectCommandLineAPI) {
+                inspectedWindow.__commandLineAPI = new CommandLineAPI(this._commandLineAPIImpl, isEvalOnCallFrame ? object : null);
+                prefix = "with (__commandLineAPI || { __proto__: null }) {";
                 suffix = "}";
             }
-            if (injectScopeChain && inspectedWindow.console) {
-                inspectedWindow.console._scopeChainForEval = scopeChain;
+            if (injectScopeChain) {
+                inspectedWindow.__scopeChainForEval = scopeChain;
                 for (var i = 0; i < scopeChain.length; ++i) {
-                    prefix = "with ((console && console._scopeChainForEval[" + i + "]) || { __proto__: null }) {" + (suffix ? " " : "") + prefix;
+                    prefix = "with (__scopeChainForEval[" + i + "] || { __proto__: null }) {" + (suffix ? " " : "") + prefix;
                     if (suffix)
                         suffix += " }";
                     else
@@ -642,10 +670,10 @@
                 this._lastResult = result;
             return result;
         } finally {
-            if (injectCommandLineAPI && inspectedWindow.console)
-                delete inspectedWindow.console._commandLineAPI;
-            if (injectScopeChain && inspectedWindow.console)
-                delete inspectedWindow.console._scopeChainForEval;
+            if (injectCommandLineAPI)
+                delete inspectedWindow.__commandLineAPI;
+            if (injectScopeChain)
+                delete inspectedWindow.__scopeChainForEval;
         }
     },
 
@@ -892,14 +920,8 @@
         if (preciseType)
             return preciseType;
 
-        // FireBug's array detection.
-        try {
-            if (typeof obj.splice === "function" && isFinite(obj.length))
-                return "array";
-            if (Object.prototype.toString.call(obj) === "[object Arguments]" && isFinite(obj.length)) // arguments.
-                return "array";
-        } catch (e) {
-        }
+        if (isArrayLike(obj))
+            return "array";
 
         // If owning frame has navigated to somewhere else window properties will be undefined.
         return null;
@@ -988,8 +1010,19 @@
             this.subtype = "null";
 
         // Provide user-friendly number values.
-        if (this.type === "number")
+        if (this.type === "number") {
             this.description = toStringDescription(object);
+            // Override "value" property for values that can not be JSON-stringified.
+            switch (this.description) {
+            case "NaN":
+            case "Infinity":
+            case "-Infinity":
+            case "-0":
+                this.value = this.description;
+                break;
+            }
+        }
+
         return;
     }
 
diff --git a/Source/core/inspector/InspectorApplicationCacheAgent.cpp b/Source/core/inspector/InspectorApplicationCacheAgent.cpp
index 0e83a41..8994242 100644
--- a/Source/core/inspector/InspectorApplicationCacheAgent.cpp
+++ b/Source/core/inspector/InspectorApplicationCacheAgent.cpp
@@ -26,12 +26,12 @@
 #include "config.h"
 #include "core/inspector/InspectorApplicationCacheAgent.h"
 
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectorPageAgent.h"
 #include "core/inspector/InspectorState.h"
 #include "core/inspector/InstrumentingAgents.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
 #include "core/page/NetworkStateNotifier.h"
 #include "wtf/text/StringBuilder.h"
 
@@ -76,7 +76,7 @@
     networkStateChanged(networkStateNotifier().onLine());
 }
 
-void InspectorApplicationCacheAgent::updateApplicationCacheStatus(Frame* frame)
+void InspectorApplicationCacheAgent::updateApplicationCacheStatus(LocalFrame* frame)
 {
     DocumentLoader* documentLoader = frame->loader().documentLoader();
     if (!documentLoader)
@@ -99,8 +99,8 @@
 {
     result = TypeBuilder::Array<TypeBuilder::ApplicationCache::FrameWithManifest>::create();
 
-    Frame* mainFrame = m_pageAgent->mainFrame();
-    for (Frame* frame = mainFrame; frame; frame = frame->tree().traverseNext(mainFrame)) {
+    LocalFrame* mainFrame = m_pageAgent->mainFrame();
+    for (LocalFrame* frame = mainFrame; frame; frame = frame->tree().traverseNext(mainFrame)) {
         DocumentLoader* documentLoader = frame->loader().documentLoader();
         if (!documentLoader)
             continue;
@@ -120,7 +120,7 @@
 
 DocumentLoader* InspectorApplicationCacheAgent::assertFrameWithDocumentLoader(ErrorString* errorString, String frameId)
 {
-    Frame* frame = m_pageAgent->assertFrame(errorString, frameId);
+    LocalFrame* frame = m_pageAgent->assertFrame(errorString, frameId);
     if (!frame)
         return 0;
 
diff --git a/Source/core/inspector/InspectorApplicationCacheAgent.h b/Source/core/inspector/InspectorApplicationCacheAgent.h
index 2f22dec..15bf8c0 100644
--- a/Source/core/inspector/InspectorApplicationCacheAgent.h
+++ b/Source/core/inspector/InspectorApplicationCacheAgent.h
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class InspectorFrontend;
 class InspectorPageAgent;
 class InstrumentingAgents;
@@ -55,7 +55,7 @@
     virtual void restore() OVERRIDE;
 
     // InspectorInstrumentation API
-    void updateApplicationCacheStatus(Frame*);
+    void updateApplicationCacheStatus(LocalFrame*);
     void networkStateChanged(bool online);
 
     // ApplicationCache API for InspectorFrontend
diff --git a/Source/core/inspector/InspectorCSSAgent.cpp b/Source/core/inspector/InspectorCSSAgent.cpp
index c1767d7..82645d6 100644
--- a/Source/core/inspector/InspectorCSSAgent.cpp
+++ b/Source/core/inspector/InspectorCSSAgent.cpp
@@ -52,6 +52,7 @@
 #include "core/fetch/ResourceClient.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/StyleSheetResourceClient.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLHeadElement.h"
 #include "core/inspector/InspectorHistory.h"
 #include "core/inspector/InspectorPageAgent.h"
@@ -59,7 +60,6 @@
 #include "core/inspector/InspectorState.h"
 #include "core/inspector/InstrumentingAgents.h"
 #include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/rendering/InlineTextBox.h"
 #include "core/rendering/RenderObject.h"
@@ -428,7 +428,7 @@
 void InspectorCSSAgent::restore()
 {
     if (m_state->getBoolean(CSSAgentState::cssAgentEnabled))
-        wasEnabled(0);
+        wasEnabled(nullptr);
 }
 
 void InspectorCSSAgent::reset()
@@ -505,7 +505,7 @@
     m_state->setBoolean(CSSAgentState::cssAgentEnabled, false);
 }
 
-void InspectorCSSAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorCSSAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
 {
     if (loader->frame() == frame->page()->mainFrame()) {
         reset();
@@ -564,7 +564,7 @@
 
 void InspectorCSSAgent::updateActiveStyleSheetsForDocument(Document* document, StyleSheetsUpdateType styleSheetsUpdateType)
 {
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
     if (!frame)
         return;
     Vector<CSSStyleSheet*> newSheetsVector;
@@ -572,7 +572,7 @@
     updateActiveStyleSheets(frame, newSheetsVector, styleSheetsUpdateType);
 }
 
-void InspectorCSSAgent::updateActiveStyleSheets(Frame* frame, const Vector<CSSStyleSheet*>& allSheetsVector, StyleSheetsUpdateType styleSheetsUpdateType)
+void InspectorCSSAgent::updateActiveStyleSheets(LocalFrame* frame, const Vector<CSSStyleSheet*>& allSheetsVector, StyleSheetsUpdateType styleSheetsUpdateType)
 {
     bool isInitialFrontendLoad = styleSheetsUpdateType == InitialFrontendLoad;
 
@@ -627,7 +627,7 @@
         m_frameToCSSStyleSheets.remove(frame);
 }
 
-void InspectorCSSAgent::frameDetachedFromParent(Frame* frame)
+void InspectorCSSAgent::frameDetachedFromParent(LocalFrame* frame)
 {
     updateActiveStyleSheets(frame, Vector<CSSStyleSheet*>(), ExistingFrontendRefresh);
 }
@@ -683,14 +683,14 @@
     // Matched rules.
     StyleResolver& styleResolver = ownerDocument->ensureStyleResolver();
 
-    RefPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules);
+    RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, elementPseudoId, StyleResolver::AllCSSRules);
     matchedCSSRules = buildArrayForMatchedRuleList(matchedRules.get(), originalElement);
 
     // Pseudo elements.
     if (!elementPseudoId && (!includePseudo || *includePseudo)) {
         RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> > pseudoElements = TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches>::create();
         for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < AFTER_LAST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) {
-            RefPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules);
+            RefPtrWillBeRawPtr<CSSRuleList> matchedRules = styleResolver.pseudoCSSRulesForElement(element, pseudoId, StyleResolver::AllCSSRules);
             if (matchedRules && matchedRules->length()) {
                 RefPtr<TypeBuilder::CSS::PseudoIdMatches> matches = TypeBuilder::CSS::PseudoIdMatches::create()
                     .setPseudoId(static_cast<int>(pseudoId))
@@ -708,7 +708,7 @@
         Element* parentElement = element->parentElement();
         while (parentElement) {
             StyleResolver& parentStyleResolver = parentElement->ownerDocument()->ensureStyleResolver();
-            RefPtr<CSSRuleList> parentMatchedRules = parentStyleResolver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules);
+            RefPtrWillBeRawPtr<CSSRuleList> parentMatchedRules = parentStyleResolver.cssRulesForElement(parentElement, StyleResolver::AllCSSRules);
             RefPtr<TypeBuilder::CSS::InheritedStyleEntry> entry = TypeBuilder::CSS::InheritedStyleEntry::create()
                 .setMatchedCSSRules(buildArrayForMatchedRuleList(parentMatchedRules.get(), parentElement));
             if (parentElement->style() && parentElement->style()->length()) {
@@ -737,7 +737,7 @@
 
     inlineStyle = styleSheet->buildObjectForStyle(element->style());
     RefPtr<TypeBuilder::CSS::CSSStyle> attributes = buildObjectForAttributesStyle(element);
-    attributesStyle = attributes ? attributes.release() : 0;
+    attributesStyle = attributes ? attributes.release() : nullptr;
 }
 
 void InspectorCSSAgent::getComputedStyleForNode(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >& style)
@@ -815,24 +815,6 @@
     }
 }
 
-void InspectorCSSAgent::getStyleSheet(ErrorString* errorString, const String& styleSheetId, RefPtr<TypeBuilder::CSS::CSSStyleSheetBody>& styleSheetObject)
-{
-    InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
-    if (!inspectorStyleSheet)
-        return;
-
-    Document* doc = inspectorStyleSheet->pageStyleSheet() ? inspectorStyleSheet->pageStyleSheet()->ownerDocument() : 0;
-    if (!doc)
-        return;
-
-    RefPtr<TypeBuilder::CSS::CSSStyleSheetBody> result = TypeBuilder::CSS::CSSStyleSheetBody::create()
-        .setRules(buildArrayForRuleList(inspectorStyleSheet->pageStyleSheet()->rules().get()));
-
-    bool success = inspectorStyleSheet->fillObjectForStyleSheet(result);
-    if (success)
-        styleSheetObject = result;
-}
-
 void InspectorCSSAgent::getStyleSheetText(ErrorString* errorString, const String& styleSheetId, String* result)
 {
     InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
@@ -890,18 +872,35 @@
     *errorString = InspectorDOMAgent::toErrorString(exceptionState);
 }
 
-void InspectorCSSAgent::addRule(ErrorString* errorString, const int contextNodeId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
+void InspectorCSSAgent::createStyleSheet(ErrorString* errorString, const String& frameId, TypeBuilder::CSS::StyleSheetId* outStyleSheetId)
 {
-    Node* node = m_domAgent->assertNode(errorString, contextNodeId);
-    if (!node)
+    LocalFrame* frame = m_pageAgent->frameForId(frameId);
+    if (!frame) {
+        *errorString = "Frame not found";
         return;
+    }
 
-    InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(&node->document(), true);
+    Document* document = frame->document();
+    if (!document) {
+        *errorString = "Frame does not have a document";
+        return;
+    }
+
+    InspectorStyleSheet* inspectorStyleSheet = viaInspectorStyleSheet(document, true);
     if (!inspectorStyleSheet) {
         *errorString = "No target stylesheet found";
         return;
     }
 
+    *outStyleSheetId = inspectorStyleSheet->id();
+}
+
+void InspectorCSSAgent::addRule(ErrorString* errorString, const String& styleSheetId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result)
+{
+    InspectorStyleSheet* inspectorStyleSheet = assertStyleSheetForId(errorString, styleSheetId);
+    if (!inspectorStyleSheet)
+        return;
+
     TrackExceptionState exceptionState;
     OwnPtr<AddRuleAction> action = adoptPtr(new AddRuleAction(inspectorStyleSheet, selector));
     AddRuleAction* rawAction = action.get();
@@ -980,7 +979,7 @@
 PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > InspectorCSSAgent::buildMediaListChain(CSSRule* rule)
 {
     if (!rule)
-        return 0;
+        return nullptr;
     RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> > mediaArray = TypeBuilder::Array<TypeBuilder::CSS::CSSMedia>::create();
     bool hasItems = false;
     MediaList* mediaList;
@@ -1039,7 +1038,7 @@
             }
         }
     }
-    return hasItems ? mediaArray : 0;
+    return hasItems ? mediaArray : nullptr;
 }
 
 InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element)
@@ -1053,7 +1052,7 @@
         return 0;
 
     String newStyleSheetId = String::number(m_lastStyleSheetId++);
-    RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_pageAgent, m_resourceAgent, newStyleSheetId, element, TypeBuilder::CSS::StyleSheetOrigin::Regular, this);
+    RefPtr<InspectorStyleSheetForInlineStyle> inspectorStyleSheet = InspectorStyleSheetForInlineStyle::create(m_pageAgent, m_resourceAgent, newStyleSheetId, element, this);
     m_idToInspectorStyleSheet.set(newStyleSheetId, inspectorStyleSheet);
     m_nodeToInspectorStyleSheet.set(element, inspectorStyleSheet);
     return inspectorStyleSheet.get();
@@ -1085,8 +1084,8 @@
 
 void InspectorCSSAgent::collectAllDocumentStyleSheets(Document* document, Vector<CSSStyleSheet*>& result)
 {
-    const Vector<RefPtr<StyleSheet> > activeStyleSheets = document->styleEngine()->activeStyleSheetsForInspector();
-    for (Vector<RefPtr<StyleSheet> >::const_iterator it = activeStyleSheets.begin(); it != activeStyleSheets.end(); ++it) {
+    const WillBeHeapVector<RefPtrWillBeMember<StyleSheet> > activeStyleSheets = document->styleEngine()->activeStyleSheetsForInspector();
+    for (WillBeHeapVector<RefPtrWillBeMember<StyleSheet> >::const_iterator it = activeStyleSheets.begin(); it != activeStyleSheets.end(); ++it) {
         StyleSheet* styleSheet = (*it).get();
         if (styleSheet->isCSSStyleSheet())
             collectStyleSheets(toCSSStyleSheet(styleSheet), result);
@@ -1202,7 +1201,7 @@
 PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorCSSAgent::buildObjectForRule(CSSStyleRule* rule)
 {
     if (!rule)
-        return 0;
+        return nullptr;
 
     // CSSRules returned by StyleResolver::pseudoCSSRulesForElement lack parent pointers if they are coming from
     // user agent stylesheets. To work around this issue, we use CSSOM wrapper created by inspector.
@@ -1214,26 +1213,6 @@
     return bindStyleSheet(rule->parentStyleSheet())->buildObjectForRule(rule, buildMediaListChain(rule));
 }
 
-PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > InspectorCSSAgent::buildArrayForRuleList(CSSRuleList* ruleList)
-{
-    RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > result = TypeBuilder::Array<TypeBuilder::CSS::CSSRule>::create();
-    if (!ruleList)
-        return result.release();
-
-    RefPtr<CSSRuleList> refRuleList = ruleList;
-    CSSRuleVector rules;
-    InspectorStyleSheet::collectFlatRules(refRuleList, &rules);
-
-    for (unsigned i = 0, size = rules.size(); i < size; ++i) {
-        CSSStyleRule* styleRule = asCSSStyleRule(rules.at(i).get());
-        if (!styleRule)
-            continue;
-        result->addItem(buildObjectForRule(styleRule));
-    }
-
-    return result.release();
-}
-
 static inline bool matchesPseudoElement(const CSSSelector* selector, PseudoId elementPseudoId)
 {
     // According to http://www.w3.org/TR/css3-selectors/#pseudo-elements, "Only one pseudo-element may appear per selector."
@@ -1283,12 +1262,12 @@
 PassRefPtr<TypeBuilder::CSS::CSSStyle> InspectorCSSAgent::buildObjectForAttributesStyle(Element* element)
 {
     if (!element->isStyledElement())
-        return 0;
+        return nullptr;
 
     // FIXME: Ugliness below.
     StylePropertySet* attributeStyle = const_cast<StylePropertySet*>(element->presentationAttributeStyle());
     if (!attributeStyle)
-        return 0;
+        return nullptr;
 
     MutableStylePropertySet* mutableAttributeStyle = toMutableStylePropertySet(attributeStyle);
 
diff --git a/Source/core/inspector/InspectorCSSAgent.h b/Source/core/inspector/InspectorCSSAgent.h
index d213ba3..d104358 100644
--- a/Source/core/inspector/InspectorCSSAgent.h
+++ b/Source/core/inspector/InspectorCSSAgent.h
@@ -27,7 +27,7 @@
 
 #include "core/css/CSSSelector.h"
 #include "core/dom/SecurityContext.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/inspector/InspectorBaseAgent.h"
 #include "core/inspector/InspectorDOMAgent.h"
 #include "core/inspector/InspectorStyleSheet.h"
@@ -111,7 +111,7 @@
     virtual void enable(ErrorString*, PassRefPtr<EnableCallback>) OVERRIDE;
     virtual void disable(ErrorString*) OVERRIDE;
     void reset();
-    void didCommitLoad(Frame*, DocumentLoader*);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
     void mediaQueryResultChanged();
     void willMutateRules();
     void didMutateRules(CSSStyleSheet*);
@@ -120,18 +120,18 @@
 
 public:
     void activeStyleSheetsUpdated(Document*);
-    void frameDetachedFromParent(Frame*);
+    void frameDetachedFromParent(LocalFrame*);
 
     virtual void getComputedStyleForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSComputedStyleProperty> >&) OVERRIDE;
     virtual void getPlatformFontsForNode(ErrorString*, int nodeId, String* cssFamilyName, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PlatformFontUsage> >&) OVERRIDE;
     virtual void getInlineStylesForNode(ErrorString*, int nodeId, RefPtr<TypeBuilder::CSS::CSSStyle>& inlineStyle, RefPtr<TypeBuilder::CSS::CSSStyle>& attributes) OVERRIDE;
     virtual void getMatchedStylesForNode(ErrorString*, int nodeId, const bool* includePseudo, const bool* includeInherited, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> >& matchedCSSRules, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::PseudoIdMatches> >&, RefPtr<TypeBuilder::Array<TypeBuilder::CSS::InheritedStyleEntry> >& inheritedEntries) OVERRIDE;
-    virtual void getStyleSheet(ErrorString*, const String& styleSheetId, RefPtr<TypeBuilder::CSS::CSSStyleSheetBody>& result) OVERRIDE;
     virtual void getStyleSheetText(ErrorString*, const String& styleSheetId, String* result) OVERRIDE;
     virtual void setStyleSheetText(ErrorString*, const String& styleSheetId, const String& text) OVERRIDE;
     virtual void setPropertyText(ErrorString*, const RefPtr<JSONObject>& styleId, int propertyIndex, const String& text, bool overwrite, RefPtr<TypeBuilder::CSS::CSSStyle>& result) OVERRIDE;
     virtual void setRuleSelector(ErrorString*, const RefPtr<JSONObject>& ruleId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result) OVERRIDE;
-    virtual void addRule(ErrorString*, int contextNodeId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result) OVERRIDE;
+    virtual void createStyleSheet(ErrorString*, const String& frameId, TypeBuilder::CSS::StyleSheetId* outStyleSheetId) OVERRIDE;
+    virtual void addRule(ErrorString*, const String& styleSheetId, const String& selector, RefPtr<TypeBuilder::CSS::CSSRule>& result) OVERRIDE;
     virtual void forcePseudoState(ErrorString*, int nodeId, const RefPtr<JSONArray>& forcedPseudoClasses) OVERRIDE;
 
     PassRefPtr<TypeBuilder::CSS::CSSMedia> buildMediaObject(const MediaList*, MediaListSource, const String&, CSSStyleSheet*);
@@ -160,7 +160,7 @@
     void collectStyleSheets(CSSStyleSheet*, Vector<CSSStyleSheet*>&);
 
     void updateActiveStyleSheetsForDocument(Document*, StyleSheetsUpdateType);
-    void updateActiveStyleSheets(Frame*, const Vector<CSSStyleSheet*>&, StyleSheetsUpdateType);
+    void updateActiveStyleSheets(LocalFrame*, const Vector<CSSStyleSheet*>&, StyleSheetsUpdateType);
 
     void collectPlatformFontsForRenderer(RenderText*, HashCountedSet<String>*);
 
@@ -172,7 +172,6 @@
     bool styleSheetEditInProgress() const { return m_styleSheetsPendingMutation || m_styleDeclarationPendingMutation || m_isSettingStyleSheetText; }
 
     PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*);
-    PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSRule> > buildArrayForRuleList(CSSRuleList*);
     PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::RuleMatch> > buildArrayForMatchedRuleList(CSSRuleList*, Element*);
     PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForAttributesStyle(Element*);
 
@@ -195,7 +194,7 @@
 
     IdToInspectorStyleSheet m_idToInspectorStyleSheet;
     HashMap<CSSStyleSheet*, RefPtr<InspectorStyleSheet> > m_cssStyleSheetToInspectorStyleSheet;
-    HashMap<Frame*, OwnPtr<HashSet<CSSStyleSheet*> > > m_frameToCSSStyleSheets;
+    HashMap<LocalFrame*, OwnPtr<HashSet<CSSStyleSheet*> > > m_frameToCSSStyleSheets;
 
     NodeToInspectorStyleSheet m_nodeToInspectorStyleSheet;
     HashMap<RefPtr<Document>, RefPtr<InspectorStyleSheet> > m_documentToViaInspectorStyleSheet; // "via inspector" stylesheets
diff --git a/Source/core/inspector/InspectorCanvasAgent.cpp b/Source/core/inspector/InspectorCanvasAgent.cpp
index d4e8af3..8683d1e 100644
--- a/Source/core/inspector/InspectorCanvasAgent.cpp
+++ b/Source/core/inspector/InspectorCanvasAgent.cpp
@@ -31,7 +31,6 @@
 #include "config.h"
 #include "core/inspector/InspectorCanvasAgent.h"
 
-#include "HTMLNames.h"
 #include "bindings/v8/ScriptObject.h"
 #include "bindings/v8/ScriptProfiler.h"
 #include "core/html/HTMLCanvasElement.h"
@@ -44,7 +43,7 @@
 #include "core/inspector/InstrumentingAgents.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 using WebCore::TypeBuilder::Array;
 using WebCore::TypeBuilder::Canvas::ResourceId;
@@ -135,7 +134,7 @@
 
 void InspectorCanvasAgent::captureFrame(ErrorString* errorString, const FrameId* frameId, TraceLogId* traceLogId)
 {
-    Frame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
+    LocalFrame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
     if (!frame)
         return;
     InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, mainWorldScriptState(frame));
@@ -145,7 +144,7 @@
 
 void InspectorCanvasAgent::startCapturing(ErrorString* errorString, const FrameId* frameId, TraceLogId* traceLogId)
 {
-    Frame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
+    LocalFrame* frame = frameId ? m_pageAgent->assertFrame(errorString, *frameId) : m_pageAgent->mainFrame();
     if (!frame)
         return;
     InjectedScriptCanvasModule module = injectedScriptCanvasModule(errorString, mainWorldScriptState(frame));
@@ -213,7 +212,7 @@
     DOMWindow* domWindow = 0;
     if (scriptState)
         domWindow = scriptState->domWindow();
-    Frame* frame = domWindow ? domWindow->frame() : 0;
+    LocalFrame* frame = domWindow ? domWindow->frame() : 0;
     if (frame && !m_framesWithUninstrumentedCanvases.contains(frame))
         m_framesWithUninstrumentedCanvases.set(frame, false);
     String frameId = m_pageAgent->frameId(frame);
@@ -270,10 +269,11 @@
 
         virtual void visitNode(Node* node) OVERRIDE
         {
-            if (!node->hasTagName(HTMLNames::canvasTag) || !node->document().frame())
+            ASSERT(node);
+            if (!isHTMLCanvasElement(*node) || !node->document().frame())
                 return;
 
-            Frame* frame = node->document().frame();
+            LocalFrame* frame = node->document().frame();
             if (frame->page() != m_page)
                 return;
 
@@ -306,11 +306,11 @@
     return false;
 }
 
-void InspectorCanvasAgent::didCommitLoad(Frame*, DocumentLoader* loader)
+void InspectorCanvasAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader)
 {
     if (!m_enabled)
         return;
-    Frame* frame = loader->frame();
+    LocalFrame* frame = loader->frame();
     if (frame == m_pageAgent->mainFrame()) {
         for (FramesWithUninstrumentedCanvases::iterator it = m_framesWithUninstrumentedCanvases.begin(); it != m_framesWithUninstrumentedCanvases.end(); ++it)
             it->value = false;
@@ -328,7 +328,7 @@
     }
 }
 
-void InspectorCanvasAgent::frameDetachedFromParent(Frame* frame)
+void InspectorCanvasAgent::frameDetachedFromParent(LocalFrame* frame)
 {
     if (m_enabled)
         m_framesWithUninstrumentedCanvases.remove(frame);
diff --git a/Source/core/inspector/InspectorCanvasAgent.h b/Source/core/inspector/InspectorCanvasAgent.h
index bc7bfa3..c651139 100644
--- a/Source/core/inspector/InspectorCanvasAgent.h
+++ b/Source/core/inspector/InspectorCanvasAgent.h
@@ -42,7 +42,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class DocumentLoader;
 class InjectedScriptCanvasModule;
 class InjectedScriptManager;
@@ -64,8 +64,8 @@
     virtual void clearFrontend() OVERRIDE;
     virtual void restore() OVERRIDE;
 
-    void didCommitLoad(Frame*, DocumentLoader*);
-    void frameDetachedFromParent(Frame*);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
+    void frameDetachedFromParent(LocalFrame*);
     void didBeginFrame();
 
     // Called from InspectorCanvasInstrumentation.
@@ -101,7 +101,7 @@
     InspectorFrontend::Canvas* m_frontend;
     bool m_enabled;
     // Contains all frames with canvases, value is true only for frames that have an uninstrumented canvas.
-    typedef HashMap<Frame*, bool> FramesWithUninstrumentedCanvases;
+    typedef HashMap<LocalFrame*, bool> FramesWithUninstrumentedCanvases;
     FramesWithUninstrumentedCanvases m_framesWithUninstrumentedCanvases;
 };
 
diff --git a/Source/core/inspector/InspectorClient.cpp b/Source/core/inspector/InspectorClient.cpp
index bc0bcd7..28b5861 100644
--- a/Source/core/inspector/InspectorClient.cpp
+++ b/Source/core/inspector/InspectorClient.cpp
@@ -33,7 +33,7 @@
 
 #include "bindings/v8/ScriptController.h"
 #include "bindings/v8/ScriptSourceCode.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 
 namespace WebCore {
@@ -43,7 +43,7 @@
     if (!frontendPage)
         return false;
 
-    Frame* frame = frontendPage->mainFrame();
+    LocalFrame* frame = frontendPage->mainFrame();
     if (!frame)
         return false;
 
diff --git a/Source/core/inspector/InspectorClient.h b/Source/core/inspector/InspectorClient.h
index 4a69725..6126ee4 100644
--- a/Source/core/inspector/InspectorClient.h
+++ b/Source/core/inspector/InspectorClient.h
@@ -50,7 +50,8 @@
     typedef void (*TraceEventCallback)(char phase, const unsigned char*, const char* name, unsigned long long id,
         int numArgs, const char* const* argNames, const unsigned char* argTypes, const unsigned long long* argValues,
         unsigned char flags, double timestamp);
-    virtual void setTraceEventCallback(TraceEventCallback) { }
+    virtual void setTraceEventCallback(const String& categoryFilter, TraceEventCallback) { }
+    virtual void resetTraceEventCallback() { }
 
     virtual void startGPUEventsRecording() { }
     virtual void stopGPUEventsRecording() { }
diff --git a/Source/core/inspector/InspectorConsoleAgent.cpp b/Source/core/inspector/InspectorConsoleAgent.cpp
index a64d052..f5316b0 100644
--- a/Source/core/inspector/InspectorConsoleAgent.cpp
+++ b/Source/core/inspector/InspectorConsoleAgent.cpp
@@ -30,7 +30,7 @@
 #include "bindings/v8/ScriptController.h"
 #include "bindings/v8/ScriptObject.h"
 #include "bindings/v8/ScriptProfiler.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/ConsoleMessage.h"
 #include "core/inspector/InjectedScriptHost.h"
 #include "core/inspector/InjectedScriptManager.h"
@@ -259,7 +259,7 @@
     m_injectedScriptManager->discardInjectedScriptsFor(window);
 }
 
-void InspectorConsoleAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorConsoleAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
 {
     if (loader->frame() != frame->page()->mainFrame())
         return;
@@ -274,7 +274,7 @@
     }
 }
 
-void InspectorConsoleAgent::didReceiveResourceResponse(Frame*, unsigned long requestIdentifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+void InspectorConsoleAgent::didReceiveResourceResponse(LocalFrame*, unsigned long requestIdentifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
 {
     if (!loader)
         return;
diff --git a/Source/core/inspector/InspectorConsoleAgent.h b/Source/core/inspector/InspectorConsoleAgent.h
index 81c9b55..3273544 100644
--- a/Source/core/inspector/InspectorConsoleAgent.h
+++ b/Source/core/inspector/InspectorConsoleAgent.h
@@ -43,7 +43,7 @@
 class ConsoleMessage;
 class DocumentLoader;
 class DOMWindow;
-class Frame;
+class LocalFrame;
 class InspectorFrontend;
 class InjectedScriptManager;
 class InspectorTimelineAgent;
@@ -92,10 +92,10 @@
     void consoleCount(ScriptState*, PassRefPtr<ScriptArguments>);
 
     void frameWindowDiscarded(DOMWindow*);
-    void didCommitLoad(Frame*, DocumentLoader*);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
 
     void didFinishXHRLoading(XMLHttpRequest*, ThreadableLoaderClient*, unsigned long requestIdentifier, ScriptString, const AtomicString& method, const String& url, const String& sendURL, unsigned sendLineNumber);
-    void didReceiveResourceResponse(Frame*, unsigned long requestIdentifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+    void didReceiveResourceResponse(LocalFrame*, unsigned long requestIdentifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
     void didFailLoading(unsigned long requestIdentifier, const ResourceError&);
     void addProfileFinishedMessageToConsole(PassRefPtr<ScriptProfile>, unsigned lineNumber, const String& sourceURL);
     void addStartProfilingMessageToConsole(const String& title, unsigned lineNumber, const String& sourceURL);
diff --git a/Source/core/inspector/InspectorController.cpp b/Source/core/inspector/InspectorController.cpp
index b4364bf..f3f7838 100644
--- a/Source/core/inspector/InspectorController.cpp
+++ b/Source/core/inspector/InspectorController.cpp
@@ -74,6 +74,7 @@
     , m_injectedScriptManager(InjectedScriptManager::createForPage())
     , m_state(adoptPtr(new InspectorCompositeState(inspectorClient)))
     , m_overlay(InspectorOverlay::create(page, inspectorClient))
+    , m_layerTreeAgent(0)
     , m_page(page)
     , m_inspectorClient(inspectorClient)
     , m_agents(m_instrumentingAgents.get(), m_state.get())
@@ -93,8 +94,13 @@
     m_domAgent = domAgentPtr.get();
     m_agents.append(domAgentPtr.release());
 
-    OwnPtr<InspectorTimelineAgent> timelineAgentPtr(InspectorTimelineAgent::create(m_pageAgent, m_domAgent, overlay,
-        InspectorTimelineAgent::PageInspector, inspectorClient));
+
+    OwnPtr<InspectorLayerTreeAgent> layerTreeAgentPtr(InspectorLayerTreeAgent::create(m_domAgent, m_page));
+    m_layerTreeAgent = layerTreeAgentPtr.get();
+    m_agents.append(layerTreeAgentPtr.release());
+
+    OwnPtr<InspectorTimelineAgent> timelineAgentPtr(InspectorTimelineAgent::create(m_pageAgent, m_domAgent, m_layerTreeAgent,
+        overlay, InspectorTimelineAgent::PageInspector, inspectorClient));
     m_timelineAgent = timelineAgentPtr.get();
     m_agents.append(timelineAgentPtr.release());
 
@@ -114,7 +120,6 @@
 {
     m_instrumentingAgents->reset();
     m_agents.discardAgents();
-    ASSERT(!m_inspectorClient);
 }
 
 PassOwnPtr<InspectorController> InspectorController::create(Page* page, InspectorClient* client)
@@ -168,8 +173,6 @@
     m_agents.append(InspectorCanvasAgent::create(m_pageAgent, injectedScriptManager));
 
     m_agents.append(InspectorInputAgent::create(m_page, m_inspectorClient));
-
-    m_agents.append(InspectorLayerTreeAgent::create(m_domAgent, m_page));
 }
 
 void InspectorController::inspectedPageDestroyed()
@@ -178,6 +181,7 @@
     m_injectedScriptManager->disconnect();
     m_inspectorClient = 0;
     m_page = 0;
+    m_instrumentingAgents->reset();
 }
 
 void InspectorController::registerModuleAgent(PassOwnPtr<InspectorAgent> agent)
@@ -191,7 +195,7 @@
     m_inspectorFrontendClient = inspectorFrontendClient;
 }
 
-void InspectorController::didClearWindowObjectInMainWorld(Frame* frame)
+void InspectorController::didClearWindowObjectInMainWorld(LocalFrame* frame)
 {
     // If the page is supposed to serve as InspectorFrontend notify inspector frontend
     // client that it's cleared so that the client can expose inspector bindings.
@@ -245,7 +249,7 @@
 {
     if (!m_inspectorFrontend)
         return;
-    InspectorFrontendChannel* frontendChannel = m_inspectorFrontend->inspector()->getInspectorFrontendChannel();
+    InspectorFrontendChannel* frontendChannel = m_inspectorFrontend->channel();
     disconnectFrontend();
     connectFrontend(frontendChannel);
 }
@@ -288,8 +292,6 @@
 
 void InspectorController::drawHighlight(GraphicsContext& context) const
 {
-    // https://code.google.com/p/chromium/issues/detail?id=343757
-    DisableCompositingQueryAsserts disabler;
     m_overlay->paint(context);
 }
 
@@ -305,7 +307,7 @@
     Document* document = node->ownerDocument();
     if (!document)
         return;
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
     if (!frame)
         return;
 
@@ -340,7 +342,7 @@
     return m_overlay->highlightedNode();
 }
 
-bool InspectorController::handleGestureEvent(Frame* frame, const PlatformGestureEvent& event)
+bool InspectorController::handleGestureEvent(LocalFrame* frame, const PlatformGestureEvent& event)
 {
     // Overlay should not consume events.
     m_overlay->handleGestureEvent(event);
@@ -349,7 +351,7 @@
     return false;
 }
 
-bool InspectorController::handleMouseEvent(Frame* frame, const PlatformMouseEvent& event)
+bool InspectorController::handleMouseEvent(LocalFrame* frame, const PlatformMouseEvent& event)
 {
     // Overlay should not consume events.
     m_overlay->handleMouseEvent(event);
@@ -366,7 +368,7 @@
     return false;
 }
 
-bool InspectorController::handleTouchEvent(Frame* frame, const PlatformTouchEvent& event)
+bool InspectorController::handleTouchEvent(LocalFrame* frame, const PlatformTouchEvent& event)
 {
     // Overlay should not consume events.
     m_overlay->handleTouchEvent(event);
@@ -375,7 +377,7 @@
     return false;
 }
 
-bool InspectorController::handleKeyboardEvent(Frame* frame, const PlatformKeyboardEvent& event)
+bool InspectorController::handleKeyboardEvent(LocalFrame* frame, const PlatformKeyboardEvent& event)
 {
     // Overlay should not consume events.
     m_overlay->handleKeyboardEvent(event);
@@ -471,4 +473,16 @@
         pageAgent->scriptsEnabled(enabled);
 }
 
+void InspectorController::willAddPageOverlay(const GraphicsLayer* layer)
+{
+    if (m_layerTreeAgent)
+        m_layerTreeAgent->willAddPageOverlay(layer);
+}
+
+void InspectorController::didRemovePageOverlay(const GraphicsLayer* layer)
+{
+    if (m_layerTreeAgent)
+        m_layerTreeAgent->didRemovePageOverlay(layer);
+}
+
 } // namespace WebCore
diff --git a/Source/core/inspector/InspectorController.h b/Source/core/inspector/InspectorController.h
index 9540292..701e883 100644
--- a/Source/core/inspector/InspectorController.h
+++ b/Source/core/inspector/InspectorController.h
@@ -41,8 +41,9 @@
 namespace WebCore {
 
 class DOMWrapperWorld;
-class Frame;
+class LocalFrame;
 class GraphicsContext;
+class GraphicsLayer;
 class InjectedScriptManager;
 class InspectorBackendDispatcher;
 class InspectorAgent;
@@ -51,6 +52,7 @@
 class InspectorFrontend;
 class InspectorFrontendChannel;
 class InspectorFrontendClient;
+class InspectorLayerTreeAgent;
 class InspectorPageAgent;
 class InspectorTimelineAgent;
 class InspectorOverlay;
@@ -83,7 +85,7 @@
     void registerModuleAgent(PassOwnPtr<InspectorAgent>);
 
     void setInspectorFrontendClient(PassOwnPtr<InspectorFrontendClient>);
-    void didClearWindowObjectInMainWorld(Frame*);
+    void didClearWindowObjectInMainWorld(LocalFrame*);
     void setInjectedScriptForOrigin(const String& origin, const String& source);
 
     void dispatchMessageFromFrontend(const String& message);
@@ -102,10 +104,10 @@
     void hideHighlight();
     Node* highlightedNode() const;
 
-    bool handleGestureEvent(Frame*, const PlatformGestureEvent&);
-    bool handleMouseEvent(Frame*, const PlatformMouseEvent&);
-    bool handleTouchEvent(Frame*, const PlatformTouchEvent&);
-    bool handleKeyboardEvent(Frame*, const PlatformKeyboardEvent&);
+    bool handleGestureEvent(LocalFrame*, const PlatformGestureEvent&);
+    bool handleMouseEvent(LocalFrame*, const PlatformMouseEvent&);
+    bool handleTouchEvent(LocalFrame*, const PlatformTouchEvent&);
+    bool handleKeyboardEvent(LocalFrame*, const PlatformKeyboardEvent&);
 
     void requestPageScaleFactor(float scale, const IntPoint& origin);
     bool deviceEmulationEnabled();
@@ -130,6 +132,8 @@
 
     void scriptsEnabled(bool);
 
+    void willAddPageOverlay(const GraphicsLayer*);
+    void didRemovePageOverlay(const GraphicsLayer*);
 private:
     InspectorController(Page*, InspectorClient*);
 
@@ -145,6 +149,7 @@
     InspectorDOMAgent* m_domAgent;
     InspectorPageAgent* m_pageAgent;
     InspectorTimelineAgent* m_timelineAgent;
+    InspectorLayerTreeAgent* m_layerTreeAgent;
 
     RefPtr<InspectorBackendDispatcher> m_inspectorBackendDispatcher;
     OwnPtr<InspectorFrontendClient> m_inspectorFrontendClient;
diff --git a/Source/core/inspector/InspectorDOMAgent.cpp b/Source/core/inspector/InspectorDOMAgent.cpp
index 4dd5f42..cb1d0af 100644
--- a/Source/core/inspector/InspectorDOMAgent.cpp
+++ b/Source/core/inspector/InspectorDOMAgent.cpp
@@ -31,7 +31,6 @@
 #include "config.h"
 #include "core/inspector/InspectorDOMAgent.h"
 
-#include "HTMLNames.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ScriptEventListener.h"
 #include "core/dom/Attr.h"
@@ -54,11 +53,12 @@
 #include "core/editing/markup.h"
 #include "core/fileapi/File.h"
 #include "core/fileapi/FileList.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLImportChild.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLLinkElement.h"
 #include "core/html/HTMLTemplateElement.h"
+#include "core/html/imports/HTMLImportChild.h"
 #include "core/inspector/DOMEditor.h"
 #include "core/inspector/DOMPatchSupport.h"
 #include "core/inspector/IdentifiersFactory.h"
@@ -68,7 +68,6 @@
 #include "core/inspector/InspectorState.h"
 #include "core/inspector/InstrumentingAgents.h"
 #include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
 #include "core/page/FrameTree.h"
 #include "core/page/Page.h"
 #include "core/rendering/HitTestResult.h"
@@ -147,7 +146,7 @@
     return true;
 }
 
-static Node* hoveredNodeForPoint(Frame* frame, const IntPoint& point, bool ignorePointerEventsNone)
+static Node* hoveredNodeForPoint(LocalFrame* frame, const IntPoint& point, bool ignorePointerEventsNone)
 {
     HitTestRequest::HitTestRequestType hitType = HitTestRequest::Move | HitTestRequest::ReadOnly | HitTestRequest::AllowChildFrameContent;
     if (ignorePointerEventsNone)
@@ -161,17 +160,17 @@
     return node;
 }
 
-static Node* hoveredNodeForEvent(Frame* frame, const PlatformGestureEvent& event, bool ignorePointerEventsNone)
+static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformGestureEvent& event, bool ignorePointerEventsNone)
 {
     return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
 }
 
-static Node* hoveredNodeForEvent(Frame* frame, const PlatformMouseEvent& event, bool ignorePointerEventsNone)
+static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformMouseEvent& event, bool ignorePointerEventsNone)
 {
     return hoveredNodeForPoint(frame, event.position(), ignorePointerEventsNone);
 }
 
-static Node* hoveredNodeForEvent(Frame* frame, const PlatformTouchEvent& event, bool ignorePointerEventsNone)
+static Node* hoveredNodeForEvent(LocalFrame* frame, const PlatformTouchEvent& event, bool ignorePointerEventsNone)
 {
     const Vector<PlatformTouchPoint>& points = event.touchPoints();
     if (!points.size())
@@ -203,7 +202,7 @@
 {
     m_elements.add(element);
     if (!m_timer.isActive())
-        m_timer.startOneShot(0);
+        m_timer.startOneShot(0, FROM_HERE);
 }
 
 void RevalidateStyleAttributeTask::onTimer(Timer<RevalidateStyleAttributeTask>*)
@@ -220,7 +219,7 @@
 String InspectorDOMAgent::toErrorString(ExceptionState& exceptionState)
 {
     if (exceptionState.hadException())
-        return DOMException::getErrorName(exceptionState.code());
+        return DOMException::getErrorName(exceptionState.code()) + " " + exceptionState.message();
     return "";
 }
 
@@ -275,14 +274,14 @@
 void InspectorDOMAgent::restore()
 {
     // Reset document to avoid early return from setDocument.
-    m_document = 0;
+    m_document = nullptr;
     setDocument(m_pageAgent->mainFrame()->document());
 }
 
 Vector<Document*> InspectorDOMAgent::documents()
 {
     Vector<Document*> result;
-    for (Frame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = m_document->frame(); frame; frame = frame->tree().traverseNext()) {
         Document* document = frame->document();
         if (!document)
             continue;
@@ -295,7 +294,7 @@
 {
     discardFrontendBindings();
     discardBackendBindings();
-    m_document = 0;
+    m_document = nullptr;
 }
 
 void InspectorDOMAgent::setDOMListener(DOMListener* listener)
@@ -363,10 +362,10 @@
         if (element->pseudoElement(AFTER))
             unbind(element->pseudoElement(AFTER), nodesMap);
 
-        if (element->hasTagName(HTMLNames::linkTag)) {
-            HTMLLinkElement* linkElement = toHTMLLinkElement(element);
-            if (linkElement->isImport() && linkElement->import())
-                unbind(linkElement->import(), nodesMap);
+        if (isHTMLLinkElement(*element)) {
+            HTMLLinkElement& linkElement = toHTMLLinkElement(*element);
+            if (linkElement.isImport() && linkElement.import())
+                unbind(linkElement.import(), nodesMap);
         }
     }
 
@@ -384,6 +383,8 @@
             child = innerNextSibling(child);
         }
     }
+    if (nodesMap == &m_documentNodeToIdMap)
+        m_cachedChildCount.remove(id);
 }
 
 Node* InspectorDOMAgent::assertNode(ErrorString* errorString, int nodeId)
@@ -429,8 +430,17 @@
         return 0;
 
     if (node->isInShadowTree()) {
-        *errorString = "Cannot edit nodes from shadow trees";
-        return 0;
+        if (node->isShadowRoot()) {
+            *errorString = "Cannot edit shadow roots";
+            return 0;
+        }
+        Node* candidate = node;
+        while (candidate && !candidate->isShadowRoot())
+            candidate = candidate->parentElementOrShadowRoot();
+        if (!candidate || (candidate->isShadowRoot() && toShadowRoot(candidate)->type() == ShadowRoot::UserAgentShadowRoot)) {
+            *errorString = "Cannot edit nodes from user-agent shadow trees";
+            return 0;
+        }
     }
 
     if (node->isPseudoElement()) {
@@ -510,6 +520,7 @@
     m_idToNode.clear();
     releaseDanglingNodes();
     m_childrenRequested.clear();
+    m_cachedChildCount.clear();
     if (m_revalidateStyleAttrTask)
         m_revalidateStyleAttrTask->reset();
 }
@@ -724,12 +735,12 @@
     unsigned numAttrs = parsedElement->attributeCount();
     for (unsigned i = 0; i < numAttrs; ++i) {
         // Add attribute pair
-        const Attribute* attribute = parsedElement->attributeItem(i);
-        String attributeName = attribute->name().toString();
+        const Attribute& attribute = parsedElement->attributeItem(i);
+        String attributeName = attribute.name().toString();
         if (shouldIgnoreCase)
             attributeName = attributeName.lower();
         foundOriginalAttribute |= name && attributeName == caseAdjustedName;
-        if (!m_domEditor->setAttribute(element, attributeName, attribute->value(), errorString))
+        if (!m_domEditor->setAttribute(element, attributeName, attribute.value(), errorString))
             return;
     }
 
@@ -984,14 +995,14 @@
                 unsigned numAttrs = element->attributeCount();
                 for (unsigned i = 0; i < numAttrs; ++i) {
                     // Add attribute pair
-                    const Attribute* attribute = element->attributeItem(i);
-                    if (attribute->localName().find(whitespaceTrimmedQuery, 0, false) != kNotFound) {
+                    const Attribute& attribute = element->attributeItem(i);
+                    if (attribute.localName().find(whitespaceTrimmedQuery, 0, false) != kNotFound) {
                         resultCollector.add(node);
                         break;
                     }
-                    size_t foundPosition = attribute->value().find(attributeQuery, 0, false);
+                    size_t foundPosition = attribute.value().find(attributeQuery, 0, false);
                     if (foundPosition != kNotFound) {
-                        if (!exactAttributeMatch || (!foundPosition && attribute->value().length() == attributeQuery.length())) {
+                        if (!exactAttributeMatch || (!foundPosition && attribute.value().length() == attributeQuery.length())) {
                             resultCollector.add(node);
                             break;
                         }
@@ -1007,8 +1018,9 @@
         // XPath evaluation
         for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
             Document* document = *it;
+            ASSERT(document);
             TrackExceptionState exceptionState;
-            RefPtr<XPathResult> result = DocumentXPathEvaluator::evaluate(document, whitespaceTrimmedQuery, document, 0, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, 0, exceptionState);
+            RefPtrWillBeRawPtr<XPathResult> result = DocumentXPathEvaluator::evaluate(*document, whitespaceTrimmedQuery, document, nullptr, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, 0, exceptionState);
             if (exceptionState.hadException() || !result)
                 continue;
 
@@ -1083,7 +1095,7 @@
     return false;
 }
 
-bool InspectorDOMAgent::handleGestureEvent(Frame* frame, const PlatformGestureEvent& event)
+bool InspectorDOMAgent::handleGestureEvent(LocalFrame* frame, const PlatformGestureEvent& event)
 {
     if (m_searchingForNode == NotSearching || event.type() != PlatformEvent::GestureTap)
         return false;
@@ -1096,7 +1108,7 @@
     return false;
 }
 
-bool InspectorDOMAgent::handleTouchEvent(Frame* frame, const PlatformTouchEvent& event)
+bool InspectorDOMAgent::handleTouchEvent(LocalFrame* frame, const PlatformTouchEvent& event)
 {
     if (m_searchingForNode == NotSearching)
         return false;
@@ -1123,7 +1135,7 @@
         m_frontend->inspectNodeRequested(nodeId);
 }
 
-void InspectorDOMAgent::handleMouseMove(Frame* frame, const PlatformMouseEvent& event)
+void InspectorDOMAgent::handleMouseMove(LocalFrame* frame, const PlatformMouseEvent& event)
 {
     if (m_searchingForNode == NotSearching)
         return;
@@ -1242,7 +1254,7 @@
     const RefPtr<JSONObject>* color,
     const RefPtr<JSONObject>* outlineColor)
 {
-    Frame* frame = m_pageAgent->frameForId(frameId);
+    LocalFrame* frame = m_pageAgent->frameForId(frameId);
     if (frame && frame->ownerElement()) {
         OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
         highlightConfig->showInfo = true; // Always show tooltips for frames.
@@ -1322,12 +1334,12 @@
     Node* node = assertNode(errorString, nodeId);
     if (!node)
         return;
-    if (!node->hasTagName(inputTag) || !toHTMLInputElement(node)->isFileUpload()) {
+    if (!isHTMLInputElement(*node) || !toHTMLInputElement(*node).isFileUpload()) {
         *errorString = "Node is not a file input element";
         return;
     }
 
-    RefPtr<FileList> fileList = FileList::create();
+    RefPtrWillBeRawPtr<FileList> fileList = FileList::create();
     for (JSONArray::const_iterator iter = files->begin(); iter != files->end(); ++iter) {
         String path;
         if (!(*iter)->asString(&path)) {
@@ -1367,7 +1379,7 @@
     }
 
     RenderObject* renderer = node->renderer();
-    Frame* frame = node->document().frame();
+    LocalFrame* frame = node->document().frame();
     FrameView* view = frame->view();
 
     IntRect boundingBox = pixelSnappedIntRect(view->contentsToRootView(renderer->absoluteBoundingBoxRect()));
@@ -1496,7 +1508,7 @@
 
         if (node->isFrameOwnerElement()) {
             HTMLFrameOwnerElement* frameOwner = toHTMLFrameOwnerElement(node);
-            if (Frame* frame = frameOwner->contentFrame())
+            if (LocalFrame* frame = frameOwner->contentFrame())
                 value->setFrameId(m_pageAgent->frameId(frame));
             if (Document* doc = frameOwner->contentDocument())
                 value->setContentDocument(buildObjectForNode(doc, 0, nodesMap));
@@ -1511,15 +1523,15 @@
             forcePushChildren = true;
         }
 
-        if (element->hasTagName(linkTag)) {
-            HTMLLinkElement* linkElement = toHTMLLinkElement(element);
-            if (linkElement->isImport() && linkElement->import() && innerParentNode(linkElement->import()) == linkElement)
-                value->setImportedDocument(buildObjectForNode(linkElement->import(), 0, nodesMap));
+        if (isHTMLLinkElement(*element)) {
+            HTMLLinkElement& linkElement = toHTMLLinkElement(*element);
+            if (linkElement.isImport() && linkElement.import() && innerParentNode(linkElement.import()) == linkElement)
+                value->setImportedDocument(buildObjectForNode(linkElement.import(), 0, nodesMap));
             forcePushChildren = true;
         }
 
-        if (element->hasTagName(templateTag)) {
-            value->setTemplateContent(buildObjectForNode(toHTMLTemplateElement(element)->content(), 0, nodesMap));
+        if (isHTMLTemplateElement(*element)) {
+            value->setTemplateContent(buildObjectForNode(toHTMLTemplateElement(*element).content(), 0, nodesMap));
             forcePushChildren = true;
         }
 
@@ -1560,6 +1572,8 @@
     if (node->isContainerNode()) {
         int nodeCount = innerChildNodeCount(node);
         value->setChildNodeCount(nodeCount);
+        if (nodesMap == &m_documentNodeToIdMap)
+            m_cachedChildCount.set(id, nodeCount);
         if (forcePushChildren && !depth)
             depth = 1;
         RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, depth, nodesMap);
@@ -1579,9 +1593,9 @@
     unsigned numAttrs = element->attributeCount();
     for (unsigned i = 0; i < numAttrs; ++i) {
         // Add attribute pair
-        const Attribute* attribute = element->attributeItem(i);
-        attributesValue->addItem(attribute->name().toString());
-        attributesValue->addItem(attribute->value());
+        const Attribute& attribute = element->attributeItem(i);
+        attributesValue->addItem(attribute.name().toString());
+        attributesValue->addItem(attribute.value());
     }
     return attributesValue.release();
 }
@@ -1617,7 +1631,7 @@
     String scriptId;
     int lineNumber;
     if (!eventListenerHandlerLocation(&node->document(), eventListener.get(), sourceName, scriptId, lineNumber))
-        return 0;
+        return nullptr;
 
     Document& document = node->document();
     RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
@@ -1633,7 +1647,7 @@
     if (objectGroupId) {
         ScriptValue functionValue = eventListenerHandler(&document, eventListener.get());
         if (!functionValue.hasNoValue()) {
-            Frame* frame = document.frame();
+            LocalFrame* frame = document.frame();
             if (frame) {
                 ScriptState* scriptState = eventListenerHandlerScriptState(frame, eventListener.get());
                 if (scriptState) {
@@ -1654,7 +1668,7 @@
 PassRefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > InspectorDOMAgent::buildArrayForPseudoElements(Element* element, NodeToIdMap* nodesMap)
 {
     if (!element->pseudoElement(BEFORE) && !element->pseudoElement(AFTER))
-        return 0;
+        return nullptr;
 
     RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > pseudoElements = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
     if (element->pseudoElement(BEFORE))
@@ -1717,7 +1731,7 @@
     return node && node->nodeType() == Node::TEXT_NODE && node->nodeValue().stripWhiteSpace().length() == 0;
 }
 
-void InspectorDOMAgent::domContentLoadedEventFired(Frame* frame)
+void InspectorDOMAgent::domContentLoadedEventFired(LocalFrame* frame)
 {
     if (!frame->isMainFrame())
         return;
@@ -1728,7 +1742,7 @@
         m_frontend->documentUpdated();
 }
 
-void InspectorDOMAgent::invalidateFrameOwnerElement(Frame* frame)
+void InspectorDOMAgent::invalidateFrameOwnerElement(LocalFrame* frame)
 {
     Element* frameOwner = frame->document()->ownerElement();
     if (!frameOwner)
@@ -1749,12 +1763,12 @@
     m_frontend->childNodeInserted(parentId, prevId, value.release());
 }
 
-void InspectorDOMAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorDOMAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
 {
     // FIXME: If "frame" is always guarenteed to be in the same Page as loader->frame()
     // then all we need to check here is loader->frame()->isMainFrame()
     // and we don't need "frame" at all.
-    Frame* mainFrame = frame->page()->mainFrame();
+    LocalFrame* mainFrame = frame->page()->mainFrame();
     if (loader->frame() != mainFrame) {
         invalidateFrameOwnerElement(loader->frame());
         return;
@@ -1774,15 +1788,16 @@
     ContainerNode* parent = node->parentNode();
     if (!parent)
         return;
-
     int parentId = m_documentNodeToIdMap.get(parent);
     // Return if parent is not mapped yet.
     if (!parentId)
         return;
 
     if (!m_childrenRequested.contains(parentId)) {
-        // No children are mapped yet -> only notify on changes of hasChildren.
-        m_frontend->childNodeCountUpdated(parentId, innerChildNodeCount(parent));
+        // No children are mapped yet -> only notify on changes of child count.
+        int count = m_cachedChildCount.get(parentId) + 1;
+        m_cachedChildCount.set(parentId, count);
+        m_frontend->childNodeCountUpdated(parentId, count);
     } else {
         // Children have been requested -> return value of a new child.
         Node* prevSibling = innerPreviousSibling(node);
@@ -1806,11 +1821,13 @@
     int parentId = m_documentNodeToIdMap.get(parent);
 
     if (!m_childrenRequested.contains(parentId)) {
-        // No children are mapped yet -> only notify on changes of hasChildren.
-        if (innerChildNodeCount(parent) == 1)
-            m_frontend->childNodeCountUpdated(parentId, 0);
-    } else
+        // No children are mapped yet -> only notify on changes of child count.
+        int count = m_cachedChildCount.get(parentId) - 1;
+        m_cachedChildCount.set(parentId, count);
+        m_frontend->childNodeCountUpdated(parentId, count);
+    } else {
         m_frontend->childNodeRemoved(parentId, m_documentNodeToIdMap.get(node));
+    }
     unbind(node, &m_documentNodeToIdMap);
 }
 
@@ -1914,7 +1931,7 @@
         m_frontend->shadowRootPopped(hostId, rootId);
 }
 
-void InspectorDOMAgent::frameDocumentUpdated(Frame* frame)
+void InspectorDOMAgent::frameDocumentUpdated(LocalFrame* frame)
 {
     Document* document = frame->document();
     if (!document)
@@ -1998,20 +2015,25 @@
         *errorString = "No node with given path found";
 }
 
-void InspectorDOMAgent::pushNodeByBackendIdToFrontend(ErrorString* errorString, BackendNodeId backendNodeId, int* nodeId)
+void InspectorDOMAgent::pushNodesByBackendIdsToFrontend(ErrorString* errorString, const RefPtr<JSONArray>& backendNodeIds, RefPtr<TypeBuilder::Array<int> >& result)
 {
-    if (!m_backendIdToNode.contains(backendNodeId)) {
-        *errorString = "No node with given backend id found";
-        return;
-    }
+    result = TypeBuilder::Array<int>::create();
+    for (JSONArray::const_iterator it = backendNodeIds->begin(); it != backendNodeIds->end(); ++it) {
+        BackendNodeId backendNodeId;
 
-    Node* node = m_backendIdToNode.get(backendNodeId).first;
-    String nodeGroup = m_backendIdToNode.get(backendNodeId).second;
-    *nodeId = pushNodePathToFrontend(node);
+        if (!(*it)->asNumber(&backendNodeId)) {
+            *errorString = "Invalid argument type";
+            return;
+        }
 
-    if (nodeGroup == "") {
-        m_backendIdToNode.remove(backendNodeId);
-        m_nodeGroupToBackendIdMap.find(nodeGroup)->value.remove(node);
+        BackendIdToNodeMap::iterator backendIdToNodeIterator = m_backendIdToNode.find(backendNodeId);
+        if (backendIdToNodeIterator == m_backendIdToNode.end()) {
+            *errorString = "Node not found";
+            return;
+        }
+
+        Node* node = backendIdToNodeIterator->value.first;
+        result->addItem(pushNodePathToFrontend(node));
     }
 }
 
@@ -2034,13 +2056,13 @@
 PassRefPtr<TypeBuilder::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
 {
     Document* document = node->isDocumentNode() ? &node->document() : node->ownerDocument();
-    Frame* frame = document ? document->frame() : 0;
+    LocalFrame* frame = document ? document->frame() : 0;
     if (!frame)
-        return 0;
+        return nullptr;
 
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldScriptState(frame));
     if (injectedScript.hasNoValue())
-        return 0;
+        return nullptr;
 
     return injectedScript.wrapNode(node, objectGroup);
 }
diff --git a/Source/core/inspector/InspectorDOMAgent.h b/Source/core/inspector/InspectorDOMAgent.h
index a5cefac..9f726ba 100644
--- a/Source/core/inspector/InspectorDOMAgent.h
+++ b/Source/core/inspector/InspectorDOMAgent.h
@@ -134,7 +134,7 @@
     virtual void setInspectModeEnabled(ErrorString*, bool enabled, const bool* inspectShadowDOM, const RefPtr<JSONObject>* highlightConfig) OVERRIDE;
     virtual void requestNode(ErrorString*, const String& objectId, int* nodeId) OVERRIDE;
     virtual void pushNodeByPathToFrontend(ErrorString*, const String& path, int* nodeId) OVERRIDE;
-    virtual void pushNodeByBackendIdToFrontend(ErrorString*, BackendNodeId, int* nodeId) OVERRIDE;
+    virtual void pushNodesByBackendIdsToFrontend(ErrorString*, const RefPtr<JSONArray>& nodeIds, RefPtr<TypeBuilder::Array<int> >&) OVERRIDE;
     virtual void releaseBackendNodeIds(ErrorString*, const String& nodeGroup) OVERRIDE;
     virtual void hideHighlight(ErrorString*) OVERRIDE;
     virtual void highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<JSONObject>* color, const RefPtr<JSONObject>* outlineColor) OVERRIDE;
@@ -158,8 +158,8 @@
     void setDocument(Document*);
     void releaseDanglingNodes();
 
-    void domContentLoadedEventFired(Frame*);
-    void didCommitLoad(Frame*, DocumentLoader*);
+    void domContentLoadedEventFired(LocalFrame*);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
 
     void didInsertDOMNode(Node*);
     void willRemoveDOMNode(Node*);
@@ -171,7 +171,7 @@
     void didInvalidateStyleAttr(Node*);
     void didPushShadowRoot(Element* host, ShadowRoot*);
     void willPopShadowRoot(Element* host, ShadowRoot*);
-    void frameDocumentUpdated(Frame*);
+    void frameDocumentUpdated(LocalFrame*);
     void pseudoElementCreated(PseudoElement*);
     void pseudoElementDestroyed(PseudoElement*);
 
@@ -185,9 +185,9 @@
 
     PassRefPtr<TypeBuilder::Runtime::RemoteObject> resolveNode(Node*, const String& objectGroup);
     bool handleMousePress();
-    bool handleGestureEvent(Frame*, const PlatformGestureEvent&);
-    bool handleTouchEvent(Frame*, const PlatformTouchEvent&);
-    void handleMouseMove(Frame*, const PlatformMouseEvent&);
+    bool handleGestureEvent(LocalFrame*, const PlatformGestureEvent&);
+    bool handleTouchEvent(LocalFrame*, const PlatformTouchEvent&);
+    void handleMouseMove(LocalFrame*, const PlatformMouseEvent&);
 
     InspectorHistory* history() { return m_history.get(); }
 
@@ -225,7 +225,7 @@
     int pushNodePathToFrontend(Node*);
     void pushChildNodesToFrontend(int nodeId, int depth = 1);
 
-    void invalidateFrameOwnerElement(Frame*);
+    void invalidateFrameOwnerElement(LocalFrame*);
 
     bool hasBreakpoint(Node*, int type);
     void updateSubtreeBreakpoints(Node* root, uint32_t rootMask, bool value);
@@ -259,7 +259,9 @@
     HashMap<int, Node*> m_idToNode;
     HashMap<int, NodeToIdMap*> m_idToNodesMap;
     HashSet<int> m_childrenRequested;
-    HashMap<BackendNodeId, std::pair<Node*, String> > m_backendIdToNode;
+    HashMap<int, int> m_cachedChildCount;
+    typedef HashMap<BackendNodeId, std::pair<Node*, String> > BackendIdToNodeMap;
+    BackendIdToNodeMap m_backendIdToNode;
     int m_lastNodeId;
     BackendNodeId m_lastBackendNodeId;
     RefPtr<Document> m_document;
diff --git a/Source/core/inspector/InspectorDOMDebuggerAgent.cpp b/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
index b0fff77..d8683e1 100644
--- a/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
+++ b/Source/core/inspector/InspectorDOMDebuggerAgent.cpp
@@ -397,7 +397,7 @@
     else {
         RefPtr<JSONObject> eventListenerBreakpoints = m_state->getObject(DOMDebuggerAgentState::eventListenerBreakpoints);
         if (eventListenerBreakpoints->find(fullEventName) == eventListenerBreakpoints->end())
-            return 0;
+            return nullptr;
     }
 
     RefPtr<JSONObject> eventData = JSONObject::create();
diff --git a/Source/core/inspector/InspectorDOMStorageAgent.cpp b/Source/core/inspector/InspectorDOMStorageAgent.cpp
index 5c79088..1ab7d2c 100644
--- a/Source/core/inspector/InspectorDOMStorageAgent.cpp
+++ b/Source/core/inspector/InspectorDOMStorageAgent.cpp
@@ -39,9 +39,8 @@
 #include "core/inspector/InspectorState.h"
 #include "core/inspector/InstrumentingAgents.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
-#include "core/page/PageGroup.h"
 #include "core/storage/Storage.h"
 #include "core/storage/StorageNamespace.h"
 #include "platform/JSONValues.h"
@@ -109,7 +108,7 @@
 
 void InspectorDOMStorageAgent::getDOMStorageItems(ErrorString* errorString, const RefPtr<JSONObject>& storageId, RefPtr<TypeBuilder::Array<TypeBuilder::Array<String> > >& items)
 {
-    Frame* frame;
+    LocalFrame* frame;
     OwnPtrWillBeRawPtr<StorageArea> storageArea = findStorageArea(errorString, storageId, frame);
     if (!storageArea)
         return;
@@ -141,7 +140,7 @@
 
 void InspectorDOMStorageAgent::setDOMStorageItem(ErrorString* errorString, const RefPtr<JSONObject>& storageId, const String& key, const String& value)
 {
-    Frame* frame;
+    LocalFrame* frame;
     OwnPtrWillBeRawPtr<StorageArea> storageArea = findStorageArea(0, storageId, frame);
     if (!storageArea) {
         *errorString = "Storage not found";
@@ -155,7 +154,7 @@
 
 void InspectorDOMStorageAgent::removeDOMStorageItem(ErrorString* errorString, const RefPtr<JSONObject>& storageId, const String& key)
 {
-    Frame* frame;
+    LocalFrame* frame;
     OwnPtrWillBeRawPtr<StorageArea> storageArea = findStorageArea(0, storageId, frame);
     if (!storageArea) {
         *errorString = "Storage not found";
@@ -191,7 +190,7 @@
         m_frontend->domstorage()->domStorageItemUpdated(id, key, oldValue, newValue);
 }
 
-PassOwnPtrWillBeRawPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<JSONObject>& storageId, Frame*& targetFrame)
+PassOwnPtrWillBeRawPtr<StorageArea> InspectorDOMStorageAgent::findStorageArea(ErrorString* errorString, const RefPtr<JSONObject>& storageId, LocalFrame*& targetFrame)
 {
     String securityOrigin;
     bool isLocalStorage = false;
@@ -204,10 +203,10 @@
         return nullptr;
     }
 
-    Frame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
+    LocalFrame* frame = m_pageAgent->findFrameWithSecurityOrigin(securityOrigin);
     if (!frame) {
         if (errorString)
-            *errorString = "Frame not found for the given security origin";
+            *errorString = "LocalFrame not found for the given security origin";
         return nullptr;
     }
     targetFrame = frame;
diff --git a/Source/core/inspector/InspectorDOMStorageAgent.h b/Source/core/inspector/InspectorDOMStorageAgent.h
index 1ab86df..0b76d3a 100644
--- a/Source/core/inspector/InspectorDOMStorageAgent.h
+++ b/Source/core/inspector/InspectorDOMStorageAgent.h
@@ -36,7 +36,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class InspectorFrontend;
 class InspectorPageAgent;
 class InstrumentingAgents;
@@ -72,7 +72,7 @@
     InspectorDOMStorageAgent(InspectorPageAgent*);
 
     bool isEnabled() const;
-    PassOwnPtrWillBeRawPtr<StorageArea> findStorageArea(ErrorString*, const RefPtr<JSONObject>&, Frame*&);
+    PassOwnPtrWillBeRawPtr<StorageArea> findStorageArea(ErrorString*, const RefPtr<JSONObject>&, LocalFrame*&);
     PassRefPtr<TypeBuilder::DOMStorage::StorageId> storageId(SecurityOrigin*, bool isLocalStorage);
 
     InspectorPageAgent* m_pageAgent;
diff --git a/Source/core/inspector/InspectorDebuggerAgent.cpp b/Source/core/inspector/InspectorDebuggerAgent.cpp
index 08edc7a..625d84b 100644
--- a/Source/core/inspector/InspectorDebuggerAgent.cpp
+++ b/Source/core/inspector/InspectorDebuggerAgent.cpp
@@ -260,7 +260,7 @@
 void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type)
 {
     if (source == ConsoleAPIMessageSource && type == AssertMessageType && scriptDebugServer().pauseOnExceptionsState() != ScriptDebugServer::DontPauseOnExceptions)
-        breakProgram(InspectorFrontend::Debugger::Reason::Assert, 0);
+        breakProgram(InspectorFrontend::Debugger::Reason::Assert, nullptr);
 }
 
 void InspectorDebuggerAgent::addMessageToConsole(MessageSource source, MessageType type, MessageLevel, const String&, PassRefPtr<ScriptCallStack>, unsigned long)
@@ -273,12 +273,12 @@
     addMessageToConsole(source, type);
 }
 
-String InspectorDebuggerAgent::preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
+String InspectorDebuggerAgent::preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
 {
     return scriptDebugServer().preprocessEventListener(frame, source, url, functionName);
 }
 
-PassOwnPtr<ScriptSourceCode> InspectorDebuggerAgent::preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
+PassOwnPtr<ScriptSourceCode> InspectorDebuggerAgent::preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
 {
     return scriptDebugServer().preprocess(frame, sourceCode);
 }
@@ -553,16 +553,16 @@
 {
     ScriptsMap::iterator scriptIterator = m_scripts.find(scriptId);
     if (scriptIterator == m_scripts.end())
-        return 0;
+        return nullptr;
     Script& script = scriptIterator->value;
     if (breakpoint.lineNumber < script.startLine || script.endLine < breakpoint.lineNumber)
-        return 0;
+        return nullptr;
 
     int actualLineNumber;
     int actualColumnNumber;
     String debugServerBreakpointId = scriptDebugServer().setBreakpoint(scriptId, breakpoint, &actualLineNumber, &actualColumnNumber, false);
     if (debugServerBreakpointId.isEmpty())
-        return 0;
+        return nullptr;
 
     m_serverBreakpoints.set(debugServerBreakpointId, std::make_pair(breakpointId, source));
 
@@ -582,10 +582,10 @@
 static PassRefPtr<JSONObject> scriptToInspectorObject(ScriptObject scriptObject)
 {
     if (scriptObject.hasNoValue())
-        return 0;
+        return nullptr;
     RefPtr<JSONValue> value = scriptObject.toJSONValue(scriptObject.scriptState());
     if (!value)
-        return 0;
+        return nullptr;
     return value->asObject();
 }
 
@@ -798,6 +798,29 @@
         m_asyncCallStackTracker.didFireAsyncCall();
 }
 
+bool InspectorDebuggerAgent::isPromiseTrackerEnabled()
+{
+    return m_promiseTracker.isEnabled();
+}
+
+void InspectorDebuggerAgent::didCreatePromise(const ScriptObject& promise)
+{
+    if (m_promiseTracker.isEnabled())
+        m_promiseTracker.didCreatePromise(promise);
+}
+
+void InspectorDebuggerAgent::didUpdatePromiseParent(const ScriptObject& promise, const ScriptObject& parentPromise)
+{
+    if (m_promiseTracker.isEnabled())
+        m_promiseTracker.didUpdatePromiseParent(promise, parentPromise);
+}
+
+void InspectorDebuggerAgent::didUpdatePromiseState(const ScriptObject& promise, V8PromiseCustom::PromiseState state, const ScriptValue& result)
+{
+    if (m_promiseTracker.isEnabled())
+        m_promiseTracker.didUpdatePromiseState(promise, state, result);
+}
+
 void InspectorDebuggerAgent::pause(ErrorString*)
 {
     if (m_javaScriptPauseScheduled)
@@ -1057,18 +1080,18 @@
 PassRefPtr<StackTrace> InspectorDebuggerAgent::currentAsyncStackTrace()
 {
     if (!m_pausedScriptState || !m_asyncCallStackTracker.isEnabled())
-        return 0;
+        return nullptr;
     InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(m_pausedScriptState);
     if (injectedScript.hasNoValue()) {
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
     const AsyncCallStackTracker::AsyncCallChain* chain = m_asyncCallStackTracker.currentAsyncCallChain();
     if (!chain)
-        return 0;
+        return nullptr;
     const AsyncCallStackTracker::AsyncCallStackVector& callStacks = chain->callStacks();
     if (callStacks.isEmpty())
-        return 0;
+        return nullptr;
     RefPtr<StackTrace> result;
     int asyncOrdinal = callStacks.size();
     for (AsyncCallStackTracker::AsyncCallStackVector::const_reverse_iterator it = callStacks.rbegin(); it != callStacks.rend(); ++it) {
@@ -1185,6 +1208,7 @@
     }
 
     m_frontend->paused(currentCallFrames(), m_breakReason, m_breakAuxData, hitBreakpointIds, currentAsyncStackTrace());
+    m_frontend->flush();
     m_javaScriptPauseScheduled = false;
 
     if (!m_continueToLocationBreakpointId.isEmpty()) {
@@ -1224,6 +1248,7 @@
     m_scripts.clear();
     m_breakpointIdToDebugServerBreakpointIds.clear();
     m_asyncCallStackTracker.clear();
+    m_promiseTracker.clear();
     m_continueToLocationBreakpointId = String();
     clearBreakDetails();
     m_javaScriptPauseScheduled = false;
@@ -1243,7 +1268,7 @@
 void InspectorDebuggerAgent::clearBreakDetails()
 {
     m_breakReason = InspectorFrontend::Debugger::Reason::Other;
-    m_breakAuxData = 0;
+    m_breakAuxData = nullptr;
 }
 
 void InspectorDebuggerAgent::setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource source, const String& condition)
@@ -1263,6 +1288,7 @@
     m_scripts.clear();
     m_breakpointIdToDebugServerBreakpointIds.clear();
     m_asyncCallStackTracker.clear();
+    m_promiseTracker.clear();
     if (m_frontend)
         m_frontend->globalObjectCleared();
 }
diff --git a/Source/core/inspector/InspectorDebuggerAgent.h b/Source/core/inspector/InspectorDebuggerAgent.h
index f44abcc..687bacb 100644
--- a/Source/core/inspector/InspectorDebuggerAgent.h
+++ b/Source/core/inspector/InspectorDebuggerAgent.h
@@ -37,6 +37,7 @@
 #include "core/inspector/ConsoleAPITypes.h"
 #include "core/inspector/InjectedScript.h"
 #include "core/inspector/InspectorBaseAgent.h"
+#include "core/inspector/PromiseTracker.h"
 #include "core/inspector/ScriptBreakpoint.h"
 #include "core/inspector/ScriptDebugListener.h"
 #include "wtf/Forward.h"
@@ -95,8 +96,8 @@
     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, PassRefPtr<ScriptCallStack>, unsigned long);
     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, ScriptState*, PassRefPtr<ScriptArguments>, unsigned long);
 
-    String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
-    PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
+    String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName);
+    PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&);
 
     // Part of the protocol.
     virtual void enable(ErrorString*) OVERRIDE FINAL;
@@ -161,6 +162,10 @@
     void didPostPromiseTask(ExecutionContext*, ExecutionContextTask*, bool isResolved);
     void willPerformPromiseTask(ExecutionContext*, ExecutionContextTask*);
     void didPerformPromiseTask();
+    bool isPromiseTrackerEnabled();
+    void didCreatePromise(const ScriptObject& promise);
+    void didUpdatePromiseParent(const ScriptObject& promise, const ScriptObject& parentPromise);
+    void didUpdatePromiseState(const ScriptObject& promise, V8PromiseCustom::PromiseState, const ScriptValue& result);
     bool canBreakProgram();
     void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
     void scriptExecutionBlockedByCSP(const String& directiveText);
@@ -248,6 +253,7 @@
     bool m_skipAllPauses;
     OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp;
     AsyncCallStackTracker m_asyncCallStackTracker;
+    PromiseTracker m_promiseTracker;
 };
 
 } // namespace WebCore
diff --git a/Source/core/inspector/InspectorFrontendChannel.h b/Source/core/inspector/InspectorFrontendChannel.h
index 9505cb6..4db3423 100644
--- a/Source/core/inspector/InspectorFrontendChannel.h
+++ b/Source/core/inspector/InspectorFrontendChannel.h
@@ -26,6 +26,7 @@
 #ifndef InspectorFrontendChannel_h
 #define InspectorFrontendChannel_h
 
+#include "platform/JSONValues.h"
 #include "wtf/Forward.h"
 
 namespace WebCore {
@@ -33,7 +34,8 @@
 class InspectorFrontendChannel {
 public:
     virtual ~InspectorFrontendChannel() { }
-    virtual bool sendMessageToFrontend(const String& message) = 0;
+    virtual void sendMessageToFrontend(PassRefPtr<JSONObject> message) = 0;
+    virtual void flush() = 0;
 };
 
 } // namespace WebCore
diff --git a/Source/core/inspector/InspectorFrontendHost.cpp b/Source/core/inspector/InspectorFrontendHost.cpp
index a6035e0..e5ad251 100644
--- a/Source/core/inspector/InspectorFrontendHost.cpp
+++ b/Source/core/inspector/InspectorFrontendHost.cpp
@@ -34,7 +34,7 @@
 #include "bindings/v8/ScriptState.h"
 #include "core/clipboard/Pasteboard.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/parser/TextResourceDecoder.h"
 #include "core/inspector/InspectorController.h"
 #include "core/inspector/InspectorFrontendClient.h"
@@ -160,16 +160,33 @@
     Pasteboard::generalPasteboard()->writePlainText(text, Pasteboard::CannotSmartReplace);
 }
 
+static String escapeUnicodeNonCharacters(const String& str)
+{
+    StringBuilder dst;
+    for (unsigned i = 0; i < str.length(); ++i) {
+        UChar c = str[i];
+        if (c >= 0xD800) {
+            unsigned symbol = static_cast<unsigned>(c);
+            String symbolCode = String::format("\\u%04X", symbol);
+            dst.append(symbolCode);
+        } else {
+            dst.append(c);
+        }
+
+    }
+    return dst.toString();
+}
+
 void InspectorFrontendHost::sendMessageToBackend(const String& message)
 {
     if (m_client)
-        m_client->sendMessageToBackend(message);
+        m_client->sendMessageToBackend(escapeUnicodeNonCharacters(message));
 }
 
 void InspectorFrontendHost::sendMessageToEmbedder(const String& message)
 {
     if (m_client)
-        m_client->sendMessageToEmbedder(message);
+        m_client->sendMessageToEmbedder(escapeUnicodeNonCharacters(message));
 }
 
 void InspectorFrontendHost::showContextMenu(Event* event, const Vector<ContextMenuItem>& items)
diff --git a/Source/core/inspector/InspectorFrontendHost.idl b/Source/core/inspector/InspectorFrontendHost.idl
index a9102bc..7f883fd 100644
--- a/Source/core/inspector/InspectorFrontendHost.idl
+++ b/Source/core/inspector/InspectorFrontendHost.idl
@@ -50,7 +50,6 @@
 
     [Custom] void recordActionTaken(unsigned long actionCode);
     [Custom] void recordPanelShown(unsigned long panelCode);
-    [Custom] void recordSettingChanged(unsigned long settingChanged);
 
     DOMString getSelectionBackgroundColor();
     DOMString getSelectionForegroundColor();
diff --git a/Source/core/inspector/InspectorHeapProfilerAgent.cpp b/Source/core/inspector/InspectorHeapProfilerAgent.cpp
index 28575a3..2344032 100644
--- a/Source/core/inspector/InspectorHeapProfilerAgent.cpp
+++ b/Source/core/inspector/InspectorHeapProfilerAgent.cpp
@@ -45,6 +45,8 @@
 
 namespace HeapProfilerAgentState {
 static const char heapProfilerEnabled[] = "heapProfilerEnabled";
+static const char heapObjectsTrackingEnabled[] = "heapObjectsTrackingEnabled";
+static const char allocationTrackingEnabled[] = "allocationTrackingEnabled";
 }
 
 class InspectorHeapProfilerAgent::HeapStatsUpdateTask {
@@ -97,6 +99,8 @@
 {
     if (m_state->getBoolean(HeapProfilerAgentState::heapProfilerEnabled))
         m_frontend->resetProfiles();
+    if (m_state->getBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled))
+        startTrackingHeapObjectsInternal(m_state->getBoolean(HeapProfilerAgentState::allocationTrackingEnabled));
 }
 
 void InspectorHeapProfilerAgent::collectGarbage(WebCore::ErrorString*)
@@ -120,7 +124,7 @@
 void InspectorHeapProfilerAgent::HeapStatsUpdateTask::startTimer()
 {
     ASSERT(!m_timer.isActive());
-    m_timer.startRepeating(0.05);
+    m_timer.startRepeating(0.05, FROM_HERE);
 }
 
 class InspectorHeapProfilerAgent::HeapStatsStream FINAL : public ScriptProfiler::OutputStream {
@@ -142,11 +146,10 @@
 
 void InspectorHeapProfilerAgent::startTrackingHeapObjects(ErrorString*, const bool* trackAllocations)
 {
-    if (m_heapStatsUpdateTask)
-        return;
-    ScriptProfiler::startTrackingHeapObjects(trackAllocations && *trackAllocations);
-    m_heapStatsUpdateTask = adoptPtr(new HeapStatsUpdateTask(this));
-    m_heapStatsUpdateTask->startTimer();
+    m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, true);
+    bool allocationTrackingEnabled = trackAllocations && *trackAllocations;
+    m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, allocationTrackingEnabled);
+    startTrackingHeapObjectsInternal(allocationTrackingEnabled);
 }
 
 void InspectorHeapProfilerAgent::requestHeapStatsUpdate()
@@ -179,6 +182,15 @@
     stopTrackingHeapObjectsInternal();
 }
 
+void InspectorHeapProfilerAgent::startTrackingHeapObjectsInternal(bool trackAllocations)
+{
+    if (m_heapStatsUpdateTask)
+        return;
+    ScriptProfiler::startTrackingHeapObjects(trackAllocations);
+    m_heapStatsUpdateTask = adoptPtr(new HeapStatsUpdateTask(this));
+    m_heapStatsUpdateTask->startTimer();
+}
+
 void InspectorHeapProfilerAgent::stopTrackingHeapObjectsInternal()
 {
     if (!m_heapStatsUpdateTask)
@@ -186,6 +198,8 @@
     ScriptProfiler::stopTrackingHeapObjects();
     m_heapStatsUpdateTask->resetTimer();
     m_heapStatsUpdateTask.clear();
+    m_state->setBoolean(HeapProfilerAgentState::heapObjectsTrackingEnabled, false);
+    m_state->setBoolean(HeapProfilerAgentState::allocationTrackingEnabled, false);
 }
 
 void InspectorHeapProfilerAgent::enable(ErrorString*)
@@ -212,14 +226,18 @@
         }
         virtual void Worked(int workDone) OVERRIDE
         {
-            if (m_frontend)
+            if (m_frontend) {
                 m_frontend->reportHeapSnapshotProgress(workDone, m_totalWork, 0);
+                m_frontend->flush();
+            }
         }
         virtual void Done() OVERRIDE
         {
             const bool finished = true;
-            if (m_frontend)
+            if (m_frontend) {
                 m_frontend->reportHeapSnapshotProgress(m_totalWork, m_totalWork, &finished);
+                m_frontend->flush();
+            }
         }
         virtual bool isCanceled() OVERRIDE { return false; }
     private:
@@ -239,7 +257,11 @@
     public:
         explicit OutputStream(InspectorFrontend::HeapProfiler* frontend)
             : m_frontend(frontend) { }
-        void Write(const String& chunk) { m_frontend->addHeapSnapshotChunk(chunk); }
+        void Write(const String& chunk)
+        {
+            m_frontend->addHeapSnapshotChunk(chunk);
+            m_frontend->flush();
+        }
         void Close() { }
     private:
         InspectorFrontend::HeapProfiler* m_frontend;
diff --git a/Source/core/inspector/InspectorHeapProfilerAgent.h b/Source/core/inspector/InspectorHeapProfilerAgent.h
index e9207a8..8d18cac 100644
--- a/Source/core/inspector/InspectorHeapProfilerAgent.h
+++ b/Source/core/inspector/InspectorHeapProfilerAgent.h
@@ -79,6 +79,7 @@
     void requestHeapStatsUpdate();
     void pushHeapStatsUpdate(const uint32_t* const data, const int size);
 
+    void startTrackingHeapObjectsInternal(bool trackAllocations);
     void stopTrackingHeapObjectsInternal();
 
     InjectedScriptManager* m_injectedScriptManager;
diff --git a/Source/core/inspector/InspectorInputAgent.cpp b/Source/core/inspector/InspectorInputAgent.cpp
index 65888eb..30af5cc 100644
--- a/Source/core/inspector/InspectorInputAgent.cpp
+++ b/Source/core/inspector/InspectorInputAgent.cpp
@@ -31,11 +31,11 @@
 #include "config.h"
 #include "core/inspector/InspectorInputAgent.h"
 
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectorClient.h"
 #include "core/page/Chrome.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "platform/JSONValues.h"
 #include "platform/PlatformKeyboardEvent.h"
@@ -271,10 +271,5 @@
     m_page->mainFrame()->eventHandler().handleTouchEvent(event);
 }
 
-void InspectorInputAgent::dispatchGestureEvent(ErrorString*, const String& type, int x, int y, const double* timestamp, const int* deltaX, const int* deltaY, const double* scale)
-{
-    // Handled on the browser level.
-}
-
 } // namespace WebCore
 
diff --git a/Source/core/inspector/InspectorInputAgent.h b/Source/core/inspector/InspectorInputAgent.h
index 830a72f..9905fab 100644
--- a/Source/core/inspector/InspectorInputAgent.h
+++ b/Source/core/inspector/InspectorInputAgent.h
@@ -56,7 +56,6 @@
     virtual void dispatchKeyEvent(ErrorString*, const String& type, const int* modifiers, const double* timestamp, const String* text, const String* unmodifiedText, const String* keyIdentifier, const int* windowsVirtualKeyCode, const int* nativeVirtualKeyCode, const int* macCharCode, const bool* autoRepeat, const bool* isKeypad, const bool* isSystemKey) OVERRIDE;
     virtual void dispatchMouseEvent(ErrorString*, const String& type, int x, int y, const int* modifiers, const double* timestamp, const String* button, const int* clickCount, const bool* deviceSpace) OVERRIDE;
     virtual void dispatchTouchEvent(ErrorString*, const String& type, const RefPtr<JSONArray>& touchPoints, const int* modifiers, const double* timestamp) OVERRIDE;
-    virtual void dispatchGestureEvent(ErrorString*, const String& type, int x, int y, const double* timestamp, const int* deltaX, const int* deltaY, const double* scale) OVERRIDE;
 private:
     InspectorInputAgent(Page*, InspectorClient*);
 
diff --git a/Source/core/inspector/InspectorInspectorAgent.cpp b/Source/core/inspector/InspectorInspectorAgent.cpp
index 95fc107..bbdce31 100644
--- a/Source/core/inspector/InspectorInspectorAgent.cpp
+++ b/Source/core/inspector/InspectorInspectorAgent.cpp
@@ -35,7 +35,7 @@
 #include "bindings/v8/DOMWrapperWorld.h"
 #include "bindings/v8/ScriptController.h"
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InjectedScriptHost.h"
 #include "core/inspector/InjectedScriptManager.h"
 #include "core/inspector/InspectorController.h"
@@ -66,7 +66,7 @@
     m_instrumentingAgents->setInspectorInspectorAgent(0);
 }
 
-void InspectorInspectorAgent::didClearWindowObjectInMainWorld(Frame* frame)
+void InspectorInspectorAgent::didClearWindowObjectInMainWorld(LocalFrame* frame)
 {
     if (m_injectedScriptForOrigin.isEmpty())
         return;
@@ -103,7 +103,7 @@
     disable(&error);
 }
 
-void InspectorInspectorAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorInspectorAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
 {
     if (loader->frame() != frame->page()->mainFrame())
         return;
@@ -133,7 +133,7 @@
     m_inspectedPage->inspectorController().reconnectFrontend();
 }
 
-void InspectorInspectorAgent::domContentLoadedEventFired(Frame* frame)
+void InspectorInspectorAgent::domContentLoadedEventFired(LocalFrame* frame)
 {
     if (frame->page()->mainFrame() != frame)
         return;
@@ -158,8 +158,8 @@
 {
     if (m_state->getBoolean(InspectorAgentState::inspectorAgentEnabled) && m_frontend) {
         m_frontend->inspector()->inspect(objectToInspect, hints);
-        m_pendingInspectData.first = 0;
-        m_pendingInspectData.second = 0;
+        m_pendingInspectData.first = nullptr;
+        m_pendingInspectData.second = nullptr;
         return;
     }
     m_pendingInspectData.first = objectToInspect;
diff --git a/Source/core/inspector/InspectorInspectorAgent.h b/Source/core/inspector/InspectorInspectorAgent.h
index 6302cff..b2e6517 100644
--- a/Source/core/inspector/InspectorInspectorAgent.h
+++ b/Source/core/inspector/InspectorInspectorAgent.h
@@ -39,7 +39,7 @@
 
 class DOMWrapperWorld;
 class DocumentLoader;
-class Frame;
+class LocalFrame;
 class InjectedScriptManager;
 class InspectorFrontend;
 class InstrumentingAgents;
@@ -67,10 +67,10 @@
     virtual void setFrontend(InspectorFrontend*) OVERRIDE;
     virtual void clearFrontend() OVERRIDE;
 
-    void didClearWindowObjectInMainWorld(Frame*);
+    void didClearWindowObjectInMainWorld(LocalFrame*);
 
-    void didCommitLoad(Frame*, DocumentLoader*);
-    void domContentLoadedEventFired(Frame*);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
+    void domContentLoadedEventFired(LocalFrame*);
 
     bool hasFrontend() const { return m_frontend; }
 
diff --git a/Source/core/inspector/InspectorInstrumentation.cpp b/Source/core/inspector/InspectorInstrumentation.cpp
index dc54b8b..cf70689 100644
--- a/Source/core/inspector/InspectorInstrumentation.cpp
+++ b/Source/core/inspector/InspectorInstrumentation.cpp
@@ -56,7 +56,7 @@
 }
 
 InspectorInstrumentationCookie::InspectorInstrumentationCookie()
-    : m_instrumentingAgents(0)
+    : m_instrumentingAgents(nullptr)
     , m_timelineAgentId(0)
 {
 }
@@ -95,22 +95,22 @@
     return false;
 }
 
-void didReceiveResourceResponseButCanceledImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void didReceiveResourceResponseButCanceledImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
 {
     didReceiveResourceResponse(frame, identifier, loader, r, 0);
 }
 
-void continueAfterXFrameOptionsDeniedImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void continueAfterXFrameOptionsDeniedImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
 {
     didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
 }
 
-void continueWithPolicyDownloadImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void continueWithPolicyDownloadImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
 {
     didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
 }
 
-void continueWithPolicyIgnoreImpl(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
+void continueWithPolicyIgnoreImpl(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r)
 {
     didReceiveResourceResponseButCanceledImpl(frame, loader, identifier, r);
 }
@@ -134,14 +134,14 @@
     return false;
 }
 
-PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, const ScriptSourceCode& sourceCode)
+PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents* instrumentingAgents, LocalFrame* frame, const ScriptSourceCode& sourceCode)
 {
     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent())
         return debuggerAgent->preprocess(frame, sourceCode);
     return PassOwnPtr<ScriptSourceCode>();
 }
 
-String preprocessEventListenerImpl(InstrumentingAgents* instrumentingAgents, Frame* frame, const String& source, const String& url, const String& functionName)
+String preprocessEventListenerImpl(InstrumentingAgents* instrumentingAgents, LocalFrame* frame, const String& source, const String& url, const String& functionName)
 {
     if (InspectorDebuggerAgent* debuggerAgent = instrumentingAgents->inspectorDebuggerAgent())
         return debuggerAgent->preprocessEventListener(frame, source, url, functionName);
@@ -239,6 +239,7 @@
 const char BeginFrame[] = "BeginFrame";
 const char ActivateLayerTree[] = "ActivateLayerTree";
 const char DrawFrame[] = "DrawFrame";
+const char EmbedderCallback[] = "EmbedderCallback";
 };
 
 namespace InstrumentationEventArguments {
@@ -246,6 +247,7 @@
 const char LayerId[] = "layerId";
 const char LayerTreeId[] = "layerTreeId";
 const char PageId[] = "pageId";
+const char CallbackName[] = "callbackName";
 };
 
 InstrumentingAgents* instrumentationForPage(Page* page)
diff --git a/Source/core/inspector/InspectorInstrumentation.h b/Source/core/inspector/InspectorInstrumentation.h
index 570e516..424db10 100644
--- a/Source/core/inspector/InspectorInstrumentation.h
+++ b/Source/core/inspector/InspectorInstrumentation.h
@@ -39,7 +39,7 @@
 #include "core/dom/Element.h"
 #include "core/dom/ExecutionContext.h"
 #include "core/events/NodeEventContext.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/ConsoleAPITypes.h"
 #include "core/page/Page.h"
 #include "core/rendering/HitTestResult.h"
@@ -106,7 +106,7 @@
 
 // Called from generated instrumentation code.
 InstrumentingAgents* instrumentingAgentsFor(Page*);
-InstrumentingAgents* instrumentingAgentsFor(Frame*);
+InstrumentingAgents* instrumentingAgentsFor(LocalFrame*);
 InstrumentingAgents* instrumentingAgentsFor(EventTarget*);
 InstrumentingAgents* instrumentingAgentsFor(ExecutionContext*);
 InstrumentingAgents* instrumentingAgentsFor(Document&);
@@ -129,6 +129,7 @@
 extern const char BeginFrame[];
 extern const char DrawFrame[];
 extern const char ActivateLayerTree[];
+extern const char EmbedderCallback[];
 };
 
 namespace InstrumentationEventArguments {
@@ -136,6 +137,7 @@
 extern const char LayerId[];
 extern const char LayerTreeId[];
 extern const char PageId[];
+extern const char CallbackName[];
 };
 
 namespace InspectorInstrumentation {
@@ -147,7 +149,7 @@
     return context->isDocument() ? instrumentingAgentsFor(*toDocument(context)) : instrumentingAgentsForNonDocumentContext(context);
 }
 
-inline InstrumentingAgents* instrumentingAgentsFor(Frame* frame)
+inline InstrumentingAgents* instrumentingAgentsFor(LocalFrame* frame)
 {
     return frame ? instrumentingAgentsFor(frame->page()) : 0;
 }
diff --git a/Source/core/inspector/InspectorInstrumentation.idl b/Source/core/inspector/InspectorInstrumentation.idl
index adda1e4..899f15e 100644
--- a/Source/core/inspector/InspectorInstrumentation.idl
+++ b/Source/core/inspector/InspectorInstrumentation.idl
@@ -65,7 +65,7 @@
 #include "core/dom/PseudoElement.h"
 
     [Page, Inspector, PageDebugger, PageRuntime]
-    void didClearWindowObjectInMainWorld([Keep] Frame*);
+    void didClearWindowObjectInMainWorld([Keep] LocalFrame*);
 
     [DOMDebugger, Inline=FastReturn]
     void willInsertDOMNode([Keep] Node* parent);
@@ -107,7 +107,7 @@
     void activeStyleSheetsUpdated([Keep] Document*);
 
     [Console]
-    void frameWindowDiscarded(Frame*, DOMWindow* domWindow);
+    void frameWindowDiscarded(LocalFrame*, DOMWindow* domWindow);
 
     [CSS, Inline=FastReturn]
     void mediaQueryResultChanged(Document*);
@@ -173,7 +173,7 @@
     void didHandleEvent(const InspectorInstrumentationCookie&);
 
     [Timeline, Inline=FastReturn]
-    InspectorInstrumentationCookie willDispatchEventOnWindow(Frame*, const Event&, DOMWindow*);
+    InspectorInstrumentationCookie willDispatchEventOnWindow(LocalFrame*, const Event&, DOMWindow*);
 
     [Timeline, Inline=FastReturn]
     void didDispatchEventOnWindow(const InspectorInstrumentationCookie&);
@@ -190,23 +190,14 @@
     [Debugger, Inline=FastReturn]
     void didDeliverMutationRecords(ExecutionContext*);
 
-    [Debugger, Inline=FastReturn]
-    void didPostPromiseTask([Keep] ExecutionContext*, ExecutionContextTask*, bool isResolved);
-
-    [Debugger, Inline=FastReturn]
-    InspectorInstrumentationCookie willPerformPromiseTask([Keep] ExecutionContext*, ExecutionContextTask*);
-
-    [Debugger, Inline=FastReturn]
-    void didPerformPromiseTask(const InspectorInstrumentationCookie&);
-
     [Timeline, Inline=FastReturn]
-    InspectorInstrumentationCookie willEvaluateScript([Keep] Frame*, const String& url, int lineNumber);
+    InspectorInstrumentationCookie willEvaluateScript([Keep] LocalFrame*, const String& url, int lineNumber);
 
     [Timeline, Inline=FastReturn]
     void didEvaluateScript(const InspectorInstrumentationCookie&);
 
     [PageRuntime, Inline=FastReturn]
-    void didCreateIsolatedContext([Keep] Frame*, ScriptState*, SecurityOrigin*);
+    void didCreateIsolatedContext([Keep] LocalFrame*, ScriptState*, SecurityOrigin*);
 
     [DOMDebugger, Debugger, Timeline, Inline=FastReturn]
     InspectorInstrumentationCookie willFireTimer([Keep] ExecutionContext*, int timerId);
@@ -215,10 +206,10 @@
     void didFireTimer(const InspectorInstrumentationCookie&);
 
     [Timeline, Inline=FastReturn]
-    void didInvalidateLayout([Keep] Frame*);
+    void didInvalidateLayout([Keep] LocalFrame*);
 
     [Timeline, Inline=FastReturn]
-    InspectorInstrumentationCookie willLayout([Keep] Frame*);
+    InspectorInstrumentationCookie willLayout([Keep] LocalFrame*);
 
     [Timeline, Page, Inline=FastReturn]
     void didLayout(const InspectorInstrumentationCookie&, RenderObject* root);
@@ -272,49 +263,49 @@
     void didScheduleStyleRecalculation([Keep] Document*);
 
     [Resource, Inline=FastReturn]
-    void applyUserAgentOverride(Frame*, String* userAgent);
+    void applyUserAgentOverride(LocalFrame*, String* userAgent);
 
     [Page, Inline=FastReturn]
     bool applyViewportStyleOverride(Document*, StyleResolver*);
 
     [Page, Inline=FastReturn]
-    void applyEmulatedMedia(Frame*, String* media);
+    void applyEmulatedMedia(LocalFrame*, String* media);
 
     [Timeline, Resource]
-    void willSendRequest(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&);
+    void willSendRequest(LocalFrame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&);
 
     [Resource]
     void markResourceAsCached(Page*, unsigned long identifier);
 
     [Timeline, Inline=FastReturn]
-    InspectorInstrumentationCookie willReceiveResourceData([Keep] Frame*, unsigned long identifier, int length);
+    InspectorInstrumentationCookie willReceiveResourceData([Keep] LocalFrame*, unsigned long identifier, int length);
 
     [Timeline, Inline=FastReturn]
     void didReceiveResourceData(const InspectorInstrumentationCookie&);
 
     [Timeline, Resource, Console] // Console should come AFTER Resource notification, front-end relies on this.
-    void didReceiveResourceResponse([Keep] Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+    void didReceiveResourceResponse([Keep] LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
 
     [Inline=Forward]
-    void continueAfterXFrameOptionsDenied(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
+    void continueAfterXFrameOptionsDenied(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
 
     [Inline=Forward]
-    void continueWithPolicyDownload(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
+    void continueWithPolicyDownload(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
 
     [Inline=Forward]
-    void continueWithPolicyIgnore(Frame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
+    void continueWithPolicyIgnore(LocalFrame* frame, DocumentLoader* loader, unsigned long identifier, const ResourceResponse& r);
 
     [Resource]
-    void didReceiveData(Frame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
+    void didReceiveData(LocalFrame*, unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
 
     [Timeline, Resource]
-    void didFinishLoading(Frame* frame, unsigned long identifier, DocumentLoader*, double finishTime, int64_t encodedDataLength);
+    void didFinishLoading(LocalFrame* frame, unsigned long identifier, DocumentLoader*, double finishTime, int64_t encodedDataLength);
 
     [Resource]
-    void didReceiveCORSRedirectResponse([Keep] Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+    void didReceiveCORSRedirectResponse([Keep] LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
 
     [Timeline, Resource, Console] // Console should come AFTER Resource notification, front-end relies on this.
-    void didFailLoading(Frame* frame, unsigned long identifier, const ResourceError&);
+    void didFailLoading(LocalFrame* frame, unsigned long identifier, const ResourceError&);
 
     [Resource]
     void documentThreadableLoaderStartedLoadingForClient(ExecutionContext*, unsigned long identifier, ThreadableLoaderClient* client);
@@ -338,37 +329,37 @@
     void didReceiveScriptResponse(ExecutionContext*, unsigned long identifier);
 
     [Timeline, Inspector, DOM, Page]
-    void domContentLoadedEventFired([Keep] Frame*);
+    void domContentLoadedEventFired([Keep] LocalFrame*);
 
     [Timeline, Page]
-    void loadEventFired([Keep] Frame*);
+    void loadEventFired([Keep] LocalFrame*);
 
     [Page]
-    void frameAttachedToParent([Keep] Frame*);
+    void frameAttachedToParent([Keep] LocalFrame*);
 
     [Canvas, Page, CSS]
-    void frameDetachedFromParent([Keep] Frame*);
+    void frameDetachedFromParent([Keep] LocalFrame*);
 
     [Console, Resource, CSS, DOM, Inspector, Canvas, Page, PageDebugger]
-    void didCommitLoad([Keep] Frame*, DocumentLoader*);
+    void didCommitLoad([Keep] LocalFrame*, DocumentLoader*);
 
     [DOM, Inline=FastReturn]
-    void frameDocumentUpdated([Keep] Frame*);
+    void frameDocumentUpdated([Keep] LocalFrame*);
 
     [Page]
-    void loaderDetachedFromFrame(Frame*, DocumentLoader*);
+    void loaderDetachedFromFrame(LocalFrame*, DocumentLoader*);
 
     [Page]
-    void frameStartedLoading([Keep] Frame*);
+    void frameStartedLoading([Keep] LocalFrame*);
 
     [Page]
-    void frameStoppedLoading([Keep] Frame*);
+    void frameStoppedLoading([Keep] LocalFrame*);
 
     [Page, Resource]
-    void frameScheduledNavigation([Keep] Frame*, double delay);
+    void frameScheduledNavigation([Keep] LocalFrame*, double delay);
 
     [Page, Resource]
-    void frameClearedScheduledNavigation([Keep] Frame*);
+    void frameClearedScheduledNavigation([Keep] LocalFrame*);
 
     [Page, Inline=FastReturn]
     InspectorInstrumentationCookie willRunJavaScriptDialog(Page*, const String& message);
@@ -425,10 +416,10 @@
     void didCreateWebSocket([Keep] Document*, unsigned long identifier, const KURL& requestURL, const String& protocol);
 
     [Resource, Timeline]
-    void willSendWebSocketHandshakeRequest([Keep] Document*, unsigned long identifier, const WebSocketHandshakeRequest& request);
+    void willSendWebSocketHandshakeRequest([Keep] Document*, unsigned long identifier, const WebSocketHandshakeRequest* request);
 
     [Resource, Timeline]
-    void didReceiveWebSocketHandshakeResponse([Keep] Document*, unsigned long identifier, const WebSocketHandshakeResponse& response);
+    void didReceiveWebSocketHandshakeResponse([Keep] Document*, unsigned long identifier, const WebSocketHandshakeRequest* request, const WebSocketHandshakeResponse* response);
 
     [Resource, Timeline]
     void didCloseWebSocket([Keep] Document*, unsigned long identifier);
@@ -446,9 +437,9 @@
     void networkStateChanged(Page*, bool online);
 
     [ApplicationCache, Inline=FastReturn]
-    void updateApplicationCacheStatus([Keep] Frame*);
+    void updateApplicationCacheStatus([Keep] LocalFrame*);
 
-    [LayerTree]
+    [Timeline, LayerTree, Inline=FastReturn]
     void layerTreeDidChange(Page*);
 
     [DOM, Inline=FastReturn]
@@ -522,3 +513,31 @@
     [Canvas]
     ScriptObject wrapWebGLRenderingContextForInstrumentation(Document*, const ScriptObject&);
 }
+
+
+interface InspectorPromiseInstrumentation {
+
+#include "bindings/v8/custom/V8PromiseCustom.h"
+#include "bindings/v8/ScriptObject.h"
+
+    [Debugger, Inline=FastReturn]
+    void didPostPromiseTask([Keep] ExecutionContext*, ExecutionContextTask*, bool isResolved);
+
+    [Debugger, Inline=FastReturn]
+    InspectorInstrumentationCookie willPerformPromiseTask([Keep] ExecutionContext*, ExecutionContextTask*);
+
+    [Debugger, Inline=FastReturn]
+    void didPerformPromiseTask(const InspectorInstrumentationCookie&);
+
+    [Debugger, Inline=FastReturn]
+    bool isPromiseTrackerEnabled(ExecutionContext*);
+
+    [Debugger, Inline=FastReturn]
+    void didCreatePromise(ExecutionContext*, const ScriptObject& promise);
+
+    [Debugger, Inline=FastReturn]
+    void didUpdatePromiseParent(ExecutionContext*, const ScriptObject& promise, const ScriptObject& parentPromise);
+
+    [Debugger, Inline=FastReturn]
+    void didUpdatePromiseState(ExecutionContext*, const ScriptObject& promise, V8PromiseCustom::PromiseState, const ScriptValue& result);
+}
diff --git a/Source/core/inspector/InspectorInstrumentationCustomInl.h b/Source/core/inspector/InspectorInstrumentationCustomInl.h
index 2ff178d..8e6f9f4 100644
--- a/Source/core/inspector/InspectorInstrumentationCustomInl.h
+++ b/Source/core/inspector/InspectorInstrumentationCustomInl.h
@@ -37,14 +37,14 @@
 
 bool isDebuggerPausedImpl(InstrumentingAgents*);
 bool collectingHTMLParseErrorsImpl(InstrumentingAgents*);
-PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents*, Frame*, const ScriptSourceCode&);
-String preprocessEventListenerImpl(InstrumentingAgents*, Frame*, const String& source, const String& url, const String& functionName);
+PassOwnPtr<ScriptSourceCode> preprocessImpl(InstrumentingAgents*, LocalFrame*, const ScriptSourceCode&);
+String preprocessEventListenerImpl(InstrumentingAgents*, LocalFrame*, const String& source, const String& url, const String& functionName);
 
 bool canvasAgentEnabled(ExecutionContext*);
 bool consoleAgentEnabled(ExecutionContext*);
 bool timelineAgentEnabled(ExecutionContext*);
 
-inline bool isDebuggerPaused(Frame* frame)
+inline bool isDebuggerPaused(LocalFrame* frame)
 {
     FAST_RETURN_IF_NO_FRONTENDS(false);
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(frame))
@@ -60,7 +60,7 @@
     return false;
 }
 
-inline String preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
+inline String preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
 {
     FAST_RETURN_IF_NO_FRONTENDS(source);
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(frame))
@@ -68,7 +68,7 @@
     return source;
 }
 
-inline PassOwnPtr<ScriptSourceCode> preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
+inline PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
 {
     FAST_RETURN_IF_NO_FRONTENDS(PassOwnPtr<ScriptSourceCode>());
     if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsFor(frame))
diff --git a/Source/core/inspector/InspectorLayerTreeAgent.cpp b/Source/core/inspector/InspectorLayerTreeAgent.cpp
index 68fa440..70914c8 100644
--- a/Source/core/inspector/InspectorLayerTreeAgent.cpp
+++ b/Source/core/inspector/InspectorLayerTreeAgent.cpp
@@ -33,22 +33,27 @@
 
 #include "core/inspector/InspectorLayerTreeAgent.h"
 
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/IdentifiersFactory.h"
 #include "core/inspector/InspectorDOMAgent.h"
 #include "core/inspector/InspectorState.h"
 #include "core/inspector/InstrumentingAgents.h"
 #include "core/loader/DocumentLoader.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
-#include "core/rendering/CompositedLayerMapping.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "platform/geometry/IntRect.h"
 #include "platform/graphics/CompositingReasons.h"
 #include "platform/graphics/GraphicsContextRecorder.h"
 #include "platform/transforms/TransformationMatrix.h"
+#include "public/platform/WebFloatPoint.h"
 #include "public/platform/WebLayer.h"
 
+namespace {
+const char LayerTreeAgentObjectGroup[] = "layerTreeAgent";
+}
+
 namespace WebCore {
 
 unsigned InspectorLayerTreeAgent::s_lastSnapshotId;
@@ -72,18 +77,19 @@
     return String::number(graphicsLayer->platformLayer()->id());
 }
 
-static PassRefPtr<TypeBuilder::LayerTree::Layer> buildObjectForLayer(GraphicsLayer* graphicsLayer, int nodeId)
+static PassRefPtr<TypeBuilder::LayerTree::Layer> buildObjectForLayer(GraphicsLayer* graphicsLayer, BackendNodeId nodeId)
 {
+    blink::WebLayer* webLayer = graphicsLayer->platformLayer();
     RefPtr<TypeBuilder::LayerTree::Layer> layerObject = TypeBuilder::LayerTree::Layer::create()
         .setLayerId(idForLayer(graphicsLayer))
-        .setOffsetX(graphicsLayer->position().x())
-        .setOffsetY(graphicsLayer->position().y())
-        .setWidth(graphicsLayer->size().width())
-        .setHeight(graphicsLayer->size().height())
+        .setOffsetX(webLayer->position().x)
+        .setOffsetY(webLayer->position().y)
+        .setWidth(webLayer->bounds().width)
+        .setHeight(webLayer->bounds().height)
         .setPaintCount(graphicsLayer->paintCount());
 
     if (nodeId)
-        layerObject->setNodeId(nodeId);
+        layerObject->setBackendNodeId(nodeId);
 
     GraphicsLayer* parent = graphicsLayer->parent();
     if (!parent)
@@ -108,16 +114,6 @@
     return layerObject;
 }
 
-void gatherGraphicsLayers(GraphicsLayer* root, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >& layers)
-{
-    int layerId = root->platformLayer()->id();
-    layers->addItem(buildObjectForLayer(root, layerIdToNodeIdMap.get(layerId)));
-    if (GraphicsLayer* replica = root->replicaLayer())
-        gatherGraphicsLayers(replica, layerIdToNodeIdMap, layers);
-    for (size_t i = 0, size = root->children().size(); i < size; ++i)
-        gatherGraphicsLayers(root->children()[i], layerIdToNodeIdMap, layers);
-}
-
 InspectorLayerTreeAgent::InspectorLayerTreeAgent(InspectorDOMAgent* domAgent, Page* page)
     : InspectorBaseAgent<InspectorLayerTreeAgent>("LayerTree")
     , m_frontend(0)
@@ -158,11 +154,13 @@
 {
     m_instrumentingAgents->setInspectorLayerTreeAgent(0);
     m_snapshotById.clear();
+    ErrorString unused;
+    m_domAgent->releaseBackendNodeIds(&unused, LayerTreeAgentObjectGroup);
 }
 
 void InspectorLayerTreeAgent::layerTreeDidChange()
 {
-    m_frontend->layerTreeDidChange(buildLayerTree());
+    m_frontend->layerTreeDidChange(buildLayerTree(LayerTreeAgentObjectGroup));
 }
 
 void InspectorLayerTreeAgent::didPaint(RenderObject*, const GraphicsLayer* graphicsLayer, GraphicsContext*, const LayoutRect& rect)
@@ -179,45 +177,54 @@
     m_frontend->layerPainted(idForLayer(graphicsLayer), domRect.release());
 }
 
-PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > InspectorLayerTreeAgent::buildLayerTree()
+PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > InspectorLayerTreeAgent::buildLayerTree(const String& nodeGroup)
 {
     RenderLayerCompositor* compositor = renderLayerCompositor();
     if (!compositor || !compositor->inCompositingMode())
-        return 0;
+        return nullptr;
+    ASSERT(!compositor->compositingLayersNeedRebuild());
+
     LayerIdToNodeIdMap layerIdToNodeIdMap;
+    buildLayerIdToNodeIdMap(compositor->rootRenderLayer(), nodeGroup, layerIdToNodeIdMap);
     RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > layers = TypeBuilder::Array<TypeBuilder::LayerTree::Layer>::create();
-    buildLayerIdToNodeIdMap(compositor->rootRenderLayer(), layerIdToNodeIdMap);
     gatherGraphicsLayers(compositor->rootGraphicsLayer(), layerIdToNodeIdMap, layers);
     return layers.release();
 }
 
-void InspectorLayerTreeAgent::buildLayerIdToNodeIdMap(RenderLayer* root, LayerIdToNodeIdMap& layerIdToNodeIdMap)
+void InspectorLayerTreeAgent::buildLayerIdToNodeIdMap(RenderLayer* root, const String& nodeGroup, LayerIdToNodeIdMap& layerIdToNodeIdMap)
 {
     if (root->hasCompositedLayerMapping()) {
         if (Node* node = root->renderer()->generatingNode()) {
             GraphicsLayer* graphicsLayer = root->compositedLayerMapping()->childForSuperlayers();
-            layerIdToNodeIdMap.set(graphicsLayer->platformLayer()->id(), idForNode(node));
+            layerIdToNodeIdMap.set(graphicsLayer->platformLayer()->id(), idForNode(node, nodeGroup));
         }
     }
     for (RenderLayer* child = root->firstChild(); child; child = child->nextSibling())
-        buildLayerIdToNodeIdMap(child, layerIdToNodeIdMap);
+        buildLayerIdToNodeIdMap(child, nodeGroup, layerIdToNodeIdMap);
     if (!root->renderer()->isRenderIFrame())
         return;
     FrameView* childFrameView = toFrameView(toRenderWidget(root->renderer())->widget());
     if (RenderView* childRenderView = childFrameView->renderView()) {
         if (RenderLayerCompositor* childCompositor = childRenderView->compositor())
-            buildLayerIdToNodeIdMap(childCompositor->rootRenderLayer(), layerIdToNodeIdMap);
+            buildLayerIdToNodeIdMap(childCompositor->rootRenderLayer(), nodeGroup, layerIdToNodeIdMap);
     }
 }
 
-int InspectorLayerTreeAgent::idForNode(Node* node)
+void InspectorLayerTreeAgent::gatherGraphicsLayers(GraphicsLayer* root, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >& layers)
 {
-    int nodeId = m_domAgent->boundNodeId(node);
-    if (!nodeId) {
-        ErrorString ignoredError;
-        nodeId = m_domAgent->pushNodeToFrontend(&ignoredError, m_domAgent->boundNodeId(&node->document()), node);
-    }
-    return nodeId;
+    int layerId = root->platformLayer()->id();
+    if (m_pageOverlayLayerIds.find(layerId) != WTF::kNotFound)
+        return;
+    layers->addItem(buildObjectForLayer(root, layerIdToNodeIdMap.get(layerId)));
+    if (GraphicsLayer* replica = root->replicaLayer())
+        gatherGraphicsLayers(replica, layerIdToNodeIdMap, layers);
+    for (size_t i = 0, size = root->children().size(); i < size; ++i)
+        gatherGraphicsLayers(root->children()[i], layerIdToNodeIdMap, layers);
+}
+
+int InspectorLayerTreeAgent::idForNode(Node* node, const String& nodeGroup)
+{
+    return m_domAgent->backendNodeIdForNode(node, nodeGroup);
 }
 
 RenderLayerCompositor* InspectorLayerTreeAgent::renderLayerCompositor()
@@ -262,60 +269,19 @@
     return result;
 }
 
-struct CompositingReasonToProtocolName {
-    uint64_t mask;
-    const char *protocolName;
-};
-
-
 void InspectorLayerTreeAgent::compositingReasons(ErrorString* errorString, const String& layerId, RefPtr<TypeBuilder::Array<String> >& reasonStrings)
 {
-    static CompositingReasonToProtocolName compositingReasonNames[] = {
-        { CompositingReason3DTransform, "transform3D" },
-        { CompositingReasonVideo, "video" },
-        { CompositingReasonCanvas, "canvas" },
-        { CompositingReasonPlugin, "plugin" },
-        { CompositingReasonIFrame, "iFrame" },
-        { CompositingReasonBackfaceVisibilityHidden, "backfaceVisibilityHidden" },
-        { CompositingReasonAnimation, "animation" },
-        { CompositingReasonFilters, "filters" },
-        { CompositingReasonPositionFixed, "positionFixed" },
-        { CompositingReasonPositionSticky, "positionSticky" },
-        { CompositingReasonOverflowScrollingTouch, "overflowScrollingTouch" },
-        { CompositingReasonAssumedOverlap, "assumedOverlap" },
-        { CompositingReasonOverlap, "overlap" },
-        { CompositingReasonNegativeZIndexChildren, "negativeZIndexChildren" },
-        { CompositingReasonTransformWithCompositedDescendants, "transformWithCompositedDescendants" },
-        { CompositingReasonOpacityWithCompositedDescendants, "opacityWithCompositedDescendants" },
-        { CompositingReasonMaskWithCompositedDescendants, "maskWithCompositedDescendants" },
-        { CompositingReasonReflectionWithCompositedDescendants, "reflectionWithCompositedDescendants" },
-        { CompositingReasonFilterWithCompositedDescendants, "filterWithCompositedDescendants" },
-        { CompositingReasonBlendingWithCompositedDescendants, "blendingWithCompositedDescendants" },
-        { CompositingReasonClipsCompositingDescendants, "clipsCompositingDescendants" },
-        { CompositingReasonPerspective, "perspective" },
-        { CompositingReasonPreserve3D, "preserve3D" },
-        { CompositingReasonRoot, "root" },
-        { CompositingReasonLayerForClip, "layerForClip" },
-        { CompositingReasonLayerForScrollbar, "layerForScrollbar" },
-        { CompositingReasonLayerForScrollingContainer, "layerForScrollingContainer" },
-        { CompositingReasonLayerForForeground, "layerForForeground" },
-        { CompositingReasonLayerForBackground, "layerForBackground" },
-        { CompositingReasonLayerForMask, "layerForMask" },
-        { CompositingReasonLayerForVideoOverlay, "layerForVideoOverlay" },
-        { CompositingReasonIsolateCompositedDescendants, "isolateCompositedDescendants" }
-    };
-
     const GraphicsLayer* graphicsLayer = layerById(errorString, layerId);
     if (!graphicsLayer)
         return;
     CompositingReasons reasonsBitmask = graphicsLayer->compositingReasons();
     reasonStrings = TypeBuilder::Array<String>::create();
-    for (size_t i = 0; i < WTF_ARRAY_LENGTH(compositingReasonNames); ++i) {
-        if (!(reasonsBitmask & compositingReasonNames[i].mask))
+    for (size_t i = 0; i < WTF_ARRAY_LENGTH(compositingReasonStringMap); ++i) {
+        if (!(reasonsBitmask & compositingReasonStringMap[i].reason))
             continue;
-        reasonStrings->addItem(compositingReasonNames[i].protocolName);
+        reasonStrings->addItem(compositingReasonStringMap[i].shortName);
 #ifndef _NDEBUG
-        reasonsBitmask &= ~compositingReasonNames[i].mask;
+        reasonsBitmask &= ~compositingReasonStringMap[i].reason;
 #endif
     }
     ASSERT(!reasonsBitmask);
@@ -382,4 +348,18 @@
     }
 }
 
+void InspectorLayerTreeAgent::willAddPageOverlay(const GraphicsLayer* layer)
+{
+    m_pageOverlayLayerIds.append(layer->platformLayer()->id());
+}
+
+void InspectorLayerTreeAgent::didRemovePageOverlay(const GraphicsLayer* layer)
+{
+    size_t index = m_pageOverlayLayerIds.find(layer->platformLayer()->id());
+    if (index == WTF::kNotFound)
+        return;
+    m_pageOverlayLayerIds.remove(index);
+}
+
+
 } // namespace WebCore
diff --git a/Source/core/inspector/InspectorLayerTreeAgent.h b/Source/core/inspector/InspectorLayerTreeAgent.h
index 9414419..f0057b9 100644
--- a/Source/core/inspector/InspectorLayerTreeAgent.h
+++ b/Source/core/inspector/InspectorLayerTreeAgent.h
@@ -63,6 +63,10 @@
     virtual void clearFrontend() OVERRIDE;
     virtual void restore() OVERRIDE;
 
+    // Called from InspectorController
+    void willAddPageOverlay(const GraphicsLayer*);
+    void didRemovePageOverlay(const GraphicsLayer*);
+
     // Called from InspectorInstrumentation
     void layerTreeDidChange();
     void didPaint(RenderObject*, const GraphicsLayer*, GraphicsContext*, const LayoutRect&);
@@ -76,6 +80,9 @@
     virtual void replaySnapshot(ErrorString*, const String& snapshotId, const int* fromStep, const int* toStep, String* dataURL) OVERRIDE;
     virtual void profileSnapshot(ErrorString*, const String& snapshotId, const int* minRepeatCount, const double* minDuration, RefPtr<TypeBuilder::Array<TypeBuilder::Array<double> > >&) OVERRIDE;
 
+    // Called by other agents.
+    PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > buildLayerTree(const String& nodeGroup);
+
 private:
     static unsigned s_lastSnapshotId;
 
@@ -84,15 +91,16 @@
     RenderLayerCompositor* renderLayerCompositor();
     GraphicsLayer* layerById(ErrorString*, const String& layerId);
     const LayerSnapshot* snapshotById(ErrorString*, const String& snapshotId);
-    PassRefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> > buildLayerTree();
 
     typedef HashMap<int, int> LayerIdToNodeIdMap;
-    void buildLayerIdToNodeIdMap(RenderLayer*, LayerIdToNodeIdMap&);
-    int idForNode(Node*);
+    void buildLayerIdToNodeIdMap(RenderLayer*, const String& nodeGroup, LayerIdToNodeIdMap&);
+    void gatherGraphicsLayers(GraphicsLayer*, HashMap<int, int>& layerIdToNodeIdMap, RefPtr<TypeBuilder::Array<TypeBuilder::LayerTree::Layer> >&);
+    int idForNode(Node*, const String& nodeGroup);
 
     InspectorFrontend::LayerTree* m_frontend;
     Page* m_page;
     InspectorDOMAgent* m_domAgent;
+    Vector<int, 2> m_pageOverlayLayerIds;
 
     typedef HashMap<String, LayerSnapshot> SnapshotById;
     SnapshotById m_snapshotById;
diff --git a/Source/core/inspector/InspectorOverlay.cpp b/Source/core/inspector/InspectorOverlay.cpp
index b8bcaff..6853e99 100644
--- a/Source/core/inspector/InspectorOverlay.cpp
+++ b/Source/core/inspector/InspectorOverlay.cpp
@@ -36,14 +36,14 @@
 #include "core/dom/Element.h"
 #include "core/dom/Node.h"
 #include "core/dom/PseudoElement.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectorClient.h"
 #include "core/inspector/InspectorOverlayHost.h"
 #include "core/loader/EmptyClients.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/page/Chrome.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/RenderBoxModelObject.h"
@@ -138,7 +138,7 @@
 static bool buildNodeQuads(Node* node, Vector<FloatQuad>& quads)
 {
     RenderObject* renderer = node->renderer();
-    Frame* containingFrame = node->document().frame();
+    LocalFrame* containingFrame = node->document().frame();
 
     if (!renderer || !containingFrame)
         return false;
@@ -213,7 +213,7 @@
 static void buildNodeHighlight(Node* node, const HighlightConfig& highlightConfig, Highlight* highlight)
 {
     RenderObject* renderer = node->renderer();
-    Frame* containingFrame = node->document().frame();
+    LocalFrame* containingFrame = node->document().frame();
 
     if (!renderer || !containingFrame)
         return;
@@ -383,7 +383,7 @@
     m_drawViewSize = true;
     m_drawViewSizeWithGrid = showGrid;
     update();
-    m_timer.startOneShot(1);
+    m_timer.startOneShot(1, FROM_HERE);
 }
 
 Node* InspectorOverlay::highlightedNode() const
@@ -413,7 +413,7 @@
     IntRect viewRect = view->visibleContentRect();
 
     // Include scrollbars to avoid masking them by the gutter.
-    IntSize frameViewFullSize = view->visibleContentRect(ScrollableArea::IncludeScrollbars).size();
+    IntSize frameViewFullSize = view->visibleContentRect(IncludeScrollbars).size();
     IntSize size = m_size.isEmpty() ? frameViewFullSize : m_size;
     size.scale(m_page->pageScaleFactor());
     overlayPage()->mainFrame()->view()->resize(size);
@@ -541,7 +541,7 @@
             elementInfo->setString("className", classNames.toString());
 
         RenderObject* renderer = node->renderer();
-        Frame* containingFrame = node->document().frame();
+        LocalFrame* containingFrame = node->document().frame();
         FrameView* containingView = containingFrame->view();
         IntRect boundingBox = pixelSnappedIntRect(containingView->contentsToRootView(renderer->absoluteBoundingBoxRect()));
         RenderBoxModelObject* modelObject = renderer->isBoxModelObject() ? toRenderBoxModelObject(renderer) : 0;
@@ -598,12 +598,11 @@
     overlaySettings.genericFontFamilySettings().setPictograph(settings.genericFontFamilySettings().pictograph());
     overlaySettings.setMinimumFontSize(settings.minimumFontSize());
     overlaySettings.setMinimumLogicalFontSize(settings.minimumLogicalFontSize());
-    overlaySettings.setMediaEnabled(false);
     overlaySettings.setScriptEnabled(true);
     overlaySettings.setPluginsEnabled(false);
     overlaySettings.setLoadsImagesAutomatically(true);
 
-    RefPtr<Frame> frame = Frame::create(FrameInit::create(0, &m_overlayPage->frameHost(), dummyFrameLoaderClient));
+    RefPtr<LocalFrame> frame = LocalFrame::create(dummyFrameLoaderClient, &m_overlayPage->frameHost(), 0);
     frame->setView(FrameView::create(frame.get()));
     frame->init();
     FrameLoader& loader = frame->loader();
diff --git a/Source/core/inspector/InspectorPageAgent.cpp b/Source/core/inspector/InspectorPageAgent.cpp
index 1677e61..ba925a0 100644
--- a/Source/core/inspector/InspectorPageAgent.cpp
+++ b/Source/core/inspector/InspectorPageAgent.cpp
@@ -47,13 +47,13 @@
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ScriptResource.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/PageConsole.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameOwnerElement.h"
-#include "core/html/HTMLImport.h"
-#include "core/html/HTMLImportChild.h"
+#include "core/html/imports/HTMLImport.h"
+#include "core/html/imports/HTMLImportChild.h"
 #include "core/html/parser/TextResourceDecoder.h"
 #include "core/inspector/ContentSearchUtils.h"
 #include "core/inspector/DOMPatchSupport.h"
@@ -247,7 +247,7 @@
 }
 
 // static
-void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded)
+void InspectorPageAgent::resourceContent(ErrorString* errorString, LocalFrame* frame, const KURL& url, String* result, bool* base64Encoded)
 {
     DocumentLoader* loader = assertDocumentLoader(errorString, frame);
     if (!loader)
@@ -256,7 +256,7 @@
         *errorString = "No resource with given URL found";
 }
 
-Resource* InspectorPageAgent::cachedResource(Frame* frame, const KURL& url)
+Resource* InspectorPageAgent::cachedResource(LocalFrame* frame, const KURL& url)
 {
     Resource* cachedResource = frame->document()->fetcher()->cachedResource(url);
     if (!cachedResource)
@@ -475,17 +475,11 @@
 void InspectorPageAgent::navigate(ErrorString*, const String& url)
 {
     UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture);
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     FrameLoadRequest request(frame->document(), ResourceRequest(frame->document()->completeURL(url)));
     frame->loader().load(request);
 }
 
-void InspectorPageAgent::getNavigationHistory(ErrorString*, int*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::NavigationEntry> >&)
-{ }
-
-void InspectorPageAgent::navigateToHistoryEntry(ErrorString*, int)
-{ }
-
 static PassRefPtr<TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie)
 {
     return TypeBuilder::Page::Cookie::create()
@@ -540,7 +534,7 @@
     }
 }
 
-static Vector<Resource*> cachedResourcesForFrame(Frame* frame)
+static Vector<Resource*> cachedResourcesForFrame(LocalFrame* frame)
 {
     Vector<Resource*> result;
     Document* rootDocument = frame->document();
@@ -559,7 +553,7 @@
     return result;
 }
 
-static Vector<HTMLImportChild*> importsForFrame(Frame* frame)
+static Vector<HTMLImportChild*> importsForFrame(LocalFrame* frame)
 {
     Vector<HTMLImportChild*> result;
     Document* rootDocument = frame->document();
@@ -575,7 +569,7 @@
     return result;
 }
 
-static Vector<KURL> allResourcesURLsForFrame(Frame* frame)
+static Vector<KURL> allResourcesURLsForFrame(LocalFrame* frame)
 {
     Vector<KURL> result;
 
@@ -592,7 +586,7 @@
 {
     ListHashSet<Cookie> rawCookiesList;
 
-    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) {
+    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext(mainFrame())) {
         Document* document = frame->document();
         Vector<KURL> allURLs = allResourcesURLsForFrame(frame);
         for (Vector<KURL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) {
@@ -612,7 +606,7 @@
 void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url)
 {
     KURL parsedURL(ParsedURLString, url);
-    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame()))
+    for (LocalFrame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext(m_page->mainFrame()))
         WebCore::deleteCookie(frame->document(), parsedURL, cookieName);
 }
 
@@ -623,7 +617,7 @@
 
 void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded)
 {
-    Frame* frame = assertFrame(errorString, frameId);
+    LocalFrame* frame = assertFrame(errorString, frameId);
     if (!frame)
         return;
     resourceContent(errorString, frame, KURL(ParsedURLString, url), content, base64Encoded);
@@ -649,7 +643,7 @@
     bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
     bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
 
-    Frame* frame = frameForId(frameId);
+    LocalFrame* frame = frameForId(frameId);
     KURL kurl(ParsedURLString, url);
 
     FrameLoader* frameLoader = frame ? &frame->loader() : 0;
@@ -671,7 +665,7 @@
 
 void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html)
 {
-    Frame* frame = assertFrame(errorString, frameId);
+    LocalFrame* frame = assertFrame(errorString, frameId);
     if (!frame)
         return;
 
@@ -791,22 +785,20 @@
 {
     bool disabledByScriptController = false;
     bool disabledInSettings = false;
-    Frame* frame = mainFrame();
+    LocalFrame* frame = mainFrame();
     if (frame) {
         disabledByScriptController = !frame->script().canExecuteScripts(NotAboutToExecuteScript);
         if (frame->settings())
             disabledInSettings = !frame->settings()->scriptEnabled();
     }
 
-    if (!disabledByScriptController) {
-        *status = PageCommandHandler::Result::Allowed;
-        return;
-    }
-
+    // Order is important.
     if (disabledInSettings)
         *status = PageCommandHandler::Result::Disabled;
-    else
+    else if (disabledByScriptController)
         *status = PageCommandHandler::Result::Forbidden;
+    else
+        *status = PageCommandHandler::Result::Allowed;
 }
 
 void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
@@ -823,7 +815,7 @@
     }
 }
 
-void InspectorPageAgent::didClearWindowObjectInMainWorld(Frame* frame)
+void InspectorPageAgent::didClearWindowObjectInMainWorld(LocalFrame* frame)
 {
     if (frame == m_page->mainFrame())
         m_injectedScriptManager->discardInjectedScripts();
@@ -844,21 +836,21 @@
         frame->script().executeScriptInMainWorld(m_scriptToEvaluateOnLoadOnce);
 }
 
-void InspectorPageAgent::domContentLoadedEventFired(Frame* frame)
+void InspectorPageAgent::domContentLoadedEventFired(LocalFrame* frame)
 {
     if (!frame->isMainFrame())
         return;
     m_frontend->domContentEventFired(currentTime());
 }
 
-void InspectorPageAgent::loadEventFired(Frame* frame)
+void InspectorPageAgent::loadEventFired(LocalFrame* frame)
 {
     if (!frame->isMainFrame())
         return;
     m_frontend->loadEventFired(currentTime());
 }
 
-void InspectorPageAgent::didCommitLoad(Frame*, DocumentLoader* loader)
+void InspectorPageAgent::didCommitLoad(LocalFrame*, DocumentLoader* loader)
 {
     // FIXME: If "frame" is always guarenteed to be in the same Page as loader->frame()
     // then all we need to check here is loader->frame()->isMainFrame()
@@ -872,14 +864,14 @@
     m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
 }
 
-void InspectorPageAgent::frameAttachedToParent(Frame* frame)
+void InspectorPageAgent::frameAttachedToParent(LocalFrame* frame)
 {
     m_frontend->frameAttached(frameId(frame), frameId(frame->tree().parent()));
 }
 
-void InspectorPageAgent::frameDetachedFromParent(Frame* frame)
+void InspectorPageAgent::frameDetachedFromParent(LocalFrame* frame)
 {
-    HashMap<Frame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
+    HashMap<LocalFrame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
     if (iterator != m_frameToIdentifier.end()) {
         m_frontend->frameDetached(iterator->value);
         m_identifierToFrame.remove(iterator->value);
@@ -887,17 +879,17 @@
     }
 }
 
-Frame* InspectorPageAgent::mainFrame()
+LocalFrame* InspectorPageAgent::mainFrame()
 {
     return m_page->mainFrame();
 }
 
-Frame* InspectorPageAgent::frameForId(const String& frameId)
+LocalFrame* InspectorPageAgent::frameForId(const String& frameId)
 {
     return frameId.isEmpty() ? 0 : m_identifierToFrame.get(frameId);
 }
 
-String InspectorPageAgent::frameId(Frame* frame)
+String InspectorPageAgent::frameId(LocalFrame* frame)
 {
     if (!frame)
         return "";
@@ -910,7 +902,7 @@
     return identifier;
 }
 
-bool InspectorPageAgent::hasIdForFrame(Frame* frame) const
+bool InspectorPageAgent::hasIdForFrame(LocalFrame* frame) const
 {
     return frame && m_frameToIdentifier.contains(frame);
 }
@@ -927,9 +919,9 @@
     return identifier;
 }
 
-Frame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
+LocalFrame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
 {
-    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         RefPtr<SecurityOrigin> documentOrigin = frame->document()->securityOrigin();
         if (documentOrigin->toRawString() == originRawString)
             return frame;
@@ -937,9 +929,9 @@
     return 0;
 }
 
-Frame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
+LocalFrame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
 {
-    Frame* frame = frameForId(frameId);
+    LocalFrame* frame = frameForId(frameId);
     if (!frame)
         *errorString = "No frame for given id found";
     return frame;
@@ -951,7 +943,7 @@
     DEFINE_STATIC_LOCAL(const AtomicString, deprecatedSourceMapHttpHeader, ("X-SourceMap", AtomicString::ConstructFromLiteral));
     if (url.isEmpty())
         return nullAtom;
-    Frame* frame = mainFrame();
+    LocalFrame* frame = mainFrame();
     if (!frame)
         return nullAtom;
     Resource* resource = cachedResource(frame, KURL(ParsedURLString, url));
@@ -971,7 +963,7 @@
 }
 
 // static
-DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, Frame* frame)
+DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, LocalFrame* frame)
 {
     DocumentLoader* documentLoader = frame->loader().documentLoader();
     if (!documentLoader)
@@ -986,22 +978,22 @@
         m_loaderToIdentifier.remove(iterator);
 }
 
-void InspectorPageAgent::frameStartedLoading(Frame* frame)
+void InspectorPageAgent::frameStartedLoading(LocalFrame* frame)
 {
     m_frontend->frameStartedLoading(frameId(frame));
 }
 
-void InspectorPageAgent::frameStoppedLoading(Frame* frame)
+void InspectorPageAgent::frameStoppedLoading(LocalFrame* frame)
 {
     m_frontend->frameStoppedLoading(frameId(frame));
 }
 
-void InspectorPageAgent::frameScheduledNavigation(Frame* frame, double delay)
+void InspectorPageAgent::frameScheduledNavigation(LocalFrame* frame, double delay)
 {
     m_frontend->frameScheduledNavigation(frameId(frame), delay);
 }
 
-void InspectorPageAgent::frameClearedScheduledNavigation(Frame* frame)
+void InspectorPageAgent::frameClearedScheduledNavigation(LocalFrame* frame)
 {
     m_frontend->frameClearedScheduledNavigation(frameId(frame));
 }
@@ -1069,7 +1061,7 @@
     m_frontend->scriptsEnabled(isEnabled);
 }
 
-PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
+PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(LocalFrame* frame)
 {
     RefPtr<TypeBuilder::Page::Frame> frameObject = TypeBuilder::Page::Frame::create()
         .setId(frameId(frame))
@@ -1089,7 +1081,7 @@
     return frameObject;
 }
 
-PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(Frame* frame)
+PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(LocalFrame* frame)
 {
     RefPtr<TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame);
     RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources> > subresources = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources>::create();
@@ -1123,7 +1115,7 @@
     }
 
     RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree> > childrenArray;
-    for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+    for (LocalFrame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
         if (!childrenArray) {
             childrenArray = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree>::create();
             result->setChildFrames(childrenArray);
@@ -1195,9 +1187,9 @@
     if (!m_deviceMetricsOverridden || !m_emulateViewportEnabled)
         return false;
 
-    RefPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
+    RefPtrWillBeRawPtr<StyleSheetContents> styleSheet = StyleSheetContents::create(CSSParserContext(UASheetMode, 0));
     styleSheet->parseString(String(viewportAndroidUserAgentStyleSheet, sizeof(viewportAndroidUserAgentStyleSheet)));
-    OwnPtr<RuleSet> ruleSet = RuleSet::create();
+    OwnPtrWillBeRawPtr<RuleSet> ruleSet = RuleSet::create();
     ruleSet->addRulesFromSheet(styleSheet.get(), MediaQueryEvaluator("screen"));
     resolver->viewportStyleResolver()->collectViewportRules(ruleSet.get(), ViewportStyleResolver::UserAgentOrigin);
     return true;
@@ -1221,42 +1213,12 @@
     if (settings.forceCompositingMode())
         return true;
     settings.setForceCompositingMode(true);
-    Frame* mainFrame = m_page->mainFrame();
+    LocalFrame* mainFrame = m_page->mainFrame();
     if (mainFrame)
         mainFrame->view()->updateCompositingLayersAfterStyleChange();
     return true;
 }
 
-void InspectorPageAgent::captureScreenshot(ErrorString*, const String*, const int*, const int*, const int*, String*, RefPtr<TypeBuilder::Page::ScreencastFrameMetadata>&)
-{
-    // Handled on the browser level.
-}
-
-void InspectorPageAgent::canScreencast(ErrorString*, bool*)
-{
-    // Handled on the browser level.
-}
-
-void InspectorPageAgent::startScreencast(ErrorString*, const String*, const int*, const int*, const int*)
-{
-    // Handled on the browser level.
-}
-
-void InspectorPageAgent::stopScreencast(ErrorString*)
-{
-    // Handled on the browser level.
-}
-
-void InspectorPageAgent::handleJavaScriptDialog(ErrorString* errorString, bool accept, const String* promptText)
-{
-    // Handled on the browser level.
-}
-
-void InspectorPageAgent::queryUsageAndQuota(WebCore::ErrorString*, const WTF::String&, WTF::RefPtr<WebCore::TypeBuilder::Page::Quota>&, WTF::RefPtr<WebCore::TypeBuilder::Page::Usage>&)
-{
-    // Handled on the browser level.
-}
-
 void InspectorPageAgent::setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid)
 {
     m_state->setBoolean(PageAgentState::showSizeOnResize, show);
diff --git a/Source/core/inspector/InspectorPageAgent.h b/Source/core/inspector/InspectorPageAgent.h
index 239573c..8b7a2a9 100644
--- a/Source/core/inspector/InspectorPageAgent.h
+++ b/Source/core/inspector/InspectorPageAgent.h
@@ -43,7 +43,7 @@
 class DOMWrapperWorld;
 class Document;
 class DocumentLoader;
-class Frame;
+class LocalFrame;
 class GraphicsContext;
 class GraphicsLayer;
 class InjectedScriptManager;
@@ -83,8 +83,8 @@
     static bool cachedResourceContent(Resource*, String* result, bool* base64Encoded);
     static bool sharedBufferContent(PassRefPtr<SharedBuffer>, const String& textEncodingName, bool withBase64Encode, String* result);
 
-    static PassRefPtr<SharedBuffer> resourceData(Frame*, const KURL&, String* textEncodingName);
-    static Resource* cachedResource(Frame*, const KURL&);
+    static PassRefPtr<SharedBuffer> resourceData(LocalFrame*, const KURL&, String* textEncodingName);
+    static Resource* cachedResource(LocalFrame*, const KURL&);
     static TypeBuilder::Page::ResourceType::Enum resourceTypeJson(ResourceType);
     static ResourceType cachedResourceType(const Resource&);
     static TypeBuilder::Page::ResourceType::Enum cachedResourceTypeJson(const Resource&);
@@ -96,8 +96,6 @@
     virtual void removeScriptToEvaluateOnLoad(ErrorString*, const String& identifier) OVERRIDE;
     virtual void reload(ErrorString*, const bool* optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor) OVERRIDE;
     virtual void navigate(ErrorString*, const String& url) OVERRIDE;
-    virtual void getNavigationHistory(ErrorString*, int*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::NavigationEntry> >&) OVERRIDE;
-    virtual void navigateToHistoryEntry(ErrorString*, int) OVERRIDE;
     virtual void getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies) OVERRIDE;
     virtual void deleteCookie(ErrorString*, const String& cookieName, const String& url) OVERRIDE;
     virtual void getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>&) OVERRIDE;
@@ -114,26 +112,20 @@
     virtual void setScriptExecutionDisabled(ErrorString*, bool) OVERRIDE;
     virtual void setTouchEmulationEnabled(ErrorString*, bool) OVERRIDE;
     virtual void setEmulatedMedia(ErrorString*, const String&) OVERRIDE;
-    virtual void captureScreenshot(ErrorString*, const String* format, const int* quality, const int* maxWidth, const int* maxHeight, String* data, RefPtr<TypeBuilder::Page::ScreencastFrameMetadata>& out_metadata) OVERRIDE;
-    virtual void canScreencast(ErrorString*, bool*) OVERRIDE;
-    virtual void startScreencast(ErrorString*, const String* format, const int* quality, const int* maxWidth, const int* maxHeight) OVERRIDE;
-    virtual void stopScreencast(ErrorString*) OVERRIDE;
-    virtual void handleJavaScriptDialog(ErrorString*, bool accept, const String* promptText) OVERRIDE;
-    virtual void queryUsageAndQuota(WebCore::ErrorString*, const WTF::String&, WTF::RefPtr<WebCore::TypeBuilder::Page::Quota>&, WTF::RefPtr<WebCore::TypeBuilder::Page::Usage>&) OVERRIDE;
     virtual void setShowViewportSizeOnResize(ErrorString*, bool show, const bool* showGrid) OVERRIDE;
 
     // InspectorInstrumentation API
-    void didClearWindowObjectInMainWorld(Frame*);
-    void domContentLoadedEventFired(Frame*);
-    void loadEventFired(Frame*);
-    void didCommitLoad(Frame*, DocumentLoader*);
-    void frameAttachedToParent(Frame*);
-    void frameDetachedFromParent(Frame*);
+    void didClearWindowObjectInMainWorld(LocalFrame*);
+    void domContentLoadedEventFired(LocalFrame*);
+    void loadEventFired(LocalFrame*);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
+    void frameAttachedToParent(LocalFrame*);
+    void frameDetachedFromParent(LocalFrame*);
     void loaderDetachedFromFrame(DocumentLoader*);
-    void frameStartedLoading(Frame*);
-    void frameStoppedLoading(Frame*);
-    void frameScheduledNavigation(Frame*, double delay);
-    void frameClearedScheduledNavigation(Frame*);
+    void frameStartedLoading(LocalFrame*);
+    void frameStoppedLoading(LocalFrame*);
+    void frameScheduledNavigation(LocalFrame*, double delay);
+    void frameClearedScheduledNavigation(LocalFrame*);
     void willRunJavaScriptDialog(const String& message);
     void didRunJavaScriptDialog();
     bool applyViewportStyleOverride(StyleResolver*);
@@ -154,21 +146,21 @@
 
     // Cross-agents API
     Page* page() { return m_page; }
-    Frame* mainFrame();
+    LocalFrame* mainFrame();
     String createIdentifier();
-    Frame* frameForId(const String& frameId);
-    String frameId(Frame*);
-    bool hasIdForFrame(Frame*) const;
+    LocalFrame* frameForId(const String& frameId);
+    String frameId(LocalFrame*);
+    bool hasIdForFrame(LocalFrame*) const;
     String loaderId(DocumentLoader*);
-    Frame* findFrameWithSecurityOrigin(const String& originRawString);
-    Frame* assertFrame(ErrorString*, const String& frameId);
+    LocalFrame* findFrameWithSecurityOrigin(const String& originRawString);
+    LocalFrame* assertFrame(ErrorString*, const String& frameId);
     String scriptPreprocessorSource() { return m_scriptPreprocessorSource; }
     const AtomicString& resourceSourceMapURL(const String& url);
     bool deviceMetricsOverrideEnabled();
-    static DocumentLoader* assertDocumentLoader(ErrorString*, Frame*);
+    static DocumentLoader* assertDocumentLoader(ErrorString*, LocalFrame*);
 
 private:
-    static void resourceContent(ErrorString*, Frame*, const KURL&, String* result, bool* base64Encoded);
+    static void resourceContent(ErrorString*, LocalFrame*, const KURL&, String* result, bool* base64Encoded);
 
     InspectorPageAgent(Page*, InjectedScriptManager*, InspectorClient*, InspectorOverlay*);
     bool deviceMetricsChanged(int width, int height, double deviceScaleFactor, bool emulateViewport, bool fitWindow, double fontScaleFactor, bool textAutosizing);
@@ -178,8 +170,8 @@
 
     static bool dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result);
 
-    PassRefPtr<TypeBuilder::Page::Frame> buildObjectForFrame(Frame*);
-    PassRefPtr<TypeBuilder::Page::FrameResourceTree> buildObjectForFrameTree(Frame*);
+    PassRefPtr<TypeBuilder::Page::Frame> buildObjectForFrame(LocalFrame*);
+    PassRefPtr<TypeBuilder::Page::FrameResourceTree> buildObjectForFrameTree(LocalFrame*);
     Page* m_page;
     InjectedScriptManager* m_injectedScriptManager;
     InspectorClient* m_client;
@@ -190,8 +182,8 @@
     String m_scriptToEvaluateOnLoadOnce;
     String m_pendingScriptPreprocessor;
     String m_scriptPreprocessorSource;
-    HashMap<Frame*, String> m_frameToIdentifier;
-    HashMap<String, Frame*> m_identifierToFrame;
+    HashMap<LocalFrame*, String> m_frameToIdentifier;
+    HashMap<String, LocalFrame*> m_identifierToFrame;
     HashMap<DocumentLoader*, String> m_loaderToIdentifier;
     bool m_enabled;
     bool m_ignoreScriptsEnabledNotification;
diff --git a/Source/core/inspector/InspectorPromiseInstrumentation.h b/Source/core/inspector/InspectorPromiseInstrumentation.h
new file mode 100644
index 0000000..a6f9d9e
--- /dev/null
+++ b/Source/core/inspector/InspectorPromiseInstrumentation.h
@@ -0,0 +1 @@
+#include "InspectorPromiseInstrumentationInl.h"
diff --git a/Source/core/inspector/InspectorResourceAgent.cpp b/Source/core/inspector/InspectorResourceAgent.cpp
index d192d71..01ba6cb 100644
--- a/Source/core/inspector/InspectorResourceAgent.cpp
+++ b/Source/core/inspector/InspectorResourceAgent.cpp
@@ -41,7 +41,7 @@
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoader.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/IdentifiersFactory.h"
 #include "core/inspector/InspectorClient.h"
 #include "core/inspector/InspectorOverlay.h"
@@ -157,7 +157,7 @@
 private:
     void dispose()
     {
-        m_loader = 0;
+        m_loader = nullptr;
         delete this;
     }
 
@@ -231,8 +231,7 @@
 static PassRefPtr<TypeBuilder::Network::Response> buildObjectForResourceResponse(const ResourceResponse& response, DocumentLoader* loader)
 {
     if (response.isNull())
-        return 0;
-
+        return nullptr;
 
     double status;
     String statusText;
@@ -337,7 +336,7 @@
     m_frontend->requestServedFromCache(IdentifiersFactory::requestId(identifier));
 }
 
-void InspectorResourceAgent::didReceiveResourceResponse(Frame*, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+void InspectorResourceAgent::didReceiveResourceResponse(LocalFrame*, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
 {
     if (!loader)
         return;
@@ -409,7 +408,7 @@
     m_frontend->loadingFinished(requestId, finishTime, encodedDataLength);
 }
 
-void InspectorResourceAgent::didReceiveCORSRedirectResponse(Frame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+void InspectorResourceAgent::didReceiveCORSRedirectResponse(LocalFrame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
 {
     // Update the response and finish loading
     didReceiveResourceResponse(frame, identifier, loader, response, resourceLoader);
@@ -540,19 +539,29 @@
     m_frontend->webSocketCreated(IdentifiersFactory::requestId(identifier), urlWithoutFragment(requestURL).string());
 }
 
-void InspectorResourceAgent::willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest& request)
+void InspectorResourceAgent::willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest* request)
 {
+    ASSERT(request);
     RefPtr<TypeBuilder::Network::WebSocketRequest> requestObject = TypeBuilder::Network::WebSocketRequest::create()
-        .setHeaders(buildObjectForHeaders(request.headerFields()));
+        .setHeaders(buildObjectForHeaders(request->headerFields()));
     m_frontend->webSocketWillSendHandshakeRequest(IdentifiersFactory::requestId(identifier), currentTime(), requestObject);
 }
 
-void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse& response)
+void InspectorResourceAgent::didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeRequest* request, const WebSocketHandshakeResponse* response)
 {
+    ASSERT(response);
     RefPtr<TypeBuilder::Network::WebSocketResponse> responseObject = TypeBuilder::Network::WebSocketResponse::create()
-        .setStatus(response.statusCode())
-        .setStatusText(response.statusText())
-        .setHeaders(buildObjectForHeaders(response.headerFields()));
+        .setStatus(response->statusCode())
+        .setStatusText(response->statusText())
+        .setHeaders(buildObjectForHeaders(response->headerFields()));
+
+    if (!response->headersText().isEmpty())
+        responseObject->setHeadersText(response->headersText());
+    if (request) {
+        responseObject->setRequestHeaders(buildObjectForHeaders(request->headerFields()));
+        if (!request->headersText().isEmpty())
+            responseObject->setRequestHeadersText(request->headersText());
+    }
     m_frontend->webSocketHandshakeResponseReceived(IdentifiersFactory::requestId(identifier), currentTime(), responseObject);
 }
 
@@ -668,7 +677,7 @@
         return;
     }
 
-    RefPtr<XMLHttpRequest> xhr = XMLHttpRequest::create(executionContext);
+    RefPtrWillBeRawPtr<XMLHttpRequest> xhr = XMLHttpRequest::create(executionContext);
 
     Resource* cachedResource = memoryCache()->resourceForURL(xhrReplayData->url());
     if (cachedResource)
@@ -706,14 +715,14 @@
     m_state->setBoolean(ResourceAgentState::cacheDisabled, cacheDisabled);
     if (cacheDisabled)
         memoryCache()->evictResources();
-    for (Frame* frame = m_pageAgent->mainFrame(); frame; frame = frame->tree().traverseNext())
+    for (LocalFrame* frame = m_pageAgent->mainFrame(); frame; frame = frame->tree().traverseNext())
         frame->document()->fetcher()->garbageCollectDocumentResources();
 }
 
 void InspectorResourceAgent::loadResourceForFrontend(ErrorString* errorString, const String& frameId, const String& url, const RefPtr<JSONObject>* requestHeaders, PassRefPtr<LoadResourceForFrontendCallback> prpCallback)
 {
     RefPtr<LoadResourceForFrontendCallback> callback = prpCallback;
-    Frame* frame = m_pageAgent->assertFrame(errorString, frameId);
+    LocalFrame* frame = m_pageAgent->assertFrame(errorString, frameId);
     if (!frame)
         return;
 
@@ -754,7 +763,7 @@
     inspectorThreadableLoaderClient->setLoader(loader.release());
 }
 
-void InspectorResourceAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void InspectorResourceAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
 {
     if (loader->frame() != frame->page()->mainFrame())
         return;
@@ -765,18 +774,18 @@
     m_resourcesData->clear(m_pageAgent->loaderId(loader));
 }
 
-void InspectorResourceAgent::frameScheduledNavigation(Frame* frame, double)
+void InspectorResourceAgent::frameScheduledNavigation(LocalFrame* frame, double)
 {
     RefPtr<TypeBuilder::Network::Initiator> initiator = buildInitiatorObject(frame->document(), FetchInitiatorInfo());
     m_frameNavigationInitiatorMap.set(m_pageAgent->frameId(frame), initiator);
 }
 
-void InspectorResourceAgent::frameClearedScheduledNavigation(Frame* frame)
+void InspectorResourceAgent::frameClearedScheduledNavigation(LocalFrame* frame)
 {
     m_frameNavigationInitiatorMap.remove(m_pageAgent->frameId(frame));
 }
 
-bool InspectorResourceAgent::fetchResourceContent(Frame* frame, const KURL& url, String* content, bool* base64Encoded)
+bool InspectorResourceAgent::fetchResourceContent(LocalFrame* frame, const KURL& url, String* content, bool* base64Encoded)
 {
     // First try to fetch content from the cached resource.
     Resource* cachedResource = frame->document()->fetcher()->cachedResource(url);
diff --git a/Source/core/inspector/InspectorResourceAgent.h b/Source/core/inspector/InspectorResourceAgent.h
index b46bbca..70bfc24 100644
--- a/Source/core/inspector/InspectorResourceAgent.h
+++ b/Source/core/inspector/InspectorResourceAgent.h
@@ -49,7 +49,7 @@
 class Document;
 class DocumentLoader;
 class FormData;
-class Frame;
+class LocalFrame;
 class HTTPHeaderMap;
 class InspectorClient;
 class InspectorFrontend;
@@ -88,12 +88,12 @@
     // Called from instrumentation.
     void willSendRequest(unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse, const FetchInitiatorInfo&);
     void markResourceAsCached(unsigned long identifier);
-    void didReceiveResourceResponse(Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+    void didReceiveResourceResponse(LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
     void didReceiveData(unsigned long identifier, const char* data, int dataLength, int encodedDataLength);
     void didFinishLoading(unsigned long identifier, DocumentLoader*, double monotonicFinishTime, int64_t encodedDataLength);
-    void didReceiveCORSRedirectResponse(Frame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+    void didReceiveCORSRedirectResponse(LocalFrame*, unsigned long identifier, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
     void didFailLoading(unsigned long identifier, const ResourceError&);
-    void didCommitLoad(Frame*, DocumentLoader*);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
     void scriptImported(unsigned long identifier, const String& sourceString);
     void didReceiveScriptResponse(unsigned long identifier);
 
@@ -111,14 +111,14 @@
     void didRecalculateStyle();
     void didScheduleStyleRecalculation(Document*);
 
-    void frameScheduledNavigation(Frame*, double);
-    void frameClearedScheduledNavigation(Frame*);
+    void frameScheduledNavigation(LocalFrame*, double);
+    void frameClearedScheduledNavigation(LocalFrame*);
 
     PassRefPtr<TypeBuilder::Network::Initiator> buildInitiatorObject(Document*, const FetchInitiatorInfo&);
 
     void didCreateWebSocket(Document*, unsigned long identifier, const KURL& requestURL, const String&);
-    void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest&);
-    void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse&);
+    void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest*);
+    void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeRequest*, const WebSocketHandshakeResponse*);
     void didCloseWebSocket(Document*, unsigned long identifier);
     void didReceiveWebSocketFrame(unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
     void didSendWebSocketFrame(unsigned long identifier, int opCode, bool masked, const char* payload, size_t payloadLength);
@@ -145,7 +145,7 @@
     virtual void loadResourceForFrontend(ErrorString*, const String& frameId, const String& url, const RefPtr<JSONObject>* requestHeaders, PassRefPtr<LoadResourceForFrontendCallback>) OVERRIDE;
 
     // Called from other agents.
-    bool fetchResourceContent(Frame*, const KURL&, String* content, bool* base64Encoded);
+    bool fetchResourceContent(LocalFrame*, const KURL&, String* content, bool* base64Encoded);
 
 private:
     InspectorResourceAgent(InspectorPageAgent*, InspectorClient*);
diff --git a/Source/core/inspector/InspectorStyleSheet.cpp b/Source/core/inspector/InspectorStyleSheet.cpp
index 22c9cd4..8e9081b 100644
--- a/Source/core/inspector/InspectorStyleSheet.cpp
+++ b/Source/core/inspector/InspectorStyleSheet.cpp
@@ -26,8 +26,6 @@
 #include "core/inspector/InspectorStyleSheet.h"
 
 #include "CSSPropertyNames.h"
-#include "HTMLNames.h"
-#include "SVGNames.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "bindings/v8/ScriptRegexp.h"
@@ -44,11 +42,13 @@
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/frame/PageConsole.h"
+#include "core/html/HTMLStyleElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/inspector/ContentSearchUtils.h"
 #include "core/inspector/InspectorCSSAgent.h"
 #include "core/inspector/InspectorPageAgent.h"
 #include "core/inspector/InspectorResourceAgent.h"
+#include "core/svg/SVGStyleElement.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/text/StringBuilder.h"
@@ -57,88 +57,17 @@
 using WebCore::TypeBuilder::Array;
 using WebCore::RuleSourceDataList;
 using WebCore::CSSRuleSourceData;
+using WebCore::CSSStyleSheet;
 
-class ParsedStyleSheet {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    ParsedStyleSheet();
-
-    const String& text() const { ASSERT(m_hasText); return m_text; }
-    void setText(const String& text);
-    bool hasText() const { return m_hasText; }
-    void setSourceData(PassOwnPtr<RuleSourceDataList>);
-    bool hasSourceData() const { return m_sourceData; }
-    PassRefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const;
-
-private:
-    void flattenSourceData(RuleSourceDataList*);
-
-    String m_text;
-    bool m_hasText;
-    OwnPtr<RuleSourceDataList> m_sourceData;
-};
-
-ParsedStyleSheet::ParsedStyleSheet()
-    : m_hasText(false)
+static PassOwnPtr<WebCore::BisonCSSParser> createCSSParser(WebCore::Document* document)
 {
-}
-
-void ParsedStyleSheet::setText(const String& text)
-{
-    m_hasText = true;
-    m_text = text;
-    setSourceData(nullptr);
-}
-
-void ParsedStyleSheet::flattenSourceData(RuleSourceDataList* dataList)
-{
-    for (size_t i = 0; i < dataList->size(); ++i) {
-        RefPtr<CSSRuleSourceData>& data = dataList->at(i);
-        if (data->type == CSSRuleSourceData::STYLE_RULE) {
-            m_sourceData->append(data);
-        } else if (data->type == CSSRuleSourceData::IMPORT_RULE) {
-            m_sourceData->append(data);
-        } else if (data->type == CSSRuleSourceData::MEDIA_RULE) {
-            m_sourceData->append(data);
-            flattenSourceData(&data->childRules);
-        } else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) {
-            flattenSourceData(&data->childRules);
-        }
-    }
-}
-
-void ParsedStyleSheet::setSourceData(PassOwnPtr<RuleSourceDataList> sourceData)
-{
-    if (!sourceData) {
-        m_sourceData.clear();
-        return;
-    }
-
-    m_sourceData = adoptPtr(new RuleSourceDataList());
-
-    // FIXME: This is a temporary solution to retain the original flat sourceData structure
-    // containing only style rules, even though BisonCSSParser now provides the full rule source data tree.
-    // Normally, we should just assign m_sourceData = sourceData;
-    flattenSourceData(sourceData.get());
-}
-
-PassRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned index) const
-{
-    if (!hasSourceData() || index >= m_sourceData->size())
-        return 0;
-
-    return m_sourceData->at(index);
-}
-
-namespace WebCore {
-
-static PassOwnPtr<BisonCSSParser> createCSSParser(Document* document)
-{
-    return adoptPtr(new BisonCSSParser(document ? CSSParserContext(*document, 0) : strictCSSParserContext()));
+    return adoptPtr(new WebCore::BisonCSSParser(document ? WebCore::CSSParserContext(*document, 0) : WebCore::strictCSSParserContext()));
 }
 
 namespace {
 
+using namespace WebCore;
+
 class StyleSheetHandler FINAL : public CSSParserObserver {
 public:
     StyleSheetHandler(const String& parsedText, Document* document, StyleSheetContents* styleSheetContents, RuleSourceDataList* result)
@@ -427,6 +356,99 @@
 
 } // namespace
 
+class ParsedStyleSheet {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    ParsedStyleSheet(CSSStyleSheet* pageStyleSheet);
+
+    const String& text() const { ASSERT(m_hasText); return m_text; }
+    void setText(const String&);
+    bool hasText() const { return m_hasText; }
+    bool ensureSourceData();
+    bool hasSourceData() const { return m_sourceData; }
+    PassRefPtr<WebCore::CSSRuleSourceData> ruleSourceDataAt(unsigned) const;
+
+private:
+    void flattenSourceData(RuleSourceDataList*);
+    void setSourceData(PassOwnPtr<RuleSourceDataList>);
+
+    String m_text;
+    bool m_hasText;
+    OwnPtr<RuleSourceDataList> m_sourceData;
+    RefPtr<CSSStyleSheet> m_pageStyleSheet;
+};
+
+ParsedStyleSheet::ParsedStyleSheet(CSSStyleSheet* pageStyleSheet)
+    : m_hasText(false)
+    , m_pageStyleSheet(pageStyleSheet)
+{
+}
+
+void ParsedStyleSheet::setText(const String& text)
+{
+    m_hasText = true;
+    m_text = text;
+    setSourceData(nullptr);
+}
+
+void ParsedStyleSheet::flattenSourceData(RuleSourceDataList* dataList)
+{
+    for (size_t i = 0; i < dataList->size(); ++i) {
+        RefPtr<CSSRuleSourceData>& data = dataList->at(i);
+        if (data->type == CSSRuleSourceData::STYLE_RULE) {
+            m_sourceData->append(data);
+        } else if (data->type == CSSRuleSourceData::IMPORT_RULE) {
+            m_sourceData->append(data);
+        } else if (data->type == CSSRuleSourceData::MEDIA_RULE) {
+            m_sourceData->append(data);
+            flattenSourceData(&data->childRules);
+        } else if (data->type == CSSRuleSourceData::SUPPORTS_RULE) {
+            flattenSourceData(&data->childRules);
+        }
+    }
+}
+
+bool ParsedStyleSheet::ensureSourceData()
+{
+    if (hasSourceData())
+        return true;
+
+    if (!hasText())
+        return false;
+
+    RefPtrWillBeRawPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::create(strictCSSParserContext());
+    OwnPtr<RuleSourceDataList> result = adoptPtr(new RuleSourceDataList());
+    StyleSheetHandler handler(text(), m_pageStyleSheet->ownerDocument(), newStyleSheet.get(), result.get());
+    createCSSParser(m_pageStyleSheet->ownerDocument())->parseSheet(newStyleSheet.get(), text(), TextPosition::minimumPosition(), &handler);
+    setSourceData(result.release());
+    return hasSourceData();
+}
+
+void ParsedStyleSheet::setSourceData(PassOwnPtr<RuleSourceDataList> sourceData)
+{
+    if (!sourceData) {
+        m_sourceData.clear();
+        return;
+    }
+
+    m_sourceData = adoptPtr(new RuleSourceDataList());
+
+    // FIXME: This is a temporary solution to retain the original flat sourceData structure
+    // containing only style rules, even though BisonCSSParser now provides the full rule source data tree.
+    // Normally, we should just assign m_sourceData = sourceData;
+    flattenSourceData(sourceData.get());
+}
+
+PassRefPtr<WebCore::CSSRuleSourceData> ParsedStyleSheet::ruleSourceDataAt(unsigned index) const
+{
+    if (!hasSourceData() || index >= m_sourceData->size())
+        return nullptr;
+
+    return m_sourceData->at(index);
+}
+
+namespace WebCore {
+
 enum MediaListSource {
     MediaListSourceLinkedSheet,
     MediaListSourceInlineSheet,
@@ -437,7 +459,7 @@
 static PassRefPtr<TypeBuilder::CSS::SourceRange> buildSourceRangeObject(const SourceRange& range, Vector<unsigned>* lineEndings)
 {
     if (!lineEndings)
-        return 0;
+        return nullptr;
     TextPosition start = TextPosition::fromOffsetAndLineEndings(range.start, *lineEndings);
     TextPosition end = TextPosition::fromOffsetAndLineEndings(range.end, *lineEndings);
 
@@ -449,13 +471,13 @@
     return result.release();
 }
 
-static PassRefPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet)
+static PassRefPtrWillBeRawPtr<CSSRuleList> asCSSRuleList(CSSStyleSheet* styleSheet)
 {
     if (!styleSheet)
-        return 0;
+        return nullptr;
 
-    RefPtr<StaticCSSRuleList> list = StaticCSSRuleList::create();
-    Vector<RefPtr<CSSRule> >& listRules = list->rules();
+    RefPtrWillBeRawPtr<StaticCSSRuleList> list = StaticCSSRuleList::create();
+    WillBeHeapVector<RefPtrWillBeMember<CSSRule> >& listRules = list->rules();
     for (unsigned i = 0, size = styleSheet->length(); i < size; ++i) {
         CSSRule* item = styleSheet->item(i);
         if (item->type() == CSSRule::CHARSET_RULE)
@@ -465,10 +487,10 @@
     return list.release();
 }
 
-static PassRefPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
+static PassRefPtrWillBeRawPtr<CSSRuleList> asCSSRuleList(CSSRule* rule)
 {
     if (!rule)
-        return 0;
+        return nullptr;
 
     if (rule->type() == CSSRule::MEDIA_RULE)
         return toCSSMediaRule(rule)->cssRules();
@@ -479,7 +501,7 @@
     if (rule->type() == CSSRule::SUPPORTS_RULE)
         return toCSSSupportsRule(rule)->cssRules();
 
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<InspectorStyle> InspectorStyle::create(const InspectorCSSId& styleId, PassRefPtr<CSSStyleDeclaration> style, InspectorStyleSheet* parentStyleSheet)
@@ -531,7 +553,7 @@
     DEFINE_STATIC_LOCAL(String, bogusPropertyName, ("-webkit-boguz-propertee"));
     RefPtr<MutableStylePropertySet> tempMutableStyle = MutableStylePropertySet::create();
     RuleSourceDataList sourceData;
-    RefPtr<StyleSheetContents> styleSheetContents = StyleSheetContents::create(strictCSSParserContext());
+    RefPtrWillBeRawPtr<StyleSheetContents> styleSheetContents = StyleSheetContents::create(strictCSSParserContext());
     String declarationText = propertyText + (canOmitSemicolon ? ";" : " ") + bogusPropertyName + ": none";
     StyleSheetHandler handler(declarationText, ownerDocument(), styleSheetContents.get(), &sourceData);
     createCSSParser(ownerDocument())->parseDeclaration(tempMutableStyle.get(), declarationText, &handler, styleSheetContents.get());
@@ -642,10 +664,7 @@
 {
     RefPtr<Array<TypeBuilder::CSS::CSSProperty> > propertiesObject = Array<TypeBuilder::CSS::CSSProperty>::create();
     RefPtr<Array<TypeBuilder::CSS::ShorthandEntry> > shorthandEntries = Array<TypeBuilder::CSS::ShorthandEntry>::create();
-    HashMap<String, RefPtr<TypeBuilder::CSS::CSSProperty> > propertyNameToPreviousActiveProperty;
     HashSet<String> foundShorthands;
-    String previousPriority;
-    String previousStatus;
     OwnPtr<Vector<unsigned> > lineEndings(m_parentStyleSheet ? m_parentStyleSheet->lineEndings() : PassOwnPtr<Vector<unsigned> >());
     RefPtr<CSSRuleSourceData> sourceData = extractSourceData();
     unsigned ruleBodyRangeStart = sourceData ? sourceData->ruleBodyRange.start : 0;
@@ -656,9 +675,6 @@
     for (Vector<InspectorStyleProperty>::iterator it = properties.begin(), itEnd = properties.end(); it != itEnd; ++it) {
         const CSSPropertySourceData& propertyEntry = it->sourceData;
         const String& name = propertyEntry.name;
-        const bool disabled = it->sourceData.disabled;
-
-        TypeBuilder::CSS::CSSProperty::Status::Enum status = disabled ? TypeBuilder::CSS::CSSProperty::Status::Disabled : TypeBuilder::CSS::CSSProperty::Status::Active;
 
         RefPtr<TypeBuilder::CSS::CSSProperty> property = TypeBuilder::CSS::CSSProperty::create()
             .setName(name)
@@ -671,9 +687,8 @@
         if (it->hasRawText())
             property->setText(it->rawText);
 
-        // Default "priority" == "".
         if (propertyEntry.important)
-            property->setPriority("important");
+            property->setImportant(true);
         if (it->hasSource) {
             // The property range is relative to the style body start.
             // Should be converted into an absolute range (relative to the stylesheet start)
@@ -682,66 +697,27 @@
             absolutePropertyRange.start += ruleBodyRangeStart;
             absolutePropertyRange.end += ruleBodyRangeStart;
             property->setRange(buildSourceRangeObject(absolutePropertyRange, lineEndings.get()));
-        }
-        if (!disabled) {
-            if (it->hasSource) {
+            if (!propertyEntry.disabled) {
                 ASSERT(sourceData);
                 property->setImplicit(false);
+            }
+            property->setDisabled(propertyEntry.disabled);
+        } else if (!propertyEntry.disabled) {
+            bool implicit = m_style->isPropertyImplicit(name);
+            // Default "implicit" == false.
+            if (implicit)
+                property->setImplicit(true);
 
-                // Parsed property overrides any property with the same name. Non-parsed property overrides
-                // previous non-parsed property with the same name (if any).
-                bool shouldInactivate = false;
-                CSSPropertyID propertyId = cssPropertyID(name);
-                // Canonicalize property names to treat non-prefixed and vendor-prefixed property names the same (opacity vs. -webkit-opacity).
-                String canonicalPropertyName = propertyId ? getPropertyNameString(propertyId) : name;
-                HashMap<String, RefPtr<TypeBuilder::CSS::CSSProperty> >::iterator activeIt = propertyNameToPreviousActiveProperty.find(canonicalPropertyName);
-                if (activeIt != propertyNameToPreviousActiveProperty.end()) {
-                    if (propertyEntry.parsedOk) {
-                        bool successPriority = activeIt->value->getString(TypeBuilder::CSS::CSSProperty::Priority, &previousPriority);
-                        bool successStatus = activeIt->value->getString(TypeBuilder::CSS::CSSProperty::Status, &previousStatus);
-                        if (successStatus && previousStatus != "inactive") {
-                            if (propertyEntry.important || !successPriority) // Priority not set == "not important".
-                                shouldInactivate = true;
-                            else if (status == TypeBuilder::CSS::CSSProperty::Status::Active) {
-                                // Inactivate a non-important property following the same-named important property.
-                                status = TypeBuilder::CSS::CSSProperty::Status::Inactive;
-                            }
-                        }
-                    } else {
-                        bool previousParsedOk;
-                        bool success = activeIt->value->getBoolean(TypeBuilder::CSS::CSSProperty::ParsedOk, &previousParsedOk);
-                        if (success && !previousParsedOk)
-                            shouldInactivate = true;
-                    }
-                } else
-                    propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property);
-
-                if (shouldInactivate) {
-                    activeIt->value->setStatus(TypeBuilder::CSS::CSSProperty::Status::Inactive);
-                    propertyNameToPreviousActiveProperty.set(canonicalPropertyName, property);
-                }
-            } else {
-                bool implicit = m_style->isPropertyImplicit(name);
-                // Default "implicit" == false.
-                if (implicit)
-                    property->setImplicit(true);
-                status = TypeBuilder::CSS::CSSProperty::Status::Style;
-
-                String shorthand = m_style->getPropertyShorthand(name);
-                if (!shorthand.isEmpty()) {
-                    if (foundShorthands.add(shorthand).isNewEntry) {
-                        RefPtr<TypeBuilder::CSS::ShorthandEntry> entry = TypeBuilder::CSS::ShorthandEntry::create()
-                            .setName(shorthand)
-                            .setValue(shorthandValue(shorthand));
-                        shorthandEntries->addItem(entry);
-                    }
+            String shorthand = m_style->getPropertyShorthand(name);
+            if (!shorthand.isEmpty()) {
+                if (foundShorthands.add(shorthand).isNewEntry) {
+                    RefPtr<TypeBuilder::CSS::ShorthandEntry> entry = TypeBuilder::CSS::ShorthandEntry::create()
+                        .setName(shorthand)
+                        .setValue(shorthandValue(shorthand));
+                    shorthandEntries->addItem(entry);
                 }
             }
         }
-
-        // Default "status" == "style".
-        if (status != TypeBuilder::CSS::CSSProperty::Status::Style)
-            property->setStatus(status);
     }
 
     RefPtr<TypeBuilder::CSS::CSSStyle> result = TypeBuilder::CSS::CSSStyle::create()
@@ -753,7 +729,7 @@
 PassRefPtr<CSSRuleSourceData> InspectorStyle::extractSourceData() const
 {
     if (!m_parentStyleSheet || !m_parentStyleSheet->ensureParsedDataReady())
-        return 0;
+        return nullptr;
     return m_parentStyleSheet->ruleSourceDataFor(m_style.get());
 }
 
@@ -787,36 +763,6 @@
     return value;
 }
 
-String InspectorStyle::shorthandPriority(const String& shorthandProperty) const
-{
-    String priority = m_style->getPropertyPriority(shorthandProperty);
-    if (priority.isEmpty()) {
-        for (unsigned i = 0; i < m_style->length(); ++i) {
-            String individualProperty = m_style->item(i);
-            if (m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
-                continue;
-            priority = m_style->getPropertyPriority(individualProperty);
-            break;
-        }
-    }
-    return priority;
-}
-
-Vector<String> InspectorStyle::longhandProperties(const String& shorthandProperty) const
-{
-    Vector<String> properties;
-    HashSet<String> foundProperties;
-    for (unsigned i = 0; i < m_style->length(); ++i) {
-        String individualProperty = m_style->item(i);
-        if (foundProperties.contains(individualProperty) || m_style->getPropertyShorthand(individualProperty) != shorthandProperty)
-            continue;
-
-        foundProperties.add(individualProperty);
-        properties.append(individualProperty);
-    }
-    return properties;
-}
-
 NewLineAndWhitespace& InspectorStyle::newLineAndWhitespaceDelimiters() const
 {
     DEFINE_STATIC_LOCAL(String, defaultPrefix, ("    "));
@@ -892,41 +838,6 @@
     return adoptRef(new InspectorStyleSheet(pageAgent, resourceAgent, id, pageStyleSheet, origin, documentURL, listener));
 }
 
-// static
-String InspectorStyleSheet::styleSheetURL(CSSStyleSheet* pageStyleSheet)
-{
-    if (pageStyleSheet && !pageStyleSheet->contents()->baseURL().isEmpty())
-        return pageStyleSheet->contents()->baseURL().string();
-    return emptyString();
-}
-
-// static
-void InspectorStyleSheet::collectFlatRules(PassRefPtr<CSSRuleList> ruleList, CSSRuleVector* result)
-{
-    if (!ruleList)
-        return;
-
-    for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
-        CSSRule* rule = ruleList->item(i);
-
-        // The result->append()'ed types should be exactly the same as in ParsedStyleSheet::flattenSourceData().
-        switch (rule->type()) {
-        case CSSRule::STYLE_RULE:
-            result->append(rule);
-            continue;
-        case CSSRule::IMPORT_RULE:
-        case CSSRule::MEDIA_RULE:
-            result->append(rule);
-            break;
-        default:
-            break;
-        }
-        RefPtr<CSSRuleList> childRuleList = asCSSRuleList(rule);
-        if (childRuleList)
-            collectFlatRules(childRuleList, result);
-    }
-}
-
 InspectorStyleSheet::InspectorStyleSheet(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, const String& documentURL, Listener* listener)
     : m_pageAgent(pageAgent)
     , m_resourceAgent(resourceAgent)
@@ -934,15 +845,20 @@
     , m_pageStyleSheet(pageStyleSheet)
     , m_origin(origin)
     , m_documentURL(documentURL)
-    , m_isRevalidating(false)
     , m_listener(listener)
 {
-    m_parsedStyleSheet = new ParsedStyleSheet();
+    m_parsedStyleSheet = adoptPtr(new ParsedStyleSheet(m_pageStyleSheet.get()));
 }
 
 InspectorStyleSheet::~InspectorStyleSheet()
 {
-    delete m_parsedStyleSheet;
+}
+
+static String styleSheetURL(CSSStyleSheet* pageStyleSheet)
+{
+    if (pageStyleSheet && !pageStyleSheet->contents()->baseURL().isEmpty())
+        return pageStyleSheet->contents()->baseURL().string();
+    return emptyString();
 }
 
 String InspectorStyleSheet::finalURL() const
@@ -1084,7 +1000,7 @@
 {
     if (!checkPageStyleSheet(exceptionState))
         return false;
-    RefPtr<CSSStyleRule> rule = ruleForId(id);
+    RefPtrWillBeRawPtr<CSSStyleRule> rule = ruleForId(id);
     if (!rule) {
         exceptionState.throwDOMException(NotFoundError, "No style rule could be found for the provided ID.");
         return false;
@@ -1116,37 +1032,19 @@
 
 CSSStyleRule* InspectorStyleSheet::ruleForId(const InspectorCSSId& id) const
 {
-    if (!m_pageStyleSheet)
-        return 0;
-
     ASSERT(!id.isEmpty());
     ensureFlatRules();
     return InspectorCSSAgent::asCSSStyleRule(id.ordinal() >= m_flatRules.size() ? 0 : m_flatRules.at(id.ordinal()).get());
 }
 
-bool InspectorStyleSheet::fillObjectForStyleSheet(PassRefPtr<TypeBuilder::CSS::CSSStyleSheetBody> prpResult)
-{
-    CSSStyleSheet* styleSheet = pageStyleSheet();
-    if (!styleSheet)
-        return false;
-
-    RefPtr<TypeBuilder::CSS::CSSStyleSheetBody> result = prpResult;
-
-    String styleSheetText;
-    bool success = getText(&styleSheetText);
-    if (success)
-        result->setText(styleSheetText);
-    return success;
-}
-
 PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> InspectorStyleSheet::buildObjectForStyleSheetInfo() const
 {
     CSSStyleSheet* styleSheet = pageStyleSheet();
     if (!styleSheet)
-        return 0;
+        return nullptr;
 
     Document* document = styleSheet->ownerDocument();
-    Frame* frame = document ? document->frame() : 0;
+    LocalFrame* frame = document ? document->frame() : 0;
 
     RefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> result = TypeBuilder::CSS::CSSStyleSheetHeader::create()
         .setStyleSheetId(id())
@@ -1216,11 +1114,16 @@
     return result.release();
 }
 
+static bool canBind(TypeBuilder::CSS::StyleSheetOrigin::Enum origin)
+{
+    return origin != TypeBuilder::CSS::StyleSheetOrigin::User_agent && origin != TypeBuilder::CSS::StyleSheetOrigin::User;
+}
+
 PassRefPtr<TypeBuilder::CSS::CSSRule> InspectorStyleSheet::buildObjectForRule(CSSStyleRule* rule, PassRefPtr<Array<TypeBuilder::CSS::CSSMedia> > mediaStack)
 {
     CSSStyleSheet* styleSheet = pageStyleSheet();
     if (!styleSheet)
-        return 0;
+        return nullptr;
 
     RefPtr<TypeBuilder::CSS::CSSRule> result = TypeBuilder::CSS::CSSRule::create()
         .setSelectorList(buildObjectForSelectorList(rule))
@@ -1231,7 +1134,7 @@
     if (!url.isEmpty())
         result->setSourceURL(url);
 
-    if (canBind()) {
+    if (canBind(m_origin)) {
         InspectorCSSId id(ruleId(rule));
         if (!id.isEmpty())
             result->setRuleId(id.asProtocolValue<TypeBuilder::CSS::CSSRuleId>());
@@ -1249,7 +1152,7 @@
     if (ensureParsedDataReady())
         sourceData = ruleSourceDataFor(style);
 
-    InspectorCSSId id = ruleOrStyleId(style);
+    InspectorCSSId id = ruleIdByStyle(style);
     if (id.isEmpty()) {
         // Any rule coming from User Agent and not from DefaultStyleSheet will not have id.
         // See InspectorCSSAgent::buildObjectForRule for details.
@@ -1272,28 +1175,6 @@
     return result.release();
 }
 
-bool InspectorStyleSheet::setStyleText(const InspectorCSSId& id, const String& text, String* oldText, ExceptionState& exceptionState)
-{
-    RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
-    if (!inspectorStyle || !inspectorStyle->cssStyle()) {
-        exceptionState.throwDOMException(NotFoundError, "No property could be found for the given ID.");
-        return false;
-    }
-
-    bool success = inspectorStyle->styleText(oldText);
-    if (!success) {
-        exceptionState.throwDOMException(NotFoundError, "Style text could not be read for the given property.");
-        return false;
-    }
-
-    success = setStyleText(inspectorStyle->cssStyle(), text);
-    if (success)
-        fireStyleSheetChanged();
-    else
-        exceptionState.throwDOMException(SyntaxError, "The style text '" + text + "' is invalid.");
-    return success;
-}
-
 bool InspectorStyleSheet::setPropertyText(const InspectorCSSId& id, unsigned propertyIndex, const String& text, bool overwrite, String* oldText, ExceptionState& exceptionState)
 {
     RefPtr<InspectorStyle> inspectorStyle = inspectorStyleForId(id);
@@ -1334,11 +1215,11 @@
 PassRefPtr<TypeBuilder::CSS::SourceRange> InspectorStyleSheet::ruleHeaderSourceRange(const CSSRule* rule)
 {
     if (!ensureParsedDataReady())
-        return 0;
+        return nullptr;
 
     RefPtr<CSSRuleSourceData> sourceData = m_parsedStyleSheet->ruleSourceDataAt(ruleIndexByRule(rule));
     if (!sourceData)
-        return 0;
+        return nullptr;
     return buildSourceRangeObject(sourceData->ruleHeaderRange, lineEndings().get());
 }
 
@@ -1346,7 +1227,7 @@
 {
     CSSStyleDeclaration* style = styleForId(id);
     if (!style)
-        return 0;
+        return nullptr;
 
     return InspectorStyle::create(id, style, this);
 }
@@ -1426,7 +1307,7 @@
     return m_pageAgent->resourceSourceMapURL(finalURL());
 }
 
-InspectorCSSId InspectorStyleSheet::ruleOrStyleId(CSSStyleDeclaration* style) const
+InspectorCSSId InspectorStyleSheet::ruleIdByStyle(CSSStyleDeclaration* style) const
 {
     unsigned index = ruleIndexByStyle(style);
     if (index != UINT_MAX)
@@ -1480,7 +1361,7 @@
 
 bool InspectorStyleSheet::ensureParsedDataReady()
 {
-    return ensureText() && ensureSourceData();
+    return ensureText() && m_parsedStyleSheet->ensureSourceData();
 }
 
 bool InspectorStyleSheet::ensureText() const
@@ -1499,20 +1380,30 @@
     return success;
 }
 
-bool InspectorStyleSheet::ensureSourceData()
+static void collectFlatRules(PassRefPtrWillBeRawPtr<CSSRuleList> ruleList, CSSRuleVector* result)
 {
-    if (m_parsedStyleSheet->hasSourceData())
-        return true;
+    if (!ruleList)
+        return;
 
-    if (!m_parsedStyleSheet->hasText())
-        return false;
+    for (unsigned i = 0, size = ruleList->length(); i < size; ++i) {
+        CSSRule* rule = ruleList->item(i);
 
-    RefPtr<StyleSheetContents> newStyleSheet = StyleSheetContents::create(strictCSSParserContext());
-    OwnPtr<RuleSourceDataList> result = adoptPtr(new RuleSourceDataList());
-    StyleSheetHandler handler(m_parsedStyleSheet->text(), m_pageStyleSheet->ownerDocument(), newStyleSheet.get(), result.get());
-    createCSSParser(m_pageStyleSheet->ownerDocument())->parseSheet(newStyleSheet.get(), m_parsedStyleSheet->text(), TextPosition::minimumPosition(), &handler);
-    m_parsedStyleSheet->setSourceData(result.release());
-    return m_parsedStyleSheet->hasSourceData();
+        // The result->append()'ed types should be exactly the same as in ParsedStyleSheet::flattenSourceData().
+        switch (rule->type()) {
+        case CSSRule::STYLE_RULE:
+            result->append(rule);
+            continue;
+        case CSSRule::IMPORT_RULE:
+        case CSSRule::MEDIA_RULE:
+            result->append(rule);
+            break;
+        default:
+            break;
+        }
+        RefPtrWillBeRawPtr<CSSRuleList> childRuleList = asCSSRuleList(rule);
+        if (childRuleList)
+            collectFlatRules(childRuleList, result);
+    }
 }
 
 void InspectorStyleSheet::ensureFlatRules() const
@@ -1534,7 +1425,7 @@
     if (!success)
         return false;
 
-    InspectorCSSId id = ruleOrStyleId(style);
+    InspectorCSSId id = ruleIdByStyle(style);
     if (id.isEmpty())
         return false;
 
@@ -1569,25 +1460,7 @@
 
 InspectorCSSId InspectorStyleSheet::ruleId(CSSStyleRule* rule) const
 {
-    return ruleOrStyleId(rule->style());
-}
-
-void InspectorStyleSheet::revalidateStyle(CSSStyleDeclaration* pageStyle)
-{
-    if (m_isRevalidating)
-        return;
-
-    m_isRevalidating = true;
-    ensureFlatRules();
-    for (unsigned i = 0, size = m_flatRules.size(); i < size; ++i) {
-        CSSStyleRule* parsedRule = InspectorCSSAgent::asCSSStyleRule(m_flatRules.at(i).get());
-        if (parsedRule && parsedRule->style() == pageStyle) {
-            if (parsedRule->styleRule()->properties()->asText() != pageStyle->cssText())
-                setStyleText(pageStyle, pageStyle->cssText());
-            break;
-        }
-    }
-    m_isRevalidating = false;
+    return ruleIdByStyle(rule->style());
 }
 
 bool InspectorStyleSheet::originalStyleSheetText(String* result) const
@@ -1619,23 +1492,23 @@
     Node* ownerNode = m_pageStyleSheet->ownerNode();
     if (!ownerNode || ownerNode->nodeType() != Node::ELEMENT_NODE)
         return false;
-    Element* ownerElement = toElement(ownerNode);
+    Element& ownerElement = toElement(*ownerNode);
 
-    if (!ownerElement->hasTagName(HTMLNames::styleTag) && !ownerElement->hasTagName(SVGNames::styleTag))
+    if (!isHTMLStyleElement(ownerElement) && !isSVGStyleElement(ownerElement))
         return false;
-    *result = ownerElement->textContent();
+    *result = ownerElement.textContent();
     return true;
 }
 
-PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<Element> element, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener)
+PassRefPtr<InspectorStyleSheetForInlineStyle> InspectorStyleSheetForInlineStyle::create(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<Element> element, Listener* listener)
 {
-    return adoptRef(new InspectorStyleSheetForInlineStyle(pageAgent, resourceAgent, id, element, origin, listener));
+    return adoptRef(new InspectorStyleSheetForInlineStyle(pageAgent, resourceAgent, id, element, listener));
 }
 
-InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<Element> element, TypeBuilder::CSS::StyleSheetOrigin::Enum origin, Listener* listener)
-    : InspectorStyleSheet(pageAgent, resourceAgent, id, 0, origin, "", listener)
+InspectorStyleSheetForInlineStyle::InspectorStyleSheetForInlineStyle(InspectorPageAgent* pageAgent, InspectorResourceAgent* resourceAgent, const String& id, PassRefPtr<Element> element, Listener* listener)
+    : InspectorStyleSheet(pageAgent, resourceAgent, id, nullptr, TypeBuilder::CSS::StyleSheetOrigin::Regular, "", listener)
     , m_element(element)
-    , m_ruleSourceData(0)
+    , m_ruleSourceData(nullptr)
     , m_isStyleTextValid(false)
 {
     ASSERT(m_element);
@@ -1743,7 +1616,7 @@
 PassRefPtr<CSSRuleSourceData> InspectorStyleSheetForInlineStyle::getStyleAttributeData() const
 {
     if (!m_element->isStyledElement())
-        return 0;
+        return nullptr;
 
     if (m_styleText.isEmpty()) {
         RefPtr<CSSRuleSourceData> result = CSSRuleSourceData::create(CSSRuleSourceData::STYLE_RULE);
@@ -1754,8 +1627,8 @@
 
     RefPtr<MutableStylePropertySet> tempDeclaration = MutableStylePropertySet::create();
     RuleSourceDataList ruleSourceDataResult;
-    StyleSheetHandler handler(m_styleText, &m_element->document(), m_element->document().elementSheet()->contents(), &ruleSourceDataResult);
-    createCSSParser(&m_element->document())->parseDeclaration(tempDeclaration.get(), m_styleText, &handler, m_element->document().elementSheet()->contents());
+    StyleSheetHandler handler(m_styleText, &m_element->document(), m_element->document().elementSheet().contents(), &ruleSourceDataResult);
+    createCSSParser(&m_element->document())->parseDeclaration(tempDeclaration.get(), m_styleText, &handler, m_element->document().elementSheet().contents());
     return ruleSourceDataResult.first().release();
 }
 
diff --git a/Source/core/inspector/InspectorStyleSheet.h b/Source/core/inspector/InspectorStyleSheet.h
index 8c3399d..15c218f 100644
--- a/Source/core/inspector/InspectorStyleSheet.h
+++ b/Source/core/inspector/InspectorStyleSheet.h
@@ -29,6 +29,7 @@
 #include "core/css/CSSPropertySourceData.h"
 #include "core/css/CSSStyleDeclaration.h"
 #include "core/inspector/InspectorStyleTextEditor.h"
+#include "heap/Handle.h"
 #include "platform/JSONValues.h"
 #include "wtf/HashMap.h"
 #include "wtf/PassRefPtr.h"
@@ -51,7 +52,7 @@
 class InspectorResourceAgent;
 class InspectorStyleSheet;
 
-typedef Vector<RefPtr<CSSRule> > CSSRuleVector;
+typedef WillBePersistentHeapVector<RefPtrWillBeMember<CSSRule> > CSSRuleVector;
 typedef String ErrorString;
 
 class InspectorCSSId {
@@ -87,7 +88,7 @@
     PassRefPtr<ID> asProtocolValue() const
     {
         if (isEmpty())
-            return 0;
+            return nullptr;
 
         RefPtr<ID> result = ID::create()
             .setStyleSheetId(m_styleSheetId)
@@ -148,8 +149,6 @@
     PassRefPtr<CSSRuleSourceData> extractSourceData() const;
     bool applyStyleText(const String&);
     String shorthandValue(const String& shorthandProperty) const;
-    String shorthandPriority(const String& shorthandProperty) const;
-    Vector<String> longhandProperties(const String& shorthandProperty) const;
     NewLineAndWhitespace& newLineAndWhitespaceDelimiters() const;
     inline Document* ownerDocument() const;
 
@@ -171,45 +170,38 @@
         virtual void didReparseStyleSheet() = 0;
     };
 
-    typedef HashMap<CSSStyleDeclaration*, RefPtr<InspectorStyle> > InspectorStyleMap;
     static PassRefPtr<InspectorStyleSheet> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
-    static String styleSheetURL(CSSStyleSheet* pageStyleSheet);
-    static void collectFlatRules(PassRefPtr<CSSRuleList>, CSSRuleVector* result);
 
     virtual ~InspectorStyleSheet();
 
     String id() const { return m_id; }
     String finalURL() const;
     virtual Document* ownerDocument() const;
-    bool canBind() const { return m_origin != TypeBuilder::CSS::StyleSheetOrigin::User_agent && m_origin != TypeBuilder::CSS::StyleSheetOrigin::User; }
     CSSStyleSheet* pageStyleSheet() const { return m_pageStyleSheet.get(); }
     virtual void reparseStyleSheet(const String&);
     virtual bool setText(const String&, ExceptionState&);
+    virtual bool getText(String* result) const;
     String ruleSelector(const InspectorCSSId&, ExceptionState&);
     bool setRuleSelector(const InspectorCSSId&, const String& selector, ExceptionState&);
     CSSStyleRule* addRule(const String& selector, ExceptionState&);
     bool deleteRule(const InspectorCSSId&, ExceptionState&);
-    CSSStyleRule* ruleForId(const InspectorCSSId&) const;
-    bool fillObjectForStyleSheet(PassRefPtr<TypeBuilder::CSS::CSSStyleSheetBody>);
+    bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, String* oldPropertyText, ExceptionState&);
+
     PassRefPtr<TypeBuilder::CSS::CSSStyleSheetHeader> buildObjectForStyleSheetInfo() const;
     PassRefPtr<TypeBuilder::CSS::CSSRule> buildObjectForRule(CSSStyleRule*, PassRefPtr<TypeBuilder::Array<TypeBuilder::CSS::CSSMedia> >);
     PassRefPtr<TypeBuilder::CSS::CSSStyle> buildObjectForStyle(CSSStyleDeclaration*);
-    bool setStyleText(const InspectorCSSId&, const String& text, String* oldText, ExceptionState&);
-    bool setPropertyText(const InspectorCSSId&, unsigned propertyIndex, const String& text, bool overwrite, String* oldPropertyText, ExceptionState&);
 
-    virtual TypeBuilder::CSS::StyleSheetOrigin::Enum origin() const { return m_origin; }
-    virtual bool getText(String* result) const;
-    virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
-    void fireStyleSheetChanged();
     PassRefPtr<TypeBuilder::CSS::SourceRange> ruleHeaderSourceRange(const CSSRule*);
 
     InspectorCSSId ruleId(CSSStyleRule*) const;
-    InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleOrStyleId(style); }
+    InspectorCSSId styleId(CSSStyleDeclaration* style) const { return ruleIdByStyle(style); }
+    virtual CSSStyleRule* ruleForId(const InspectorCSSId&) const;
+    virtual CSSStyleDeclaration* styleForId(const InspectorCSSId&) const;
 
 protected:
     InspectorStyleSheet(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<CSSStyleSheet> pageStyleSheet, TypeBuilder::CSS::StyleSheetOrigin::Enum, const String& documentURL, Listener*);
 
-    InspectorCSSId ruleOrStyleId(CSSStyleDeclaration* style) const;
+    void fireStyleSheetChanged();
     virtual PassRefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration*) const;
     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const;
     virtual unsigned ruleIndexByRule(const CSSRule*) const;
@@ -225,12 +217,11 @@
 private:
     friend class InspectorStyle;
 
+    InspectorCSSId ruleIdByStyle(CSSStyleDeclaration*) const;
     bool checkPageStyleSheet(ExceptionState&) const;
     bool ensureText() const;
-    bool ensureSourceData();
     void ensureFlatRules() const;
     bool styleSheetTextWithChangedStyle(CSSStyleDeclaration*, const String& newStyleText, String* result);
-    void revalidateStyle(CSSStyleDeclaration*);
     bool originalStyleSheetText(String* result) const;
     bool resourceStyleSheetText(String* result) const;
     bool inlineStyleSheetText(String* result) const;
@@ -246,8 +237,7 @@
     RefPtr<CSSStyleSheet> m_pageStyleSheet;
     TypeBuilder::CSS::StyleSheetOrigin::Enum m_origin;
     String m_documentURL;
-    bool m_isRevalidating;
-    ParsedStyleSheet* m_parsedStyleSheet;
+    OwnPtr<ParsedStyleSheet> m_parsedStyleSheet;
     mutable CSSRuleVector m_flatRules;
     Listener* m_listener;
     mutable String m_sourceURL;
@@ -255,19 +245,19 @@
 
 class InspectorStyleSheetForInlineStyle FINAL : public InspectorStyleSheet {
 public:
-    static PassRefPtr<InspectorStyleSheetForInlineStyle> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
+    static PassRefPtr<InspectorStyleSheetForInlineStyle> create(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, Listener*);
 
     void didModifyElementAttribute();
+    virtual Document* ownerDocument() const OVERRIDE;
     virtual void reparseStyleSheet(const String&) OVERRIDE;
     virtual bool setText(const String&, ExceptionState&) OVERRIDE;
     virtual bool getText(String* result) const OVERRIDE;
+    virtual CSSStyleRule* ruleForId(const InspectorCSSId&) const OVERRIDE { return 0; }
     virtual CSSStyleDeclaration* styleForId(const InspectorCSSId& id) const OVERRIDE { ASSERT_UNUSED(id, !id.ordinal()); return inlineStyle(); }
-    virtual TypeBuilder::CSS::StyleSheetOrigin::Enum origin() const OVERRIDE { return TypeBuilder::CSS::StyleSheetOrigin::Regular; }
 
 protected:
-    InspectorStyleSheetForInlineStyle(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, TypeBuilder::CSS::StyleSheetOrigin::Enum, Listener*);
+    InspectorStyleSheetForInlineStyle(InspectorPageAgent*, InspectorResourceAgent*, const String& id, PassRefPtr<Element>, Listener*);
 
-    virtual Document* ownerDocument() const OVERRIDE;
     virtual PassRefPtr<CSSRuleSourceData> ruleSourceDataFor(CSSStyleDeclaration* style) const OVERRIDE { ASSERT_UNUSED(style, style == inlineStyle()); return m_ruleSourceData; }
     virtual unsigned ruleIndexByStyle(CSSStyleDeclaration*) const OVERRIDE { return 0; }
     virtual bool ensureParsedDataReady() OVERRIDE;
diff --git a/Source/core/inspector/InspectorTimelineAgent.cpp b/Source/core/inspector/InspectorTimelineAgent.cpp
index 1d6ba95..6a4d028 100644
--- a/Source/core/inspector/InspectorTimelineAgent.cpp
+++ b/Source/core/inspector/InspectorTimelineAgent.cpp
@@ -33,14 +33,16 @@
 
 #include "core/events/Event.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/PageConsole.h"
 #include "core/inspector/IdentifiersFactory.h"
 #include "core/inspector/InspectorClient.h"
 #include "core/inspector/InspectorCounters.h"
 #include "core/inspector/InspectorDOMAgent.h"
 #include "core/inspector/InspectorInstrumentation.h"
+#include "core/inspector/InspectorLayerTreeAgent.h"
 #include "core/inspector/InspectorOverlay.h"
 #include "core/inspector/InspectorPageAgent.h"
 #include "core/inspector/InspectorState.h"
@@ -50,7 +52,6 @@
 #include "core/inspector/TraceEventDispatcher.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/page/Page.h"
-#include "core/frame/PageConsole.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/RenderView.h"
 #include "core/xml/XMLHttpRequest.h"
@@ -81,6 +82,7 @@
 static const char RecalculateStyles[] = "RecalculateStyles";
 static const char InvalidateLayout[] = "InvalidateLayout";
 static const char Layout[] = "Layout";
+static const char UpdateLayerTree[] = "UpdateLayerTree";
 static const char AutosizeText[] = "AutosizeText";
 static const char Paint[] = "Paint";
 static const char ScrollLayer[] = "ScrollLayer";
@@ -100,8 +102,7 @@
 static const char MarkFirstPaint[] = "MarkFirstPaint";
 
 static const char TimeStamp[] = "TimeStamp";
-static const char Time[] = "Time";
-static const char TimeEnd[] = "TimeEnd";
+static const char ConsoleTime[] = "ConsoleTime";
 
 static const char ScheduleResourceRequest[] = "ScheduleResourceRequest";
 static const char ResourceSendRequest[] = "ResourceSendRequest";
@@ -132,6 +133,8 @@
 static const char GPUTask[] = "GPUTask";
 static const char Rasterize[] = "Rasterize";
 static const char PaintSetup[] = "PaintSetup";
+
+static const char EmbedderCallback[] = "EmbedderCallback";
 }
 
 namespace {
@@ -142,7 +145,12 @@
 
 struct TimelineRecordEntry {
     TimelineRecordEntry(PassRefPtr<TimelineEvent> record, PassRefPtr<JSONObject> data, PassRefPtr<TypeBuilder::Array<TimelineEvent> > children, const String& type, size_t usedHeapSizeAtStart)
-        : record(record), data(data), children(children), type(type), usedHeapSizeAtStart(usedHeapSizeAtStart)
+        : record(record)
+        , data(data)
+        , children(children)
+        , type(type)
+        , usedHeapSizeAtStart(usedHeapSizeAtStart)
+        , skipWhenUnbalanced(false)
     {
     }
     RefPtr<TimelineEvent> record;
@@ -150,6 +158,7 @@
     RefPtr<TypeBuilder::Array<TimelineEvent> > children;
     String type;
     size_t usedHeapSizeAtStart;
+    bool skipWhenUnbalanced;
 };
 
 class TimelineRecordStack {
@@ -223,9 +232,9 @@
     TimelineImageInfo(int backendNodeId, String url) : backendNodeId(backendNodeId), url(url) { }
 };
 
-static Frame* frameForExecutionContext(ExecutionContext* context)
+static LocalFrame* frameForExecutionContext(ExecutionContext* context)
 {
-    Frame* frame = 0;
+    LocalFrame* frame = 0;
     if (context->isDocument())
         frame = toDocument(context)->frame();
     return frame;
@@ -375,6 +384,8 @@
         dispatcher->addListener(PlatformInstrumentation::DecodeLazyPixelRefEvent, TRACE_EVENT_PHASE_BEGIN, this, &InspectorTimelineAgent::onDecodeLazyPixelRefBegin, m_client);
         dispatcher->addListener(PlatformInstrumentation::DecodeLazyPixelRefEvent, TRACE_EVENT_PHASE_END, this, &InspectorTimelineAgent::onDecodeLazyPixelRefEnd, m_client);
         dispatcher->addListener(PlatformInstrumentation::LazyPixelRef, TRACE_EVENT_PHASE_DELETE_OBJECT, this, &InspectorTimelineAgent::onLazyPixelRefDeleted, m_client);
+        dispatcher->addListener(InstrumentationEvents::EmbedderCallback, TRACE_EVENT_PHASE_BEGIN, this, &InspectorTimelineAgent::onEmbedderCallbackBegin, m_client);
+        dispatcher->addListener(InstrumentationEvents::EmbedderCallback, TRACE_EVENT_PHASE_END, this, &InspectorTimelineAgent::onEmbedderCallbackEnd, m_client);
 
         if (m_state->getBoolean(TimelineAgentState::includeGPUEvents)) {
             m_pendingGPURecord.clear();
@@ -455,7 +466,7 @@
 bool InspectorTimelineAgent::willDispatchEvent(Document* document, const Event& event, DOMWindow* window, Node* node, const EventPath& eventPath)
 {
     if (!eventHasListeners(event.type(), window, node, eventPath))
-       return false;
+        return false;
 
     pushCurrentRecord(TimelineRecordFactory::createEventDispatchData(event), TimelineRecordType::EventDispatch, false, document->frame());
     return true;
@@ -479,12 +490,12 @@
     didDispatchEvent();
 }
 
-void InspectorTimelineAgent::didInvalidateLayout(Frame* frame)
+void InspectorTimelineAgent::didInvalidateLayout(LocalFrame* frame)
 {
     appendRecord(JSONObject::create(), TimelineRecordType::InvalidateLayout, true, frame);
 }
 
-bool InspectorTimelineAgent::willLayout(Frame* frame)
+bool InspectorTimelineAgent::willLayout(LocalFrame* frame)
 {
     bool isPartial;
     unsigned needsLayoutObjects;
@@ -510,6 +521,12 @@
     didCompleteCurrentRecord(TimelineRecordType::Layout);
 }
 
+void InspectorTimelineAgent::layerTreeDidChange()
+{
+    RefPtr<JSONValue> layerTree = m_layerTreeAgent->buildLayerTree(BackendNodeIdGroup);
+    appendRecord(TimelineRecordFactory::createLayerTreeData(layerTree), TimelineRecordType::UpdateLayerTree, false, 0);
+}
+
 void InspectorTimelineAgent::willAutosizeText(RenderObject* renderer)
 {
     pushCurrentRecord(TimelineRecordFactory::createNodeData(nodeId(renderer)), TimelineRecordType::AutosizeText, false, renderer->frame());
@@ -555,7 +572,7 @@
 
 void InspectorTimelineAgent::willPaint(RenderObject* renderer, const GraphicsLayer* graphicsLayer)
 {
-    Frame* frame = renderer->frame();
+    LocalFrame* frame = renderer->frame();
 
     TraceEventDispatcher::instance()->processBackgroundEvents();
     double paintSetupStart = m_paintSetupStart;
@@ -712,7 +729,7 @@
     didCompleteCurrentRecord(TimelineRecordType::XHRLoad);
 }
 
-bool InspectorTimelineAgent::willEvaluateScript(Frame* frame, const String& url, int lineNumber)
+bool InspectorTimelineAgent::willEvaluateScript(LocalFrame* frame, const String& url, int lineNumber)
 {
     pushCurrentRecord(TimelineRecordFactory::createEvaluateScriptData(url, lineNumber), TimelineRecordType::EvaluateScript, true, frame);
     return true;
@@ -734,7 +751,7 @@
     appendRecord(TimelineRecordFactory::createResourceSendRequestData(requestId, request), TimelineRecordType::ResourceSendRequest, true, loader->frame());
 }
 
-bool InspectorTimelineAgent::willReceiveResourceData(Frame* frame, unsigned long identifier, int length)
+bool InspectorTimelineAgent::willReceiveResourceData(LocalFrame* frame, unsigned long identifier, int length)
 {
     String requestId = IdentifiersFactory::requestId(identifier);
     pushCurrentRecord(TimelineRecordFactory::createReceiveResourceData(requestId, length), TimelineRecordType::ResourceReceivedData, false, frame);
@@ -746,7 +763,7 @@
     didCompleteCurrentRecord(TimelineRecordType::ResourceReceivedData);
 }
 
-void InspectorTimelineAgent::didReceiveResourceResponse(Frame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
+void InspectorTimelineAgent::didReceiveResourceResponse(LocalFrame* frame, unsigned long identifier, DocumentLoader* loader, const ResourceResponse& response, ResourceLoader* resourceLoader)
 {
     String requestId = IdentifiersFactory::requestId(identifier);
     appendRecord(TimelineRecordFactory::createResourceReceiveResponseData(requestId, response), TimelineRecordType::ResourceReceiveResponse, false, 0);
@@ -779,12 +796,19 @@
 
 void InspectorTimelineAgent::consoleTime(ExecutionContext* context, const String& message)
 {
-    appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::Time, true, frameForExecutionContext(context));
+    pushCurrentRecord(TimelineRecordFactory::createConsoleTimeData(message), TimelineRecordType::ConsoleTime, false, frameForExecutionContext(context));
+    m_recordStack.last().skipWhenUnbalanced = true;
 }
 
 void InspectorTimelineAgent::consoleTimeEnd(ExecutionContext* context, const String& message, ScriptState*)
 {
-    appendRecord(TimelineRecordFactory::createTimeStampData(message), TimelineRecordType::TimeEnd, true, frameForExecutionContext(context));
+    if (m_recordStack.last().type != TimelineRecordType::ConsoleTime)
+        return;
+    String originalMessage;
+    if (m_recordStack.last().data->getString("message", &originalMessage) && message != originalMessage)
+        return;
+    // Only complete console.time that is balanced.
+    didCompleteCurrentRecord(TimelineRecordType::ConsoleTime);
 }
 
 void InspectorTimelineAgent::consoleTimeline(ExecutionContext* context, const String& title, ScriptState* state)
@@ -793,7 +817,7 @@
         return;
 
     String message = String::format("Timeline '%s' started.", title.utf8().data());
-    frameHost()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, 0, state);
+    frameHost()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, nullptr, state);
     m_consoleTimelines.append(title);
     if (!isStarted()) {
         innerStart();
@@ -811,7 +835,7 @@
     size_t index = m_consoleTimelines.find(title);
     if (index == kNotFound) {
         String message = String::format("Timeline '%s' was not started.", title.utf8().data());
-        frameHost()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, 0, state);
+        frameHost()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, nullptr, state);
         return;
     }
 
@@ -822,10 +846,10 @@
         unwindRecordStack();
         innerStop(true);
     }
-    frameHost()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, 0, state);
+    frameHost()->console().addMessage(ConsoleAPIMessageSource, DebugMessageLevel, message, String(), 0, 0, nullptr, state);
 }
 
-void InspectorTimelineAgent::domContentLoadedEventFired(Frame* frame)
+void InspectorTimelineAgent::domContentLoadedEventFired(LocalFrame* frame)
 {
     bool isMainFrame = frame && m_pageAgent && (frame == m_pageAgent->mainFrame());
     appendRecord(TimelineRecordFactory::createMarkData(isMainFrame), TimelineRecordType::MarkDOMContent, false, frame);
@@ -833,7 +857,7 @@
         m_mayEmitFirstPaint = true;
 }
 
-void InspectorTimelineAgent::loadEventFired(Frame* frame)
+void InspectorTimelineAgent::loadEventFired(LocalFrame* frame)
 {
     bool isMainFrame = frame && m_pageAgent && (frame == m_pageAgent->mainFrame());
     appendRecord(TimelineRecordFactory::createMarkData(isMainFrame), TimelineRecordType::MarkLoad, false, frame);
@@ -880,12 +904,12 @@
     appendRecord(TimelineRecordFactory::createWebSocketCreateData(identifier, url, protocol), TimelineRecordType::WebSocketCreate, true, document->frame());
 }
 
-void InspectorTimelineAgent::willSendWebSocketHandshakeRequest(Document* document, unsigned long identifier, const WebSocketHandshakeRequest&)
+void InspectorTimelineAgent::willSendWebSocketHandshakeRequest(Document* document, unsigned long identifier, const WebSocketHandshakeRequest*)
 {
     appendRecord(TimelineRecordFactory::createGenericWebSocketData(identifier), TimelineRecordType::WebSocketSendHandshakeRequest, true, document->frame());
 }
 
-void InspectorTimelineAgent::didReceiveWebSocketHandshakeResponse(Document* document, unsigned long identifier, const WebSocketHandshakeResponse&)
+void InspectorTimelineAgent::didReceiveWebSocketHandshakeResponse(Document* document, unsigned long identifier, const WebSocketHandshakeRequest*, const WebSocketHandshakeResponse*)
 {
     appendRecord(TimelineRecordFactory::createGenericWebSocketData(identifier), TimelineRecordType::WebSocketReceiveHandshakeResponse, false, document->frame());
 }
@@ -1052,6 +1076,21 @@
     }
 }
 
+void InspectorTimelineAgent::onEmbedderCallbackBegin(const TraceEventDispatcher::TraceEvent& event)
+{
+    TimelineThreadState& state = threadState(event.threadIdentifier());
+    double timestamp = m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp());
+    RefPtr<JSONObject> data = TimelineRecordFactory::createEmbedderCallbackData(event.asString(InstrumentationEventArguments::CallbackName));
+    RefPtr<TimelineEvent> record = TimelineRecordFactory::createGenericRecord(timestamp, 0, TimelineRecordType::EmbedderCallback, data);
+    state.recordStack.addScopedRecord(record, TimelineRecordType::EmbedderCallback);
+}
+
+void InspectorTimelineAgent::onEmbedderCallbackEnd(const TraceEventDispatcher::TraceEvent& event)
+{
+    TimelineThreadState& state = threadState(event.threadIdentifier());
+    state.recordStack.closeScopedRecord(m_timeConverter.fromMonotonicallyIncreasingTime(event.timestamp()));
+}
+
 void InspectorTimelineAgent::addRecordToTimeline(PassRefPtr<TimelineEvent> record)
 {
     commitFrameRecord();
@@ -1091,7 +1130,7 @@
     record->setCounters(counters.release());
 }
 
-void InspectorTimelineAgent::setFrameIdentifier(TimelineEvent* record, Frame* frame)
+void InspectorTimelineAgent::setFrameIdentifier(TimelineEvent* record, LocalFrame* frame)
 {
     if (!frame || !m_pageAgent)
         return;
@@ -1110,7 +1149,7 @@
 void InspectorTimelineAgent::didCompleteCurrentRecord(const String& type)
 {
     // An empty stack could merely mean that the timeline agent was turned on in the middle of
-    // an event.  Don't treat as an error.
+    // an event. Don't treat as an error.
     if (!m_recordStack.isEmpty()) {
         if (m_platformInstrumentationClientInstalledAtStackDepth == m_recordStack.size()) {
             m_platformInstrumentationClientInstalledAtStackDepth = 0;
@@ -1120,6 +1159,13 @@
         pushGCEventRecords();
         TimelineRecordEntry entry = m_recordStack.last();
         m_recordStack.removeLast();
+        while (entry.type != type && entry.skipWhenUnbalanced && !m_recordStack.isEmpty()) {
+            // Discard pending skippable entry, paste its children inplace.
+            if (entry.children)
+                m_recordStack.last().children->concat(entry.children);
+            entry = m_recordStack.last();
+            m_recordStack.removeLast();
+        }
         ASSERT(entry.type == type);
         entry.record->setChildren(entry.children);
         entry.record->setEndTime(timestamp());
@@ -1138,10 +1184,12 @@
     }
 }
 
-InspectorTimelineAgent::InspectorTimelineAgent(InspectorPageAgent* pageAgent, InspectorDOMAgent* domAgent, InspectorOverlay* overlay, InspectorType type, InspectorClient* client)
+InspectorTimelineAgent::InspectorTimelineAgent(InspectorPageAgent* pageAgent, InspectorDOMAgent* domAgent, InspectorLayerTreeAgent* layerTreeAgent,
+    InspectorOverlay* overlay, InspectorType type, InspectorClient* client)
     : InspectorBaseAgent<InspectorTimelineAgent>("Timeline")
     , m_pageAgent(pageAgent)
     , m_domAgent(domAgent)
+    , m_layerTreeAgent(layerTreeAgent)
     , m_frontend(0)
     , m_client(client)
     , m_overlay(overlay)
@@ -1157,7 +1205,7 @@
 {
 }
 
-void InspectorTimelineAgent::appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame* frame)
+void InspectorTimelineAgent::appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame* frame)
 {
     pushGCEventRecords();
     RefPtr<TimelineEvent> record = TimelineRecordFactory::createGenericRecord(timestamp(), captureCallStack ? m_maxCallStackDepth : 0, type, data);
@@ -1173,7 +1221,7 @@
         m_frontend->eventRecorded(record);
 }
 
-void InspectorTimelineAgent::pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame* frame, bool hasLowLevelDetails)
+void InspectorTimelineAgent::pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame* frame, bool hasLowLevelDetails)
 {
     pushGCEventRecords();
     commitFrameRecord();
@@ -1214,7 +1262,7 @@
 
 void InspectorTimelineAgent::localToPageQuad(const RenderObject& renderer, const LayoutRect& rect, FloatQuad* quad)
 {
-    Frame* frame = renderer.frame();
+    LocalFrame* frame = renderer.frame();
     FrameView* view = frame->view();
     FloatQuad absolute = renderer.localToAbsoluteQuad(FloatQuad(rect));
     quad->setP1(view->contentsToRootView(roundedIntPoint(absolute.p1())));
diff --git a/Source/core/inspector/InspectorTimelineAgent.h b/Source/core/inspector/InspectorTimelineAgent.h
index 7f85231..693457a 100644
--- a/Source/core/inspector/InspectorTimelineAgent.h
+++ b/Source/core/inspector/InspectorTimelineAgent.h
@@ -59,7 +59,7 @@
 class Event;
 class ExecutionContext;
 class FloatQuad;
-class Frame;
+class LocalFrame;
 class FrameHost;
 class GraphicsContext;
 class GraphicsLayer;
@@ -68,6 +68,7 @@
 class InspectorFrontend;
 class InspectorOverlay;
 class InspectorPageAgent;
+class InspectorLayerTreeAgent;
 class InstrumentingAgents;
 class KURL;
 class Node;
@@ -124,9 +125,10 @@
         size_t usedGPUMemoryBytes;
     };
 
-    static PassOwnPtr<InspectorTimelineAgent> create(InspectorPageAgent* pageAgent, InspectorDOMAgent* domAgent, InspectorOverlay* overlay, InspectorType type, InspectorClient* client)
+    static PassOwnPtr<InspectorTimelineAgent> create(InspectorPageAgent* pageAgent, InspectorDOMAgent* domAgent, InspectorLayerTreeAgent* layerTreeAgent,
+        InspectorOverlay* overlay, InspectorType type, InspectorClient* client)
     {
-        return adoptPtr(new InspectorTimelineAgent(pageAgent, domAgent, overlay, type, client));
+        return adoptPtr(new InspectorTimelineAgent(pageAgent, domAgent, layerTreeAgent, overlay, type, client));
     }
 
     virtual ~InspectorTimelineAgent();
@@ -157,10 +159,12 @@
     void didBeginFrame(int frameId);
     void didCancelFrame();
 
-    void didInvalidateLayout(Frame*);
-    bool willLayout(Frame*);
+    void didInvalidateLayout(LocalFrame*);
+    bool willLayout(LocalFrame*);
     void didLayout(RenderObject*);
 
+    void layerTreeDidChange();
+
     void willAutosizeText(RenderObject*);
     void didAutosizeText(RenderObject*);
 
@@ -194,12 +198,12 @@
     bool willDispatchXHRLoadEvent(ExecutionContext*, XMLHttpRequest*);
     void didDispatchXHRLoadEvent();
 
-    bool willEvaluateScript(Frame*, const String&, int);
+    bool willEvaluateScript(LocalFrame*, const String&, int);
     void didEvaluateScript();
 
     void consoleTimeStamp(ExecutionContext*, const String& title);
-    void domContentLoadedEventFired(Frame*);
-    void loadEventFired(Frame*);
+    void domContentLoadedEventFired(LocalFrame*);
+    void loadEventFired(LocalFrame*);
 
     void consoleTime(ExecutionContext*, const String&);
     void consoleTimeEnd(ExecutionContext*, const String&, ScriptState*);
@@ -208,10 +212,10 @@
 
     void didScheduleResourceRequest(Document*, const String& url);
     void willSendRequest(unsigned long, DocumentLoader*, const ResourceRequest&, const ResourceResponse&, const FetchInitiatorInfo&);
-    void didReceiveResourceResponse(Frame*, unsigned long, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
+    void didReceiveResourceResponse(LocalFrame*, unsigned long, DocumentLoader*, const ResourceResponse&, ResourceLoader*);
     void didFinishLoading(unsigned long, DocumentLoader*, double monotonicFinishTime, int64_t);
     void didFailLoading(unsigned long identifier, const ResourceError&);
-    bool willReceiveResourceData(Frame*, unsigned long identifier, int length);
+    bool willReceiveResourceData(LocalFrame*, unsigned long identifier, int length);
     void didReceiveResourceData();
 
     void didRequestAnimationFrame(Document*, int callbackId);
@@ -223,8 +227,8 @@
     void didProcessTask();
 
     void didCreateWebSocket(Document*, unsigned long identifier, const KURL&, const String& protocol);
-    void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest&);
-    void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeResponse&);
+    void willSendWebSocketHandshakeRequest(Document*, unsigned long identifier, const WebSocketHandshakeRequest*);
+    void didReceiveWebSocketHandshakeResponse(Document*, unsigned long identifier, const WebSocketHandshakeRequest*, const WebSocketHandshakeResponse*);
     void didCloseWebSocket(Document*, unsigned long identifier);
 
     void processGPUEvent(const GPUEvent&);
@@ -242,7 +246,7 @@
 
     friend class TimelineRecordStack;
 
-    InspectorTimelineAgent(InspectorPageAgent*, InspectorDOMAgent*, InspectorOverlay*, InspectorType, InspectorClient*);
+    InspectorTimelineAgent(InspectorPageAgent*, InspectorDOMAgent*, InspectorLayerTreeAgent*, InspectorOverlay*, InspectorType, InspectorClient*);
 
     // Trace event handlers
     void onBeginImplSideFrame(const TraceEventDispatcher::TraceEvent&);
@@ -260,16 +264,18 @@
     void onActivateLayerTree(const TraceEventDispatcher::TraceEvent&);
     void onDrawFrame(const TraceEventDispatcher::TraceEvent&);
     void onLazyPixelRefDeleted(const TraceEventDispatcher::TraceEvent&);
+    void onEmbedderCallbackBegin(const TraceEventDispatcher::TraceEvent&);
+    void onEmbedderCallbackEnd(const TraceEventDispatcher::TraceEvent&);
 
     void didFinishLoadingResource(unsigned long, bool didFail, double finishTime);
 
     void sendEvent(PassRefPtr<TypeBuilder::Timeline::TimelineEvent>);
-    void appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame*);
-    void pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, Frame*, bool hasLowLevelDetails = false);
+    void appendRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame*);
+    void pushCurrentRecord(PassRefPtr<JSONObject> data, const String& type, bool captureCallStack, LocalFrame*, bool hasLowLevelDetails = false);
     TimelineThreadState& threadState(ThreadIdentifier);
 
     void setCounters(TypeBuilder::Timeline::TimelineEvent*);
-    void setFrameIdentifier(TypeBuilder::Timeline::TimelineEvent* record, Frame*);
+    void setFrameIdentifier(TypeBuilder::Timeline::TimelineEvent* record, LocalFrame*);
     void populateImageDetails(JSONObject* data, const RenderImage&);
 
     void pushGCEventRecords();
@@ -299,6 +305,7 @@
 
     InspectorPageAgent* m_pageAgent;
     InspectorDOMAgent* m_domAgent;
+    InspectorLayerTreeAgent* m_layerTreeAgent;
     InspectorFrontend::Timeline* m_frontend;
     InspectorClient* m_client;
     InspectorOverlay* m_overlay;
diff --git a/Source/core/inspector/JSONParser.cpp b/Source/core/inspector/JSONParser.cpp
index 58adb02..712781d 100644
--- a/Source/core/inspector/JSONParser.cpp
+++ b/Source/core/inspector/JSONParser.cpp
@@ -341,7 +341,7 @@
 PassRefPtr<JSONValue> buildValue(const CharType* start, const CharType* end, const CharType** valueTokenEnd, int depth)
 {
     if (depth > stackLimit)
-        return 0;
+        return nullptr;
 
     RefPtr<JSONValue> result;
     const CharType* tokenStart;
@@ -349,7 +349,7 @@
     Token token = parseToken(start, end, &tokenStart, &tokenEnd);
     switch (token) {
     case InvalidToken:
-        return 0;
+        return nullptr;
     case NullToken:
         result = JSONValue::null();
         break;
@@ -363,7 +363,7 @@
         bool ok;
         double value = charactersToDouble(tokenStart, tokenEnd - tokenStart, &ok);
         if (!ok)
-            return 0;
+            return nullptr;
         result = JSONBasicValue::create(value);
         break;
     }
@@ -371,7 +371,7 @@
         String value;
         bool ok = decodeString(tokenStart + 1, tokenEnd - 1, &value);
         if (!ok)
-            return 0;
+            return nullptr;
         result = JSONString::create(value);
         break;
     }
@@ -382,7 +382,7 @@
         while (token != ArrayEnd) {
             RefPtr<JSONValue> arrayNode = buildValue(start, end, &tokenEnd, depth + 1);
             if (!arrayNode)
-                return 0;
+                return nullptr;
             array->pushValue(arrayNode);
 
             // After a list value, we expect a comma or the end of the list.
@@ -392,14 +392,14 @@
                 start = tokenEnd;
                 token = parseToken(start, end, &tokenStart, &tokenEnd);
                 if (token == ArrayEnd)
-                    return 0;
+                    return nullptr;
             } else if (token != ArrayEnd) {
                 // Unexpected value after list value. Bail out.
-                return 0;
+                return nullptr;
             }
         }
         if (token != ArrayEnd)
-            return 0;
+            return nullptr;
         result = array.release();
         break;
     }
@@ -409,20 +409,20 @@
         token = parseToken(start, end, &tokenStart, &tokenEnd);
         while (token != ObjectEnd) {
             if (token != StringLiteral)
-                return 0;
+                return nullptr;
             String key;
             if (!decodeString(tokenStart + 1, tokenEnd - 1, &key))
-                return 0;
+                return nullptr;
             start = tokenEnd;
 
             token = parseToken(start, end, &tokenStart, &tokenEnd);
             if (token != ObjectPairSeparator)
-                return 0;
+                return nullptr;
             start = tokenEnd;
 
             RefPtr<JSONValue> value = buildValue(start, end, &tokenEnd, depth + 1);
             if (!value)
-                return 0;
+                return nullptr;
             object->setValue(key, value);
             start = tokenEnd;
 
@@ -433,21 +433,21 @@
                 start = tokenEnd;
                 token = parseToken(start, end, &tokenStart, &tokenEnd);
                 if (token == ObjectEnd)
-                    return 0;
+                    return nullptr;
             } else if (token != ObjectEnd) {
                 // Unexpected value after last object value. Bail out.
-                return 0;
+                return nullptr;
             }
         }
         if (token != ObjectEnd)
-            return 0;
+            return nullptr;
         result = object.release();
         break;
     }
 
     default:
         // We got a token that's not a value.
-        return 0;
+        return nullptr;
     }
     *valueTokenEnd = tokenEnd;
     return result.release();
@@ -460,7 +460,7 @@
     const CharType *tokenEnd;
     RefPtr<JSONValue> value = buildValue(start, end, &tokenEnd, 0);
     if (!value || tokenEnd != end)
-        return 0;
+        return nullptr;
     return value.release();
 }
 
@@ -469,7 +469,7 @@
 PassRefPtr<JSONValue> parseJSON(const String& json)
 {
     if (json.isEmpty())
-        return 0;
+        return nullptr;
     if (json.is8Bit())
         return parseJSONInternal(json.characters8(), json.length());
     return parseJSONInternal(json.characters16(), json.length());
diff --git a/Source/core/inspector/JavaScriptCallFrame.cpp b/Source/core/inspector/JavaScriptCallFrame.cpp
index 38032cc..7d451e6 100644
--- a/Source/core/inspector/JavaScriptCallFrame.cpp
+++ b/Source/core/inspector/JavaScriptCallFrame.cpp
@@ -62,47 +62,51 @@
     return m_caller.get();
 }
 
-int JavaScriptCallFrame::sourceID() const
+int JavaScriptCallFrame::callV8FunctionReturnInt(const char* name) const
 {
     v8::HandleScope handleScope(m_isolate);
-    v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
-    v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "sourceID"));
+    v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
+    v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, name)));
+    v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0);
     if (result->IsInt32())
         return result->Int32Value();
     return 0;
 }
 
+String JavaScriptCallFrame::callV8FunctionReturnString(const char* name) const
+{
+    v8::HandleScope handleScope(m_isolate);
+    v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
+    v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, name)));
+    v8::Handle<v8::Value> result = func->Call(callFrame, 0, 0);
+    return toCoreStringWithUndefinedOrNullCheck(result);
+}
+
+int JavaScriptCallFrame::sourceID() const
+{
+    return callV8FunctionReturnInt("sourceID");
+}
+
 int JavaScriptCallFrame::line() const
 {
-    v8::HandleScope handleScope(m_isolate);
-    v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
-    v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "line"));
-    if (result->IsInt32())
-        return result->Int32Value();
-    return 0;
+    return callV8FunctionReturnInt("line");
 }
 
 int JavaScriptCallFrame::column() const
 {
-    v8::HandleScope handleScope(m_isolate);
-    v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
-    v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "column"));
-    if (result->IsInt32())
-        return result->Int32Value();
-    return 0;
+    return callV8FunctionReturnInt("column");
 }
 
 String JavaScriptCallFrame::functionName() const
 {
-    v8::HandleScope handleScope(m_isolate);
-    v8::Context::Scope contextScope(m_debuggerContext.newLocal(m_isolate));
-    v8::Handle<v8::Value> result = m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "functionName"));
-    return toCoreStringWithUndefinedOrNullCheck(result);
+    return callV8FunctionReturnString("functionName");
 }
 
 v8::Handle<v8::Value> JavaScriptCallFrame::scopeChain() const
 {
-    v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(m_callFrame.newLocal(m_isolate)->Get(v8AtomicString(m_isolate, "scopeChain")));
+    v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
+    v8::Handle<v8::Function> func = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "scopeChain")));
+    v8::Handle<v8::Array> scopeChain = v8::Handle<v8::Array>::Cast(func->Call(callFrame, 0, 0));
     v8::Handle<v8::Array> result = v8::Array::New(m_isolate, scopeChain->Length());
     for (uint32_t i = 0; i < scopeChain->Length(); i++)
         result->Set(i, scopeChain->Get(i));
@@ -122,10 +126,7 @@
 
 String JavaScriptCallFrame::stepInPositions() const
 {
-    v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
-    v8::Handle<v8::Function> stepInPositions = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "stepInPositions")));
-    v8::Handle<v8::Value> result = stepInPositions->Call(callFrame, 0, 0);
-    return toCoreStringWithUndefinedOrNullCheck(result);
+    return callV8FunctionReturnString("stepInPositions");
 }
 
 bool JavaScriptCallFrame::isAtReturn() const
@@ -148,7 +149,7 @@
     v8::Handle<v8::Object> callFrame = m_callFrame.newLocal(m_isolate);
     v8::Handle<v8::Function> evalFunction = v8::Handle<v8::Function>::Cast(callFrame->Get(v8AtomicString(m_isolate, "evaluate")));
     v8::Handle<v8::Value> argv[] = { v8String(m_debuggerContext.newLocal(m_isolate)->GetIsolate(), expression) };
-    return evalFunction->Call(callFrame, 1, argv);
+    return evalFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv);
 }
 
 v8::Handle<v8::Value> JavaScriptCallFrame::restart()
@@ -175,7 +176,7 @@
         v8String(m_isolate, variableName),
         newValue.v8Value()
     };
-    return ScriptValue(setVariableValueFunction->Call(callFrame, 3, argv), m_isolate);
+    return ScriptValue(setVariableValueFunction->Call(callFrame, WTF_ARRAY_LENGTH(argv), argv), m_isolate);
 }
 
 } // namespace WebCore
diff --git a/Source/core/inspector/JavaScriptCallFrame.h b/Source/core/inspector/JavaScriptCallFrame.h
index ac0c035..2ccb37e 100644
--- a/Source/core/inspector/JavaScriptCallFrame.h
+++ b/Source/core/inspector/JavaScriptCallFrame.h
@@ -72,6 +72,9 @@
 private:
     JavaScriptCallFrame(v8::Handle<v8::Context> debuggerContext, v8::Handle<v8::Object> callFrame);
 
+    int callV8FunctionReturnInt(const char* name) const;
+    String callV8FunctionReturnString(const char* name) const;
+
     v8::Isolate* m_isolate;
     RefPtr<JavaScriptCallFrame> m_caller;
     ScopedPersistent<v8::Context> m_debuggerContext;
diff --git a/Source/core/inspector/PageConsoleAgent.cpp b/Source/core/inspector/PageConsoleAgent.cpp
index 122b636..195f16c 100644
--- a/Source/core/inspector/PageConsoleAgent.cpp
+++ b/Source/core/inspector/PageConsoleAgent.cpp
@@ -75,11 +75,11 @@
         return;
     }
     while (node->isInShadowTree()) {
-        Node* ancestor = node->highestAncestor();
-        if (!ancestor->isShadowRoot() || toShadowRoot(ancestor)->type() == ShadowRoot::AuthorShadowRoot)
+        Node& ancestor = node->highestAncestor();
+        if (!ancestor.isShadowRoot() || toShadowRoot(ancestor).type() == ShadowRoot::AuthorShadowRoot)
             break;
         // User agent shadow root, keep climbing up.
-        node = toShadowRoot(ancestor)->host();
+        node = toShadowRoot(ancestor).host();
     }
     m_injectedScriptManager->injectedScriptHost()->addInspectedObject(adoptPtr(new InspectableNode(node)));
 }
diff --git a/Source/core/inspector/PageDebuggerAgent.cpp b/Source/core/inspector/PageDebuggerAgent.cpp
index 1738b2b..56d3e49 100644
--- a/Source/core/inspector/PageDebuggerAgent.cpp
+++ b/Source/core/inspector/PageDebuggerAgent.cpp
@@ -34,7 +34,7 @@
 #include "bindings/v8/DOMWrapperWorld.h"
 #include "bindings/v8/ScriptController.h"
 #include "bindings/v8/ScriptSourceCode.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/PageConsole.h"
 #include "core/inspector/InspectorOverlay.h"
 #include "core/inspector/InspectorPageAgent.h"
@@ -128,7 +128,7 @@
     m_overlay->setPausedInDebuggerMessage(message);
 }
 
-void PageDebuggerAgent::didClearWindowObjectInMainWorld(Frame* frame)
+void PageDebuggerAgent::didClearWindowObjectInMainWorld(LocalFrame* frame)
 {
     if (frame != m_pageAgent->mainFrame())
         return;
@@ -141,23 +141,23 @@
         scriptDebugServer().setPreprocessorSource(m_pageAgent->scriptPreprocessorSource());
 }
 
-String PageDebuggerAgent::preprocessEventListener(Frame* frame, const String& source, const String& url, const String& functionName)
+String PageDebuggerAgent::preprocessEventListener(LocalFrame* frame, const String& source, const String& url, const String& functionName)
 {
     ASSERT(frame);
     ASSERT(m_pageScriptDebugServer);
     return m_pageScriptDebugServer->preprocessEventListener(frame, source, url, functionName);
 }
 
-PassOwnPtr<ScriptSourceCode> PageDebuggerAgent::preprocess(Frame* frame, const ScriptSourceCode& sourceCode)
+PassOwnPtr<ScriptSourceCode> PageDebuggerAgent::preprocess(LocalFrame* frame, const ScriptSourceCode& sourceCode)
 {
     ASSERT(m_pageScriptDebugServer);
     ASSERT(frame);
     return m_pageScriptDebugServer->preprocess(frame, sourceCode);
 }
 
-void PageDebuggerAgent::didCommitLoad(Frame* frame, DocumentLoader* loader)
+void PageDebuggerAgent::didCommitLoad(LocalFrame* frame, DocumentLoader* loader)
 {
-    Frame* mainFrame = frame->page()->mainFrame();
+    LocalFrame* mainFrame = frame->page()->mainFrame();
     if (loader->frame() == mainFrame)
         pageDidCommitLoad();
 }
diff --git a/Source/core/inspector/PageDebuggerAgent.h b/Source/core/inspector/PageDebuggerAgent.h
index 4316666..d585493 100644
--- a/Source/core/inspector/PageDebuggerAgent.h
+++ b/Source/core/inspector/PageDebuggerAgent.h
@@ -53,10 +53,10 @@
     static PassOwnPtr<PageDebuggerAgent> create(PageScriptDebugServer*, InspectorPageAgent*, InjectedScriptManager*, InspectorOverlay*);
     virtual ~PageDebuggerAgent();
 
-    void didClearWindowObjectInMainWorld(Frame*);
-    String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
-    PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
-    void didCommitLoad(Frame*, DocumentLoader*);
+    void didClearWindowObjectInMainWorld(LocalFrame*);
+    String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName);
+    PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&);
+    void didCommitLoad(LocalFrame*, DocumentLoader*);
 
 protected:
     virtual void enable() OVERRIDE;
diff --git a/Source/core/inspector/PageRuntimeAgent.cpp b/Source/core/inspector/PageRuntimeAgent.cpp
index 72102c7..574e68d 100644
--- a/Source/core/inspector/PageRuntimeAgent.cpp
+++ b/Source/core/inspector/PageRuntimeAgent.cpp
@@ -33,7 +33,7 @@
 
 #include "bindings/v8/DOMWrapperWorld.h"
 #include "bindings/v8/ScriptController.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/PageConsole.h"
 #include "core/inspector/InjectedScript.h"
 #include "core/inspector/InjectedScriptManager.h"
@@ -113,7 +113,7 @@
     m_state->setBoolean(PageRuntimeAgentState::runtimeEnabled, false);
 }
 
-void PageRuntimeAgent::didClearWindowObjectInMainWorld(Frame* frame)
+void PageRuntimeAgent::didClearWindowObjectInMainWorld(LocalFrame* frame)
 {
     m_mainWorldContextCreated = true;
 
@@ -125,7 +125,7 @@
     notifyContextCreated(frameId, scriptState, 0, true);
 }
 
-void PageRuntimeAgent::didCreateIsolatedContext(Frame* frame, ScriptState* scriptState, SecurityOrigin* origin)
+void PageRuntimeAgent::didCreateIsolatedContext(LocalFrame* frame, ScriptState* scriptState, SecurityOrigin* origin)
 {
     if (!m_enabled)
         return;
@@ -162,7 +162,7 @@
 void PageRuntimeAgent::reportExecutionContextCreation()
 {
     Vector<std::pair<ScriptState*, SecurityOrigin*> > isolatedContexts;
-    for (Frame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = m_inspectedPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         if (!frame->script().canExecuteScripts(NotAboutToExecuteScript))
             continue;
         String frameId = m_pageAgent->frameId(frame);
diff --git a/Source/core/inspector/PageRuntimeAgent.h b/Source/core/inspector/PageRuntimeAgent.h
index c78f418..71885fa 100644
--- a/Source/core/inspector/PageRuntimeAgent.h
+++ b/Source/core/inspector/PageRuntimeAgent.h
@@ -56,8 +56,8 @@
     virtual void enable(ErrorString*) OVERRIDE;
     virtual void disable(ErrorString*) OVERRIDE;
 
-    void didClearWindowObjectInMainWorld(Frame*);
-    void didCreateIsolatedContext(Frame*, ScriptState*, SecurityOrigin*);
+    void didClearWindowObjectInMainWorld(LocalFrame*);
+    void didCreateIsolatedContext(LocalFrame*, ScriptState*, SecurityOrigin*);
 
 private:
     PageRuntimeAgent(InjectedScriptManager*, ScriptDebugServer*, Page*, InspectorPageAgent*);
diff --git a/Source/core/inspector/PromiseTracker.cpp b/Source/core/inspector/PromiseTracker.cpp
new file mode 100644
index 0000000..da7eee9
--- /dev/null
+++ b/Source/core/inspector/PromiseTracker.cpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "bindings/v8/ScriptCallStackFactory.h"
+#include "core/inspector/PromiseTracker.h"
+#include "wtf/CurrentTime.h"
+
+namespace WebCore {
+
+PromiseTracker::PromiseData::PromiseData(const ScriptObject& promise, const ScriptObject& parentPromise, const ScriptValue& result, V8PromiseCustom::PromiseState state, double timestamp)
+    : m_promise(promise)
+    , m_parentPromise(parentPromise)
+    , m_result(result)
+    , m_state(state)
+    , m_timeOnCreate(timestamp)
+    , m_timeOnSettle(-1)
+    , m_callStackOnCreate(createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true))
+{
+}
+
+void PromiseTracker::PromiseData::didSettlePromise(double timestamp)
+{
+    m_timeOnSettle = timestamp;
+    m_callStackOnSettle = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true);
+}
+
+void PromiseTracker::enable()
+{
+    m_isEnabled = true;
+}
+
+void PromiseTracker::disable()
+{
+    m_isEnabled = false;
+    clear();
+}
+
+void PromiseTracker::clear()
+{
+    m_promiseDataMap.clear();
+}
+
+void PromiseTracker::didCreatePromise(const ScriptObject& promise)
+{
+    ASSERT(isEnabled());
+
+    double timestamp = currentTimeMS();
+    m_promiseDataMap.set(promise, adoptRef(new PromiseData(promise, ScriptObject(), ScriptValue(), V8PromiseCustom::Pending, timestamp)));
+}
+
+void PromiseTracker::didUpdatePromiseParent(const ScriptObject& promise, const ScriptObject& parentPromise)
+{
+    ASSERT(isEnabled());
+
+    RefPtr<PromiseData> data = m_promiseDataMap.get(promise);
+    ASSERT(data != NULL && data->m_promise == promise);
+    data->m_parentPromise = parentPromise;
+}
+
+void PromiseTracker::didUpdatePromiseState(const ScriptObject& promise, V8PromiseCustom::PromiseState state, const ScriptValue& result)
+{
+    ASSERT(isEnabled());
+
+    double timestamp = currentTimeMS();
+    RefPtr<PromiseData> data = m_promiseDataMap.get(promise);
+    ASSERT(data != NULL && data->m_promise == promise);
+    data->m_state = state;
+    data->m_result = result;
+    if (state == V8PromiseCustom::Fulfilled || state == V8PromiseCustom::Rejected)
+        data->didSettlePromise(timestamp);
+}
+
+} // namespace WebCore
diff --git a/Source/core/inspector/PromiseTracker.h b/Source/core/inspector/PromiseTracker.h
new file mode 100644
index 0000000..150930d
--- /dev/null
+++ b/Source/core/inspector/PromiseTracker.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PromiseTracker_h
+#define PromiseTracker_h
+
+#include "bindings/v8/custom/V8PromiseCustom.h"
+#include "bindings/v8/ScriptObjectTraits.h"
+#include "core/inspector/ScriptCallStack.h"
+#include "wtf/HashMap.h"
+#include "wtf/Noncopyable.h"
+#include "wtf/RefPtr.h"
+
+namespace WebCore {
+
+class ExecutionContext;
+
+class PromiseTracker {
+    WTF_MAKE_NONCOPYABLE(PromiseTracker);
+public:
+    PromiseTracker() : m_isEnabled(false) { }
+
+    bool isEnabled() const { return m_isEnabled; }
+    void enable();
+    void disable();
+
+    void clear();
+
+    void didCreatePromise(const ScriptObject& promise);
+    void didUpdatePromiseParent(const ScriptObject& promise, const ScriptObject& parentPromise);
+    void didUpdatePromiseState(const ScriptObject& promise, V8PromiseCustom::PromiseState, const ScriptValue& result);
+
+private:
+    class PromiseData : public RefCounted<PromiseData> {
+    public:
+        PromiseData(const ScriptObject& promise, const ScriptObject& parentPromise, const ScriptValue& result, V8PromiseCustom::PromiseState state, double timestamp);
+
+        void didSettlePromise(double timestamp);
+
+        ScriptObject m_promise;
+        ScriptObject m_parentPromise;
+        ScriptValue m_result;
+        V8PromiseCustom::PromiseState m_state;
+
+        // Time in milliseconds.
+        double m_timeOnCreate;
+        double m_timeOnSettle;
+
+        RefPtr<ScriptCallStack> m_callStackOnCreate;
+        RefPtr<ScriptCallStack> m_callStackOnSettle;
+    };
+
+    bool m_isEnabled;
+    typedef HashMap<ScriptObject, RefPtr<PromiseData>, ScriptObjectHash, ScriptObjectHashTraits> PromiseDataMap;
+    PromiseDataMap m_promiseDataMap;
+};
+
+} // namespace WebCore
+
+#endif // !defined(PromiseTracker_h)
diff --git a/Source/core/inspector/TimelineRecordFactory.cpp b/Source/core/inspector/TimelineRecordFactory.cpp
index 9ea01aa..5c6f757 100644
--- a/Source/core/inspector/TimelineRecordFactory.cpp
+++ b/Source/core/inspector/TimelineRecordFactory.cpp
@@ -131,6 +131,13 @@
     return data.release();
 }
 
+PassRefPtr<JSONObject> TimelineRecordFactory::createConsoleTimeData(const String& message)
+{
+    RefPtr<JSONObject> data = JSONObject::create();
+    data->setString("message", message);
+    return data.release();
+}
+
 PassRefPtr<JSONObject> TimelineRecordFactory::createTimeStampData(const String& message)
 {
     RefPtr<JSONObject> data = JSONObject::create();
@@ -258,6 +265,13 @@
     return createNodeData(rootNodeId);
 }
 
+PassRefPtr<JSONObject> TimelineRecordFactory::createLayerTreeData(PassRefPtr<JSONValue> layerTree)
+{
+    RefPtr<JSONObject> data = JSONObject::create();
+    data->setValue("layerTree", layerTree);
+    return data.release();
+}
+
 void TimelineRecordFactory::setNodeData(JSONObject* data, long long nodeId)
 {
     if (nodeId)
@@ -303,5 +317,12 @@
         data->setString("url", url);
 }
 
+PassRefPtr<JSONObject> TimelineRecordFactory::createEmbedderCallbackData(const String& callbackName)
+{
+    RefPtr<JSONObject> data = JSONObject::create();
+    data->setString("callbackName", callbackName);
+    return data.release();
+}
+
 } // namespace WebCore
 
diff --git a/Source/core/inspector/TimelineRecordFactory.h b/Source/core/inspector/TimelineRecordFactory.h
index 8f53206..b2d4e82 100644
--- a/Source/core/inspector/TimelineRecordFactory.h
+++ b/Source/core/inspector/TimelineRecordFactory.h
@@ -59,6 +59,7 @@
     static PassRefPtr<JSONObject> createXHRReadyStateChangeData(const String& url, int readyState);
     static PassRefPtr<JSONObject> createXHRLoadData(const String& url);
     static PassRefPtr<JSONObject> createEvaluateScriptData(const String&, double lineNumber);
+    static PassRefPtr<JSONObject> createConsoleTimeData(const String&);
     static PassRefPtr<JSONObject> createTimeStampData(const String&);
     static PassRefPtr<JSONObject> createResourceSendRequestData(const String& requestId, const ResourceRequest&);
     static PassRefPtr<JSONObject> createScheduleResourceRequestData(const String&);
@@ -73,6 +74,7 @@
     static PassRefPtr<JSONObject> createAnimationFrameData(int callbackId);
     static PassRefPtr<JSONObject> createNodeData(long long nodeId);
     static PassRefPtr<JSONObject> createLayerData(long long layerRootNodeId);
+    static PassRefPtr<JSONObject> createLayerTreeData(PassRefPtr<JSONValue> layerTree);
     static PassRefPtr<JSONObject> createFrameData(int frameId);
     static PassRefPtr<JSONObject> createGPUTaskData(bool foreign);
 
@@ -99,6 +101,8 @@
         data->setNumber("identifier", identifier);
         return data.release();
     }
+
+    static PassRefPtr<JSONObject> createEmbedderCallbackData(const String& callbackName);
 private:
     TimelineRecordFactory() { }
 };
diff --git a/Source/core/inspector/TraceEventDispatcher.cpp b/Source/core/inspector/TraceEventDispatcher.cpp
index a75f4a4..8351b81 100644
--- a/Source/core/inspector/TraceEventDispatcher.cpp
+++ b/Source/core/inspector/TraceEventDispatcher.cpp
@@ -100,10 +100,12 @@
 
 void TraceEventDispatcher::innerAddListener(const char* name, char phase, TraceEventTargetBase* instance, TraceEventHandlerMethod method, InspectorClient* client)
 {
+    static const char CategoryFilter[] = "devtools,webkit";
+
     ASSERT(isMainThread());
     MutexLocker locker(m_mutex);
     if (m_handlers.isEmpty())
-        client->setTraceEventCallback(dispatchEventOnAnyThread);
+        client->setTraceEventCallback(CategoryFilter, dispatchEventOnAnyThread);
     HandlersMap::iterator it = m_handlers.find(std::make_pair(name, phase));
     if (it == m_handlers.end())
         m_handlers.add(std::make_pair(name, phase), Vector<BoundTraceEventHandler>()).storedValue->value.append(BoundTraceEventHandler(instance, method));
@@ -133,7 +135,7 @@
         m_handlers.swap(remainingHandlers);
     }
     if (m_handlers.isEmpty())
-        client->setTraceEventCallback(0);
+        client->resetTraceEventCallback();
 }
 
 size_t TraceEventDispatcher::TraceEvent::findParameter(const char* name) const
@@ -149,11 +151,12 @@
 {
     static WebCore::TraceEvent::TraceValueUnion missingValue;
     size_t index = findParameter(name);
+    ASSERT(isMainThread());
     if (index == kNotFound || m_argumentTypes[index] != expectedType) {
         ASSERT_NOT_REACHED();
         return missingValue;
     }
-    return *reinterpret_cast<const WebCore::TraceEvent::TraceValueUnion*>(m_argumentValues + index);
+    return m_argumentValues[index];
 }
 
 } // namespace WebCore
diff --git a/Source/core/inspector/TraceEventDispatcher.h b/Source/core/inspector/TraceEventDispatcher.h
index 22e14e7..5fae9a8 100644
--- a/Source/core/inspector/TraceEventDispatcher.h
+++ b/Source/core/inspector/TraceEventDispatcher.h
@@ -74,8 +74,14 @@
             }
             for (int i = 0; i < m_argumentCount; ++i) {
                 m_argumentNames[i] = argumentNames[i];
-                m_argumentTypes[i] = argumentTypes[i];
-                m_argumentValues[i] = argumentValues[i];
+                if (argumentTypes[i] == TRACE_VALUE_TYPE_COPY_STRING) {
+                    m_stringArguments[i] = reinterpret_cast<const char*>(argumentValues[i]);
+                    m_argumentValues[i].m_string = reinterpret_cast<const char*>(m_stringArguments[i].characters8());
+                    m_argumentTypes[i] = TRACE_VALUE_TYPE_STRING;
+                } else {
+                    m_argumentValues[i].m_int = argumentValues[i];
+                    m_argumentTypes[i] = argumentTypes[i];
+                }
             }
         }
 
@@ -127,7 +133,11 @@
         int m_argumentCount;
         const char* m_argumentNames[MaxArguments];
         unsigned char m_argumentTypes[MaxArguments];
-        unsigned long long m_argumentValues[MaxArguments];
+        WebCore::TraceEvent::TraceValueUnion m_argumentValues[MaxArguments];
+        // These are only used as buffers for TRACE_VALUE_TYPE_COPY_STRING.
+        // Consider allocating the entire vector of buffered trace events and their copied arguments out of a special arena
+        // to make things more compact.
+        String m_stringArguments[MaxArguments];
     };
 
     typedef void (TraceEventTargetBase::*TraceEventHandlerMethod)(const TraceEvent&);
diff --git a/Source/core/inspector/WorkerDebuggerAgent.cpp b/Source/core/inspector/WorkerDebuggerAgent.cpp
index 7eeec11..5148cc7 100644
--- a/Source/core/inspector/WorkerDebuggerAgent.cpp
+++ b/Source/core/inspector/WorkerDebuggerAgent.cpp
@@ -57,27 +57,22 @@
 
 class RunInspectorCommandsTask FINAL : public ScriptDebugServer::Task {
 public:
-    RunInspectorCommandsTask(WorkerThread* thread, WorkerGlobalScope* workerGlobalScope)
-        : m_thread(thread)
-        , m_workerGlobalScope(workerGlobalScope) { }
+    explicit RunInspectorCommandsTask(WorkerThread* thread)
+        : m_thread(thread) { }
     virtual ~RunInspectorCommandsTask() { }
     virtual void run() OVERRIDE
     {
-        // Process all queued debugger commands. It is safe to use m_workerGlobalScope here
-        // because it is alive if RunWorkerLoop is not terminated, otherwise it will
-        // just be ignored. WorkerThread is certainly alive if this task is being executed.
-        while (MessageQueueMessageReceived == m_thread->runLoop().runInMode(m_workerGlobalScope, WorkerDebuggerAgent::debuggerTaskMode, WorkerRunLoop::DontWaitForMessage)) { }
+        // Process all queued debugger commands. WorkerThread is certainly
+        // alive if this task is being executed.
+        while (MessageQueueMessageReceived == m_thread->runLoop().runDebuggerTask(WorkerRunLoop::DontWaitForMessage)) { }
     }
 
 private:
     WorkerThread* m_thread;
-    WorkerGlobalScope* m_workerGlobalScope;
 };
 
 } // namespace
 
-const char WorkerDebuggerAgent::debuggerTaskMode[] = "debugger";
-
 PassOwnPtr<WorkerDebuggerAgent> WorkerDebuggerAgent::create(WorkerScriptDebugServer* scriptDebugServer, WorkerGlobalScope* inspectedWorkerGlobalScope, InjectedScriptManager* injectedScriptManager)
 {
     return adoptPtr(new WorkerDebuggerAgent(scriptDebugServer, inspectedWorkerGlobalScope, injectedScriptManager));
@@ -104,7 +99,7 @@
     MutexLocker lock(workerDebuggerAgentsMutex());
     WorkerDebuggerAgent* agent = workerDebuggerAgents().get(thread);
     if (agent)
-        agent->m_scriptDebugServer->interruptAndRunTask(adoptPtr(new RunInspectorCommandsTask(thread, agent->m_inspectedWorkerGlobalScope)));
+        agent->m_scriptDebugServer->interruptAndRunTask(adoptPtr(new RunInspectorCommandsTask(thread)));
 }
 
 void WorkerDebuggerAgent::startListeningScriptDebugServer()
diff --git a/Source/core/inspector/WorkerDebuggerAgent.h b/Source/core/inspector/WorkerDebuggerAgent.h
index e0ea4a7..2383bfd 100644
--- a/Source/core/inspector/WorkerDebuggerAgent.h
+++ b/Source/core/inspector/WorkerDebuggerAgent.h
@@ -46,7 +46,6 @@
     static PassOwnPtr<WorkerDebuggerAgent> create(WorkerScriptDebugServer*, WorkerGlobalScope*, InjectedScriptManager*);
     virtual ~WorkerDebuggerAgent();
 
-    static const char debuggerTaskMode[];
     static void interruptAndDispatchInspectorCommands(WorkerThread*);
 
 private:
diff --git a/Source/core/inspector/WorkerInspectorController.cpp b/Source/core/inspector/WorkerInspectorController.cpp
index b569802..9f0e9d8 100644
--- a/Source/core/inspector/WorkerInspectorController.cpp
+++ b/Source/core/inspector/WorkerInspectorController.cpp
@@ -62,11 +62,11 @@
     explicit PageInspectorProxy(WorkerGlobalScope* workerGlobalScope) : m_workerGlobalScope(workerGlobalScope) { }
     virtual ~PageInspectorProxy() { }
 private:
-    virtual bool sendMessageToFrontend(const String& message) OVERRIDE
+    virtual void sendMessageToFrontend(PassRefPtr<JSONObject> message) OVERRIDE
     {
-        m_workerGlobalScope->thread()->workerReportingProxy().postMessageToPageInspector(message);
-        return true;
+        m_workerGlobalScope->thread()->workerReportingProxy().postMessageToPageInspector(message->toJSONString());
     }
+    virtual void flush() OVERRIDE { }
     WorkerGlobalScope* m_workerGlobalScope;
 };
 
@@ -93,12 +93,12 @@
     , m_state(adoptPtr(new InspectorCompositeState(m_stateClient.get())))
     , m_instrumentingAgents(InstrumentingAgents::create())
     , m_injectedScriptManager(InjectedScriptManager::createForWorker())
-    , m_debugServer(adoptPtr(new WorkerScriptDebugServer(workerGlobalScope, WorkerDebuggerAgent::debuggerTaskMode)))
+    , m_debugServer(adoptPtr(new WorkerScriptDebugServer(workerGlobalScope)))
     , m_agents(m_instrumentingAgents.get(), m_state.get())
 {
     m_agents.append(WorkerRuntimeAgent::create(m_injectedScriptManager.get(), m_debugServer.get(), workerGlobalScope));
 
-    OwnPtr<InspectorTimelineAgent> timelineAgent = InspectorTimelineAgent::create(0, 0, 0, InspectorTimelineAgent::WorkerInspector, 0);
+    OwnPtr<InspectorTimelineAgent> timelineAgent = InspectorTimelineAgent::create(0, 0, 0, 0, InspectorTimelineAgent::WorkerInspector, 0);
     m_agents.append(WorkerDebuggerAgent::create(m_debugServer.get(), workerGlobalScope, m_injectedScriptManager.get()));
 
     m_agents.append(InspectorProfilerAgent::create(m_injectedScriptManager.get(), 0));
diff --git a/Source/core/inspector/WorkerRuntimeAgent.cpp b/Source/core/inspector/WorkerRuntimeAgent.cpp
index 52ec387..a91d976 100644
--- a/Source/core/inspector/WorkerRuntimeAgent.cpp
+++ b/Source/core/inspector/WorkerRuntimeAgent.cpp
@@ -92,7 +92,7 @@
     m_paused = true;
     MessageQueueWaitResult result;
     do {
-        result = context->thread()->runLoop().runInMode(context, WorkerDebuggerAgent::debuggerTaskMode);
+        result = context->thread()->runLoop().runDebuggerTask();
     // Keep waiting until execution is resumed.
     } while (result == MessageQueueMessageReceived && m_paused);
 }
diff --git a/Source/core/inspector_instrumentation_sources.target.darwin-arm.mk b/Source/core/inspector_instrumentation_sources.target.darwin-arm.mk
index f826e07..11d0e41 100644
--- a/Source/core/inspector_instrumentation_sources.target.darwin-arm.mk
+++ b/Source/core/inspector_instrumentation_sources.target.darwin-arm.mk
@@ -25,6 +25,7 @@
 $(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
+$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 
@@ -34,6 +35,7 @@
 	$(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h \
+	$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp
 
diff --git a/Source/core/inspector_instrumentation_sources.target.darwin-mips.mk b/Source/core/inspector_instrumentation_sources.target.darwin-mips.mk
index f826e07..11d0e41 100644
--- a/Source/core/inspector_instrumentation_sources.target.darwin-mips.mk
+++ b/Source/core/inspector_instrumentation_sources.target.darwin-mips.mk
@@ -25,6 +25,7 @@
 $(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
+$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 
@@ -34,6 +35,7 @@
 	$(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h \
+	$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp
 
diff --git a/Source/core/inspector_instrumentation_sources.target.darwin-x86.mk b/Source/core/inspector_instrumentation_sources.target.darwin-x86.mk
index f826e07..11d0e41 100644
--- a/Source/core/inspector_instrumentation_sources.target.darwin-x86.mk
+++ b/Source/core/inspector_instrumentation_sources.target.darwin-x86.mk
@@ -25,6 +25,7 @@
 $(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
+$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 
@@ -34,6 +35,7 @@
 	$(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h \
+	$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp
 
diff --git a/Source/core/inspector_instrumentation_sources.target.linux-arm.mk b/Source/core/inspector_instrumentation_sources.target.linux-arm.mk
index f826e07..11d0e41 100644
--- a/Source/core/inspector_instrumentation_sources.target.linux-arm.mk
+++ b/Source/core/inspector_instrumentation_sources.target.linux-arm.mk
@@ -25,6 +25,7 @@
 $(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
+$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 
@@ -34,6 +35,7 @@
 	$(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h \
+	$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp
 
diff --git a/Source/core/inspector_instrumentation_sources.target.linux-mips.mk b/Source/core/inspector_instrumentation_sources.target.linux-mips.mk
index f826e07..11d0e41 100644
--- a/Source/core/inspector_instrumentation_sources.target.linux-mips.mk
+++ b/Source/core/inspector_instrumentation_sources.target.linux-mips.mk
@@ -25,6 +25,7 @@
 $(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
+$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 
@@ -34,6 +35,7 @@
 	$(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h \
+	$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp
 
diff --git a/Source/core/inspector_instrumentation_sources.target.linux-x86.mk b/Source/core/inspector_instrumentation_sources.target.linux-x86.mk
index f826e07..11d0e41 100644
--- a/Source/core/inspector_instrumentation_sources.target.linux-x86.mk
+++ b/Source/core/inspector_instrumentation_sources.target.linux-x86.mk
@@ -25,6 +25,7 @@
 $(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
+$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 $(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp: $(gyp_shared_intermediate_dir)/blink/InspectorCanvasInstrumentationInl.h ;
 
@@ -34,6 +35,7 @@
 	$(gyp_shared_intermediate_dir)/blink/InspectorConsoleInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorOverridesInl.h \
+	$(gyp_shared_intermediate_dir)/blink/InspectorPromiseInstrumentationInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InstrumentingAgentsInl.h \
 	$(gyp_shared_intermediate_dir)/blink/InspectorInstrumentationImpl.cpp
 
diff --git a/Source/core/loader/CookieJar.cpp b/Source/core/loader/CookieJar.cpp
index 4ba0ca1..d8ad40d 100644
--- a/Source/core/loader/CookieJar.cpp
+++ b/Source/core/loader/CookieJar.cpp
@@ -32,8 +32,8 @@
 #include "core/loader/CookieJar.h"
 
 #include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
 #include "platform/Cookie.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebCookie.h"
diff --git a/Source/core/loader/CrossOriginPreflightResultCache.cpp b/Source/core/loader/CrossOriginPreflightResultCache.cpp
index babd969..d2a119b 100644
--- a/Source/core/loader/CrossOriginPreflightResultCache.cpp
+++ b/Source/core/loader/CrossOriginPreflightResultCache.cpp
@@ -172,10 +172,4 @@
     return false;
 }
 
-void CrossOriginPreflightResultCache::empty()
-{
-    ASSERT(isMainThread());
-    m_preflightHashMap.clear();
-}
-
 } // namespace WebCore
diff --git a/Source/core/loader/CrossOriginPreflightResultCache.h b/Source/core/loader/CrossOriginPreflightResultCache.h
index 1c65c96..434555d 100644
--- a/Source/core/loader/CrossOriginPreflightResultCache.h
+++ b/Source/core/loader/CrossOriginPreflightResultCache.h
@@ -73,8 +73,6 @@
         void appendEntry(const String& origin, const KURL&, PassOwnPtr<CrossOriginPreflightResultCacheItem>);
         bool canSkipPreflight(const String& origin, const KURL&, StoredCredentials, const String& method, const HTTPHeaderMap& requestHeaders);
 
-        void empty();
-
     private:
         CrossOriginPreflightResultCache() { }
 
diff --git a/Source/core/loader/DocumentLoadTiming.h b/Source/core/loader/DocumentLoadTiming.h
index 28db5d5..608c3c1 100644
--- a/Source/core/loader/DocumentLoadTiming.h
+++ b/Source/core/loader/DocumentLoadTiming.h
@@ -30,7 +30,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class KURL;
 
 class DocumentLoadTiming {
diff --git a/Source/core/loader/DocumentLoader.cpp b/Source/core/loader/DocumentLoader.cpp
index ef8bf14..f8af711 100644
--- a/Source/core/loader/DocumentLoader.cpp
+++ b/Source/core/loader/DocumentLoader.cpp
@@ -44,9 +44,9 @@
 #include "core/loader/FrameLoaderClient.h"
 #include "core/loader/UniqueIdentifier.h"
 #include "core/loader/appcache/ApplicationCacheHost.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/page/FrameTree.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
@@ -69,7 +69,7 @@
     return mimeType == "multipart/related";
 }
 
-DocumentLoader::DocumentLoader(Frame* frame, const ResourceRequest& req, const SubstituteData& substituteData)
+DocumentLoader::DocumentLoader(LocalFrame* frame, const ResourceRequest& req, const SubstituteData& substituteData)
     : m_frame(frame)
     , m_fetcher(ResourceFetcher::create(this))
     , m_originalRequest(req)
@@ -141,9 +141,9 @@
     appendRedirect(newURL);
 }
 
-bool DocumentLoader::isURLValidForNewHistoryEntry() const
+const KURL& DocumentLoader::urlForHistory() const
 {
-    return !originalRequest().url().isEmpty() || !unreachableURL().isEmpty();
+    return unreachableURL().isEmpty() ? url() : unreachableURL();
 }
 
 void DocumentLoader::setMainDocumentError(const ResourceError& error)
@@ -170,7 +170,7 @@
 // but not loads initiated by child frames' data sources -- that's the WebFrame's job.
 void DocumentLoader::stopLoading()
 {
-    RefPtr<Frame> protectFrame(m_frame);
+    RefPtr<LocalFrame> protectFrame(m_frame);
     RefPtr<DocumentLoader> protectLoader(this);
 
     // In some rare cases, calling FrameLoader::stopLoading could cause isLoading() to return false.
@@ -314,7 +314,7 @@
         return true;
     if (policy == NavigationPolicyIgnore)
         return false;
-    if (!DOMWindow::allowPopUp(m_frame) && !UserGestureIndicator::processingUserGesture())
+    if (!DOMWindow::allowPopUp(*m_frame) && !UserGestureIndicator::processingUserGesture())
         return false;
     frameLoader()->client()->loadURLExternally(request, policy);
     return false;
@@ -375,7 +375,7 @@
 
     // If this is a sub-frame, check for mixed content blocking against the top frame.
     if (m_frame->tree().parent()) {
-        Frame* top = m_frame->tree().top();
+        LocalFrame* top = m_frame->tree().top();
         if (!top->loader().mixedContentChecker()->canRunInsecureContent(top->document()->securityOrigin(), newRequest.url())) {
             cancelMainResourceLoad(ResourceError::cancelledError(newRequest.url()));
             return;
@@ -522,7 +522,7 @@
 
     // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
     // by starting a new load, so retain temporarily.
-    RefPtr<Frame> protectFrame(m_frame);
+    RefPtr<LocalFrame> protectFrame(m_frame);
     RefPtr<DocumentLoader> protectLoader(this);
 
     m_applicationCacheHost->mainResourceDataReceived(data, length);
@@ -543,7 +543,7 @@
 
 void DocumentLoader::checkLoadComplete()
 {
-    if (!m_frame || isLoading())
+    if (!m_frame || isLoading() || !m_committed)
         return;
     m_frame->domWindow()->finishedLoading();
 }
@@ -561,7 +561,7 @@
 void DocumentLoader::detachFromFrame()
 {
     ASSERT(m_frame);
-    RefPtr<Frame> protectFrame(m_frame);
+    RefPtr<LocalFrame> protectFrame(m_frame);
     RefPtr<DocumentLoader> protectLoader(this);
 
     // It never makes sense to have a document loader that is detached from its
@@ -587,26 +587,6 @@
     m_mainResource = 0;
 }
 
-bool DocumentLoader::isLoadingInAPISense() const
-{
-    // Once a frame has loaded, we no longer need to consider subresources,
-    // but we still need to consider subframes.
-    if (frameLoader()->state() != FrameStateComplete) {
-        Document* doc = m_frame->document();
-        if ((m_loadingMainResource || !m_frame->document()->loadEventFinished()) && isLoading())
-            return true;
-        if (m_fetcher->requestCount())
-            return true;
-        if (doc->isDelayingLoadEvent() && !doc->loadEventFinished())
-            return true;
-        if (doc->processingLoadEvent())
-            return true;
-        if (doc->hasActiveParser())
-            return true;
-    }
-    return frameLoader()->subframeIsLoading();
-}
-
 bool DocumentLoader::maybeCreateArchive()
 {
     // Give the archive machinery a crack at this document. If the MIME type is not an archive type, it will return 0.
@@ -685,11 +665,6 @@
     return true;
 }
 
-const KURL& DocumentLoader::originalURL() const
-{
-    return m_originalRequest.url();
-}
-
 const AtomicString& DocumentLoader::responseMIMEType() const
 {
     return m_response.mimeType();
@@ -741,7 +716,7 @@
     timing()->markFetchStart();
     willSendRequest(m_request, ResourceResponse());
 
-    // willSendRequest() may lead to our Frame being detached or cancelling the load via nulling the ResourceRequest.
+    // willSendRequest() may lead to our LocalFrame being detached or cancelling the load via nulling the ResourceRequest.
     if (!m_frame || m_request.isNull())
         return;
 
@@ -792,7 +767,7 @@
     m_writer.clear();
 }
 
-PassRefPtr<DocumentWriter> DocumentLoader::createWriterFor(Frame* frame, const Document* ownerDocument, const KURL& url, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch)
+PassRefPtr<DocumentWriter> DocumentLoader::createWriterFor(LocalFrame* frame, const Document* ownerDocument, const KURL& url, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch)
 {
     // Create a new document before clearing the frame, because it may need to
     // inherit an aliased security context.
@@ -814,7 +789,7 @@
         frame->document()->prepareForDestruction();
 
     if (!shouldReuseDefaultView)
-        frame->setDOMWindow(DOMWindow::create(frame));
+        frame->setDOMWindow(DOMWindow::create(*frame));
 
     RefPtr<Document> document = frame->domWindow()->installNewDocument(mimeType, init);
     if (ownerDocument) {
diff --git a/Source/core/loader/DocumentLoader.h b/Source/core/loader/DocumentLoader.h
index a54d183..3d32b9c 100644
--- a/Source/core/loader/DocumentLoader.h
+++ b/Source/core/loader/DocumentLoader.h
@@ -54,7 +54,7 @@
     class ResourceFetcher;
     class ContentFilter;
     class FormState;
-    class Frame;
+    class LocalFrame;
     class FrameLoader;
     class MHTMLArchive;
     class Page;
@@ -64,13 +64,13 @@
     class DocumentLoader : public RefCounted<DocumentLoader>, private RawResourceClient {
         WTF_MAKE_FAST_ALLOCATED;
     public:
-        static PassRefPtr<DocumentLoader> create(Frame* frame, const ResourceRequest& request, const SubstituteData& data)
+        static PassRefPtr<DocumentLoader> create(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& data)
         {
             return adoptRef(new DocumentLoader(frame, request, data));
         }
         virtual ~DocumentLoader();
 
-        Frame* frame() const { return m_frame; }
+        LocalFrame* frame() const { return m_frame; }
 
         void detachFromFrame();
 
@@ -92,22 +92,21 @@
 
         const KURL& url() const;
         const KURL& unreachableURL() const;
-        bool isURLValidForNewHistoryEntry() const;
+        const KURL& urlForHistory() const;
 
-        const KURL& originalURL() const;
         const AtomicString& responseMIMEType() const;
 
         void updateForSameDocumentNavigation(const KURL&);
         void stopLoading();
         bool isCommitted() const { return m_committed; }
         bool isLoading() const;
+        bool isLoadingMainResource() const { return m_loadingMainResource; }
         const ResourceResponse& response() const { return m_response; }
         const ResourceError& mainDocumentError() const { return m_mainDocumentError; }
         bool isClientRedirect() const { return m_isClientRedirect; }
         void setIsClientRedirect(bool isClientRedirect) { m_isClientRedirect = isClientRedirect; }
         bool replacesCurrentHistoryItem() const { return m_replacesCurrentHistoryItem; }
         void setReplacesCurrentHistoryItem(bool replacesCurrentHistoryItem) { m_replacesCurrentHistoryItem = replacesCurrentHistoryItem; }
-        bool isLoadingInAPISense() const;
         const AtomicString& overrideEncoding() const { return m_overrideEncoding; }
 
         bool scheduleArchiveLoad(Resource*, const ResourceRequest&);
@@ -134,12 +133,12 @@
         void appendRedirect(const KURL&);
 
     protected:
-        DocumentLoader(Frame*, const ResourceRequest&, const SubstituteData&);
+        DocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&);
 
         Vector<KURL> m_redirectChain;
 
     private:
-        static PassRefPtr<DocumentWriter> createWriterFor(Frame*, const Document* ownerDocument, const KURL&, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch);
+        static PassRefPtr<DocumentWriter> createWriterFor(LocalFrame*, const Document* ownerDocument, const KURL&, const AtomicString& mimeType, const AtomicString& encoding, bool userChosen, bool dispatch);
 
         void ensureWriter(const AtomicString& mimeType, const KURL& overridingURL = KURL());
         void endWriting(DocumentWriter*);
@@ -175,7 +174,7 @@
 
         bool shouldContinueForResponse() const;
 
-        Frame* m_frame;
+        LocalFrame* m_frame;
         RefPtr<ResourceFetcher> m_fetcher;
 
         ResourcePtr<RawResource> m_mainResource;
diff --git a/Source/core/loader/DocumentThreadableLoader.cpp b/Source/core/loader/DocumentThreadableLoader.cpp
index 1888afb..2448aed 100644
--- a/Source/core/loader/DocumentThreadableLoader.cpp
+++ b/Source/core/loader/DocumentThreadableLoader.cpp
@@ -37,8 +37,8 @@
 #include "core/fetch/FetchRequest.h"
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/CrossOriginPreflightResultCache.h"
 #include "core/loader/DocumentThreadableLoaderClient.h"
@@ -63,7 +63,7 @@
 {
     RefPtr<DocumentThreadableLoader> loader = adoptRef(new DocumentThreadableLoader(document, client, LoadAsynchronously, request, options));
     if (!loader->resource())
-        loader = 0;
+        loader = nullptr;
     return loader.release();
 }
 
@@ -98,44 +98,33 @@
 {
     ASSERT(m_options.crossOriginRequestPolicy == UseAccessControl);
 
-    OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
+    if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight) {
+        // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
+        if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) {
+            m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP."));
+            return;
+        }
 
-    if ((m_options.preflightPolicy == ConsiderPreflight && isSimpleCrossOriginAccessRequest(crossOriginRequest->httpMethod(), crossOriginRequest->httpHeaderFields())) || m_options.preflightPolicy == PreventPreflight) {
-        updateRequestForAccessControl(*crossOriginRequest, securityOrigin(), m_options.allowCredentials);
-        makeSimpleCrossOriginAccessRequest(*crossOriginRequest);
+        ResourceRequest crossOriginRequest(request);
+        updateRequestForAccessControl(crossOriginRequest, securityOrigin(), m_options.allowCredentials);
+        loadRequest(crossOriginRequest);
     } else {
         m_simpleRequest = false;
+
+        OwnPtr<ResourceRequest> crossOriginRequest = adoptPtr(new ResourceRequest(request));
         // Do not set the Origin header for preflight requests.
         updateRequestForAccessControl(*crossOriginRequest, 0, m_options.allowCredentials);
         m_actualRequest = crossOriginRequest.release();
 
-        if (CrossOriginPreflightResultCache::shared().canSkipPreflight(securityOrigin()->toString(), m_actualRequest->url(), m_options.allowCredentials, m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields()))
+        if (CrossOriginPreflightResultCache::shared().canSkipPreflight(securityOrigin()->toString(), m_actualRequest->url(), m_options.allowCredentials, m_actualRequest->httpMethod(), m_actualRequest->httpHeaderFields())) {
             preflightSuccess();
-        else
-            makeCrossOriginAccessRequestWithPreflight(*m_actualRequest);
+        } else {
+            ResourceRequest preflightRequest = createAccessControlPreflightRequest(*m_actualRequest, securityOrigin());
+            loadRequest(preflightRequest);
+        }
     }
 }
 
-void DocumentThreadableLoader::makeSimpleCrossOriginAccessRequest(const ResourceRequest& request)
-{
-    ASSERT(m_options.preflightPolicy != ForcePreflight);
-    ASSERT(m_options.preflightPolicy == PreventPreflight || isSimpleCrossOriginAccessRequest(request.httpMethod(), request.httpHeaderFields()));
-
-    // Cross-origin requests are only allowed for HTTP and registered schemes. We would catch this when checking response headers later, but there is no reason to send a request that's guaranteed to be denied.
-    if (!SchemeRegistry::shouldTreatURLSchemeAsCORSEnabled(request.url().protocol())) {
-        m_client->didFailAccessControlCheck(ResourceError(errorDomainBlinkInternal, 0, request.url().string(), "Cross origin requests are only supported for HTTP."));
-        return;
-    }
-
-    loadRequest(request);
-}
-
-void DocumentThreadableLoader::makeCrossOriginAccessRequestWithPreflight(const ResourceRequest& request)
-{
-    ResourceRequest preflightRequest = createAccessControlPreflightRequest(request, securityOrigin());
-    loadRequest(preflightRequest);
-}
-
 DocumentThreadableLoader::~DocumentThreadableLoader()
 {
 }
@@ -392,7 +381,7 @@
         }
 
         if (m_options.timeoutMilliseconds > 0)
-            m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0);
+            m_timeoutTimer.startOneShot(m_options.timeoutMilliseconds / 1000.0, FROM_HERE);
 
         FetchRequest newRequest(request, m_options.initiator, options);
         ASSERT(!resource());
diff --git a/Source/core/loader/DocumentThreadableLoader.h b/Source/core/loader/DocumentThreadableLoader.h
index 2a32096..59331a5 100644
--- a/Source/core/loader/DocumentThreadableLoader.h
+++ b/Source/core/loader/DocumentThreadableLoader.h
@@ -90,8 +90,6 @@
         void didFinishLoading(unsigned long identifier, double finishTime);
         void didTimeout(Timer<DocumentThreadableLoader>*);
         void makeCrossOriginAccessRequest(const ResourceRequest&);
-        void makeSimpleCrossOriginAccessRequest(const ResourceRequest&);
-        void makeCrossOriginAccessRequestWithPreflight(const ResourceRequest&);
         void preflightSuccess();
         void preflightFailure(const String& url, const String& errorDescription);
 
diff --git a/Source/core/loader/DocumentWriter.cpp b/Source/core/loader/DocumentWriter.cpp
index 8294fbd..9455cfa 100644
--- a/Source/core/loader/DocumentWriter.cpp
+++ b/Source/core/loader/DocumentWriter.cpp
@@ -35,8 +35,8 @@
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderStateMachine.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
@@ -100,7 +100,7 @@
     // http://bugs.webkit.org/show_bug.cgi?id=10854
     // The frame's last ref may be removed and it can be deleted by checkCompleted(),
     // so we'll add a protective refcount
-    RefPtr<Frame> protector(m_document->frame());
+    RefPtr<LocalFrame> protector(m_document->frame());
 
     if (!m_parser)
         return;
@@ -117,7 +117,7 @@
         return;
 
     m_parser->finish();
-    m_parser = 0;
+    m_parser = nullptr;
     m_document = 0;
 }
 
diff --git a/Source/core/loader/DocumentWriter.h b/Source/core/loader/DocumentWriter.h
index 4e79045..f558213 100644
--- a/Source/core/loader/DocumentWriter.h
+++ b/Source/core/loader/DocumentWriter.h
@@ -37,7 +37,7 @@
 
 class Document;
 class DocumentParser;
-class Frame;
+class LocalFrame;
 class KURL;
 class SecurityOrigin;
 class TextResourceDecoder;
diff --git a/Source/core/loader/EmptyClients.cpp b/Source/core/loader/EmptyClients.cpp
index da1c28d..26510c7 100644
--- a/Source/core/loader/EmptyClients.cpp
+++ b/Source/core/loader/EmptyClients.cpp
@@ -28,14 +28,14 @@
 #include "config.h"
 #include "core/loader/EmptyClients.h"
 
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/loader/DocumentLoader.h"
-#include "core/loader/FormState.h"
-#include "core/frame/Frame.h"
 #include "core/storage/StorageNamespace.h"
 #include "platform/ColorChooser.h"
 #include "platform/DateTimeChooser.h"
 #include "platform/FileChooser.h"
+#include "public/platform/WebApplicationCacheHost.h"
 #include "public/platform/WebServiceWorkerProvider.h"
 #include "public/platform/WebServiceWorkerProviderClient.h"
 
@@ -76,7 +76,7 @@
     virtual void disconnectClient() OVERRIDE { }
 };
 
-PassRefPtr<PopupMenu> EmptyChromeClient::createPopupMenu(Frame&, PopupMenuClient*) const
+PassRefPtr<PopupMenu> EmptyChromeClient::createPopupMenu(LocalFrame&, PopupMenuClient*) const
 {
     return adoptRef(new EmptyPopupMenu());
 }
@@ -95,7 +95,7 @@
 {
 }
 
-void EmptyChromeClient::runOpenPanel(Frame*, PassRefPtr<FileChooser>)
+void EmptyChromeClient::runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>)
 {
 }
 
@@ -109,43 +109,48 @@
     return NavigationPolicyIgnore;
 }
 
-void EmptyFrameLoaderClient::dispatchWillSendSubmitEvent(PassRefPtr<FormState>)
+void EmptyFrameLoaderClient::dispatchWillSendSubmitEvent(HTMLFormElement*)
 {
 }
 
-void EmptyFrameLoaderClient::dispatchWillSubmitForm(PassRefPtr<FormState>)
+void EmptyFrameLoaderClient::dispatchWillSubmitForm(HTMLFormElement*)
 {
 }
 
-PassRefPtr<DocumentLoader> EmptyFrameLoaderClient::createDocumentLoader(Frame* frame, const ResourceRequest& request, const SubstituteData& substituteData)
+PassRefPtr<DocumentLoader> EmptyFrameLoaderClient::createDocumentLoader(LocalFrame* frame, const ResourceRequest& request, const SubstituteData& substituteData)
 {
     return DocumentLoader::create(frame, request, substituteData);
 }
 
-PassRefPtr<Frame> EmptyFrameLoaderClient::createFrame(const KURL&, const AtomicString&, const Referrer&, HTMLFrameOwnerElement*)
+PassRefPtr<LocalFrame> EmptyFrameLoaderClient::createFrame(const KURL&, const AtomicString&, const Referrer&, HTMLFrameOwnerElement*)
 {
-    return 0;
+    return nullptr;
 }
 
-PassRefPtr<Widget> EmptyFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool)
+PassRefPtr<Widget> EmptyFrameLoaderClient::createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool, DetachedPluginPolicy)
 {
-    return 0;
+    return nullptr;
 }
 
-PassRefPtr<Widget> EmptyFrameLoaderClient::createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&)
+PassRefPtr<Widget> EmptyFrameLoaderClient::createJavaAppletWidget(HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&)
 {
-    return 0;
+    return nullptr;
 }
 
 void EmptyTextCheckerClient::requestCheckingOfString(PassRefPtr<TextCheckingRequest>)
 {
 }
 
-void EmptyFrameLoaderClient::didRequestAutocomplete(PassRefPtr<FormState>)
+void EmptyFrameLoaderClient::didRequestAutocomplete(HTMLFormElement*)
 {
 }
 
-PassOwnPtr<blink::WebServiceWorkerProvider> EmptyFrameLoaderClient::createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>)
+PassOwnPtr<blink::WebServiceWorkerProvider> EmptyFrameLoaderClient::createServiceWorkerProvider()
+{
+    return nullptr;
+}
+
+PassOwnPtr<blink::WebApplicationCacheHost> EmptyFrameLoaderClient::createApplicationCacheHost(blink::WebApplicationCacheHostClient*)
 {
     return nullptr;
 }
diff --git a/Source/core/loader/EmptyClients.h b/Source/core/loader/EmptyClients.h
index f66e933..39d0a99 100644
--- a/Source/core/loader/EmptyClients.h
+++ b/Source/core/loader/EmptyClients.h
@@ -52,7 +52,7 @@
 
 /*
  This file holds empty Client stubs for use by WebCore.
- Viewless element needs to create a dummy Page->Frame->FrameView tree for use in parsing or executing JavaScript.
+ Viewless element needs to create a dummy Page->LocalFrame->FrameView tree for use in parsing or executing JavaScript.
  This tree depends heavily on Clients (usually provided by WebKit classes).
 
  This file was first created for SVGImage as it had no way to access the current Page (nor should it,
@@ -83,7 +83,8 @@
     virtual void takeFocus(FocusType) OVERRIDE { }
 
     virtual void focusedNodeChanged(Node*) OVERRIDE { }
-    virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) OVERRIDE { return 0; }
+    virtual void focusedFrameChanged(LocalFrame*) OVERRIDE { }
+    virtual Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) OVERRIDE { return 0; }
     virtual void show(NavigationPolicy) OVERRIDE { }
 
     virtual bool canRunModal() OVERRIDE { return false; }
@@ -107,16 +108,16 @@
     virtual void addMessageToConsole(MessageSource, MessageLevel, const String&, unsigned, const String&, const String&) OVERRIDE { }
 
     virtual bool canRunBeforeUnloadConfirmPanel() OVERRIDE { return false; }
-    virtual bool runBeforeUnloadConfirmPanel(const String&, Frame*) OVERRIDE { return true; }
+    virtual bool runBeforeUnloadConfirmPanel(const String&, LocalFrame*) OVERRIDE { return true; }
 
     virtual void closeWindowSoon() OVERRIDE { }
 
-    virtual void runJavaScriptAlert(Frame*, const String&) OVERRIDE { }
-    virtual bool runJavaScriptConfirm(Frame*, const String&) OVERRIDE { return false; }
-    virtual bool runJavaScriptPrompt(Frame*, const String&, const String&, String&) OVERRIDE { return false; }
+    virtual void runJavaScriptAlert(LocalFrame*, const String&) OVERRIDE { }
+    virtual bool runJavaScriptConfirm(LocalFrame*, const String&) OVERRIDE { return false; }
+    virtual bool runJavaScriptPrompt(LocalFrame*, const String&, const String&, String&) OVERRIDE { return false; }
 
     virtual bool hasOpenedPopup() const OVERRIDE { return false; }
-    virtual PassRefPtr<PopupMenu> createPopupMenu(Frame&, PopupMenuClient*) const OVERRIDE;
+    virtual PassRefPtr<PopupMenu> createPopupMenu(LocalFrame&, PopupMenuClient*) const OVERRIDE;
     virtual void setPagePopupDriver(PagePopupDriver*) OVERRIDE { }
     virtual void resetPagePopupDriver() OVERRIDE { }
 
@@ -135,13 +136,13 @@
 
     virtual IntRect rootViewToScreen(const IntRect& r) const OVERRIDE { return r; }
     virtual blink::WebScreenInfo screenInfo() const OVERRIDE { return blink::WebScreenInfo(); }
-    virtual void contentsSizeChanged(Frame*, const IntSize&) const OVERRIDE { }
+    virtual void contentsSizeChanged(LocalFrame*, const IntSize&) const OVERRIDE { }
 
     virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned) OVERRIDE { }
 
     virtual void setToolTip(const String&, TextDirection) OVERRIDE { }
 
-    virtual void print(Frame*) OVERRIDE { }
+    virtual void print(LocalFrame*) OVERRIDE { }
 
     virtual void enumerateChosenDirectory(FileChooser*) OVERRIDE { }
 
@@ -149,13 +150,11 @@
     virtual PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&) OVERRIDE;
     virtual void openTextDataListChooser(HTMLInputElement&) OVERRIDE;
 
-    virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) OVERRIDE;
-
-    virtual void formStateDidChange(const Node*) OVERRIDE { }
+    virtual void runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>) OVERRIDE;
 
     virtual void setCursor(const Cursor&) OVERRIDE { }
 
-    virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) OVERRIDE { }
+    virtual void attachRootGraphicsLayer(GraphicsLayer*) OVERRIDE { }
 
     virtual void needTouchEvents(bool) OVERRIDE { }
     virtual void setTouchAction(TouchAction touchAction) OVERRIDE { };
@@ -179,6 +178,9 @@
 
     virtual bool hasWebView() const OVERRIDE { return true; } // mainly for assertions
 
+    virtual Frame* opener() const OVERRIDE { return 0; }
+    virtual void setOpener(Frame*) OVERRIDE { }
+
     virtual Frame* parent() const OVERRIDE { return 0; }
     virtual Frame* top() const OVERRIDE { return 0; }
     virtual Frame* previousSibling() const OVERRIDE { return 0; }
@@ -198,7 +200,7 @@
     virtual void dispatchDidStartProvisionalLoad() OVERRIDE { }
     virtual void dispatchDidReceiveTitle(const String&) OVERRIDE { }
     virtual void dispatchDidChangeIcons(IconType) OVERRIDE { }
-    virtual void dispatchDidCommitLoad(Frame*, HistoryItem*, HistoryCommitType) OVERRIDE { }
+    virtual void dispatchDidCommitLoad(LocalFrame*, HistoryItem*, HistoryCommitType) OVERRIDE { }
     virtual void dispatchDidFailProvisionalLoad(const ResourceError&) OVERRIDE { }
     virtual void dispatchDidFailLoad(const ResourceError&) OVERRIDE { }
     virtual void dispatchDidFinishDocumentLoad() OVERRIDE { }
@@ -207,8 +209,8 @@
 
     virtual NavigationPolicy decidePolicyForNavigation(const ResourceRequest&, DocumentLoader*, NavigationPolicy) OVERRIDE;
 
-    virtual void dispatchWillSendSubmitEvent(PassRefPtr<FormState>) OVERRIDE;
-    virtual void dispatchWillSubmitForm(PassRefPtr<FormState>) OVERRIDE;
+    virtual void dispatchWillSendSubmitEvent(HTMLFormElement*) OVERRIDE;
+    virtual void dispatchWillSubmitForm(HTMLFormElement*) OVERRIDE;
 
     virtual void postProgressStartedNotification(LoadStartType) OVERRIDE { }
     virtual void postProgressEstimateChangedNotification() OVERRIDE { }
@@ -216,7 +218,7 @@
 
     virtual void loadURLExternally(const ResourceRequest&, NavigationPolicy, const String& = String()) OVERRIDE { }
 
-    virtual PassRefPtr<DocumentLoader> createDocumentLoader(Frame*, const ResourceRequest&, const SubstituteData&) OVERRIDE;
+    virtual PassRefPtr<DocumentLoader> createDocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&) OVERRIDE;
 
     virtual String userAgent(const KURL&) OVERRIDE { return ""; }
 
@@ -230,9 +232,9 @@
     virtual void didDetectXSS(const KURL&, bool) OVERRIDE { }
     virtual void didDispatchPingLoader(const KURL&) OVERRIDE { }
     virtual void selectorMatchChanged(const Vector<String>&, const Vector<String>&) OVERRIDE { }
-    virtual PassRefPtr<Frame> createFrame(const KURL&, const AtomicString&, const Referrer&, HTMLFrameOwnerElement*) OVERRIDE;
-    virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool) OVERRIDE;
-    virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&) OVERRIDE;
+    virtual PassRefPtr<LocalFrame> createFrame(const KURL&, const AtomicString&, const Referrer&, HTMLFrameOwnerElement*) OVERRIDE;
+    virtual PassRefPtr<Widget> createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool, DetachedPluginPolicy) OVERRIDE;
+    virtual PassRefPtr<Widget> createJavaAppletWidget(HTMLAppletElement*, const KURL&, const Vector<String>&, const Vector<String>&) OVERRIDE;
 
     virtual ObjectContentType objectContentType(const KURL&, const String&, bool) OVERRIDE { return ObjectContentType(); }
 
@@ -245,8 +247,10 @@
 
     virtual blink::WebCookieJar* cookieJar() const OVERRIDE { return 0; }
 
-    virtual void didRequestAutocomplete(PassRefPtr<FormState>) OVERRIDE;
-    virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>) OVERRIDE;
+    virtual void didRequestAutocomplete(HTMLFormElement*) OVERRIDE;
+
+    virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider() OVERRIDE;
+    virtual PassOwnPtr<blink::WebApplicationCacheHost> createApplicationCacheHost(blink::WebApplicationCacheHostClient*) OVERRIDE;
 };
 
 class EmptyTextCheckerClient FINAL : public TextCheckerClient {
@@ -287,8 +291,8 @@
     virtual void respondToChangedContents() OVERRIDE { }
     virtual void respondToChangedSelection(SelectionType) OVERRIDE { }
 
-    virtual bool canCopyCut(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; }
-    virtual bool canPaste(Frame*, bool defaultValue) const OVERRIDE { return defaultValue; }
+    virtual bool canCopyCut(LocalFrame*, bool defaultValue) const OVERRIDE { return defaultValue; }
+    virtual bool canPaste(LocalFrame*, bool defaultValue) const OVERRIDE { return defaultValue; }
 
     virtual void didExecuteCommand(String) OVERRIDE { }
     virtual bool handleKeyboardEvent() OVERRIDE { return false; }
@@ -309,7 +313,7 @@
     EmptyDragClient() { }
     virtual ~EmptyDragClient() {}
     virtual DragDestinationAction actionMaskForDrag(DragData*) OVERRIDE { return DragDestinationActionNone; }
-    virtual void startDrag(DragImage*, const IntPoint&, const IntPoint&, Clipboard*, Frame*, bool) OVERRIDE { }
+    virtual void startDrag(DragImage*, const IntPoint&, const IntPoint&, Clipboard*, LocalFrame*, bool) OVERRIDE { }
 };
 
 class EmptyInspectorClient FINAL : public InspectorClient {
@@ -332,7 +336,7 @@
 class EmptyStorageClient FINAL : public StorageClient {
 public:
     virtual PassOwnPtr<StorageNamespace> createSessionStorageNamespace() OVERRIDE;
-    virtual bool canAccessStorage(Frame*, StorageType) const OVERRIDE { return false; }
+    virtual bool canAccessStorage(LocalFrame*, StorageType) const OVERRIDE { return false; }
 };
 
 void fillWithEmptyClients(Page::PageClients&);
diff --git a/Source/core/loader/FormState.cpp b/Source/core/loader/FormState.cpp
index 7bbea43..affecfb 100644
--- a/Source/core/loader/FormState.cpp
+++ b/Source/core/loader/FormState.cpp
@@ -29,22 +29,20 @@
 #include "config.h"
 #include "core/loader/FormState.h"
 
-#include "core/dom/Document.h"
 #include "core/html/HTMLFormElement.h"
 
 namespace WebCore {
 
-inline FormState::FormState(PassRefPtr<HTMLFormElement> form, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document> sourceDocument, FormSubmissionTrigger formSubmissionTrigger)
+inline FormState::FormState(HTMLFormElement& form, FormSubmissionTrigger formSubmissionTrigger)
     : m_form(form)
-    , m_sourceDocument(sourceDocument)
+    , m_sourceDocument(form.document())
     , m_formSubmissionTrigger(formSubmissionTrigger)
 {
-    m_textFieldValues.swap(textFieldValuesToAdopt);
 }
 
-PassRefPtr<FormState> FormState::create(PassRefPtr<HTMLFormElement> form, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document> sourceDocument, FormSubmissionTrigger formSubmissionTrigger)
+PassRefPtr<FormState> FormState::create(HTMLFormElement& form, FormSubmissionTrigger formSubmissionTrigger)
 {
-    return adoptRef(new FormState(form, textFieldValuesToAdopt, sourceDocument, formSubmissionTrigger));
+    return adoptRef(new FormState(form, formSubmissionTrigger));
 }
 
 }
diff --git a/Source/core/loader/FormState.h b/Source/core/loader/FormState.h
index 058db51..675a987 100644
--- a/Source/core/loader/FormState.h
+++ b/Source/core/loader/FormState.h
@@ -30,7 +30,7 @@
 #define FormState_h
 
 #include "wtf/RefCounted.h"
-#include "wtf/text/WTFString.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
@@ -42,22 +42,18 @@
         NotSubmittedByJavaScript
     };
 
-    typedef Vector<std::pair<String, String> > StringPairVector;
-
     class FormState : public RefCounted<FormState> {
     public:
-        static PassRefPtr<FormState> create(PassRefPtr<HTMLFormElement>, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document>, FormSubmissionTrigger);
+        static PassRefPtr<FormState> create(HTMLFormElement&, FormSubmissionTrigger);
 
         HTMLFormElement* form() const { return m_form.get(); }
-        const StringPairVector& textFieldValues() const { return m_textFieldValues; }
         Document* sourceDocument() const { return m_sourceDocument.get(); }
         FormSubmissionTrigger formSubmissionTrigger() const { return m_formSubmissionTrigger; }
 
     private:
-        FormState(PassRefPtr<HTMLFormElement>, StringPairVector& textFieldValuesToAdopt, PassRefPtr<Document>, FormSubmissionTrigger);
+        FormState(HTMLFormElement&, FormSubmissionTrigger);
 
         RefPtr<HTMLFormElement> m_form;
-        StringPairVector m_textFieldValues;
         RefPtr<Document> m_sourceDocument;
         FormSubmissionTrigger m_formSubmissionTrigger;
     };
diff --git a/Source/core/loader/FormSubmission.cpp b/Source/core/loader/FormSubmission.cpp
index dea9f79..f422977 100644
--- a/Source/core/loader/FormSubmission.cpp
+++ b/Source/core/loader/FormSubmission.cpp
@@ -42,6 +42,7 @@
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/loader/FrameLoader.h"
+#include "heap/Handle.h"
 #include "platform/network/FormData.h"
 #include "platform/network/FormDataBuilder.h"
 #include "wtf/CurrentTime.h"
@@ -188,8 +189,11 @@
             copiedAttributes.setTarget(attributeValue);
     }
 
-    if (copiedAttributes.method() == DialogMethod)
-        return adoptRef(new FormSubmission(submitButton->resultForDialogSubmit()));
+    if (copiedAttributes.method() == DialogMethod) {
+        if (submitButton)
+            return adoptRef(new FormSubmission(submitButton->resultForDialogSubmit()));
+        return adoptRef(new FormSubmission(""));
+    }
 
     Document& document = form->document();
     KURL actionURL = document.completeURL(copiedAttributes.action().isEmpty() ? document.url().string() : copiedAttributes.action());
@@ -205,20 +209,18 @@
         }
     }
     WTF::TextEncoding dataEncoding = isMailtoForm ? UTF8Encoding() : FormDataBuilder::encodingFromAcceptCharset(copiedAttributes.acceptCharset(), document.inputEncoding(), document.defaultCharset());
-    RefPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
-    Vector<pair<String, String> > formValues;
+    RefPtrWillBeRawPtr<DOMFormData> domFormData = DOMFormData::create(dataEncoding.encodingForFormSubmission());
 
     bool containsPasswordData = false;
     for (unsigned i = 0; i < form->associatedElements().size(); ++i) {
         FormAssociatedElement* control = form->associatedElements()[i];
-        HTMLElement* element = toHTMLElement(control);
-        if (!element->isDisabledFormControl())
+        ASSERT(control);
+        HTMLElement& element = toHTMLElement(*control);
+        if (!element.isDisabledFormControl())
             control->appendFormData(*domFormData, isMultiPartForm);
-        if (element->hasTagName(inputTag)) {
-            HTMLInputElement* input = toHTMLInputElement(element);
-            if (input->isTextField())
-                formValues.append(pair<String, String>(input->name().string(), input->value()));
-            if (input->isPasswordField() && !input->value().isEmpty())
+        if (isHTMLInputElement(element)) {
+            HTMLInputElement& input = toHTMLInputElement(element);
+            if (input.isPasswordField() && !input.value().isEmpty())
                 containsPasswordData = true;
         }
     }
@@ -241,7 +243,7 @@
     formData->setIdentifier(generateFormDataIdentifier());
     formData->setContainsPasswordData(containsPasswordData);
     AtomicString targetOrBaseTarget = copiedAttributes.target().isEmpty() ? document.baseTarget() : copiedAttributes.target();
-    RefPtr<FormState> formState = FormState::create(form, formValues, &document, trigger);
+    RefPtr<FormState> formState = FormState::create(*form, trigger);
     return adoptRef(new FormSubmission(copiedAttributes.method(), actionURL, targetOrBaseTarget, encodingType, formState.release(), formData.release(), boundary, event));
 }
 
diff --git a/Source/core/loader/FormSubmission.h b/Source/core/loader/FormSubmission.h
index 65bdfe2..0ed026c 100644
--- a/Source/core/loader/FormSubmission.h
+++ b/Source/core/loader/FormSubmission.h
@@ -102,15 +102,11 @@
     const KURL& action() const { return m_action; }
     const AtomicString& target() const { return m_target; }
     void clearTarget() { m_target = nullAtom; }
-    const AtomicString& contentType() const { return m_contentType; }
     FormState* state() const { return m_formState.get(); }
     FormData* data() const { return m_formData.get(); }
-    const String boundary() const { return m_boundary; }
     Event* event() const { return m_event.get(); }
 
-    const Referrer& referrer() const { return m_referrer; }
     void setReferrer(const Referrer& referrer) { m_referrer = referrer; }
-    const String& origin() const { return m_origin; }
     void setOrigin(const String& origin) { m_origin = origin; }
 
     const String& result() const { return m_result; }
diff --git a/Source/core/loader/FrameFetchContext.cpp b/Source/core/loader/FrameFetchContext.cpp
index c8ad61b..508176d 100644
--- a/Source/core/loader/FrameFetchContext.cpp
+++ b/Source/core/loader/FrameFetchContext.cpp
@@ -32,12 +32,12 @@
 #include "core/loader/FrameFetchContext.h"
 
 #include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
 #include "core/loader/ProgressTracker.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "platform/weborigin/SecurityPolicy.h"
@@ -46,7 +46,7 @@
 
 static const char defaultAcceptHeader[] = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
 
-FrameFetchContext::FrameFetchContext(Frame* frame)
+FrameFetchContext::FrameFetchContext(LocalFrame* frame)
     : m_frame(frame)
 {
 }
@@ -115,7 +115,7 @@
     if (loadType == FrameLoadTypeReloadFromOrigin)
         return CachePolicyReload;
 
-    if (Frame* parentFrame = m_frame->tree().parent()) {
+    if (LocalFrame* parentFrame = m_frame->tree().parent()) {
         CachePolicy parentCachePolicy = parentFrame->loader().fetchContext().cachePolicy(parentFrame->document());
         if (parentCachePolicy != CachePolicyVerify)
             return parentCachePolicy;
diff --git a/Source/core/loader/FrameFetchContext.h b/Source/core/loader/FrameFetchContext.h
index 8f6e554..ea26a84 100644
--- a/Source/core/loader/FrameFetchContext.h
+++ b/Source/core/loader/FrameFetchContext.h
@@ -39,7 +39,7 @@
 
 class Document;
 class DocumentLoader;
-class Frame;
+class LocalFrame;
 class Page;
 class ResourceError;
 class ResourceLoader;
@@ -48,7 +48,7 @@
 
 class FrameFetchContext FINAL : public FetchContext {
 public:
-    static PassOwnPtr<FrameFetchContext> create(Frame* frame) { return adoptPtr(new FrameFetchContext(frame)); }
+    static PassOwnPtr<FrameFetchContext> create(LocalFrame* frame) { return adoptPtr(new FrameFetchContext(frame)); }
 
     virtual void reportLocalLoadFailed(const KURL&) OVERRIDE;
     virtual void addAdditionalRequestHeaders(Document*, ResourceRequest&, FetchResourceType) OVERRIDE;
@@ -64,10 +64,10 @@
     virtual void sendRemainingDelegateMessages(DocumentLoader*, unsigned long identifier, const ResourceResponse&, int dataLength) OVERRIDE;
 
 private:
-    explicit FrameFetchContext(Frame*);
+    explicit FrameFetchContext(LocalFrame*);
     inline DocumentLoader* ensureLoader(DocumentLoader*);
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
 };
 
 }
diff --git a/Source/core/loader/FrameLoadRequest.h b/Source/core/loader/FrameLoadRequest.h
index 09d992a..5b29d4d 100644
--- a/Source/core/loader/FrameLoadRequest.h
+++ b/Source/core/loader/FrameLoadRequest.h
@@ -34,7 +34,7 @@
 #include "platform/network/ResourceRequest.h"
 
 namespace WebCore {
-class Frame;
+class LocalFrame;
 
 struct FrameLoadRequest {
 public:
diff --git a/Source/core/loader/FrameLoader.cpp b/Source/core/loader/FrameLoader.cpp
index 6887bdd..2f3d4e2 100644
--- a/Source/core/loader/FrameLoader.cpp
+++ b/Source/core/loader/FrameLoader.cpp
@@ -49,11 +49,10 @@
 #include "core/fetch/FetchContext.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ResourceLoader.h"
-#include "core/frame/ContentSecurityPolicy.h"
-#include "core/frame/ContentSecurityPolicyResponseHeaders.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
@@ -80,10 +79,10 @@
 #include "core/page/WindowFeatures.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
 #include "core/xml/parser/XMLDocumentParser.h"
-#include "modules/webdatabase/DatabaseManager.h"
 #include "platform/Logging.h"
 #include "platform/UserGestureIndicator.h"
 #include "platform/geometry/FloatRect.h"
+#include "platform/network/ContentSecurityPolicyResponseHeaders.h"
 #include "platform/network/HTTPParsers.h"
 #include "platform/network/ResourceRequest.h"
 #include "platform/scroll/ScrollAnimator.h"
@@ -102,9 +101,14 @@
     return type == FrameLoadTypeBackForward;
 }
 
+static bool needsHistoryItemRestore(FrameLoadType type)
+{
+    return type == FrameLoadTypeBackForward || type == FrameLoadTypeReload || type == FrameLoadTypeReloadFromOrigin;
+}
+
 class FrameLoader::FrameProgressTracker {
 public:
-    static PassOwnPtr<FrameProgressTracker> create(Frame* frame) { return adoptPtr(new FrameProgressTracker(frame)); }
+    static PassOwnPtr<FrameProgressTracker> create(LocalFrame* frame) { return adoptPtr(new FrameProgressTracker(frame)); }
     ~FrameProgressTracker()
     {
         ASSERT(!m_inProgress || m_frame->page());
@@ -129,17 +133,17 @@
     }
 
 private:
-    FrameProgressTracker(Frame* frame)
+    FrameProgressTracker(LocalFrame* frame)
         : m_frame(frame)
         , m_inProgress(false)
     {
     }
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
     bool m_inProgress;
 };
 
-FrameLoader::FrameLoader(Frame* frame, FrameLoaderClient* client)
+FrameLoader::FrameLoader(LocalFrame* frame, FrameLoaderClient* client)
     : m_frame(frame)
     , m_client(client)
     , m_mixedContentChecker(frame)
@@ -151,7 +155,6 @@
     , m_isComplete(false)
     , m_checkTimer(this, &FrameLoader::checkTimerFired)
     , m_shouldCallCheckCompleted(false)
-    , m_opener(0)
     , m_didAccessInitialDocument(false)
     , m_didAccessInitialDocumentTimer(this, &FrameLoader::didAccessInitialDocumentTimerFired)
     , m_forcedSandboxFlags(SandboxNone)
@@ -160,9 +163,6 @@
 
 FrameLoader::~FrameLoader()
 {
-    HashSet<Frame*>::iterator end = m_openedFrames.end();
-    for (HashSet<Frame*>::iterator it = m_openedFrames.begin(); it != end; ++it)
-        (*it)->loader().m_opener = 0;
 }
 
 void FrameLoader::init()
@@ -183,6 +183,10 @@
         m_policyDocumentLoader->setDefersLoading(defers);
 
     if (!defers) {
+        if (m_deferredHistoryLoad.isValid()) {
+            loadHistoryItem(m_deferredHistoryLoad.m_item.get(), m_deferredHistoryLoad.m_type, m_deferredHistoryLoad.m_cachePolicy);
+            m_deferredHistoryLoad = DeferredHistoryLoad();
+        }
         m_frame->navigationScheduler().startTimer();
         startCheckCompleteTimer();
     }
@@ -201,30 +205,45 @@
         // FIXME: HTML5 doesn't tell us to set the state to complete when aborting, but we do anyway to match legacy behavior.
         // http://www.w3.org/Bugs/Public/show_bug.cgi?id=10537
         doc->setReadyState(Document::Complete);
-
-        // FIXME: Should the DatabaseManager watch for something like ActiveDOMObject::stop() rather than being special-cased here?
-        DatabaseManager::manager().stopDatabases(doc, 0);
     }
 
     // FIXME: This will cancel redirection timer, which really needs to be restarted when restoring the frame from b/f cache.
     m_frame->navigationScheduler().cancel();
 }
 
-void FrameLoader::saveDocumentAndScrollState()
+void FrameLoader::markDocumentStateDirty()
 {
-    if (!m_currentItem)
+    Document* document = m_frame->document();
+    document->setHistoryItemDocumentStateDirty(true);
+    m_client->didUpdateCurrentHistoryItem();
+}
+
+void FrameLoader::saveDocumentState()
+{
+    Document* document = m_frame->document();
+    if (!m_currentItem || !document->historyItemDocumentStateDirty())
         return;
 
-    Document* document = m_frame->document();
     if (m_currentItem->isCurrentDocument(document) && document->isActive())
         m_currentItem->setDocumentState(document->formElementsState());
 
-    if (!m_frame->view())
+    document->setHistoryItemDocumentStateDirty(false);
+}
+
+void FrameLoader::saveScrollState()
+{
+    if (!m_currentItem || !m_frame->view())
+        return;
+
+    // Shouldn't clobber anything if we might still restore later.
+    if (needsHistoryItemRestore(m_loadType) && !m_frame->view()->wasScrolledByUser())
         return;
 
     m_currentItem->setScrollPoint(m_frame->view()->scrollPosition());
     if (m_frame->isMainFrame() && !m_frame->page()->inspectorController().deviceEmulationEnabled())
         m_currentItem->setPageScaleFactor(m_frame->page()->pageScaleFactor());
+
+    m_client->didUpdateCurrentHistoryItem();
 }
 
 void FrameLoader::clearScrollPositionAndViewState()
@@ -238,7 +257,8 @@
 
 bool FrameLoader::closeURL()
 {
-    saveDocumentAndScrollState();
+    saveDocumentState();
+    saveScrollState();
 
     // Should only send the pagehide event here if the current document exists.
     if (m_frame->document())
@@ -299,13 +319,8 @@
         m_currentItem = HistoryItem::create();
     else if (!isPushOrReplaceState && m_documentLoader->url() != m_currentItem->url())
         m_currentItem->generateNewSequenceNumbers();
-    const KURL& unreachableURL = m_documentLoader->unreachableURL();
-    const KURL& url = unreachableURL.isEmpty() ? m_documentLoader->url() : unreachableURL;
-    const KURL& originalURL = unreachableURL.isEmpty() ? m_documentLoader->originalURL() : unreachableURL;
-    m_currentItem->setURL(url);
+    m_currentItem->setURL(m_documentLoader->urlForHistory());
     m_currentItem->setTarget(m_frame->tree().uniqueName());
-    m_currentItem->setTargetFrameID(m_frame->frameID());
-    m_currentItem->setOriginalURLString(originalURL.string());
     if (isPushOrReplaceState)
         m_currentItem->setStateObject(stateObject);
     m_currentItem->setReferrer(Referrer(m_documentLoader->request().httpReferrer(), m_documentLoader->request().referrerPolicy()));
@@ -332,7 +347,8 @@
     if (m_stateMachine.creatingInitialEmptyDocument())
         return;
 
-    HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType, m_documentLoader->isURLValidForNewHistoryEntry());
+    bool isValidHistoryURL = !m_documentLoader->urlForHistory().isEmpty() && (!opener() || m_currentItem || !m_documentLoader->originalRequest().url().isEmpty());
+    HistoryCommitType historyCommitType = loadTypeToCommitType(m_loadType, isValidHistoryURL);
     setHistoryItemStateForCommit(historyCommitType);
 
     if (!m_stateMachine.committedMultipleRealLoads() && m_loadType == FrameLoadTypeStandard)
@@ -347,8 +363,8 @@
 
 static void didFailContentSecurityPolicyCheck(FrameLoader* loader)
 {
-    // load event and stopAllLoaders can detach the Frame, so protect it.
-    RefPtr<Frame> frame(loader->frame());
+    // load event and stopAllLoaders can detach the LocalFrame, so protect it.
+    RefPtr<LocalFrame> frame(loader->frame());
 
     // Move the page to a unique origin, and cancel the load.
     frame->document()->enforceSandboxFlags(SandboxOrigin);
@@ -409,10 +425,10 @@
     if (m_stateMachine.creatingInitialEmptyDocument())
         return;
 
-    // This can be called from the Frame's destructor, in which case we shouldn't protect ourselves
+    // This can be called from the LocalFrame's destructor, in which case we shouldn't protect ourselves
     // because doing so will cause us to re-enter the destructor when protector goes out of scope.
     // Null-checking the FrameView indicates whether or not we're in the destructor.
-    RefPtr<Frame> protector = m_frame->view() ? m_frame : 0;
+    RefPtr<LocalFrame> protector = m_frame->view() ? m_frame : 0;
 
     if (m_client)
         m_client->dispatchDidFinishDocumentLoad();
@@ -435,7 +451,7 @@
 
 bool FrameLoader::allChildrenAreComplete() const
 {
-    for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+    for (LocalFrame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
         if (!child->loader().m_isComplete)
             return false;
     }
@@ -444,7 +460,7 @@
 
 bool FrameLoader::allAncestorsAreComplete() const
 {
-    for (Frame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent()) {
+    for (LocalFrame* ancestor = m_frame; ancestor; ancestor = ancestor->tree().parent()) {
         if (!ancestor->document()->loadEventFinished())
             return false;
     }
@@ -453,7 +469,7 @@
 
 void FrameLoader::checkCompleted()
 {
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
     m_shouldCallCheckCompleted = false;
 
     if (m_frame->view())
@@ -467,6 +483,10 @@
     if (m_frame->document()->parsing())
         return;
 
+    // Still waiting imports?
+    if (!m_frame->document()->haveImportsLoaded())
+        return;
+
     // Still waiting for images/scripts?
     if (m_frame->document()->fetcher()->requestCount())
         return;
@@ -497,7 +517,7 @@
 
 void FrameLoader::checkTimerFired(Timer<FrameLoader>*)
 {
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
 
     if (Page* page = m_frame->page()) {
         if (page->defersLoading())
@@ -513,7 +533,7 @@
         return;
     if (m_checkTimer.isActive())
         return;
-    m_checkTimer.startOneShot(0);
+    m_checkTimer.startOneShot(0, FROM_HERE);
 }
 
 void FrameLoader::scheduleCheckCompleted()
@@ -522,24 +542,17 @@
     startCheckCompleteTimer();
 }
 
-Frame* FrameLoader::opener()
+LocalFrame* FrameLoader::opener()
 {
-    return m_opener;
+    ASSERT(m_client);
+    // FIXME: Temporary hack to stage converting locations that really should be Frame.
+    return toLocalFrame(m_client->opener());
 }
 
-void FrameLoader::setOpener(Frame* opener)
+void FrameLoader::setOpener(LocalFrame* opener)
 {
-    if (m_opener && !opener)
-        m_client->didDisownOpener();
-
-    if (m_opener)
-        m_opener->loader().m_openedFrames.remove(m_frame);
-    if (opener)
-        opener->loader().m_openedFrames.add(m_frame);
-    m_opener = opener;
-
-    if (m_frame->document())
-        m_frame->document()->initSecurityContext();
+    ASSERT(m_client);
+    m_client->setOpener(opener);
 }
 
 bool FrameLoader::allowPlugins(ReasonForCallingAllowPlugins reason)
@@ -581,9 +594,10 @@
         m_provisionalDocumentLoader->stopLoading();
         if (m_provisionalDocumentLoader)
             m_provisionalDocumentLoader->detachFromFrame();
-        m_provisionalDocumentLoader = 0;
+        m_provisionalDocumentLoader = nullptr;
     }
-    saveDocumentAndScrollState();
+    saveDocumentState();
+    saveScrollState();
 
     KURL oldURL = m_frame->document()->url();
     // If we were in the autoscroll/panScroll mode we want to stop it before following the link to the anchor
@@ -593,8 +607,11 @@
         m_frame->domWindow()->enqueueHashchangeEvent(oldURL, url);
     }
     m_documentLoader->setIsClientRedirect(clientRedirect == ClientRedirect);
-    m_documentLoader->setReplacesCurrentHistoryItem(updateBackForwardList == DoNotUpdateBackForwardList);
-    updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, 0, updateBackForwardList);
+    bool replacesCurrentHistoryItem = updateBackForwardList == DoNotUpdateBackForwardList;
+    m_documentLoader->setReplacesCurrentHistoryItem(replacesCurrentHistoryItem);
+    updateForSameDocumentNavigation(url, SameDocumentNavigationDefault, nullptr, updateBackForwardList);
+
+    m_frame->view()->setWasScrolledByUser(false);
 
     // It's important to model this as a load that starts and immediately finishes.
     // Otherwise, the parent frame may think we never finished loading.
@@ -612,12 +629,12 @@
 
 void FrameLoader::completed()
 {
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
 
-    for (Frame* descendant = m_frame->tree().traverseNext(m_frame); descendant; descendant = descendant->tree().traverseNext(m_frame))
+    for (LocalFrame* descendant = m_frame->tree().traverseNext(m_frame); descendant; descendant = descendant->tree().traverseNext(m_frame))
         descendant->navigationScheduler().startTimer();
 
-    if (Frame* parent = m_frame->tree().parent())
+    if (LocalFrame* parent = m_frame->tree().parent())
         parent->loader().checkCompleted();
 
     if (m_frame->view())
@@ -626,7 +643,7 @@
 
 void FrameLoader::started()
 {
-    for (Frame* frame = m_frame; frame; frame = frame->tree().parent())
+    for (LocalFrame* frame = m_frame; frame; frame = frame->tree().parent())
         frame->loader().m_isComplete = false;
 }
 
@@ -666,15 +683,15 @@
         return FrameLoadTypeInitialInChildFrame;
     if (!m_frame->tree().parent() && !m_frame->page()->backForward().backForwardListCount())
         return FrameLoadTypeStandard;
-    if (request.resourceRequest().cachePolicy() == ReloadIgnoringCacheData)
-        return FrameLoadTypeReload;
     if (m_provisionalDocumentLoader && request.substituteData().failingURL() == m_provisionalDocumentLoader->url() && m_loadType == FrameLoadTypeBackForward)
         return FrameLoadTypeBackForward;
+    if (request.resourceRequest().cachePolicy() == ReloadIgnoringCacheData)
+        return FrameLoadTypeReload;
     if (request.lockBackForwardList() || isScriptTriggeredFormSubmissionInChildFrame(request))
         return FrameLoadTypeRedirectWithLockedBackForwardList;
-    if (!request.originDocument() && shouldTreatURLAsSameAsCurrent(request.resourceRequest().url()))
+    if (!request.originDocument() && request.resourceRequest().url() == m_documentLoader->urlForHistory())
         return FrameLoadTypeSame;
-    if (shouldTreatURLAsSameAsCurrent(request.substituteData().failingURL()) && m_loadType == FrameLoadTypeReload)
+    if (request.substituteData().failingURL() == m_documentLoader->urlForHistory() && m_loadType == FrameLoadTypeReload)
         return FrameLoadTypeReload;
     return FrameLoadTypeStandard;
 }
@@ -701,12 +718,21 @@
     return true;
 }
 
+static bool shouldOpenInNewWindow(LocalFrame* targetFrame, const FrameLoadRequest& request, const NavigationAction& action)
+{
+    if (!targetFrame && !request.frameName().isEmpty())
+        return true;
+    // FIXME: This case is a workaround for the fact that ctrl+clicking a form submission incorrectly
+    // sends as a GET rather than a POST if it creates a new window in a different process.
+    return request.formState() && action.shouldOpenInNewWindow();
+}
+
 void FrameLoader::load(const FrameLoadRequest& passedRequest)
 {
     ASSERT(m_frame->document());
 
     // Protect frame from getting blown away inside dispatchBeforeLoadEvent in loadWithDocumentLoader.
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
 
     if (m_inStopAllLoaders)
         return;
@@ -715,7 +741,7 @@
     if (!prepareRequestForThisFrame(request))
         return;
 
-    RefPtr<Frame> targetFrame = request.formState() ? 0 : findFrameForNavigation(AtomicString(request.frameName()), request.formState() ? request.formState()->sourceDocument() : m_frame->document());
+    RefPtr<LocalFrame> targetFrame = request.formState() ? 0 : findFrameForNavigation(AtomicString(request.frameName()), request.formState() ? request.formState()->sourceDocument() : m_frame->document());
     if (targetFrame && targetFrame != m_frame) {
         request.setFrameName("_self");
         targetFrame->loader().load(request);
@@ -726,21 +752,21 @@
 
     FrameLoadType newLoadType = determineFrameLoadType(request);
     NavigationAction action(request.resourceRequest(), newLoadType, request.formState(), request.triggeringEvent());
-    if ((!targetFrame && !request.frameName().isEmpty()) || action.shouldOpenInNewWindow()) {
+    if (shouldOpenInNewWindow(targetFrame.get(), request, action)) {
         if (action.policy() == NavigationPolicyDownload)
             m_client->loadURLExternally(action.resourceRequest(), NavigationPolicyDownload);
         else
-            createWindowForRequest(request, m_frame, action.policy(), request.shouldSendReferrer());
+            createWindowForRequest(request, *m_frame, action.policy(), request.shouldSendReferrer());
         return;
     }
 
     const KURL& url = request.resourceRequest().url();
-    if (shouldPerformFragmentNavigation(request.formState(), request.resourceRequest().httpMethod(), newLoadType, url)) {
+    if (!action.shouldOpenInNewWindow() && shouldPerformFragmentNavigation(request.formState(), request.resourceRequest().httpMethod(), newLoadType, url)) {
         m_documentLoader->setTriggeringAction(action);
-        loadInSameDocument(url, 0, newLoadType == FrameLoadTypeStandard ? UpdateBackForwardList : DoNotUpdateBackForwardList, request.clientRedirect());
+        loadInSameDocument(url, nullptr, newLoadType == FrameLoadTypeStandard ? UpdateBackForwardList : DoNotUpdateBackForwardList, request.clientRedirect());
         return;
     }
-    bool sameURL = shouldTreatURLAsSameAsCurrent(url);
+    bool sameURL = url == m_documentLoader->urlForHistory();
     loadWithNavigationAction(action, newLoadType, request.formState(), request.substituteData(), request.clientRedirect());
     // Example of this case are sites that reload the same URL with a different cookie
     // driving the generated content, or a master frame with links that drive a target
@@ -759,7 +785,7 @@
     return SubstituteData(SharedBuffer::create(encodedSrcdoc.data(), encodedSrcdoc.length()), "text/html", "UTF-8", KURL());
 }
 
-void FrameLoader::reportLocalLoadFailed(Frame* frame, const String& url)
+void FrameLoader::reportLocalLoadFailed(LocalFrame* frame, const String& url)
 {
     ASSERT(!url.isEmpty());
     if (!frame)
@@ -795,7 +821,7 @@
     }
 
     FrameLoadType type = reloadPolicy == EndToEndReload ? FrameLoadTypeReloadFromOrigin : FrameLoadTypeReload;
-    loadWithNavigationAction(NavigationAction(request, type), type, 0, SubstituteData(), NotClientRedirect, overrideEncoding);
+    loadWithNavigationAction(NavigationAction(request, type), type, nullptr, SubstituteData(), NotClientRedirect, overrideEncoding);
 }
 
 void FrameLoader::stopAllLoaders()
@@ -809,11 +835,11 @@
 
     // Calling stopLoading() on the provisional document loader can blow away
     // the frame from underneath.
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
 
     m_inStopAllLoaders = true;
 
-    for (RefPtr<Frame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling())
+    for (RefPtr<LocalFrame> child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling())
         child->loader().stopAllLoaders();
     if (m_provisionalDocumentLoader)
         m_provisionalDocumentLoader->stopLoading();
@@ -822,13 +848,13 @@
 
     if (m_provisionalDocumentLoader)
         m_provisionalDocumentLoader->detachFromFrame();
-    m_provisionalDocumentLoader = 0;
+    m_provisionalDocumentLoader = nullptr;
 
     m_checkTimer.stop();
 
     m_inStopAllLoaders = false;
 
-    // detachFromParent() can be called multiple times on same Frame, which
+    // detachFromParent() can be called multiple times on same LocalFrame, which
     // means we may no longer have a FrameLoaderClient to talk to.
     if (m_client)
         m_client->didStopAllLoaders();
@@ -840,7 +866,7 @@
     if (isLoadingMainFrame() && !m_didAccessInitialDocument) {
         m_didAccessInitialDocument = true;
         // Notify asynchronously, since this is called within a JavaScript security check.
-        m_didAccessInitialDocumentTimer.startOneShot(0);
+        m_didAccessInitialDocumentTimer.startOneShot(0, FROM_HERE);
     }
 }
 
@@ -869,7 +895,7 @@
     ASSERT(m_client->hasWebView());
     ASSERT(m_state == FrameStateProvisional);
     RefPtr<DocumentLoader> pdl = m_provisionalDocumentLoader;
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
 
     // Check if the destination page is allowed to access the previous page's timing information.
     if (m_frame->document()) {
@@ -916,52 +942,62 @@
     return m_frame->isMainFrame();
 }
 
-bool FrameLoader::subframeIsLoading() const
-{
-    // It's most likely that the last added frame is the last to load so we walk backwards.
-    for (Frame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling()) {
-        const FrameLoader& childLoader = child->loader();
-        DocumentLoader* documentLoader = childLoader.documentLoader();
-        if (documentLoader && documentLoader->isLoadingInAPISense())
-            return true;
-        documentLoader = childLoader.provisionalDocumentLoader();
-        if (documentLoader && documentLoader->isLoadingInAPISense())
-            return true;
-        documentLoader = childLoader.policyDocumentLoader();
-        if (documentLoader)
-            return true;
-    }
-    return false;
-}
-
 FrameLoadType FrameLoader::loadType() const
 {
     return m_loadType;
 }
 
-void FrameLoader::checkLoadCompleteForThisFrame()
+// This function is an incomprehensible mess and is only used in checkLoadCompleteForThisFrame.
+// If you're thinking of using it elsewhere, stop right now and reconsider your life.
+static bool isDocumentDoneLoading(Document* document)
+{
+    if (document->loader()->isLoadingMainResource())
+        return false;
+    if (!document->loadEventFinished()) {
+        if (document->loader()->isLoading() || document->isDelayingLoadEvent())
+            return false;
+    }
+    if (document->fetcher()->requestCount())
+        return false;
+    if (document->processingLoadEvent())
+        return false;
+    if (document->hasActiveParser())
+        return false;
+    return true;
+}
+
+bool FrameLoader::checkLoadCompleteForThisFrame()
 {
     ASSERT(m_client->hasWebView());
+    RefPtr<LocalFrame> protect(m_frame);
 
     if (m_state == FrameStateProvisional && m_provisionalDocumentLoader) {
         const ResourceError& error = m_provisionalDocumentLoader->mainDocumentError();
         if (error.isNull())
-            return;
+            return false;
         RefPtr<DocumentLoader> loader = m_provisionalDocumentLoader;
         m_client->dispatchDidFailProvisionalLoad(error);
         if (loader != m_provisionalDocumentLoader)
-            return;
+            return false;
         m_provisionalDocumentLoader->detachFromFrame();
-        m_provisionalDocumentLoader = 0;
+        m_provisionalDocumentLoader = nullptr;
         m_progressTracker->progressCompleted();
         m_state = FrameStateComplete;
+        return true;
     }
 
-    if (m_state != FrameStateCommittedPage)
-        return;
+    bool allChildrenAreDoneLoading = true;
+    for (LocalFrame* child = m_frame->tree().firstChild(); child; child = child->tree().nextSibling())
+        allChildrenAreDoneLoading &= child->loader().checkLoadCompleteForThisFrame();
+    if (!allChildrenAreDoneLoading)
+        return false;
 
-    if (!m_documentLoader || (m_documentLoader->isLoadingInAPISense() && !m_inStopAllLoaders))
-        return;
+    if (m_state == FrameStateComplete)
+        return true;
+    if (m_provisionalDocumentLoader || !m_documentLoader)
+        return false;
+    if (!isDocumentDoneLoading(m_frame->document()) && !m_inStopAllLoaders)
+        return false;
 
     m_state = FrameStateComplete;
 
@@ -969,11 +1005,12 @@
     // Maybe there are bugs because of that, or extra work we can skip because
     // the new page is ready.
 
-    // If the user had a scroll point, scroll to it, overriding the anchor point if any.
+    // Retry restoring scroll offset since FrameStateComplete disables content
+    // size clamping.
     restoreScrollPositionAndViewState();
 
     if (!m_stateMachine.committedFirstRealDocumentLoad())
-        return;
+        return true;
 
     m_progressTracker->progressCompleted();
 
@@ -983,58 +1020,54 @@
     else
         m_client->dispatchDidFinishLoad();
     m_loadType = FrameLoadTypeStandard;
+    return true;
 }
 
-// There is a race condition between the layout and load completion that affects restoring the scroll position.
-// We try to restore the scroll position at both the first layout and upon load completion.
-// 1) If first layout happens before the load completes, we want to restore the scroll position then so that the
-// first time we draw the page is already scrolled to the right place, instead of starting at the top and later
-// jumping down. It is possible that the old scroll position is past the part of the doc laid out so far, in
-// which case the restore silent fails and we will fix it in when we try to restore on doc completion.
-// 2) If the layout happens after the load completes, the attempt to restore at load completion time silently
-// fails. We then successfully restore it when the layout happens.
-void FrameLoader::restoreScrollPositionAndViewState(RestorePolicy restorePolicy)
+void FrameLoader::restoreScrollPositionAndViewState()
 {
-    if (!isBackForwardLoadType(m_loadType) && m_loadType != FrameLoadTypeReload && m_loadType != FrameLoadTypeReloadFromOrigin && restorePolicy != ForcedRestoreForSameDocumentHistoryNavigation)
-        return;
-    if (!m_frame->page() || !m_currentItem || !m_stateMachine.committedFirstRealDocumentLoad())
+    FrameView* view = m_frame->view();
+    if (!m_frame->page() || !view || !m_currentItem || !m_stateMachine.committedFirstRealDocumentLoad())
         return;
 
-    if (FrameView* view = m_frame->view()) {
-        if (m_frame->isMainFrame()) {
-            if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator())
-                scrollingCoordinator->frameViewRootLayerDidChange(view);
-        }
+    if (!needsHistoryItemRestore(m_loadType))
+        return;
 
-        if (!view->wasScrolledByUser() || restorePolicy == ForcedRestoreForSameDocumentHistoryNavigation) {
-            if (m_frame->isMainFrame() && m_currentItem->pageScaleFactor())
-                m_frame->page()->setPageScaleFactor(m_currentItem->pageScaleFactor(), m_currentItem->scrollPoint());
-            else
-                view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint());
-        }
+    // This tries to balance 1. restoring as soon as possible, 2. detecting
+    // clamping to avoid repeatedly popping the scroll position down as the
+    // page height increases, 3. ignore clamp detection after load completes
+    // because that may be because the page will never reach its previous
+    // height.
+    bool canRestoreWithoutClamping = view->clampOffsetAtScale(m_currentItem->scrollPoint(), m_currentItem->pageScaleFactor()) == m_currentItem->scrollPoint();
+    bool canRestoreWithoutAnnoyingUser = !view->wasScrolledByUser() && (canRestoreWithoutClamping || m_state == FrameStateComplete);
+    if (!canRestoreWithoutAnnoyingUser)
+        return;
+
+    if (m_frame->isMainFrame() && m_currentItem->pageScaleFactor())
+        m_frame->page()->setPageScaleFactor(m_currentItem->pageScaleFactor(), m_currentItem->scrollPoint());
+    else
+        view->setScrollPositionNonProgrammatically(m_currentItem->scrollPoint());
+
+    if (m_frame->isMainFrame()) {
+        if (ScrollingCoordinator* scrollingCoordinator = m_frame->page()->scrollingCoordinator())
+            scrollingCoordinator->frameViewRootLayerDidChange(view);
     }
 }
 
-void FrameLoader::didFirstLayout()
-{
-    restoreScrollPositionAndViewState();
-}
-
 void FrameLoader::detachChildren()
 {
-    typedef Vector<RefPtr<Frame> > FrameVector;
+    typedef Vector<RefPtr<LocalFrame> > FrameVector;
     FrameVector childrenToDetach;
     childrenToDetach.reserveCapacity(m_frame->tree().childCount());
-    for (Frame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling())
+    for (LocalFrame* child = m_frame->tree().lastChild(); child; child = child->tree().previousSibling())
         childrenToDetach.append(child);
     FrameVector::iterator end = childrenToDetach.end();
     for (FrameVector::iterator it = childrenToDetach.begin(); it != end; ++it)
         (*it)->loader().detachFromParent();
 }
 
-void FrameLoader::closeAndRemoveChild(Frame* child)
+void FrameLoader::closeAndRemoveChild(LocalFrame* child)
 {
-    child->setView(0);
+    child->setView(nullptr);
     if (child->ownerElement() && child->page())
         child->page()->decrementSubframeCount();
     child->willDetachFrameHost();
@@ -1045,17 +1078,8 @@
 void FrameLoader::checkLoadComplete()
 {
     ASSERT(m_client->hasWebView());
-
-    // FIXME: Always traversing the entire frame tree is a bit inefficient, but
-    // is currently needed in order to null out the previous history item for all frames.
-    if (Page* page = m_frame->page()) {
-        Vector<RefPtr<Frame>, 10> frames;
-        for (RefPtr<Frame> frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
-            frames.append(frame);
-        // To process children before their parents, iterate the vector backwards.
-        for (size_t i = frames.size(); i; --i)
-            frames[i - 1]->loader().checkLoadCompleteForThisFrame();
-    }
+    if (Page* page = m_frame->page())
+        page->mainFrame()->loader().checkLoadCompleteForThisFrame();
 }
 
 void FrameLoader::checkLoadComplete(DocumentLoader* documentLoader)
@@ -1071,7 +1095,7 @@
         return m_frame->document()->fetcher()->requestCount();
 
     int count = 0;
-    for (Frame* frame = m_frame; frame; frame = frame->tree().traverseNext(m_frame))
+    for (LocalFrame* frame = m_frame; frame; frame = frame->tree().traverseNext(m_frame))
         count += frame->document()->fetcher()->requestCount();
     return count;
 }
@@ -1085,16 +1109,16 @@
 
 void FrameLoader::frameDetached()
 {
-    // stopAllLoaders can detach the Frame, so protect it.
-    RefPtr<Frame> protect(m_frame);
+    // stopAllLoaders can detach the LocalFrame, so protect it.
+    RefPtr<LocalFrame> protect(m_frame);
     stopAllLoaders();
     detachFromParent();
 }
 
 void FrameLoader::detachFromParent()
 {
-    // stopAllLoaders can detach the Frame, so protect it.
-    RefPtr<Frame> protect(m_frame);
+    // stopAllLoaders can detach the LocalFrame, so protect it.
+    RefPtr<LocalFrame> protect(m_frame);
 
     closeURL();
     detachChildren();
@@ -1107,17 +1131,17 @@
 
     if (m_documentLoader)
         m_documentLoader->detachFromFrame();
-    m_documentLoader = 0;
+    m_documentLoader = nullptr;
 
     if (!m_client)
         return;
 
     // FIXME: All this code belongs up in Page.
-    if (Frame* parent = m_frame->tree().parent()) {
+    if (LocalFrame* parent = m_frame->tree().parent()) {
         parent->loader().closeAndRemoveChild(m_frame);
         parent->loader().scheduleCheckCompleted();
     } else {
-        m_frame->setView(0);
+        m_frame->setView(nullptr);
         m_frame->willDetachFrameHost();
         detachClient();
     }
@@ -1137,7 +1161,7 @@
     m_frame->script().clearForClose();
 
     // After this, we must no longer talk to the client since this clears
-    // its owning reference back to our owning Frame.
+    // its owning reference back to our owning LocalFrame.
     m_client->detachedFromParent();
     m_client = 0;
 }
@@ -1172,7 +1196,7 @@
 void FrameLoader::receivedMainResourceError(const ResourceError& error)
 {
     // Retain because the stop may release the last reference to it.
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
 
     if (m_frame->document()->parser())
         m_frame->document()->parser()->stopParsing();
@@ -1211,7 +1235,7 @@
         return;
 
     // Leaking scroll position to a cross-origin ancestor would permit the so-called "framesniffing" attack.
-    RefPtr<Frame> boundaryFrame(url.hasFragmentIdentifier() ? m_frame->document()->findUnsafeParentScrollPropagationBoundary() : 0);
+    RefPtr<LocalFrame> boundaryFrame(url.hasFragmentIdentifier() ? m_frame->document()->findUnsafeParentScrollPropagationBoundary() : 0);
 
     if (boundaryFrame)
         boundaryFrame->view()->setSafeToPropagateScrollToParent(false);
@@ -1229,9 +1253,9 @@
         return true;
 
     // Store all references to each subframe in advance since beforeunload's event handler may modify frame
-    Vector<RefPtr<Frame> > targetFrames;
+    Vector<RefPtr<LocalFrame> > targetFrames;
     targetFrames.append(m_frame);
-    for (Frame* child = m_frame->tree().firstChild(); child; child = child->tree().traverseNext(m_frame))
+    for (LocalFrame* child = m_frame->tree().firstChild(); child; child = child->tree().traverseNext(m_frame))
         targetFrames.append(child);
 
     bool shouldClose = false;
@@ -1287,18 +1311,18 @@
     m_policyDocumentLoader->setReplacesCurrentHistoryItem(replacesCurrentHistoryItem);
     m_policyDocumentLoader->setIsClientRedirect(clientRedirect == ClientRedirect);
 
-    if (Frame* parent = m_frame->tree().parent())
+    if (LocalFrame* parent = m_frame->tree().parent())
         m_policyDocumentLoader->setOverrideEncoding(parent->loader().documentLoader()->overrideEncoding());
     else if (!overrideEncoding.isEmpty())
         m_policyDocumentLoader->setOverrideEncoding(overrideEncoding);
     else if (m_documentLoader)
         m_policyDocumentLoader->setOverrideEncoding(m_documentLoader->overrideEncoding());
 
-    // stopAllLoaders can detach the Frame, so protect it.
-    RefPtr<Frame> protect(m_frame);
+    // stopAllLoaders can detach the LocalFrame, so protect it.
+    RefPtr<LocalFrame> protect(m_frame);
     if ((!m_policyDocumentLoader->shouldContinueForNavigationPolicy(request) || !shouldClose()) && m_policyDocumentLoader) {
         m_policyDocumentLoader->detachFromFrame();
-        m_policyDocumentLoader = 0;
+        m_policyDocumentLoader = nullptr;
         return;
     }
 
@@ -1319,7 +1343,7 @@
     m_state = FrameStateProvisional;
 
     if (formState)
-        m_client->dispatchWillSubmitForm(formState);
+        m_client->dispatchWillSubmitForm(formState->form());
 
     m_progressTracker->progressStarted();
     if (m_provisionalDocumentLoader->isClientRedirect())
@@ -1341,7 +1365,7 @@
 {
     UseCounter::count(m_frame->domWindow()->document(), UseCounter::XFrameOptions);
 
-    Frame* topFrame = m_frame->tree().top();
+    LocalFrame* topFrame = m_frame->tree().top();
     if (m_frame == topFrame)
         return false;
 
@@ -1353,7 +1377,7 @@
         RefPtr<SecurityOrigin> origin = SecurityOrigin::create(url);
         if (!origin->isSameSchemeHostPort(topFrame->document()->securityOrigin()))
             return true;
-        for (Frame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) {
+        for (LocalFrame* frame = m_frame->tree().parent(); frame; frame = frame->tree().parent()) {
             if (!origin->isSameSchemeHostPort(frame->document()->securityOrigin())) {
                 UseCounter::count(m_frame->domWindow()->document(), UseCounter::XFrameOptionsSameOriginWithBadAncestorChain);
                 break;
@@ -1377,29 +1401,20 @@
     }
 }
 
-bool FrameLoader::shouldTreatURLAsSameAsCurrent(const KURL& url) const
-{
-    if (!m_currentItem)
-        return false;
-    return url == m_currentItem->url() || url == m_currentItem->originalURL();
-}
-
 bool FrameLoader::shouldTreatURLAsSrcdocDocument(const KURL& url) const
 {
     if (!equalIgnoringCase(url.string(), "about:srcdoc"))
         return false;
     HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement();
-    if (!ownerElement)
-        return false;
-    if (!ownerElement->hasTagName(iframeTag))
+    if (!isHTMLIFrameElement(ownerElement))
         return false;
     return ownerElement->fastHasAttribute(srcdocAttr);
 }
 
-Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* activeDocument)
+LocalFrame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* activeDocument)
 {
     ASSERT(activeDocument);
-    Frame* frame = m_frame->tree().find(name);
+    LocalFrame* frame = m_frame->tree().find(name);
     if (!activeDocument->canNavigate(frame))
         return 0;
     return frame;
@@ -1407,13 +1422,19 @@
 
 void FrameLoader::loadHistoryItem(HistoryItem* item, HistoryLoadType historyLoadType, ResourceRequestCachePolicy cachePolicy)
 {
-    m_provisionalItem = item;
-    if (historyLoadType == HistorySameDocumentLoad) {
-        loadInSameDocument(item->url(), item->stateObject(), DoNotUpdateBackForwardList, NotClientRedirect);
-        restoreScrollPositionAndViewState(ForcedRestoreForSameDocumentHistoryNavigation);
+    if (m_frame->page()->defersLoading()) {
+        m_deferredHistoryLoad = DeferredHistoryLoad(item, historyLoadType, cachePolicy);
         return;
     }
-    loadWithNavigationAction(NavigationAction(requestFromHistoryItem(item, cachePolicy), FrameLoadTypeBackForward), FrameLoadTypeBackForward, 0, SubstituteData());
+
+    m_provisionalItem = item;
+    if (historyLoadType == HistorySameDocumentLoad) {
+        m_loadType = FrameLoadTypeBackForward;
+        loadInSameDocument(item->url(), item->stateObject(), DoNotUpdateBackForwardList, NotClientRedirect);
+        restoreScrollPositionAndViewState();
+        return;
+    }
+    loadWithNavigationAction(NavigationAction(requestFromHistoryItem(item, cachePolicy), FrameLoadTypeBackForward), FrameLoadTypeBackForward, nullptr, SubstituteData());
 }
 
 void FrameLoader::dispatchDocumentElementAvailable()
@@ -1431,7 +1452,7 @@
     InspectorInstrumentation::didClearWindowObjectInMainWorld(m_frame);
 
     Vector<RefPtr<DOMWrapperWorld> > worlds;
-    DOMWrapperWorld::getAllWorldsInMainThread(worlds);
+    DOMWrapperWorld::allWorldsInMainThread(worlds);
     for (size_t i = 0; i < worlds.size(); ++i)
         m_client->dispatchDidClearWindowObjectInWorld(worlds[i].get());
 }
@@ -1447,7 +1468,7 @@
 SandboxFlags FrameLoader::effectiveSandboxFlags() const
 {
     SandboxFlags flags = m_forcedSandboxFlags;
-    if (Frame* parentFrame = m_frame->tree().parent())
+    if (LocalFrame* parentFrame = m_frame->tree().parent())
         flags |= parentFrame->document()->sandboxFlags();
     if (HTMLFrameOwnerElement* ownerElement = m_frame->ownerElement())
         flags |= ownerElement->sandboxFlags();
diff --git a/Source/core/loader/FrameLoader.h b/Source/core/loader/FrameLoader.h
index 3454dec..5d0ffaa 100644
--- a/Source/core/loader/FrameLoader.h
+++ b/Source/core/loader/FrameLoader.h
@@ -74,12 +74,12 @@
 class FrameLoader {
     WTF_MAKE_NONCOPYABLE(FrameLoader);
 public:
-    FrameLoader(Frame*, FrameLoaderClient*);
+    FrameLoader(LocalFrame*, FrameLoaderClient*);
     ~FrameLoader();
 
     void init();
 
-    Frame* frame() const { return m_frame; }
+    LocalFrame* frame() const { return m_frame; }
 
     MixedContentChecker* mixedContentChecker() const { return &m_mixedContentChecker; }
 
@@ -88,11 +88,11 @@
     void reload(ReloadPolicy = NormalReload, const KURL& overrideURL = KURL(), const AtomicString& overrideEncoding = nullAtom);
     void loadHistoryItem(HistoryItem*, HistoryLoadType = HistoryDifferentDocumentLoad, ResourceRequestCachePolicy = UseProtocolCachePolicy); // The entry point for all back/forward loads
 
-    static void reportLocalLoadFailed(Frame*, const String& url);
+    static void reportLocalLoadFailed(LocalFrame*, const String& url);
 
     // FIXME: These are all functions which stop loads. We have too many.
-    // Warning: stopAllLoaders can and will detach the Frame out from under you. All callers need to either protect the Frame
-    // or guarantee they won't in any way access the Frame after stopAllLoaders returns.
+    // Warning: stopAllLoaders can and will detach the LocalFrame out from under you. All callers need to either protect the LocalFrame
+    // or guarantee they won't in any way access the LocalFrame after stopAllLoaders returns.
     void stopAllLoaders();
     void stopLoading();
     bool closeURL();
@@ -123,16 +123,11 @@
 
     bool isLoadingMainFrame() const;
 
-    bool subframeIsLoading() const;
-
-    bool shouldTreatURLAsSameAsCurrent(const KURL&) const;
     bool shouldTreatURLAsSrcdocDocument(const KURL&) const;
 
     FrameLoadType loadType() const;
     void setLoadType(FrameLoadType loadType) { m_loadType = loadType; }
 
-    void didFirstLayout();
-
     void checkLoadComplete(DocumentLoader*);
     void checkLoadComplete();
 
@@ -160,8 +155,8 @@
     void forceSandboxFlags(SandboxFlags flags) { m_forcedSandboxFlags |= flags; }
     SandboxFlags effectiveSandboxFlags() const;
 
-    Frame* opener();
-    void setOpener(Frame*);
+    LocalFrame* opener();
+    void setOpener(LocalFrame*);
 
     void frameDetached();
 
@@ -173,7 +168,7 @@
 
     FrameLoaderStateMachine* stateMachine() const { return &m_stateMachine; }
 
-    Frame* findFrameForNavigation(const AtomicString& name, Document* activeDocument);
+    LocalFrame* findFrameForNavigation(const AtomicString& name, Document* activeDocument);
 
     void applyUserAgent(ResourceRequest&);
 
@@ -190,14 +185,12 @@
     void updateForSameDocumentNavigation(const KURL&, SameDocumentNavigationSource, PassRefPtr<SerializedScriptValue>, UpdateBackForwardListPolicy);
 
     HistoryItem* currentItem() const { return m_currentItem.get(); }
-    void saveDocumentAndScrollState();
+    void markDocumentStateDirty();
+    void saveDocumentState();
+    void saveScrollState();
     void clearScrollPositionAndViewState();
 
-    enum RestorePolicy {
-        StandardRestore,
-        ForcedRestoreForSameDocumentHistoryNavigation
-    };
-    void restoreScrollPositionAndViewState(RestorePolicy = StandardRestore);
+    void restoreScrollPositionAndViewState();
 
 private:
     bool allChildrenAreComplete() const; // immediate children, not all descendants
@@ -217,7 +210,7 @@
     bool shouldPerformFragmentNavigation(bool isFormSubmission, const String& httpMethod, FrameLoadType, const KURL&);
     void scrollToFragmentWithParentBoundary(const KURL&);
 
-    void checkLoadCompleteForThisFrame();
+    bool checkLoadCompleteForThisFrame();
 
     // Calls continueLoadAfterNavigationPolicy
     void loadWithNavigationAction(const NavigationAction&, FrameLoadType, PassRefPtr<FormState>,
@@ -225,17 +218,17 @@
 
     void detachFromParent();
     void detachChildren();
-    void closeAndRemoveChild(Frame*);
+    void closeAndRemoveChild(LocalFrame*);
     void detachClient();
 
-    void setHistoryItemStateForCommit(HistoryCommitType, bool isPushOrReplaceState = false, PassRefPtr<SerializedScriptValue> = 0);
+    void setHistoryItemStateForCommit(HistoryCommitType, bool isPushOrReplaceState = false, PassRefPtr<SerializedScriptValue> = nullptr);
 
     void loadInSameDocument(const KURL&, PassRefPtr<SerializedScriptValue> stateObject, UpdateBackForwardListPolicy, ClientRedirectPolicy);
 
     void scheduleCheckCompleted();
     void startCheckCompleteTimer();
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
     FrameLoaderClient* m_client;
 
     // FIXME: These should be OwnPtr<T> to reduce build times and simplify
@@ -261,6 +254,23 @@
 
     RefPtr<HistoryItem> m_currentItem;
     RefPtr<HistoryItem> m_provisionalItem;
+    struct DeferredHistoryLoad {
+        DeferredHistoryLoad(HistoryItem* item, HistoryLoadType type, ResourceRequestCachePolicy cachePolicy)
+            : m_item(item)
+            , m_type(type)
+            , m_cachePolicy(cachePolicy)
+        {
+        }
+
+        DeferredHistoryLoad() { }
+
+        bool isValid() { return m_item; }
+
+        RefPtr<HistoryItem> m_item;
+        HistoryLoadType m_type;
+        ResourceRequestCachePolicy m_cachePolicy;
+    };
+    DeferredHistoryLoad m_deferredHistoryLoad;
 
     bool m_inStopAllLoaders;
 
@@ -270,9 +280,6 @@
     Timer<FrameLoader> m_checkTimer;
     bool m_shouldCallCheckCompleted;
 
-    Frame* m_opener;
-    HashSet<Frame*> m_openedFrames;
-
     bool m_didAccessInitialDocument;
     Timer<FrameLoader> m_didAccessInitialDocumentTimer;
 
diff --git a/Source/core/loader/FrameLoaderClient.h b/Source/core/loader/FrameLoaderClient.h
index ac8c5ca..52ea3e7 100644
--- a/Source/core/loader/FrameLoaderClient.h
+++ b/Source/core/loader/FrameLoaderClient.h
@@ -31,6 +31,7 @@
 #define FrameLoaderClient_h
 
 #include "core/dom/IconURL.h"
+#include "core/frame/FrameClient.h"
 #include "core/loader/FrameLoaderTypes.h"
 #include "core/loader/NavigationPolicy.h"
 #include "platform/network/ResourceLoadPriority.h"
@@ -50,6 +51,8 @@
 class WebRTCPeerConnectionHandler;
 class WebServiceWorkerProvider;
 class WebServiceWorkerProviderClient;
+class WebApplicationCacheHost;
+class WebApplicationCacheHostClient;
 }
 
 namespace WebCore {
@@ -59,18 +62,17 @@
     class DOMWrapperWorld;
     class DocumentLoader;
     class Element;
-class FetchRequest;
-    class FormState;
-    class Frame;
+    class FetchRequest;
     class FrameLoader;
     class FrameNetworkingContext;
-    class HistoryItem;
     class HTMLAppletElement;
     class HTMLFormElement;
     class HTMLFrameOwnerElement;
     class HTMLPlugInElement;
+    class HistoryItem;
     class IntSize;
     class KURL;
+    class LocalFrame;
     class MessageEvent;
     class Page;
     class PluginView;
@@ -85,18 +87,12 @@
     class SubstituteData;
     class Widget;
 
-    class FrameLoaderClient {
+    class FrameLoaderClient : public FrameClient {
     public:
         virtual ~FrameLoaderClient() { }
 
         virtual bool hasWebView() const = 0; // mainly for assertions
 
-        virtual Frame* parent() const = 0;
-        virtual Frame* top() const = 0;
-        virtual Frame* previousSibling() const = 0;
-        virtual Frame* nextSibling() const = 0;
-        virtual Frame* firstChild() const = 0;
-        virtual Frame* lastChild() const = 0;
         virtual void detachedFromParent() = 0;
 
         virtual void dispatchWillRequestAfterPreconnect(ResourceRequest&) { }
@@ -112,7 +108,7 @@
         virtual void dispatchDidStartProvisionalLoad() = 0;
         virtual void dispatchDidReceiveTitle(const String&) = 0;
         virtual void dispatchDidChangeIcons(IconType) = 0;
-        virtual void dispatchDidCommitLoad(Frame*, HistoryItem*, HistoryCommitType) = 0;
+        virtual void dispatchDidCommitLoad(LocalFrame*, HistoryItem*, HistoryCommitType) = 0;
         virtual void dispatchDidFailProvisionalLoad(const ResourceError&) = 0;
         virtual void dispatchDidFailLoad(const ResourceError&) = 0;
         virtual void dispatchDidFinishDocumentLoad() = 0;
@@ -123,8 +119,8 @@
 
         virtual void dispatchWillRequestResource(FetchRequest*) { }
 
-        virtual void dispatchWillSendSubmitEvent(PassRefPtr<FormState>) = 0;
-        virtual void dispatchWillSubmitForm(PassRefPtr<FormState>) = 0;
+        virtual void dispatchWillSendSubmitEvent(HTMLFormElement*) = 0;
+        virtual void dispatchWillSubmitForm(HTMLFormElement*) = 0;
 
         // Maybe these should go into a ProgressTrackerClient some day
         virtual void postProgressStartedNotification(LoadStartType) = 0;
@@ -140,11 +136,6 @@
         // is now possible.
         virtual void didAccessInitialDocument() { }
 
-        // This frame has set its opener to null, disowning it for the lifetime of the frame.
-        // See http://html.spec.whatwg.org/#dom-opener.
-        // FIXME: JSC should allow disowning opener. - <https://bugs.webkit.org/show_bug.cgi?id=103913>.
-        virtual void didDisownOpener() { }
-
         // This frame has displayed inactive content (such as an image) from an
         // insecure source.  Inactive content cannot spread to other frames.
         virtual void didDisplayInsecureContent() = 0;
@@ -160,7 +151,7 @@
         // that match any element on the frame.
         virtual void selectorMatchChanged(const Vector<String>& addedSelectors, const Vector<String>& removedSelectors) = 0;
 
-        virtual PassRefPtr<DocumentLoader> createDocumentLoader(Frame*, const ResourceRequest&, const SubstituteData&) = 0;
+        virtual PassRefPtr<DocumentLoader> createDocumentLoader(LocalFrame*, const ResourceRequest&, const SubstituteData&) = 0;
 
         virtual String userAgent(const KURL&) = 0;
 
@@ -168,23 +159,27 @@
 
         virtual void transitionToCommittedForNewPage() = 0;
 
-        virtual PassRefPtr<Frame> createFrame(const KURL&, const AtomicString& name, const Referrer&, HTMLFrameOwnerElement*) = 0;
-        virtual PassRefPtr<Widget> createPlugin(const IntSize&, HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually) = 0;
+        virtual PassRefPtr<LocalFrame> createFrame(const KURL&, const AtomicString& name, const Referrer&, HTMLFrameOwnerElement*) = 0;
+        // Whether or not plugin creation should fail if the HTMLPlugInElement isn't in the DOM after plugin initialization.
+        enum DetachedPluginPolicy {
+            FailOnDetachedPlugin,
+            AllowDetachedPlugin,
+        };
+        virtual PassRefPtr<Widget> createPlugin(HTMLPlugInElement*, const KURL&, const Vector<String>&, const Vector<String>&, const String&, bool loadManually, DetachedPluginPolicy) = 0;
 
-        virtual PassRefPtr<Widget> createJavaAppletWidget(const IntSize&, HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) = 0;
+        virtual PassRefPtr<Widget> createJavaAppletWidget(HTMLAppletElement*, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues) = 0;
 
         virtual ObjectContentType objectContentType(const KURL&, const String& mimeType, bool shouldPreferPlugInsForImages) = 0;
 
         virtual void dispatchDidClearWindowObjectInWorld(DOMWrapperWorld*) = 0;
         virtual void documentElementAvailable() = 0;
 
-        virtual void didExhaustMemoryAvailableForScript() { };
-
         virtual void didCreateScriptContext(v8::Handle<v8::Context>, int extensionGroup, int worldId) = 0;
         virtual void willReleaseScriptContext(v8::Handle<v8::Context>, int worldId) = 0;
         virtual bool allowScriptExtension(const String& extensionName, int extensionGroup, int worldId) = 0;
 
         virtual void didChangeScrollOffset() { }
+        virtual void didUpdateCurrentHistoryItem() { }
 
         virtual bool allowScript(bool enabledPerSettings) { return enabledPerSettings; }
         virtual bool allowScriptFromSource(bool enabledPerSettings, const KURL&) { return enabledPerSettings; }
@@ -213,7 +208,7 @@
 
         virtual void dispatchWillStartUsingPeerConnectionHandler(blink::WebRTCPeerConnectionHandler*) { }
 
-        virtual void didRequestAutocomplete(PassRefPtr<FormState>) = 0;
+        virtual void didRequestAutocomplete(HTMLFormElement*) = 0;
 
         virtual bool allowWebGL(bool enabledPerSettings) { return enabledPerSettings; }
         // Informs the embedder that a WebGL canvas inside this frame received a lost context
@@ -225,10 +220,12 @@
 
         virtual void dispatchDidChangeResourcePriority(unsigned long /*identifier*/, ResourceLoadPriority) { }
 
-        virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider(PassOwnPtr<blink::WebServiceWorkerProviderClient>) = 0;
+        virtual PassOwnPtr<blink::WebServiceWorkerProvider> createServiceWorkerProvider() = 0;
 
         virtual SharedWorkerRepositoryClient* sharedWorkerRepositoryClient() { return 0; }
 
+        virtual PassOwnPtr<blink::WebApplicationCacheHost> createApplicationCacheHost(blink::WebApplicationCacheHostClient*) = 0;
+
         virtual void didStopAllLoaders() { }
 
         virtual bool isFrameLoaderClientImpl() const { return false; }
diff --git a/Source/core/loader/HistoryItem.cpp b/Source/core/loader/HistoryItem.cpp
index e9600e9..514ee1a 100644
--- a/Source/core/loader/HistoryItem.cpp
+++ b/Source/core/loader/HistoryItem.cpp
@@ -45,7 +45,6 @@
     : m_pageScaleFactor(0)
     , m_itemSequenceNumber(generateSequenceNumber())
     , m_documentSequenceNumber(generateSequenceNumber())
-    , m_targetFrameID(0)
 {
 }
 
@@ -56,7 +55,6 @@
 inline HistoryItem::HistoryItem(const HistoryItem& item)
     : RefCounted<HistoryItem>()
     , m_urlString(item.m_urlString)
-    , m_originalURLString(item.m_originalURLString)
     , m_referrer(item.m_referrer)
     , m_target(item.m_target)
     , m_scrollPoint(item.m_scrollPoint)
@@ -64,7 +62,6 @@
     , m_documentState(item.m_documentState)
     , m_itemSequenceNumber(item.m_itemSequenceNumber)
     , m_documentSequenceNumber(item.m_documentSequenceNumber)
-    , m_targetFrameID(item.m_targetFrameID)
     , m_stateObject(item.m_stateObject)
     , m_formContentType(item.m_formContentType)
 {
@@ -93,23 +90,11 @@
     return m_urlString;
 }
 
-// The first URL we loaded to get to where this history item points. Includes both client
-// and server redirects.
-const String& HistoryItem::originalURLString() const
-{
-    return m_originalURLString;
-}
-
 KURL HistoryItem::url() const
 {
     return KURL(ParsedURLString, m_urlString);
 }
 
-KURL HistoryItem::originalURL() const
-{
-    return KURL(ParsedURLString, m_originalURLString);
-}
-
 const Referrer& HistoryItem::referrer() const
 {
     return m_referrer;
@@ -132,11 +117,6 @@
     clearDocumentState();
 }
 
-void HistoryItem::setOriginalURLString(const String& urlString)
-{
-    m_originalURLString = urlString;
-}
-
 void HistoryItem::setReferrer(const Referrer& referrer)
 {
     m_referrer = referrer;
@@ -221,7 +201,7 @@
         m_formData = request.httpBody();
         m_formContentType = request.httpContentType();
     } else {
-        m_formData = 0;
+        m_formData = nullptr;
         m_formContentType = nullAtom;
     }
 }
diff --git a/Source/core/loader/HistoryItem.h b/Source/core/loader/HistoryItem.h
index 8a5677c..d02c164 100644
--- a/Source/core/loader/HistoryItem.h
+++ b/Source/core/loader/HistoryItem.h
@@ -56,10 +56,8 @@
     // url but a new item wasn't created.
     void generateNewSequenceNumbers();
 
-    const String& originalURLString() const;
     const String& urlString() const;
     KURL url() const;
-    KURL originalURL() const;
 
     const Referrer& referrer() const;
     const String& target() const;
@@ -80,7 +78,6 @@
 
     void setURL(const KURL&);
     void setURLString(const String&);
-    void setOriginalURLString(const String&);
     void setReferrer(const Referrer&);
     void setTarget(const String&);
 
@@ -93,9 +90,6 @@
     void setDocumentSequenceNumber(long long number) { m_documentSequenceNumber = number; }
     long long documentSequenceNumber() const { return m_documentSequenceNumber; }
 
-    void setTargetFrameID(int64_t id) { m_targetFrameID = id; }
-    int64_t targetFrameID() const { return m_targetFrameID; }
-
     void setFormInfoFromRequest(const ResourceRequest&);
     void setFormData(PassRefPtr<FormData>);
     void setFormContentType(const AtomicString&);
@@ -111,7 +105,6 @@
     explicit HistoryItem(const HistoryItem&);
 
     String m_urlString;
-    String m_originalURLString;
     Referrer m_referrer;
     String m_target;
 
@@ -132,8 +125,6 @@
     // such HistoryItem to another preserves the document.
     int64_t m_documentSequenceNumber;
 
-    int64_t m_targetFrameID;
-
     // Support for HTML5 History
     RefPtr<SerializedScriptValue> m_stateObject;
 
diff --git a/Source/core/loader/ImageLoader.cpp b/Source/core/loader/ImageLoader.cpp
index 1d99b40..ff02d1e 100644
--- a/Source/core/loader/ImageLoader.cpp
+++ b/Source/core/loader/ImageLoader.cpp
@@ -22,7 +22,6 @@
 #include "config.h"
 #include "core/loader/ImageLoader.h"
 
-#include "HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/events/Event.h"
@@ -338,7 +337,7 @@
             m_element->ref();
     } else {
         ASSERT(!m_derefElementTimer.isActive());
-        m_derefElementTimer.startOneShot(0);
+        m_derefElementTimer.startOneShot(0, FROM_HERE);
     }
 }
 
@@ -380,8 +379,8 @@
     loadEventSender().cancelEvent(this);
     m_hasPendingLoadEvent = false;
 
-    if (m_element->hasTagName(HTMLNames::objectTag))
-        toHTMLObjectElement(m_element)->renderFallbackContent();
+    if (isHTMLObjectElement(*m_element))
+        toHTMLObjectElement(*m_element).renderFallbackContent();
 
     // Only consider updating the protection ref-count of the Element immediately before returning
     // from this function as doing so might result in the destruction of this ImageLoader.
@@ -458,8 +457,8 @@
 
 void ImageLoader::sourceImageChanged()
 {
-    HashSet<ImageLoaderClient*>::iterator end = m_clients.end();
-    for (HashSet<ImageLoaderClient*>::iterator it = m_clients.begin(); it != end; ++it) {
+    ImageLoaderClientSet::iterator end = m_clients.end();
+    for (ImageLoaderClientSet::iterator it = m_clients.begin(); it != end; ++it) {
         ImageLoaderClient* handle = *it;
         handle->notifyImageSourceChanged();
     }
diff --git a/Source/core/loader/ImageLoader.h b/Source/core/loader/ImageLoader.h
index ad0deb6..aa9de30 100644
--- a/Source/core/loader/ImageLoader.h
+++ b/Source/core/loader/ImageLoader.h
@@ -26,18 +26,21 @@
 #include "core/fetch/ImageResource.h"
 #include "core/fetch/ImageResourceClient.h"
 #include "core/fetch/ResourcePtr.h"
+#include "heap/Handle.h"
 #include "wtf/HashSet.h"
 #include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
-class ImageLoaderClient {
+class ImageLoaderClient : public WillBeGarbageCollectedMixin {
 public:
     virtual void notifyImageSourceChanged() = 0;
 
     // Determines whether the observed ImageResource should have higher priority in the decoded resources cache.
     virtual bool requestsHighLiveResourceCachePriority() { return false; }
 
+    virtual void trace(Visitor*) = 0;
+
 protected:
     ImageLoaderClient() { }
 };
@@ -106,9 +109,11 @@
 
     void timerFired(Timer<ImageLoader>*);
 
+    typedef WillBePersistentHeapHashSet<RawPtrWillBeWeakMember<ImageLoaderClient> > ImageLoaderClientSet;
+
     Element* m_element;
     ResourcePtr<ImageResource> m_image;
-    HashSet<ImageLoaderClient*> m_clients;
+    ImageLoaderClientSet m_clients;
     Timer<ImageLoader> m_derefElementTimer;
     AtomicString m_failedLoadURL;
     bool m_hasPendingBeforeLoadEvent : 1;
diff --git a/Source/core/loader/LinkLoader.cpp b/Source/core/loader/LinkLoader.cpp
index adbc51e..ab8542f 100644
--- a/Source/core/loader/LinkLoader.cpp
+++ b/Source/core/loader/LinkLoader.cpp
@@ -83,9 +83,9 @@
     ASSERT(this->resource() == resource);
 
     if (resource->errorOccurred())
-        m_linkLoadingErrorTimer.startOneShot(0);
+        m_linkLoadingErrorTimer.startOneShot(0, FROM_HERE);
     else
-        m_linkLoadTimer.startOneShot(0);
+        m_linkLoadTimer.startOneShot(0, FROM_HERE);
 
     clearResource();
 }
diff --git a/Source/core/loader/MixedContentChecker.cpp b/Source/core/loader/MixedContentChecker.cpp
index 750f130..874f22b 100644
--- a/Source/core/loader/MixedContentChecker.cpp
+++ b/Source/core/loader/MixedContentChecker.cpp
@@ -30,15 +30,15 @@
 #include "core/loader/MixedContentChecker.h"
 
 #include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
-#include "core/frame/Frame.h"
-#include "core/frame/Settings.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace WebCore {
 
-MixedContentChecker::MixedContentChecker(Frame* frame)
+MixedContentChecker::MixedContentChecker(LocalFrame* frame)
     : m_frame(frame)
 {
 }
diff --git a/Source/core/loader/MixedContentChecker.h b/Source/core/loader/MixedContentChecker.h
index f4d6647..9f9f41c 100644
--- a/Source/core/loader/MixedContentChecker.h
+++ b/Source/core/loader/MixedContentChecker.h
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class FrameLoaderClient;
 class KURL;
 class SecurityOrigin;
@@ -43,7 +43,7 @@
 class MixedContentChecker {
     WTF_MAKE_NONCOPYABLE(MixedContentChecker);
 public:
-    MixedContentChecker(Frame*);
+    MixedContentChecker(LocalFrame*);
 
     bool canDisplayInsecureContent(SecurityOrigin*, const KURL&) const;
     bool canRunInsecureContent(SecurityOrigin*, const KURL&) const;
@@ -55,7 +55,7 @@
 
     void logWarning(bool allowed, const String& action, const KURL&) const;
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
 };
 
 } // namespace WebCore
diff --git a/Source/core/loader/NavigationAction.h b/Source/core/loader/NavigationAction.h
index e50716b..966aa7b 100644
--- a/Source/core/loader/NavigationAction.h
+++ b/Source/core/loader/NavigationAction.h
@@ -41,7 +41,7 @@
     class NavigationAction {
     public:
         NavigationAction();
-        NavigationAction(const ResourceRequest&, FrameLoadType = FrameLoadTypeStandard, bool isFormSubmission = false, PassRefPtr<Event> = 0);
+        NavigationAction(const ResourceRequest&, FrameLoadType = FrameLoadTypeStandard, bool isFormSubmission = false, PassRefPtr<Event> = nullptr);
 
         const ResourceRequest& resourceRequest() const { return m_resourceRequest; }
         NavigationType type() const { return m_type; }
diff --git a/Source/core/loader/NavigationScheduler.cpp b/Source/core/loader/NavigationScheduler.cpp
index 295cdfc..9dda7c0 100644
--- a/Source/core/loader/NavigationScheduler.cpp
+++ b/Source/core/loader/NavigationScheduler.cpp
@@ -34,6 +34,7 @@
 
 #include "bindings/v8/ScriptController.h"
 #include "core/events/Event.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/DocumentLoader.h"
@@ -43,7 +44,6 @@
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
 #include "core/loader/FrameLoaderStateMachine.h"
-#include "core/frame/Frame.h"
 #include "core/page/BackForwardClient.h"
 #include "core/page/Page.h"
 #include "platform/UserGestureIndicator.h"
@@ -67,9 +67,9 @@
     }
     virtual ~ScheduledNavigation() { }
 
-    virtual void fire(Frame*) = 0;
+    virtual void fire(LocalFrame*) = 0;
 
-    virtual bool shouldStartTimer(Frame*) { return true; }
+    virtual bool shouldStartTimer(LocalFrame*) { return true; }
 
     double delay() const { return m_delay; }
     bool lockBackForwardList() const { return m_lockBackForwardList; }
@@ -104,7 +104,7 @@
     {
     }
 
-    virtual void fire(Frame* frame) OVERRIDE
+    virtual void fire(LocalFrame* frame) OVERRIDE
     {
         OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
         FrameLoadRequest request(m_originDocument.get(), ResourceRequest(KURL(ParsedURLString, m_url), m_referrer), "_self");
@@ -131,9 +131,9 @@
         clearUserGesture();
     }
 
-    virtual bool shouldStartTimer(Frame* frame) OVERRIDE { return frame->loader().allAncestorsAreComplete(); }
+    virtual bool shouldStartTimer(LocalFrame* frame) OVERRIDE { return frame->loader().allAncestorsAreComplete(); }
 
-    virtual void fire(Frame* frame) OVERRIDE
+    virtual void fire(LocalFrame* frame) OVERRIDE
     {
         OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
         FrameLoadRequest request(originDocument(), ResourceRequest(KURL(ParsedURLString, url()), referrer()), "_self");
@@ -158,7 +158,7 @@
     {
     }
 
-    virtual void fire(Frame* frame) OVERRIDE
+    virtual void fire(LocalFrame* frame) OVERRIDE
     {
         OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
         FrameLoadRequest request(originDocument(), ResourceRequest(KURL(ParsedURLString, url()), referrer(), ReloadIgnoringCacheData), "_self");
@@ -176,7 +176,7 @@
     {
     }
 
-    virtual void fire(Frame* frame) OVERRIDE
+    virtual void fire(LocalFrame* frame) OVERRIDE
     {
         OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
 
@@ -206,7 +206,7 @@
         ASSERT(m_submission->state());
     }
 
-    virtual void fire(Frame* frame) OVERRIDE
+    virtual void fire(LocalFrame* frame) OVERRIDE
     {
         OwnPtr<UserGestureIndicator> gestureIndicator = createUserGestureIndicator();
         FrameLoadRequest frameRequest(m_submission->state()->sourceDocument());
@@ -224,7 +224,7 @@
     RefPtr<FormSubmission> m_submission;
 };
 
-NavigationScheduler::NavigationScheduler(Frame* frame)
+NavigationScheduler::NavigationScheduler(LocalFrame* frame)
     : m_frame(frame)
     , m_timer(this, &NavigationScheduler::timerFired)
 {
@@ -271,7 +271,7 @@
         schedule(adoptPtr(new ScheduledRedirect(delay, m_frame->document(), url, delay <= 1)));
 }
 
-bool NavigationScheduler::mustLockBackForwardList(Frame* targetFrame)
+bool NavigationScheduler::mustLockBackForwardList(LocalFrame* targetFrame)
 {
     // Non-user navigation before the page has finished firing onload should not create a new back/forward item.
     // See https://webkit.org/b/42861 for the original motivation for this.
@@ -363,7 +363,7 @@
         return;
     }
 
-    RefPtr<Frame> protect(m_frame);
+    RefPtr<LocalFrame> protect(m_frame);
 
     OwnPtr<ScheduledNavigation> redirect(m_redirect.release());
     redirect->fire(m_frame);
@@ -389,7 +389,7 @@
     if (!m_redirect->shouldStartTimer(m_frame))
         return;
 
-    m_timer.startOneShot(m_redirect->delay());
+    m_timer.startOneShot(m_redirect->delay(), FROM_HERE);
     InspectorInstrumentation::frameScheduledNavigation(m_frame, m_redirect->delay());
 }
 
diff --git a/Source/core/loader/NavigationScheduler.h b/Source/core/loader/NavigationScheduler.h
index 5d5fb01..18745a8 100644
--- a/Source/core/loader/NavigationScheduler.h
+++ b/Source/core/loader/NavigationScheduler.h
@@ -45,7 +45,7 @@
 
 class Document;
 class FormSubmission;
-class Frame;
+class LocalFrame;
 class ScheduledNavigation;
 
 class NavigationDisablerForBeforeUnload {
@@ -71,7 +71,7 @@
     WTF_MAKE_NONCOPYABLE(NavigationScheduler);
 
 public:
-    explicit NavigationScheduler(Frame*);
+    explicit NavigationScheduler(LocalFrame*);
     ~NavigationScheduler();
 
     bool locationChangePending();
@@ -94,9 +94,9 @@
     void timerFired(Timer<NavigationScheduler>*);
     void schedule(PassOwnPtr<ScheduledNavigation>);
 
-    static bool mustLockBackForwardList(Frame* targetFrame);
+    static bool mustLockBackForwardList(LocalFrame* targetFrame);
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
     Timer<NavigationScheduler> m_timer;
     OwnPtr<ScheduledNavigation> m_redirect;
 };
diff --git a/Source/core/loader/PingLoader.cpp b/Source/core/loader/PingLoader.cpp
index c629979..3a078b3 100644
--- a/Source/core/loader/PingLoader.cpp
+++ b/Source/core/loader/PingLoader.cpp
@@ -35,7 +35,7 @@
 #include "FetchInitiatorTypeNames.h"
 #include "core/dom/Document.h"
 #include "core/fetch/FetchContext.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
@@ -55,7 +55,7 @@
 
 namespace WebCore {
 
-void PingLoader::loadImage(Frame* frame, const KURL& url)
+void PingLoader::loadImage(LocalFrame* frame, const KURL& url)
 {
     if (!frame->document()->securityOrigin()->canDisplay(url)) {
         FrameLoader::reportLocalLoadFailed(frame, url.string());
@@ -73,7 +73,7 @@
 }
 
 // http://www.whatwg.org/specs/web-apps/current-work/multipage/links.html#hyperlink-auditing
-void PingLoader::sendPing(Frame* frame, const KURL& pingURL, const KURL& destinationURL)
+void PingLoader::sendPing(LocalFrame* frame, const KURL& pingURL, const KURL& destinationURL)
 {
     ResourceRequest request(pingURL);
     request.setTargetType(ResourceRequest::TargetIsPing);
@@ -101,7 +101,7 @@
     PingLoader::start(frame, request, initiatorInfo);
 }
 
-void PingLoader::sendViolationReport(Frame* frame, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType type)
+void PingLoader::sendViolationReport(LocalFrame* frame, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType type)
 {
     ResourceRequest request(reportURL);
     request.setTargetType(ResourceRequest::TargetIsSubresource);
@@ -115,7 +115,7 @@
     PingLoader::start(frame, request, initiatorInfo, SecurityOrigin::create(reportURL)->isSameSchemeHostPort(frame->document()->securityOrigin()) ? AllowStoredCredentials : DoNotAllowStoredCredentials);
 }
 
-void PingLoader::start(Frame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed)
+void PingLoader::start(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed)
 {
     OwnPtr<PingLoader> pingLoader = adoptPtr(new PingLoader(frame, request, initiatorInfo, credentialsAllowed));
 
@@ -123,7 +123,7 @@
     PingLoader* ALLOW_UNUSED leakedPingLoader = pingLoader.leakPtr();
 }
 
-PingLoader::PingLoader(Frame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed)
+PingLoader::PingLoader(LocalFrame* frame, ResourceRequest& request, const FetchInitiatorInfo& initiatorInfo, StoredCredentials credentialsAllowed)
     : PageLifecycleObserver(frame->page())
     , m_timeout(this, &PingLoader::timeout)
     , m_url(request.url())
@@ -141,7 +141,7 @@
 
     // If the server never responds, FrameLoader won't be able to cancel this load and
     // we'll sit here waiting forever. Set a very generous timeout, just in case.
-    m_timeout.startOneShot(60000);
+    m_timeout.startOneShot(60000, FROM_HERE);
 }
 
 PingLoader::~PingLoader()
diff --git a/Source/core/loader/PingLoader.h b/Source/core/loader/PingLoader.h
index 5651aa2..168a0c1 100644
--- a/Source/core/loader/PingLoader.h
+++ b/Source/core/loader/PingLoader.h
@@ -42,14 +42,14 @@
 namespace WebCore {
 
 class FormData;
-class Frame;
+class LocalFrame;
 class KURL;
 class ResourceError;
 class ResourceHandle;
 class ResourceRequest;
 class ResourceResponse;
 
-// This class triggers asynchronous loads independent of Frame staying alive (i.e., auditing pingbacks).
+// This class triggers asynchronous loads independent of LocalFrame staying alive (i.e., auditing pingbacks).
 // Since nothing depends on resources loaded through this class, we just want
 // to allow the load to live long enough to ensure the message was actually sent.
 // Therefore, as soon as a callback is received from the ResourceHandle, this class
@@ -62,16 +62,16 @@
         XSSAuditorViolationReport
     };
 
-    static void loadImage(Frame*, const KURL& url);
-    static void sendPing(Frame*, const KURL& pingURL, const KURL& destinationURL);
-    static void sendViolationReport(Frame*, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType);
+    static void loadImage(LocalFrame*, const KURL& url);
+    static void sendPing(LocalFrame*, const KURL& pingURL, const KURL& destinationURL);
+    static void sendViolationReport(LocalFrame*, const KURL& reportURL, PassRefPtr<FormData> report, ViolationReportType);
 
     virtual ~PingLoader();
 
 private:
-    PingLoader(Frame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials);
+    PingLoader(LocalFrame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials);
 
-    static void start(Frame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials = AllowStoredCredentials);
+    static void start(LocalFrame*, ResourceRequest&, const FetchInitiatorInfo&, StoredCredentials = AllowStoredCredentials);
 
     virtual void didReceiveResponse(blink::WebURLLoader*, const blink::WebURLResponse&) OVERRIDE;
     virtual void didReceiveData(blink::WebURLLoader*, const char*, int, int) OVERRIDE;
diff --git a/Source/core/loader/PrerenderHandle.cpp b/Source/core/loader/PrerenderHandle.cpp
index e822ff5..2181670 100644
--- a/Source/core/loader/PrerenderHandle.cpp
+++ b/Source/core/loader/PrerenderHandle.cpp
@@ -32,7 +32,7 @@
 #include "core/loader/PrerenderHandle.h"
 
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/PrerendererClient.h"
 #include "platform/Prerender.h"
diff --git a/Source/core/loader/PrerendererClient.cpp b/Source/core/loader/PrerendererClient.cpp
index 3db4826..3ce4a2c 100644
--- a/Source/core/loader/PrerendererClient.cpp
+++ b/Source/core/loader/PrerendererClient.cpp
@@ -49,7 +49,7 @@
     return supplement;
 }
 
-void providePrerendererClientTo(Page* page, PrerendererClient* client)
+void providePrerendererClientTo(Page& page, PrerendererClient* client)
 {
     PrerendererClient::provideTo(page, PrerendererClient::supplementName(), adoptPtr(client));
 }
diff --git a/Source/core/loader/PrerendererClient.h b/Source/core/loader/PrerendererClient.h
index 4c6a195..bf82b72 100644
--- a/Source/core/loader/PrerendererClient.h
+++ b/Source/core/loader/PrerendererClient.h
@@ -53,7 +53,7 @@
     PrerendererClient() { }
 };
 
-void providePrerendererClientTo(Page*, PrerendererClient*);
+void providePrerendererClientTo(Page&, PrerendererClient*);
 
 } // namespace WebCore
 
diff --git a/Source/core/loader/ProgressTracker.cpp b/Source/core/loader/ProgressTracker.cpp
index b96844a..be2b29a 100644
--- a/Source/core/loader/ProgressTracker.cpp
+++ b/Source/core/loader/ProgressTracker.cpp
@@ -26,8 +26,8 @@
 #include "config.h"
 #include "core/loader/ProgressTracker.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/FrameLoaderClient.h"
@@ -99,10 +99,10 @@
     m_lastNotifiedProgressTime = 0;
     m_finalProgressChangedSent = false;
     m_numProgressTrackedFrames = 0;
-    m_originatingProgressFrame = 0;
+    m_originatingProgressFrame = nullptr;
 }
 
-void ProgressTracker::progressStarted(Frame* frame)
+void ProgressTracker::progressStarted(LocalFrame* frame)
 {
     WTF_LOG(Progress, "Progress started (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree().uniqueName().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
 
@@ -117,7 +117,7 @@
     InspectorInstrumentation::frameStartedLoading(frame);
 }
 
-void ProgressTracker::progressCompleted(Frame* frame)
+void ProgressTracker::progressCompleted(LocalFrame* frame)
 {
     WTF_LOG(Progress, "Progress completed (%p) - frame %p(\"%s\"), value %f, tracked frames %d, originating frame %p", this, frame, frame->tree().uniqueName().utf8().data(), m_progressValue, m_numProgressTrackedFrames, m_originatingProgressFrame.get());
 
@@ -132,7 +132,7 @@
 {
     WTF_LOG(Progress, "Final progress complete (%p)", this);
 
-    RefPtr<Frame> frame = m_originatingProgressFrame.release();
+    RefPtr<LocalFrame> frame = m_originatingProgressFrame.release();
 
     // Before resetting progress value be sure to send client a least one notification
     // with final progress value.
@@ -174,7 +174,7 @@
     if (!item)
         return;
 
-    RefPtr<Frame> frame = m_originatingProgressFrame;
+    RefPtr<LocalFrame> frame = m_originatingProgressFrame;
 
     unsigned bytesReceived = length;
     double increment, percentOfRemainingBytes;
diff --git a/Source/core/loader/ProgressTracker.h b/Source/core/loader/ProgressTracker.h
index c6d73af..60ca22c 100644
--- a/Source/core/loader/ProgressTracker.h
+++ b/Source/core/loader/ProgressTracker.h
@@ -35,7 +35,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class ResourceResponse;
 struct ProgressItem;
 
@@ -52,8 +52,8 @@
 
     double estimatedProgress() const;
 
-    void progressStarted(Frame*);
-    void progressCompleted(Frame*);
+    void progressStarted(LocalFrame*);
+    void progressCompleted(LocalFrame*);
 
     void incrementProgress(unsigned long identifier, const ResourceResponse&);
     void incrementProgress(unsigned long identifier, const char*, int);
@@ -76,7 +76,7 @@
     double m_progressNotificationTimeInterval;
     bool m_finalProgressChangedSent;
     double m_progressValue;
-    RefPtr<Frame> m_originatingProgressFrame;
+    RefPtr<LocalFrame> m_originatingProgressFrame;
 
     int m_numProgressTrackedFrames;
     HashMap<unsigned long, OwnPtr<ProgressItem> > m_progressItems;
diff --git a/Source/core/loader/TextResourceDecoderBuilder.cpp b/Source/core/loader/TextResourceDecoderBuilder.cpp
index ff4002a..8330114 100644
--- a/Source/core/loader/TextResourceDecoderBuilder.cpp
+++ b/Source/core/loader/TextResourceDecoderBuilder.cpp
@@ -32,13 +32,13 @@
 #include "core/loader/TextResourceDecoderBuilder.h"
 
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace WebCore {
 
-static inline bool canReferToParentFrameEncoding(const Frame* frame, const Frame* parentFrame)
+static inline bool canReferToParentFrameEncoding(const LocalFrame* frame, const LocalFrame* parentFrame)
 {
     return parentFrame && parentFrame->document()->securityOrigin()->canAccess(frame->document()->securityOrigin());
 }
@@ -58,7 +58,7 @@
 
 inline PassOwnPtr<TextResourceDecoder> TextResourceDecoderBuilder::createDecoderInstance(Document* document)
 {
-    if (Frame* frame = document->frame()) {
+    if (LocalFrame* frame = document->frame()) {
         if (Settings* settings = frame->settings())
             return TextResourceDecoder::create(m_mimeType, settings->defaultTextEncodingName(), settings->usesEncodingDetector());
     }
@@ -68,8 +68,8 @@
 
 inline void TextResourceDecoderBuilder::setupEncoding(TextResourceDecoder* decoder, Document* document)
 {
-    Frame* frame = document->frame();
-    Frame* parentFrame = frame ? frame->tree().parent() : 0;
+    LocalFrame* frame = document->frame();
+    LocalFrame* parentFrame = frame ? frame->tree().parent() : 0;
 
     if (!m_encoding.isEmpty())
         decoder->setEncoding(m_encoding.string(), m_encodingWasChosenByUser ? TextResourceDecoder::UserChosenEncoding : TextResourceDecoder::EncodingFromHTTPHeader);
diff --git a/Source/core/loader/TextTrackLoader.cpp b/Source/core/loader/TextTrackLoader.cpp
index a6691c2..a5eb3ba 100644
--- a/Source/core/loader/TextTrackLoader.cpp
+++ b/Source/core/loader/TextTrackLoader.cpp
@@ -99,7 +99,7 @@
         m_cueParser->flush();
 
     if (!m_cueLoadTimer.isActive())
-        m_cueLoadTimer.startOneShot(0);
+        m_cueLoadTimer.startOneShot(0, FROM_HERE);
 
     cancelLoad();
 }
@@ -129,7 +129,7 @@
         return;
 
     m_newCuesAvailable = true;
-    m_cueLoadTimer.startOneShot(0);
+    m_cueLoadTimer.startOneShot(0, FROM_HERE);
 }
 
 void TextTrackLoader::newRegionsParsed()
@@ -144,7 +144,7 @@
     m_state = Failed;
 
     if (!m_cueLoadTimer.isActive())
-        m_cueLoadTimer.startOneShot(0);
+        m_cueLoadTimer.startOneShot(0, FROM_HERE);
 
     cancelLoad();
 }
diff --git a/Source/core/loader/ThreadableLoaderClient.h b/Source/core/loader/ThreadableLoaderClient.h
index 0604120..2aefffa 100644
--- a/Source/core/loader/ThreadableLoaderClient.h
+++ b/Source/core/loader/ThreadableLoaderClient.h
@@ -31,6 +31,7 @@
 #ifndef ThreadableLoaderClient_h
 #define ThreadableLoaderClient_h
 
+#include "heap/Handle.h"
 #include "wtf/FastAllocBase.h"
 #include "wtf/Noncopyable.h"
 
@@ -40,7 +41,8 @@
     class ResourceResponse;
 
     class ThreadableLoaderClient {
-        WTF_MAKE_NONCOPYABLE(ThreadableLoaderClient); WTF_MAKE_FAST_ALLOCATED;
+        WTF_MAKE_NONCOPYABLE(ThreadableLoaderClient);
+        WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
     public:
         virtual void didSendData(unsigned long long /*bytesSent*/, unsigned long long /*totalBytesToBeSent*/) { }
 
diff --git a/Source/core/loader/WorkerThreadableLoader.cpp b/Source/core/loader/WorkerThreadableLoader.cpp
index fd07cca..3f09f09 100644
--- a/Source/core/loader/WorkerThreadableLoader.cpp
+++ b/Source/core/loader/WorkerThreadableLoader.cpp
@@ -156,7 +156,7 @@
     if (!thisPtr->m_mainThreadLoader)
         return;
     thisPtr->m_mainThreadLoader->cancel();
-    thisPtr->m_mainThreadLoader = 0;
+    thisPtr->m_mainThreadLoader = nullptr;
 }
 
 void WorkerThreadableLoader::MainThreadBridge::cancel()
diff --git a/Source/core/loader/WorkerThreadableLoader.h b/Source/core/loader/WorkerThreadableLoader.h
index ec69fec..f1a7472 100644
--- a/Source/core/loader/WorkerThreadableLoader.h
+++ b/Source/core/loader/WorkerThreadableLoader.h
@@ -34,6 +34,7 @@
 #include "core/loader/ThreadableLoader.h"
 #include "core/loader/ThreadableLoaderClient.h"
 #include "core/loader/ThreadableLoaderClientWrapper.h"
+#include "heap/Handle.h"
 #include "wtf/PassOwnPtr.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -133,7 +134,7 @@
 
         WorkerThreadableLoader(WorkerGlobalScope*, PassRefPtr<ThreadableLoaderClientWrapper>, PassOwnPtr<ThreadableLoaderClient>, const ResourceRequest&, const ThreadableLoaderOptions&);
 
-        RefPtr<WorkerGlobalScope> m_workerGlobalScope;
+        RefPtrWillBePersistent<WorkerGlobalScope> m_workerGlobalScope;
         RefPtr<ThreadableLoaderClientWrapper> m_workerClientWrapper;
         MainThreadBridge& m_bridge;
     };
diff --git a/Source/core/loader/appcache/ApplicationCache.cpp b/Source/core/loader/appcache/ApplicationCache.cpp
index 862f37a..1cfe134 100644
--- a/Source/core/loader/appcache/ApplicationCache.cpp
+++ b/Source/core/loader/appcache/ApplicationCache.cpp
@@ -30,13 +30,13 @@
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/events/EventListener.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
 
 namespace WebCore {
 
-ApplicationCache::ApplicationCache(Frame* frame)
+ApplicationCache::ApplicationCache(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
diff --git a/Source/core/loader/appcache/ApplicationCache.h b/Source/core/loader/appcache/ApplicationCache.h
index ca0366f..614569a 100644
--- a/Source/core/loader/appcache/ApplicationCache.h
+++ b/Source/core/loader/appcache/ApplicationCache.h
@@ -38,13 +38,13 @@
 namespace WebCore {
 
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class KURL;
 
 class ApplicationCache FINAL : public ScriptWrappable, public RefCounted<ApplicationCache>, public EventTargetWithInlineData, public DOMWindowProperty {
     REFCOUNTED_EVENT_TARGET(ApplicationCache);
 public:
-    static PassRefPtr<ApplicationCache> create(Frame* frame) { return adoptRef(new ApplicationCache(frame)); }
+    static PassRefPtr<ApplicationCache> create(LocalFrame* frame) { return adoptRef(new ApplicationCache(frame)); }
     virtual ~ApplicationCache() { ASSERT(!m_frame); }
 
     virtual void willDestroyGlobalObjectInFrame() OVERRIDE;
@@ -71,7 +71,7 @@
     static const AtomicString& toEventType(ApplicationCacheHost::EventID);
 
 private:
-    explicit ApplicationCache(Frame*);
+    explicit ApplicationCache(LocalFrame*);
 
     ApplicationCacheHost* applicationCacheHost() const;
 };
diff --git a/Source/core/loader/appcache/ApplicationCacheHost.cpp b/Source/core/loader/appcache/ApplicationCacheHost.cpp
new file mode 100644
index 0000000..67e0c6d
--- /dev/null
+++ b/Source/core/loader/appcache/ApplicationCacheHost.cpp
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2009 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/loader/appcache/ApplicationCacheHost.h"
+
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/events/ProgressEvent.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/inspector/InspectorApplicationCacheAgent.h"
+#include "core/inspector/InspectorInstrumentation.h"
+#include "core/loader/DocumentLoader.h"
+#include "core/loader/FrameLoader.h"
+#include "core/loader/FrameLoaderClient.h"
+#include "core/loader/appcache/ApplicationCache.h"
+#include "core/page/FrameTree.h"
+#include "core/page/Page.h"
+#include "platform/exported/WrappedResourceRequest.h"
+#include "platform/exported/WrappedResourceResponse.h"
+#include "platform/weborigin/SecurityOrigin.h"
+#include "public/platform/WebURL.h"
+#include "public/platform/WebURLError.h"
+#include "public/platform/WebURLResponse.h"
+#include "public/platform/WebVector.h"
+
+using namespace blink;
+
+namespace WebCore {
+
+// We provide a custom implementation of this class that calls out to the
+// embedding application instead of using WebCore's built in appcache system.
+// This file replaces webcore/appcache/ApplicationCacheHost.cpp in our build.
+
+ApplicationCacheHost::ApplicationCacheHost(DocumentLoader* documentLoader)
+    : m_domApplicationCache(0)
+    , m_documentLoader(documentLoader)
+    , m_defersEvents(true)
+{
+    ASSERT(m_documentLoader);
+}
+
+ApplicationCacheHost::~ApplicationCacheHost()
+{
+}
+
+void ApplicationCacheHost::willStartLoadingMainResource(ResourceRequest& request)
+{
+    // We defer creating the outer host object to avoid spurious creation/destruction
+    // around creating empty documents. At this point, we're initiating a main resource
+    // load for the document, so its for real.
+
+    if (!isApplicationCacheEnabled())
+        return;
+
+    ASSERT(m_documentLoader->frame());
+    LocalFrame& frame = *m_documentLoader->frame();
+    m_host = frame.loader().client()->createApplicationCacheHost(this);
+    if (m_host) {
+        WrappedResourceRequest wrapped(request);
+
+        const WebApplicationCacheHost* spawningHost = 0;
+        LocalFrame* spawningFrame = frame.tree().parent();
+        if (!spawningFrame)
+            spawningFrame = frame.loader().opener();
+        if (!spawningFrame)
+            spawningFrame = &frame;
+        if (DocumentLoader* spawningDocLoader = spawningFrame->loader().documentLoader())
+            spawningHost = spawningDocLoader->applicationCacheHost() ? spawningDocLoader->applicationCacheHost()->m_host.get() : 0;
+
+        m_host->willStartMainResourceRequest(wrapped, spawningHost);
+    }
+
+    // NOTE: The semantics of this method, and others in this interface, are subtly different
+    // than the method names would suggest. For example, in this method never returns an appcached
+    // response in the SubstituteData out argument, instead we return the appcached response thru
+    // the usual resource loading pipeline.
+}
+
+void ApplicationCacheHost::selectCacheWithoutManifest()
+{
+    if (m_host)
+        m_host->selectCacheWithoutManifest();
+}
+
+void ApplicationCacheHost::selectCacheWithManifest(const KURL& manifestURL)
+{
+    if (m_host && !m_host->selectCacheWithManifest(manifestURL)) {
+        // It's a foreign entry, restart the current navigation from the top
+        // of the navigation algorithm. The navigation will not result in the
+        // same resource being loaded, because "foreign" entries are never picked
+        // during navigation.
+        // see WebCore::ApplicationCacheGroup::selectCache()
+        LocalFrame* frame = m_documentLoader->frame();
+        frame->navigationScheduler().scheduleLocationChange(frame->document(), frame->document()->url(), Referrer(frame->document()->referrer(), frame->document()->referrerPolicy()));
+    }
+}
+
+void ApplicationCacheHost::didReceiveResponseForMainResource(const ResourceResponse& response)
+{
+    if (m_host) {
+        WrappedResourceResponse wrapped(response);
+        m_host->didReceiveResponseForMainResource(wrapped);
+    }
+}
+
+void ApplicationCacheHost::mainResourceDataReceived(const char* data, int length)
+{
+    if (m_host)
+        m_host->didReceiveDataForMainResource(data, length);
+}
+
+void ApplicationCacheHost::failedLoadingMainResource()
+{
+    if (m_host)
+        m_host->didFinishLoadingMainResource(false);
+}
+
+void ApplicationCacheHost::finishedLoadingMainResource()
+{
+    if (m_host)
+        m_host->didFinishLoadingMainResource(true);
+}
+
+void ApplicationCacheHost::willStartLoadingResource(ResourceRequest& request)
+{
+    if (m_host) {
+        WrappedResourceRequest wrapped(request);
+        m_host->willStartSubResourceRequest(wrapped);
+    }
+}
+
+void ApplicationCacheHost::setApplicationCache(ApplicationCache* domApplicationCache)
+{
+    ASSERT(!m_domApplicationCache || !domApplicationCache);
+    m_domApplicationCache = domApplicationCache;
+}
+
+void ApplicationCacheHost::notifyApplicationCache(EventID id, int total, int done)
+{
+    if (id != PROGRESS_EVENT)
+        InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader->frame());
+
+    if (m_defersEvents) {
+        // Event dispatching is deferred until document.onload has fired.
+        m_deferredEvents.append(DeferredEvent(id, total, done));
+        return;
+    }
+    dispatchDOMEvent(id, total, done);
+}
+
+ApplicationCacheHost::CacheInfo ApplicationCacheHost::applicationCacheInfo()
+{
+    if (!m_host)
+        return CacheInfo(KURL(), 0, 0, 0);
+
+    blink::WebApplicationCacheHost::CacheInfo webInfo;
+    m_host->getAssociatedCacheInfo(&webInfo);
+    return CacheInfo(webInfo.manifestURL, webInfo.creationTime, webInfo.updateTime, webInfo.totalSize);
+}
+
+void ApplicationCacheHost::fillResourceList(ResourceInfoList* resources)
+{
+    if (!m_host)
+        return;
+
+    blink::WebVector<blink::WebApplicationCacheHost::ResourceInfo> webResources;
+    m_host->getResourceList(&webResources);
+    for (size_t i = 0; i < webResources.size(); ++i) {
+        resources->append(ResourceInfo(
+            webResources[i].url, webResources[i].isMaster, webResources[i].isManifest, webResources[i].isFallback,
+            webResources[i].isForeign, webResources[i].isExplicit, webResources[i].size));
+    }
+}
+
+void ApplicationCacheHost::stopDeferringEvents()
+{
+    RefPtr<DocumentLoader> protect(documentLoader());
+    for (unsigned i = 0; i < m_deferredEvents.size(); ++i) {
+        const DeferredEvent& deferred = m_deferredEvents[i];
+        dispatchDOMEvent(deferred.eventID, deferred.progressTotal, deferred.progressDone);
+    }
+    m_deferredEvents.clear();
+    m_defersEvents = false;
+}
+
+void ApplicationCacheHost::dispatchDOMEvent(EventID id, int total, int done)
+{
+    if (m_domApplicationCache) {
+        const AtomicString& eventType = ApplicationCache::toEventType(id);
+        RefPtr<Event> event;
+        if (id == PROGRESS_EVENT)
+            event = ProgressEvent::create(eventType, true, done, total);
+        else
+            event = Event::create(eventType);
+        m_domApplicationCache->dispatchEvent(event, ASSERT_NO_EXCEPTION);
+    }
+}
+
+ApplicationCacheHost::Status ApplicationCacheHost::status() const
+{
+    return m_host ? static_cast<Status>(m_host->status()) : UNCACHED;
+}
+
+bool ApplicationCacheHost::update()
+{
+    return m_host ? m_host->startUpdate() : false;
+}
+
+bool ApplicationCacheHost::swapCache()
+{
+    bool success = m_host ? m_host->swapCache() : false;
+    if (success)
+        InspectorInstrumentation::updateApplicationCacheStatus(m_documentLoader->frame());
+    return success;
+}
+
+void ApplicationCacheHost::abort()
+{
+    if (m_host)
+        m_host->abort();
+}
+
+bool ApplicationCacheHost::isApplicationCacheEnabled()
+{
+    ASSERT(m_documentLoader->frame());
+    return m_documentLoader->frame()->settings() && m_documentLoader->frame()->settings()->offlineWebApplicationCacheEnabled();
+}
+
+void ApplicationCacheHost::didChangeCacheAssociation()
+{
+    // FIXME: Prod the inspector to update its notion of what cache the page is using.
+}
+
+void ApplicationCacheHost::notifyEventListener(blink::WebApplicationCacheHost::EventID eventID)
+{
+    notifyApplicationCache(static_cast<ApplicationCacheHost::EventID>(eventID), 0, 0);
+}
+
+void ApplicationCacheHost::notifyProgressEventListener(const blink::WebURL&, int progressTotal, int progressDone)
+{
+    notifyApplicationCache(PROGRESS_EVENT, progressTotal, progressDone);
+}
+
+} // namespace WebCore
diff --git a/Source/core/loader/appcache/ApplicationCacheHost.h b/Source/core/loader/appcache/ApplicationCacheHost.h
index 1405589..b2401be 100644
--- a/Source/core/loader/appcache/ApplicationCacheHost.h
+++ b/Source/core/loader/appcache/ApplicationCacheHost.h
@@ -32,6 +32,7 @@
 #define ApplicationCacheHost_h
 
 #include "platform/weborigin/KURL.h"
+#include "public/platform/WebApplicationCacheHostClient.h"
 #include "wtf/Deque.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassRefPtr.h"
@@ -41,16 +42,15 @@
 namespace WebCore {
     class ApplicationCache;
     class DocumentLoader;
-    class Frame;
+    class LocalFrame;
     class ResourceLoader;
     class ResourceError;
     class ResourceRequest;
     class ResourceResponse;
     class SubstituteData;
-    class ApplicationCacheHostInternal;
 
-    class ApplicationCacheHost {
-        WTF_MAKE_NONCOPYABLE(ApplicationCacheHost); WTF_MAKE_FAST_ALLOCATED;
+    class ApplicationCacheHost : public blink::WebApplicationCacheHostClient {
+        WTF_MAKE_NONCOPYABLE(ApplicationCacheHost);
     public:
         // The Status numeric values are specified in the HTML5 spec.
         enum Status {
@@ -105,8 +105,8 @@
 
         typedef Vector<ResourceInfo> ResourceInfoList;
 
-        ApplicationCacheHost(DocumentLoader*);
-        ~ApplicationCacheHost();
+        explicit ApplicationCacheHost(DocumentLoader*);
+        virtual ~ApplicationCacheHost();
 
         void selectCacheWithoutManifest();
         void selectCacheWithManifest(const KURL& manifestURL);
@@ -133,6 +133,11 @@
         CacheInfo applicationCacheInfo();
 
     private:
+        // WebApplicationCacheHostClient implementation
+        virtual void didChangeCacheAssociation() OVERRIDE FINAL;
+        virtual void notifyEventListener(blink::WebApplicationCacheHost::EventID) OVERRIDE FINAL;
+        virtual void notifyProgressEventListener(const blink::WebURL&, int progressTotal, int progressDone) OVERRIDE FINAL;
+
         bool isApplicationCacheEnabled();
         DocumentLoader* documentLoader() const { return m_documentLoader; }
 
@@ -150,8 +155,7 @@
 
         void dispatchDOMEvent(EventID, int progressTotal, int progressDone);
 
-        friend class ApplicationCacheHostInternal;
-        OwnPtr<ApplicationCacheHostInternal> m_internal;
+        OwnPtr<blink::WebApplicationCacheHost> m_host;
     };
 
 }  // namespace WebCore
diff --git a/Source/core/make_core_generated.target.darwin-arm.mk b/Source/core/make_core_generated.target.darwin-arm.mk
index adffd5f..0625545 100644
--- a/Source/core/make_core_generated.target.darwin-arm.mk
+++ b/Source/core/make_core_generated.target.darwin-arm.mk
@@ -52,10 +52,42 @@
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_property_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSPropertyNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSPropertyNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h: $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp ;
 
+### Rules for action "MediaFeatureNames":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_feature_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatureNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_feature_names.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp ;
+
+### Rules for action "MediaFeatures":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_features.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatures ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_features.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+
+### Rules for action "MediaTypeNames":
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaTypeNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaTypeNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_names.py css/MediaTypeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp ;
+
 ### Rules for action "StylePropertyShorthand":
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -86,7 +118,7 @@
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_value_keywords.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSValueKeywords.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSValueKeywords ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.h: $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp ;
 
@@ -105,6 +137,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 
+### Rules for action "HTMLElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/HTMLTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_HTMLElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py html/HTMLTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "SVGNames":
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -120,6 +162,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 
+### Rules for action "SVGElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/svg/SVGTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_SVGElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py svg/SVGTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "EventFactory":
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -172,7 +224,7 @@
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MathMLNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.h: $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp ;
 
@@ -181,9 +233,9 @@
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeMac.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_UserAgentStyleSheets ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeMac.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
 
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp: $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h ;
 
@@ -328,6 +380,11 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.h \
 	$(gyp_shared_intermediate_dir)/blink/StyleBuilder.cpp \
@@ -341,12 +398,14 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/Event.cpp \
 	$(gyp_shared_intermediate_dir)/blink/EventHeaders.h \
 	$(gyp_shared_intermediate_dir)/blink/EventInterfaces.h \
@@ -430,6 +489,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -437,13 +497,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -514,6 +575,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -521,13 +583,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -565,6 +628,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/Source/core/make_core_generated.target.darwin-mips.mk b/Source/core/make_core_generated.target.darwin-mips.mk
index fc97fa2..160d32e 100644
--- a/Source/core/make_core_generated.target.darwin-mips.mk
+++ b/Source/core/make_core_generated.target.darwin-mips.mk
@@ -52,10 +52,42 @@
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_property_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSPropertyNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSPropertyNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h: $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp ;
 
+### Rules for action "MediaFeatureNames":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_feature_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatureNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_feature_names.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp ;
+
+### Rules for action "MediaFeatures":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_features.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatures ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_features.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+
+### Rules for action "MediaTypeNames":
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaTypeNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaTypeNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_names.py css/MediaTypeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp ;
+
 ### Rules for action "StylePropertyShorthand":
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -86,7 +118,7 @@
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_value_keywords.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSValueKeywords.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSValueKeywords ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.h: $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp ;
 
@@ -105,6 +137,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 
+### Rules for action "HTMLElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/HTMLTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_HTMLElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py html/HTMLTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "SVGNames":
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -120,6 +162,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 
+### Rules for action "SVGElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/svg/SVGTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_SVGElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py svg/SVGTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "EventFactory":
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -172,7 +224,7 @@
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MathMLNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.h: $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp ;
 
@@ -181,9 +233,9 @@
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeMac.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_UserAgentStyleSheets ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeMac.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
 
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp: $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h ;
 
@@ -328,6 +380,11 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.h \
 	$(gyp_shared_intermediate_dir)/blink/StyleBuilder.cpp \
@@ -341,12 +398,14 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/Event.cpp \
 	$(gyp_shared_intermediate_dir)/blink/EventHeaders.h \
 	$(gyp_shared_intermediate_dir)/blink/EventInterfaces.h \
@@ -429,6 +488,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -436,13 +496,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -512,6 +573,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -519,13 +581,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -563,6 +626,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/Source/core/make_core_generated.target.darwin-x86.mk b/Source/core/make_core_generated.target.darwin-x86.mk
index 00c2b62..ecf03e2 100644
--- a/Source/core/make_core_generated.target.darwin-x86.mk
+++ b/Source/core/make_core_generated.target.darwin-x86.mk
@@ -52,10 +52,42 @@
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_property_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSPropertyNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSPropertyNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h: $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp ;
 
+### Rules for action "MediaFeatureNames":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_feature_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatureNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_feature_names.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp ;
+
+### Rules for action "MediaFeatures":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_features.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatures ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_features.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+
+### Rules for action "MediaTypeNames":
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaTypeNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaTypeNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_names.py css/MediaTypeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp ;
+
 ### Rules for action "StylePropertyShorthand":
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -86,7 +118,7 @@
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_value_keywords.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSValueKeywords.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSValueKeywords ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.h: $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp ;
 
@@ -105,6 +137,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 
+### Rules for action "HTMLElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/HTMLTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_HTMLElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py html/HTMLTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "SVGNames":
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -120,6 +162,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 
+### Rules for action "SVGElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/svg/SVGTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_SVGElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py svg/SVGTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "EventFactory":
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -172,7 +224,7 @@
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MathMLNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.h: $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp ;
 
@@ -181,9 +233,9 @@
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeMac.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_UserAgentStyleSheets ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeMac.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
 
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp: $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h ;
 
@@ -328,6 +380,11 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.h \
 	$(gyp_shared_intermediate_dir)/blink/StyleBuilder.cpp \
@@ -341,12 +398,14 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/Event.cpp \
 	$(gyp_shared_intermediate_dir)/blink/EventHeaders.h \
 	$(gyp_shared_intermediate_dir)/blink/EventInterfaces.h \
@@ -405,11 +464,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -432,6 +490,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -439,13 +498,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -490,11 +550,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -517,6 +576,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -524,13 +584,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -567,6 +628,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/Source/core/make_core_generated.target.linux-arm.mk b/Source/core/make_core_generated.target.linux-arm.mk
index adffd5f..0625545 100644
--- a/Source/core/make_core_generated.target.linux-arm.mk
+++ b/Source/core/make_core_generated.target.linux-arm.mk
@@ -52,10 +52,42 @@
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_property_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSPropertyNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSPropertyNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h: $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp ;
 
+### Rules for action "MediaFeatureNames":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_feature_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatureNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_feature_names.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp ;
+
+### Rules for action "MediaFeatures":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_features.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatures ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_features.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+
+### Rules for action "MediaTypeNames":
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaTypeNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaTypeNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_names.py css/MediaTypeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp ;
+
 ### Rules for action "StylePropertyShorthand":
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -86,7 +118,7 @@
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_value_keywords.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSValueKeywords.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSValueKeywords ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.h: $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp ;
 
@@ -105,6 +137,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 
+### Rules for action "HTMLElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/HTMLTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_HTMLElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py html/HTMLTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "SVGNames":
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -120,6 +162,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 
+### Rules for action "SVGElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/svg/SVGTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_SVGElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py svg/SVGTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "EventFactory":
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -172,7 +224,7 @@
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MathMLNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.h: $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp ;
 
@@ -181,9 +233,9 @@
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeMac.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_UserAgentStyleSheets ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeMac.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
 
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp: $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h ;
 
@@ -328,6 +380,11 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.h \
 	$(gyp_shared_intermediate_dir)/blink/StyleBuilder.cpp \
@@ -341,12 +398,14 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/Event.cpp \
 	$(gyp_shared_intermediate_dir)/blink/EventHeaders.h \
 	$(gyp_shared_intermediate_dir)/blink/EventInterfaces.h \
@@ -430,6 +489,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -437,13 +497,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -514,6 +575,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -521,13 +583,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -565,6 +628,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/Source/core/make_core_generated.target.linux-mips.mk b/Source/core/make_core_generated.target.linux-mips.mk
index fc97fa2..160d32e 100644
--- a/Source/core/make_core_generated.target.linux-mips.mk
+++ b/Source/core/make_core_generated.target.linux-mips.mk
@@ -52,10 +52,42 @@
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_property_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSPropertyNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSPropertyNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h: $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp ;
 
+### Rules for action "MediaFeatureNames":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_feature_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatureNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_feature_names.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp ;
+
+### Rules for action "MediaFeatures":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_features.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatures ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_features.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+
+### Rules for action "MediaTypeNames":
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaTypeNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaTypeNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_names.py css/MediaTypeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp ;
+
 ### Rules for action "StylePropertyShorthand":
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -86,7 +118,7 @@
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_value_keywords.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSValueKeywords.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSValueKeywords ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.h: $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp ;
 
@@ -105,6 +137,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 
+### Rules for action "HTMLElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/HTMLTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_HTMLElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py html/HTMLTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "SVGNames":
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -120,6 +162,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 
+### Rules for action "SVGElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/svg/SVGTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_SVGElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py svg/SVGTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "EventFactory":
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -172,7 +224,7 @@
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MathMLNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.h: $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp ;
 
@@ -181,9 +233,9 @@
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeMac.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_UserAgentStyleSheets ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeMac.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
 
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp: $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h ;
 
@@ -328,6 +380,11 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.h \
 	$(gyp_shared_intermediate_dir)/blink/StyleBuilder.cpp \
@@ -341,12 +398,14 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/Event.cpp \
 	$(gyp_shared_intermediate_dir)/blink/EventHeaders.h \
 	$(gyp_shared_intermediate_dir)/blink/EventInterfaces.h \
@@ -429,6 +488,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -436,13 +496,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -512,6 +573,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -519,13 +581,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -563,6 +626,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/Source/core/make_core_generated.target.linux-x86.mk b/Source/core/make_core_generated.target.linux-x86.mk
index 00c2b62..ecf03e2 100644
--- a/Source/core/make_core_generated.target.linux-x86.mk
+++ b/Source/core/make_core_generated.target.linux-x86.mk
@@ -52,10 +52,42 @@
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_property_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSPropertyNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSPropertyNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSPropertyNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_property_names.py css/CSSPropertyNames.in css/SVGCSSPropertyNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h: $(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp ;
 
+### Rules for action "MediaFeatureNames":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_feature_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatureNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_feature_names.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp ;
+
+### Rules for action "MediaFeatures":
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_media_features.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaFeatureNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaFeatures ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_media_features.py css/MediaFeatureNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+
+### Rules for action "MediaTypeNames":
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_names.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/MediaTypeNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MediaTypeNames ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_names.py css/MediaTypeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+
+$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp ;
+
 ### Rules for action "StylePropertyShorthand":
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -86,7 +118,7 @@
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_css_value_keywords.py $(LOCAL_PATH)/third_party/WebKit/Source/core/css/CSSValueKeywords.in $(LOCAL_PATH)/third_party/WebKit/Source/core/css/SVGCSSValueKeywords.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_CSSValueKeywords ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_css_value_keywords.py css/CSSValueKeywords.in css/SVGCSSValueKeywords.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --gperf gperf --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.h: $(gyp_shared_intermediate_dir)/blink/CSSValueKeywords.cpp ;
 
@@ -105,6 +137,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/HTMLElementFactory.cpp ;
 
+### Rules for action "HTMLElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/HTMLTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_HTMLElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py html/HTMLTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "SVGNames":
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -120,6 +162,16 @@
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 $(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h: $(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp ;
 
+### Rules for action "SVGElementTypeHelpers":
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_local_path := $(LOCAL_PATH)
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
+$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_element_type_helpers.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/ElementTypeHelpers.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/svg/SVGTagNames.in $(GYP_TARGET_DEPENDENCIES)
+	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_SVGElementTypeHelpers ($@)"
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_element_type_helpers.py svg/SVGTagNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink"
+
+
 ### Rules for action "EventFactory":
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_local_path := $(LOCAL_PATH)
 $(gyp_shared_intermediate_dir)/blink/Event.cpp: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
@@ -172,7 +224,7 @@
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp: $(LOCAL_PATH)/third_party/jinja2/__init__.py $(LOCAL_PATH)/third_party/markupsafe/__init__.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/hasher.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_file.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/in_generator.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/license.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_macros.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/name_utilities.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/template_expander.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/macros.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/make_qualified_names.py $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.cpp.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/templates/MakeQualifiedNames.h.tmpl $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLTagNames.in $(LOCAL_PATH)/third_party/WebKit/Source/core/html/parser/MathMLAttributeNames.in $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_MathMLNames ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/make_qualified_names.py html/parser/MathMLTagNames.in html/parser/MathMLAttributeNames.in --output_dir "$(gyp_shared_intermediate_dir)/blink" --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\""
 
 $(gyp_shared_intermediate_dir)/blink/MathMLNames.h: $(gyp_shared_intermediate_dir)/blink/MathMLNames.cpp ;
 
@@ -181,9 +233,9 @@
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_intermediate_dir := $(abspath $(gyp_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: gyp_shared_intermediate_dir := $(abspath $(gyp_shared_intermediate_dir))
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: export PATH := $(subst $(ANDROID_BUILD_PATHS),,$(PATH))
-$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
+$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h: $(LOCAL_PATH)/third_party/WebKit/Source/core/css/make-css-file-arrays.pl $(LOCAL_PATH)/third_party/WebKit/Source/build/scripts/preprocessor.pm $(LOCAL_PATH)/third_party/WebKit/Source/core/css/html.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/quirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/view-source.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromium.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumLinux.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeChromiumSkia.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeMac.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWin.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/themeWinQuirks.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/svg.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControls.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/mediaControlsAndroid.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/fullscreen.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/xhtmlmp.css $(LOCAL_PATH)/third_party/WebKit/Source/core/css/viewportAndroid.css $(GYP_TARGET_DEPENDENCIES)
 	@echo "Gyp action: third_party_WebKit_Source_core_core_generated_gyp_make_core_generated_target_UserAgentStyleSheets ($@)"
-	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"ENABLE_GDI_FONTS_ON_WINDOWS=0\" \"ENABLE_HARFBUZZ_ON_WINDOWS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_LEGACY_NOTIFICATIONS=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
+	$(hide)cd $(gyp_local_path)/third_party/WebKit/Source/core; mkdir -p $(gyp_shared_intermediate_dir)/blink; python ../build/scripts/action_useragentstylesheets.py "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h" "$(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp" css/html.css css/quirks.css css/view-source.css css/themeChromium.css css/themeChromiumAndroid.css css/themeChromiumLinux.css css/themeChromiumSkia.css css/themeMac.css css/themeWin.css css/themeWinQuirks.css css/svg.css css/mediaControls.css css/mediaControlsAndroid.css css/fullscreen.css css/xhtmlmp.css css/viewportAndroid.css -- css/make-css-file-arrays.pl ../build/scripts/preprocessor.pm -- --defines "\"ENABLE_CUSTOM_SCHEME_HANDLER=0\" \"ENABLE_SVG_FONTS=1\" \"WTF_USE_CONCATENATED_IMPULSE_RESPONSES=1\" \"ENABLE_FAST_MOBILE_SCROLLING=1\" \"ENABLE_INPUT_SPEECH=0\" \"ENABLE_MEDIA_CAPTURE=1\" \"ENABLE_OPENTYPE_VERTICAL=1\"" --preprocessor "/usr/bin/gcc -E -P -x c++" --perl perl
 
 $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheetsData.cpp: $(gyp_shared_intermediate_dir)/blink/UserAgentStyleSheets.h ;
 
@@ -328,6 +380,11 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/CSSPropertyNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaFeatures.h \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp \
+	$(gyp_shared_intermediate_dir)/blink/MediaTypeNames.h \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.cpp \
 	$(gyp_shared_intermediate_dir)/blink/StylePropertyShorthand.h \
 	$(gyp_shared_intermediate_dir)/blink/StyleBuilder.cpp \
@@ -341,12 +398,14 @@
 	$(gyp_shared_intermediate_dir)/blink/HTMLNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8HTMLElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/HTMLElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGElementFactory.h \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.cpp \
 	$(gyp_shared_intermediate_dir)/blink/SVGNames.h \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.cpp \
 	$(gyp_shared_intermediate_dir)/blink/V8SVGElementWrapperFactory.h \
+	$(gyp_shared_intermediate_dir)/blink/SVGElementTypeHelpers.h \
 	$(gyp_shared_intermediate_dir)/blink/Event.cpp \
 	$(gyp_shared_intermediate_dir)/blink/EventHeaders.h \
 	$(gyp_shared_intermediate_dir)/blink/EventInterfaces.h \
@@ -405,11 +464,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -432,6 +490,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -439,13 +498,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -490,11 +550,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -517,6 +576,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -524,13 +584,14 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
 	'-DENABLE_MANAGED_USERS=1' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -567,6 +628,7 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 # Add target alias to "gyp_all_modules" target.
 .PHONY: gyp_all_modules
diff --git a/Source/core/page/AutoscrollController.cpp b/Source/core/page/AutoscrollController.cpp
index 281e16b..b168e00 100644
--- a/Source/core/page/AutoscrollController.cpp
+++ b/Source/core/page/AutoscrollController.cpp
@@ -29,10 +29,10 @@
 #include "config.h"
 #include "core/page/AutoscrollController.h"
 
-#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Chrome.h"
+#include "core/page/EventHandler.h"
 #include "core/page/Page.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/RenderBox.h"
@@ -172,7 +172,7 @@
 }
 
 #if OS(WIN)
-void AutoscrollController::handleMouseReleaseForPanScrolling(Frame* frame, const PlatformMouseEvent& mouseEvent)
+void AutoscrollController::handleMouseReleaseForPanScrolling(LocalFrame* frame, const PlatformMouseEvent& mouseEvent)
 {
     if (!frame->isMainFrame())
         return;
diff --git a/Source/core/page/AutoscrollController.h b/Source/core/page/AutoscrollController.h
index c66b3a0..62f7fd6 100644
--- a/Source/core/page/AutoscrollController.h
+++ b/Source/core/page/AutoscrollController.h
@@ -32,7 +32,7 @@
 namespace WebCore {
 
 class EventHandler;
-class Frame;
+class LocalFrame;
 class FrameView;
 class Node;
 class Page;
@@ -65,7 +65,7 @@
     void updateAutoscrollRenderer();
     void updateDragAndDrop(Node* targetNode, const IntPoint& eventPosition, double eventTime);
 #if OS(WIN)
-    void handleMouseReleaseForPanScrolling(Frame*, const PlatformMouseEvent&);
+    void handleMouseReleaseForPanScrolling(LocalFrame*, const PlatformMouseEvent&);
     void startPanScrolling(RenderBox*, const IntPoint&);
 #endif
 
diff --git a/Source/core/page/Chrome.cpp b/Source/core/page/Chrome.cpp
index dc4774a..191dba3 100644
--- a/Source/core/page/Chrome.cpp
+++ b/Source/core/page/Chrome.cpp
@@ -25,14 +25,14 @@
 #include "public/platform/WebScreenInfo.h"
 #include "HTMLNames.h"
 #include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/page/ChromeClient.h"
-#include "core/frame/Frame.h"
 #include "core/page/FrameTree.h"
 #include "core/page/Page.h"
-#include "core/page/PageGroupLoadDeferrer.h"
 #include "core/page/PopupOpeningObserver.h"
+#include "core/page/ScopedPageLoadDeferrer.h"
 #include "core/page/WindowFeatures.h"
 #include "core/rendering/HitTestResult.h"
 #include "platform/ColorChooser.h"
@@ -90,7 +90,7 @@
     return m_client->screenInfo();
 }
 
-void Chrome::contentsSizeChanged(Frame* frame, const IntSize& size) const
+void Chrome::contentsSizeChanged(LocalFrame* frame, const IntSize& size) const
 {
     m_client->contentsSizeChanged(frame, size);
 }
@@ -142,7 +142,7 @@
 
 static bool canRunModalIfDuringPageDismissal(Page* page, ChromeClient::DialogType dialog, const String& message)
 {
-    for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         Document::PageDismissalType dismissal = frame->document()->pageDismissalEventBeingDispatched();
         if (dismissal != Document::NoDismissal)
             return page->chrome().client().shouldRunModalDialogDuringPageDismissal(dialog, message, dismissal);
@@ -157,9 +157,9 @@
 
 void Chrome::runModal() const
 {
-    // Defer callbacks in all the other pages in this group, so we don't try to run JavaScript
+    // Defer callbacks in all the other pages, so we don't try to run JavaScript
     // in a way that could interact with this view.
-    PageGroupLoadDeferrer deferrer(m_page, false);
+    ScopedPageLoadDeferrer deferrer(m_page);
 
     TimerBase::fireTimersInNestedEventLoop();
     m_client->runModal();
@@ -199,11 +199,11 @@
     return m_client->canRunBeforeUnloadConfirmPanel();
 }
 
-bool Chrome::runBeforeUnloadConfirmPanel(const String& message, Frame* frame)
+bool Chrome::runBeforeUnloadConfirmPanel(const String& message, LocalFrame* frame)
 {
     // Defer loads in case the client method runs a new event loop that would
     // otherwise cause the load to continue while we're in the middle of executing JavaScript.
-    PageGroupLoadDeferrer deferrer(m_page, true);
+    ScopedPageLoadDeferrer deferrer;
 
     InspectorInstrumentationCookie cookie = InspectorInstrumentation::willRunJavaScriptDialog(m_page, message);
     bool ok = m_client->runBeforeUnloadConfirmPanel(message, frame);
@@ -216,14 +216,14 @@
     m_client->closeWindowSoon();
 }
 
-void Chrome::runJavaScriptAlert(Frame* frame, const String& message)
+void Chrome::runJavaScriptAlert(LocalFrame* frame, const String& message)
 {
     if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::AlertDialog, message))
         return;
 
     // Defer loads in case the client method runs a new event loop that would
     // otherwise cause the load to continue while we're in the middle of executing JavaScript.
-    PageGroupLoadDeferrer deferrer(m_page, true);
+    ScopedPageLoadDeferrer deferrer;
 
     ASSERT(frame);
     notifyPopupOpeningObservers();
@@ -233,14 +233,14 @@
     InspectorInstrumentation::didRunJavaScriptDialog(cookie);
 }
 
-bool Chrome::runJavaScriptConfirm(Frame* frame, const String& message)
+bool Chrome::runJavaScriptConfirm(LocalFrame* frame, const String& message)
 {
     if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::ConfirmDialog, message))
         return false;
 
     // Defer loads in case the client method runs a new event loop that would
     // otherwise cause the load to continue while we're in the middle of executing JavaScript.
-    PageGroupLoadDeferrer deferrer(m_page, true);
+    ScopedPageLoadDeferrer deferrer;
 
     ASSERT(frame);
     notifyPopupOpeningObservers();
@@ -251,14 +251,14 @@
     return ok;
 }
 
-bool Chrome::runJavaScriptPrompt(Frame* frame, const String& prompt, const String& defaultValue, String& result)
+bool Chrome::runJavaScriptPrompt(LocalFrame* frame, const String& prompt, const String& defaultValue, String& result)
 {
     if (!canRunModalIfDuringPageDismissal(m_page, ChromeClient::PromptDialog, prompt))
         return false;
 
     // Defer loads in case the client method runs a new event loop that would
     // otherwise cause the load to continue while we're in the middle of executing JavaScript.
-    PageGroupLoadDeferrer deferrer(m_page, true);
+    ScopedPageLoadDeferrer deferrer;
 
     ASSERT(frame);
     notifyPopupOpeningObservers();
@@ -270,7 +270,7 @@
     return ok;
 }
 
-void Chrome::setStatusbarText(Frame* frame, const String& status)
+void Chrome::setStatusbarText(LocalFrame* frame, const String& status)
 {
     ASSERT(frame);
     m_client->setStatusbarText(status);
@@ -303,7 +303,7 @@
     // Lastly, for <input type="file"> that allow multiple files, we'll consider a tooltip for the selected filenames
     if (toolTip.isEmpty()) {
         if (Node* node = result.innerNonSharedNode()) {
-            if (node->hasTagName(inputTag)) {
+            if (isHTMLInputElement(*node)) {
                 HTMLInputElement* input = toHTMLInputElement(node);
                 toolTip = input->defaultToolTip();
 
@@ -320,9 +320,12 @@
     m_client->setToolTip(toolTip, toolTipDirection);
 }
 
-void Chrome::print(Frame* frame)
+void Chrome::print(LocalFrame* frame)
 {
-    // FIXME: This should have PageGroupLoadDeferrer, like runModal() or runJavaScriptAlert(), becasue it's no different from those.
+    // Defer loads in case the client method runs a new event loop that would
+    // otherwise cause the load to continue while we're in the middle of executing JavaScript.
+    ScopedPageLoadDeferrer deferrer;
+
     m_client->print(frame);
 }
 
@@ -349,7 +352,7 @@
     m_client->openTextDataListChooser(input);
 }
 
-void Chrome::runOpenPanel(Frame* frame, PassRefPtr<FileChooser> fileChooser)
+void Chrome::runOpenPanel(LocalFrame* frame, PassRefPtr<FileChooser> fileChooser)
 {
     notifyPopupOpeningObservers();
     m_client->runOpenPanel(frame, fileChooser);
@@ -367,6 +370,7 @@
 
 void Chrome::scheduleAnimation()
 {
+    m_page->animator().setAnimationFramePending();
     m_client->scheduleAnimation();
 }
 
@@ -377,7 +381,7 @@
     return m_client->hasOpenedPopup();
 }
 
-PassRefPtr<PopupMenu> Chrome::createPopupMenu(Frame& frame, PopupMenuClient* client) const
+PassRefPtr<PopupMenu> Chrome::createPopupMenu(LocalFrame& frame, PopupMenuClient* client) const
 {
     notifyPopupOpeningObservers();
     return m_client->createPopupMenu(frame, client);
diff --git a/Source/core/page/Chrome.h b/Source/core/page/Chrome.h
index ab2cf0c..22aad14 100644
--- a/Source/core/page/Chrome.h
+++ b/Source/core/page/Chrome.h
@@ -37,7 +37,7 @@
 class DateTimeChooserClient;
 class FileChooser;
 class FloatRect;
-class Frame;
+class LocalFrame;
 class HTMLInputElement;
 class HitTestResult;
 class IntRect;
@@ -69,7 +69,7 @@
 
     virtual void scheduleAnimation() OVERRIDE;
 
-    void contentsSizeChanged(Frame*, const IntSize&) const;
+    void contentsSizeChanged(LocalFrame*, const IntSize&) const;
 
     void setCursor(const Cursor&);
 
@@ -99,14 +99,14 @@
     bool menubarVisible() const;
 
     bool canRunBeforeUnloadConfirmPanel();
-    bool runBeforeUnloadConfirmPanel(const String& message, Frame*);
+    bool runBeforeUnloadConfirmPanel(const String& message, LocalFrame*);
 
     void closeWindowSoon();
 
-    void runJavaScriptAlert(Frame*, const String&);
-    bool runJavaScriptConfirm(Frame*, const String&);
-    bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result);
-    void setStatusbarText(Frame*, const String&);
+    void runJavaScriptAlert(LocalFrame*, const String&);
+    bool runJavaScriptConfirm(LocalFrame*, const String&);
+    bool runJavaScriptPrompt(LocalFrame*, const String& message, const String& defaultValue, String& result);
+    void setStatusbarText(LocalFrame*, const String&);
 
     IntRect windowResizerRect() const;
 
@@ -114,19 +114,19 @@
 
     void setToolTip(const HitTestResult&);
 
-    void print(Frame*);
+    void print(LocalFrame*);
 
     PassOwnPtr<ColorChooser> createColorChooser(ColorChooserClient*, const Color& initialColor);
     PassRefPtr<DateTimeChooser> openDateTimeChooser(DateTimeChooserClient*, const DateTimeChooserParameters&);
     void openTextDataListChooser(HTMLInputElement&);
 
-    void runOpenPanel(Frame*, PassRefPtr<FileChooser>);
+    void runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>);
     void enumerateChosenDirectory(FileChooser*);
 
     void dispatchViewportPropertiesDidChange(const ViewportDescription&) const;
 
     bool hasOpenedPopup() const;
-    PassRefPtr<PopupMenu> createPopupMenu(Frame&, PopupMenuClient*) const;
+    PassRefPtr<PopupMenu> createPopupMenu(LocalFrame&, PopupMenuClient*) const;
 
     void registerPopupOpeningObserver(PopupOpeningObserver*);
     void unregisterPopupOpeningObserver(PopupOpeningObserver*);
diff --git a/Source/core/page/ChromeClient.h b/Source/core/page/ChromeClient.h
index b92337b..5414cd5 100644
--- a/Source/core/page/ChromeClient.h
+++ b/Source/core/page/ChromeClient.h
@@ -56,10 +56,11 @@
 class Element;
 class FileChooser;
 class FloatRect;
-class Frame;
+class LocalFrame;
 class GraphicsLayer;
 class GraphicsLayerFactory;
 class HitTestResult;
+class HTMLFormControlElement;
 class HTMLInputElement;
 class IntRect;
 class Node;
@@ -93,13 +94,15 @@
 
     virtual void focusedNodeChanged(Node*) = 0;
 
-    // The Frame pointer provides the ChromeClient with context about which
-    // Frame wants to create the new Page. Also, the newly created window
+    virtual void focusedFrameChanged(LocalFrame*) = 0;
+
+    // The LocalFrame pointer provides the ChromeClient with context about which
+    // LocalFrame wants to create the new Page. Also, the newly created window
     // should not be shown to the user until the ChromeClient of the newly
     // created Page has its show method called.
     // The FrameLoadRequest parameter is only for ChromeClient to check if the
     // request could be fulfilled. The ChromeClient should not load the request.
-    virtual Page* createWindow(Frame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) = 0;
+    virtual Page* createWindow(LocalFrame*, const FrameLoadRequest&, const WindowFeatures&, NavigationPolicy, ShouldSendReferrer) = 0;
     virtual void show(NavigationPolicy) = 0;
 
     virtual bool canRunModal() = 0;
@@ -123,13 +126,13 @@
     virtual void addMessageToConsole(MessageSource, MessageLevel, const String& message, unsigned lineNumber, const String& sourceID, const String& stackTrace) = 0;
 
     virtual bool canRunBeforeUnloadConfirmPanel() = 0;
-    virtual bool runBeforeUnloadConfirmPanel(const String& message, Frame*) = 0;
+    virtual bool runBeforeUnloadConfirmPanel(const String& message, LocalFrame*) = 0;
 
     virtual void closeWindowSoon() = 0;
 
-    virtual void runJavaScriptAlert(Frame*, const String&) = 0;
-    virtual bool runJavaScriptConfirm(Frame*, const String&) = 0;
-    virtual bool runJavaScriptPrompt(Frame*, const String& message, const String& defaultValue, String& result) = 0;
+    virtual void runJavaScriptAlert(LocalFrame*, const String&) = 0;
+    virtual bool runJavaScriptConfirm(LocalFrame*, const String&) = 0;
+    virtual bool runJavaScriptPrompt(LocalFrame*, const String& message, const String& defaultValue, String& result) = 0;
     virtual void setStatusbarText(const String&) = 0;
     virtual bool tabsToLinks() = 0;
 
@@ -151,15 +154,15 @@
 
     virtual void dispatchViewportPropertiesDidChange(const ViewportDescription&) const { }
 
-    virtual void contentsSizeChanged(Frame*, const IntSize&) const = 0;
+    virtual void contentsSizeChanged(LocalFrame*, const IntSize&) const = 0;
     virtual void deviceOrPageScaleFactorChanged() const { }
-    virtual void layoutUpdated(Frame*) const { }
+    virtual void layoutUpdated(LocalFrame*) const { }
 
     virtual void mouseDidMoveOverElement(const HitTestResult&, unsigned modifierFlags) = 0;
 
     virtual void setToolTip(const String&, TextDirection) = 0;
 
-    virtual void print(Frame*) = 0;
+    virtual void print(LocalFrame*) = 0;
     virtual bool shouldRubberBandInDirection(ScrollDirection) const = 0;
 
     virtual void annotatedRegionsChanged() = 0;
@@ -178,20 +181,16 @@
 
     virtual void openTextDataListChooser(HTMLInputElement&) = 0;
 
-    virtual void runOpenPanel(Frame*, PassRefPtr<FileChooser>) = 0;
+    virtual void runOpenPanel(LocalFrame*, PassRefPtr<FileChooser>) = 0;
 
     // Asychronous request to enumerate all files in a directory chosen by the user.
     virtual void enumerateChosenDirectory(FileChooser*) = 0;
 
-    // Notification that the given form element has changed. This function
-    // will be called frequently, so handling should be very fast.
-    virtual void formStateDidChange(const Node*) = 0;
-
     // Allows ports to customize the type of graphics layers created by this page.
     virtual GraphicsLayerFactory* graphicsLayerFactory() const { return 0; }
 
     // Pass 0 as the GraphicsLayer to detatch the root layer.
-    virtual void attachRootGraphicsLayer(Frame*, GraphicsLayer*) = 0;
+    virtual void attachRootGraphicsLayer(GraphicsLayer*) = 0;
 
     enum CompositingTrigger {
         ThreeDTransformTrigger = 1 << 0,
@@ -217,7 +216,7 @@
 
     // Checks if there is an opened popup, called by RenderMenuList::showPopup().
     virtual bool hasOpenedPopup() const = 0;
-    virtual PassRefPtr<PopupMenu> createPopupMenu(Frame&, PopupMenuClient*) const = 0;
+    virtual PassRefPtr<PopupMenu> createPopupMenu(LocalFrame&, PopupMenuClient*) const = 0;
     // For testing.
     virtual void setPagePopupDriver(PagePopupDriver*) = 0;
     virtual void resetPagePopupDriver() = 0;
@@ -249,7 +248,10 @@
     virtual bool isChromeClientImpl() const { return false; }
 
     virtual void didAssociateFormControls(const Vector<RefPtr<Element> >&) { };
+    // FIXME: This function is to be removed once both chromium and blink changes
+    // for BUG332557 are in.
     virtual void didChangeValueInTextField(HTMLInputElement&) { }
+    virtual void didChangeValueInTextField(HTMLFormControlElement&) { }
     virtual void didEndEditingOnTextField(HTMLInputElement&) { }
     virtual void handleKeyboardEventOnTextField(HTMLInputElement&, KeyboardEvent&) { }
 
diff --git a/Source/core/page/ContextMenuController.cpp b/Source/core/page/ContextMenuController.cpp
index cf5b8ba..cd8b65b 100644
--- a/Source/core/page/ContextMenuController.cpp
+++ b/Source/core/page/ContextMenuController.cpp
@@ -31,10 +31,10 @@
 #include "core/events/Event.h"
 #include "core/events/MouseEvent.h"
 #include "core/dom/Node.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/ContextMenuClient.h"
 #include "core/page/ContextMenuProvider.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "platform/ContextMenu.h"
 #include "platform/ContextMenuItem.h"
 
@@ -60,9 +60,9 @@
     m_contextMenu.clear();
     if (m_menuProvider)
         m_menuProvider->contextMenuCleared();
-    m_menuProvider = 0;
-    m_hitTestResult = HitTestResult();
+    m_menuProvider = nullptr;
     m_client->clearContextMenu();
+    m_hitTestResult = HitTestResult();
 }
 
 void ContextMenuController::documentDetached(Document* document)
@@ -107,7 +107,7 @@
     MouseEvent* mouseEvent = toMouseEvent(event);
     HitTestResult result(mouseEvent->absoluteLocation());
 
-    if (Frame* frame = event->target()->toNode()->document().frame())
+    if (LocalFrame* frame = event->target()->toNode()->document().frame())
         result = frame->eventHandler().hitTestResultAtPoint(mouseEvent->absoluteLocation(), HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
 
     if (!result.innerNonSharedNode())
diff --git a/Source/core/page/CreateWindow.cpp b/Source/core/page/CreateWindow.cpp
index 2b6b5b8..9c2adf3 100644
--- a/Source/core/page/CreateWindow.cpp
+++ b/Source/core/page/CreateWindow.cpp
@@ -28,8 +28,8 @@
 #include "core/page/CreateWindow.h"
 
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/page/Chrome.h"
@@ -44,12 +44,12 @@
 
 namespace WebCore {
 
-static Frame* createWindow(Frame* openerFrame, Frame* lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, bool& created)
+static LocalFrame* createWindow(LocalFrame& openerFrame, LocalFrame& lookupFrame, const FrameLoadRequest& request, const WindowFeatures& features, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer, bool& created)
 {
     ASSERT(!features.dialog || request.frameName().isEmpty());
 
     if (!request.frameName().isEmpty() && request.frameName() != "_blank" && policy == NavigationPolicyIgnore) {
-        if (Frame* frame = lookupFrame->loader().findFrameForNavigation(request.frameName(), openerFrame->document())) {
+        if (LocalFrame* frame = lookupFrame.loader().findFrameForNavigation(request.frameName(), openerFrame.document())) {
             if (request.frameName() != "_self")
                 frame->page()->focusController().setFocusedFrame(frame);
             created = false;
@@ -58,32 +58,33 @@
     }
 
     // Sandboxed frames cannot open new auxiliary browsing contexts.
-    if (openerFrame->document()->isSandboxed(SandboxPopups)) {
+    if (openerFrame.document()->isSandboxed(SandboxPopups)) {
         // FIXME: This message should be moved off the console once a solution to https://bugs.webkit.org/show_bug.cgi?id=103274 exists.
-        openerFrame->document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
+        openerFrame.document()->addConsoleMessage(SecurityMessageSource, ErrorMessageLevel, "Blocked opening '" + request.resourceRequest().url().elidedString() + "' in a new window because the request was made in a sandboxed frame whose 'allow-popups' permission is not set.");
         return 0;
     }
 
-    if (openerFrame->settings() && !openerFrame->settings()->supportsMultipleWindows()) {
+    if (openerFrame.settings() && !openerFrame.settings()->supportsMultipleWindows()) {
         created = false;
-        return openerFrame->tree().top();
+        return openerFrame.tree().top();
     }
 
-    Page* oldPage = openerFrame->page();
+    Page* oldPage = openerFrame.page();
     if (!oldPage)
         return 0;
 
-    Page* page = oldPage->chrome().client().createWindow(openerFrame, request, features, policy, shouldSendReferrer);
+    Page* page = oldPage->chrome().client().createWindow(&openerFrame, request, features, policy, shouldSendReferrer);
     if (!page)
         return 0;
     FrameHost* host = &page->frameHost();
 
-    Frame* frame = page->mainFrame();
+    ASSERT(page->mainFrame());
+    LocalFrame& frame = *page->mainFrame();
 
-    frame->loader().forceSandboxFlags(openerFrame->document()->sandboxFlags());
+    frame.loader().forceSandboxFlags(openerFrame.document()->sandboxFlags());
 
     if (request.frameName() != "_blank")
-        frame->tree().setName(request.frameName());
+        frame.tree().setName(request.frameName());
 
     host->chrome().setWindowFeatures(features);
 
@@ -110,59 +111,60 @@
     host->chrome().show(policy);
 
     created = true;
-    return frame;
+    return &frame;
 }
 
-Frame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures,
-    DOMWindow* activeWindow, Frame* firstFrame, Frame* openerFrame, DOMWindow::PrepareDialogFunction function, void* functionContext)
+LocalFrame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures& windowFeatures,
+    DOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame, DOMWindow::PrepareDialogFunction function, void* functionContext)
 {
-    Frame* activeFrame = activeWindow->frame();
+    LocalFrame* activeFrame = callingWindow.frame();
+    ASSERT(activeFrame);
 
-    KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString()) : firstFrame->document()->completeURL(urlString);
+    KURL completedURL = urlString.isEmpty() ? KURL(ParsedURLString, emptyString()) : firstFrame.document()->completeURL(urlString);
     if (!completedURL.isEmpty() && !completedURL.isValid()) {
         // Don't expose client code to invalid URLs.
-        activeWindow->printErrorMessage("Unable to open a window with invalid URL '" + completedURL.string() + "'.\n");
+        callingWindow.printErrorMessage("Unable to open a window with invalid URL '" + completedURL.string() + "'.\n");
         return 0;
     }
 
     // For whatever reason, Firefox uses the first frame to determine the outgoingReferrer. We replicate that behavior here.
-    Referrer referrer(SecurityPolicy::generateReferrerHeader(firstFrame->document()->referrerPolicy(), completedURL, firstFrame->document()->outgoingReferrer()), firstFrame->document()->referrerPolicy());
+    Referrer referrer(SecurityPolicy::generateReferrerHeader(firstFrame.document()->referrerPolicy(), completedURL, firstFrame.document()->outgoingReferrer()), firstFrame.document()->referrerPolicy());
 
     ResourceRequest request(completedURL, referrer);
-    FrameLoader::addHTTPOriginIfNeeded(request, AtomicString(firstFrame->document()->outgoingOrigin()));
-    FrameLoadRequest frameRequest(activeWindow->document(), request, frameName);
+    FrameLoader::addHTTPOriginIfNeeded(request, AtomicString(firstFrame.document()->outgoingOrigin()));
+    FrameLoadRequest frameRequest(callingWindow.document(), request, frameName);
 
     // We pass the opener frame for the lookupFrame in case the active frame is different from
     // the opener frame, and the name references a frame relative to the opener frame.
     bool created;
-    Frame* newFrame = createWindow(activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, MaybeSendReferrer, created);
+    LocalFrame* newFrame = createWindow(*activeFrame, openerFrame, frameRequest, windowFeatures, NavigationPolicyIgnore, MaybeSendReferrer, created);
     if (!newFrame)
         return 0;
 
-    newFrame->loader().setOpener(openerFrame);
+    newFrame->loader().setOpener(&openerFrame);
     newFrame->page()->setOpenedByDOM();
 
-    if (newFrame->domWindow()->isInsecureScriptAccess(activeWindow, completedURL))
+    if (newFrame->domWindow()->isInsecureScriptAccess(callingWindow, completedURL))
         return newFrame;
 
     if (function)
         function(newFrame->domWindow(), functionContext);
 
     if (created) {
-        FrameLoadRequest request(activeWindow->document(), ResourceRequest(completedURL, referrer));
+        FrameLoadRequest request(callingWindow.document(), ResourceRequest(completedURL, referrer));
         newFrame->loader().load(request);
     } else if (!urlString.isEmpty()) {
-        newFrame->navigationScheduler().scheduleLocationChange(activeWindow->document(), completedURL.string(), referrer, false);
+        newFrame->navigationScheduler().scheduleLocationChange(callingWindow.document(), completedURL.string(), referrer, false);
     }
     return newFrame;
 }
 
-void createWindowForRequest(const FrameLoadRequest& request, Frame* openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer)
+void createWindowForRequest(const FrameLoadRequest& request, LocalFrame& openerFrame, NavigationPolicy policy, ShouldSendReferrer shouldSendReferrer)
 {
-    if (openerFrame->document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
+    if (openerFrame.document()->pageDismissalEventBeingDispatched() != Document::NoDismissal)
         return;
 
-    if (openerFrame->document() && openerFrame->document()->isSandboxed(SandboxPopups))
+    if (openerFrame.document() && openerFrame.document()->isSandboxed(SandboxPopups))
         return;
 
     if (!DOMWindow::allowPopUp(openerFrame))
@@ -173,13 +175,13 @@
 
     WindowFeatures features;
     bool created;
-    Frame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSendReferrer, created);
+    LocalFrame* newFrame = createWindow(openerFrame, openerFrame, request, features, policy, shouldSendReferrer, created);
     if (!newFrame)
         return;
     newFrame->page()->setOpenedByDOM();
     if (shouldSendReferrer == MaybeSendReferrer) {
-        newFrame->loader().setOpener(openerFrame);
-        newFrame->document()->setReferrerPolicy(openerFrame->document()->referrerPolicy());
+        newFrame->loader().setOpener(&openerFrame);
+        newFrame->document()->setReferrerPolicy(openerFrame.document()->referrerPolicy());
     }
     FrameLoadRequest newRequest(0, request.resourceRequest());
     newRequest.setFormState(request.formState());
diff --git a/Source/core/page/CreateWindow.h b/Source/core/page/CreateWindow.h
index 1c2f353..50f5f45 100644
--- a/Source/core/page/CreateWindow.h
+++ b/Source/core/page/CreateWindow.h
@@ -33,14 +33,14 @@
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
-class Frame;
+class LocalFrame;
 struct FrameLoadRequest;
 struct WindowFeatures;
 
-Frame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&,
-    DOMWindow* activeWindow, Frame* firstFrame, Frame* openerFrame, DOMWindow::PrepareDialogFunction = 0, void* functionContext = 0);
+LocalFrame* createWindow(const String& urlString, const AtomicString& frameName, const WindowFeatures&,
+    DOMWindow& callingWindow, LocalFrame& firstFrame, LocalFrame& openerFrame, DOMWindow::PrepareDialogFunction = 0, void* functionContext = 0);
 
-void createWindowForRequest(const FrameLoadRequest&, Frame* openerFrame, NavigationPolicy, ShouldSendReferrer);
+void createWindowForRequest(const FrameLoadRequest&, LocalFrame& openerFrame, NavigationPolicy, ShouldSendReferrer);
 
 } // namespace WebCore
 
diff --git a/Source/core/page/DOMSelection.cpp b/Source/core/page/DOMSelection.cpp
index fb95fef..99c29c2 100644
--- a/Source/core/page/DOMSelection.cpp
+++ b/Source/core/page/DOMSelection.cpp
@@ -31,6 +31,7 @@
 #include "config.h"
 #include "core/page/DOMSelection.h"
 
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/Document.h"
@@ -41,12 +42,12 @@
 #include "core/editing/FrameSelection.h"
 #include "core/editing/TextIterator.h"
 #include "core/editing/htmlediting.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-static Node* selectionShadowAncestor(Frame* frame)
+static Node* selectionShadowAncestor(LocalFrame* frame)
 {
     Node* node = frame->selection().selection().base().anchorNode();
     if (!node)
@@ -328,7 +329,7 @@
         return;
 
     if (!node) {
-        exceptionState.throwDOMException(TypeMismatchError, "The node provided is invalid.");
+        exceptionState.throwDOMException(TypeMismatchError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return;
     }
 
@@ -336,7 +337,7 @@
         exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is not a valid offset.");
         return;
     }
-    if (offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->childNodeCount())) {
+    if (offset > (node->offsetInCharacters() ? caretMaxOffset(node) : (int)node->countChildren())) {
         exceptionState.throwDOMException(IndexSizeError, String::number(offset) + " is larger than the given node's length.");
         return;
     }
@@ -351,11 +352,11 @@
 PassRefPtr<Range> DOMSelection::getRangeAt(int index, ExceptionState& exceptionState)
 {
     if (!m_frame)
-        return 0;
+        return nullptr;
 
     if (index < 0 || index >= rangeCount()) {
         exceptionState.throwDOMException(IndexSizeError, String::number(index) + " is not a valid index.");
-        return 0;
+        return nullptr;
     }
 
     // If you're hitting this, you've added broken multi-range selection support
@@ -368,8 +369,7 @@
         return Range::create(shadowAncestor->document(), container, offset, container, offset);
     }
 
-    const VisibleSelection& selection = m_frame->selection().selection();
-    return selection.firstRange();
+    return m_frame->selection().firstRange();
 }
 
 void DOMSelection::removeAllRanges()
@@ -379,42 +379,61 @@
     m_frame->selection().clear();
 }
 
-void DOMSelection::addRange(Range* r)
+void DOMSelection::addRange(Range* newRange)
 {
     if (!m_frame)
         return;
-    if (!r)
+
+    // FIXME: Should we throw DOMException for error cases below?
+    if (!newRange) {
+        addConsoleError("The given range is null.");
         return;
+    }
+
+    if (!newRange->startContainer()) {
+        addConsoleError("The given range has no container. Perhaps 'detach()' has been invoked on it?");
+        return;
+    }
 
     FrameSelection& selection = m_frame->selection();
 
     if (selection.isNone()) {
-        selection.setSelection(VisibleSelection(r));
+        selection.setSelectedRange(newRange, VP_DEFAULT_AFFINITY);
         return;
     }
 
-    RefPtr<Range> range = selection.selection().toNormalizedRange();
-    if (r->compareBoundaryPoints(Range::START_TO_START, range.get(), IGNORE_EXCEPTION) == -1) {
-        // We don't support discontiguous selection. We don't do anything if r and range don't intersect.
-        if (r->compareBoundaryPoints(Range::START_TO_END, range.get(), IGNORE_EXCEPTION) > -1) {
-            if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1) {
-                // The original range and r intersect.
-                selection.setSelection(VisibleSelection(r->startPosition(), range->endPosition(), DOWNSTREAM));
+    RefPtr<Range> originalRange = selection.selection().toNormalizedRange();
+
+    if (originalRange->startContainer()->document() != newRange->startContainer()->document()) {
+        addConsoleError("The given range does not belong to the current selection's document.");
+        return;
+    }
+    if (originalRange->startContainer()->treeScope() != newRange->startContainer()->treeScope()) {
+        addConsoleError("The given range and the current selection belong to two different document fragments.");
+        return;
+    }
+
+    // FIXME: Emit a console error if the combined ranges would form a discontiguous selection.
+    if (newRange->compareBoundaryPoints(Range::START_TO_START, originalRange.get(), ASSERT_NO_EXCEPTION) == -1) {
+        // We don't support discontiguous selection. We don't do anything if newRange and originalRange don't intersect.
+        if (newRange->compareBoundaryPoints(Range::START_TO_END, originalRange.get(), ASSERT_NO_EXCEPTION) > -1) {
+            if (newRange->compareBoundaryPoints(Range::END_TO_END, originalRange.get(), ASSERT_NO_EXCEPTION) == -1) {
+                // The original originalRange and newRange intersect.
+                selection.setSelection(VisibleSelection(newRange->startPosition(), originalRange->endPosition(), DOWNSTREAM));
             } else {
-                // r contains the original range.
-                selection.setSelection(VisibleSelection(r));
+                // newRange contains the original originalRange.
+                selection.setSelection(VisibleSelection(newRange));
             }
         }
     } else {
-        // We don't support discontiguous selection. We don't do anything if r and range don't intersect.
-        TrackExceptionState exceptionState;
-        if (r->compareBoundaryPoints(Range::END_TO_START, range.get(), exceptionState) < 1 && !exceptionState.hadException()) {
-            if (r->compareBoundaryPoints(Range::END_TO_END, range.get(), IGNORE_EXCEPTION) == -1) {
-                // The original range contains r.
-                selection.setSelection(VisibleSelection(range.get()));
+        // We don't support discontiguous selection. We don't do anything if newRange and originalRange don't intersect.
+        if (newRange->compareBoundaryPoints(Range::END_TO_START, originalRange.get(), ASSERT_NO_EXCEPTION) < 1) {
+            if (newRange->compareBoundaryPoints(Range::END_TO_END, originalRange.get(), ASSERT_NO_EXCEPTION) == -1) {
+                // The original range contains newRange.
+                selection.setSelection(VisibleSelection(originalRange.get()));
             } else {
                 // The original range and r intersect.
-                selection.setSelection(VisibleSelection(range->startPosition(), r->endPosition(), DOWNSTREAM));
+                selection.setSelection(VisibleSelection(originalRange->startPosition(), newRange->endPosition(), DOWNSTREAM));
             }
         }
     }
@@ -481,7 +500,7 @@
         return;
 
     // This doesn't (and shouldn't) select text node characters.
-    setBaseAndExtent(n, 0, n, n->childNodeCount(), exceptionState);
+    setBaseAndExtent(n, 0, n, n->countChildren(), exceptionState);
 }
 
 String DOMSelection::toString()
@@ -535,4 +554,10 @@
     return node->document() == m_frame->document();
 }
 
+void DOMSelection::addConsoleError(const String& message)
+{
+    if (m_treeScope)
+        m_treeScope->document().addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
+}
+
 } // namespace WebCore
diff --git a/Source/core/page/DOMSelection.h b/Source/core/page/DOMSelection.h
index 693349b..80919a8 100644
--- a/Source/core/page/DOMSelection.h
+++ b/Source/core/page/DOMSelection.h
@@ -33,6 +33,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/frame/DOMWindowProperty.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -40,16 +41,19 @@
 namespace WebCore {
 
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class Node;
 class Position;
 class Range;
 class TreeScope;
 class VisibleSelection;
 
-class DOMSelection FINAL : public RefCounted<DOMSelection>, public ScriptWrappable, public DOMWindowProperty {
+class DOMSelection FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMSelection>, public ScriptWrappable, public DOMWindowProperty {
 public:
-    static PassRefPtr<DOMSelection> create(const TreeScope* treeScope) { return adoptRef(new DOMSelection(treeScope)); }
+    static PassRefPtrWillBeRawPtr<DOMSelection> create(const TreeScope* treeScope)
+    {
+        return adoptRefWillBeNoop(new DOMSelection(treeScope));
+    }
 
     void clearTreeScope();
 
@@ -91,9 +95,9 @@
     // Microsoft Selection Object API
     void empty();
 
-private:
-    const TreeScope* m_treeScope;
+    void trace(Visitor*) { }
 
+private:
     explicit DOMSelection(const TreeScope*);
 
     // Convenience method for accessors, does not check m_frame present.
@@ -103,6 +107,10 @@
     int shadowAdjustedOffset(const Position&) const;
 
     bool isValidForPosition(Node*) const;
+
+    void addConsoleError(const String& message);
+
+    const TreeScope* m_treeScope;
 };
 
 } // namespace WebCore
diff --git a/Source/core/page/DOMWindowPagePopup.cpp b/Source/core/page/DOMWindowPagePopup.cpp
index 348c589..beea8d9 100644
--- a/Source/core/page/DOMWindowPagePopup.cpp
+++ b/Source/core/page/DOMWindowPagePopup.cpp
@@ -52,24 +52,22 @@
     return "DOMWindowPagePopup";
 }
 
-PagePopupController* DOMWindowPagePopup::pagePopupController(DOMWindow* window)
+PagePopupController* DOMWindowPagePopup::pagePopupController(DOMWindow& window)
 {
-    DOMWindowPagePopup* supplement = static_cast<DOMWindowPagePopup*>(from(window, supplementName()));
+    DOMWindowPagePopup* supplement = static_cast<DOMWindowPagePopup*>(from(&window, supplementName()));
     ASSERT(supplement);
     return supplement->m_controller.get();
 }
 
-void DOMWindowPagePopup::install(DOMWindow* window, PagePopupClient* popupClient)
+void DOMWindowPagePopup::install(DOMWindow& window, PagePopupClient* popupClient)
 {
-    ASSERT(window);
     ASSERT(popupClient);
     provideTo(window, supplementName(), adoptPtr(new DOMWindowPagePopup(popupClient)));
 }
 
-void DOMWindowPagePopup::uninstall(DOMWindow* window)
+void DOMWindowPagePopup::uninstall(DOMWindow& window)
 {
-    ASSERT(window);
-    window->removeSupplement(supplementName());
+    window.removeSupplement(supplementName());
 }
 
 }
diff --git a/Source/core/page/DOMWindowPagePopup.h b/Source/core/page/DOMWindowPagePopup.h
index 0a2e8d8..9209eb3 100644
--- a/Source/core/page/DOMWindowPagePopup.h
+++ b/Source/core/page/DOMWindowPagePopup.h
@@ -31,6 +31,7 @@
 #ifndef DOMWindowPagePopup_h
 #define DOMWindowPagePopup_h
 
+#include "heap/Handle.h"
 #include "platform/Supplementable.h"
 
 namespace WebCore {
@@ -41,16 +42,16 @@
 
 class DOMWindowPagePopup FINAL : public Supplement<DOMWindow> {
 public:
-    static PagePopupController* pagePopupController(DOMWindow*);
-    static void install(DOMWindow*, PagePopupClient*);
-    static void uninstall(DOMWindow*);
+    static PagePopupController* pagePopupController(DOMWindow&);
+    static void install(DOMWindow&, PagePopupClient*);
+    static void uninstall(DOMWindow&);
     virtual ~DOMWindowPagePopup();
 
 private:
     explicit DOMWindowPagePopup(PagePopupClient*);
     static const char* supplementName();
 
-    RefPtr<PagePopupController> m_controller;
+    RefPtrWillBePersistent<PagePopupController> m_controller;
 };
 
 }
diff --git a/Source/core/page/DragClient.h b/Source/core/page/DragClient.h
index dcc2e41..c1e2e1a 100644
--- a/Source/core/page/DragClient.h
+++ b/Source/core/page/DragClient.h
@@ -34,13 +34,13 @@
 class Clipboard;
 class DragData;
 class DragImage;
-class Frame;
+class LocalFrame;
 class IntPoint;
 
 class DragClient {
 public:
     virtual DragDestinationAction actionMaskForDrag(DragData*) = 0;
-    virtual void startDrag(DragImage*, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, Frame*, bool linkDrag = false) = 0;
+    virtual void startDrag(DragImage*, const IntPoint& dragImageOrigin, const IntPoint& eventPos, Clipboard*, LocalFrame*, bool linkDrag = false) = 0;
     virtual ~DragClient() { }
 };
 
diff --git a/Source/core/page/DragController.cpp b/Source/core/page/DragController.cpp
index fe17aef..a254211 100644
--- a/Source/core/page/DragController.cpp
+++ b/Source/core/page/DragController.cpp
@@ -47,8 +47,8 @@
 #include "core/events/TextEvent.h"
 #include "core/fetch/ImageResource.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/HTMLInputElement.h"
@@ -121,7 +121,7 @@
                               metaKey, currentTime());
 }
 
-static PassRefPtr<Clipboard> createDraggingClipboard(ClipboardAccessPolicy policy, DragData* dragData)
+static PassRefPtrWillBeRawPtr<Clipboard> createDraggingClipboard(ClipboardAccessPolicy policy, DragData* dragData)
 {
     return Clipboard::create(Clipboard::DragAndDrop, policy, dragData->platformData());
 }
@@ -129,9 +129,9 @@
 DragController::DragController(Page* page, DragClient* client)
     : m_page(page)
     , m_client(client)
-    , m_documentUnderMouse(0)
-    , m_dragInitiator(0)
-    , m_fileInputElementUnderMouse(0)
+    , m_documentUnderMouse(nullptr)
+    , m_dragInitiator(nullptr)
+    , m_fileInputElementUnderMouse(nullptr)
     , m_documentIsHandlingDrag(false)
     , m_dragDestinationAction(DragDestinationActionNone)
     , m_didInitiateDrag(false)
@@ -148,7 +148,7 @@
     return adoptPtr(new DragController(page, client));
 }
 
-static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragData, Frame* frame, RefPtr<Range> context,
+static PassRefPtr<DocumentFragment> documentFragmentFromDragData(DragData* dragData, LocalFrame* frame, RefPtr<Range> context,
                                           bool allowPlainText, bool& chosePlainText)
 {
     ASSERT(dragData);
@@ -185,7 +185,7 @@
         return createFragmentFromText(context.get(), dragData->asPlainText()).get();
     }
 
-    return 0;
+    return nullptr;
 }
 
 bool DragController::dragIsMove(FrameSelection& selection, DragData* dragData)
@@ -201,7 +201,7 @@
 
 void DragController::dragEnded()
 {
-    m_dragInitiator = 0;
+    m_dragInitiator = nullptr;
     m_didInitiateDrag = false;
     m_page->dragCaretController().clear();
 }
@@ -214,11 +214,11 @@
 void DragController::dragExited(DragData* dragData)
 {
     ASSERT(dragData);
-    Frame* mainFrame = m_page->mainFrame();
+    LocalFrame* mainFrame = m_page->mainFrame();
 
     if (RefPtr<FrameView> v = mainFrame->view()) {
         ClipboardAccessPolicy policy = (!m_documentUnderMouse || m_documentUnderMouse->securityOrigin()->isLocal()) ? ClipboardReadable : ClipboardTypesReadable;
-        RefPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
+        RefPtrWillBeRawPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
         clipboard->setSourceOperation(dragData->draggingSourceOperationMask());
         mainFrame->eventHandler().cancelDragAndDrop(createMouseEvent(dragData), clipboard.get());
         clipboard->setAccessPolicy(ClipboardNumb);    // invalidate clipboard here for security
@@ -226,7 +226,7 @@
     mouseMovedIntoDocument(0);
     if (m_fileInputElementUnderMouse)
         m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
-    m_fileInputElementUnderMouse = 0;
+    m_fileInputElementUnderMouse = nullptr;
 }
 
 DragSession DragController::dragUpdated(DragData* dragData)
@@ -239,32 +239,33 @@
     ASSERT(dragData);
     m_documentUnderMouse = m_page->mainFrame()->documentAtPoint(dragData->clientPosition());
     if ((m_dragDestinationAction & DragDestinationActionDHTML) && m_documentIsHandlingDrag) {
-        RefPtr<Frame> mainFrame = m_page->mainFrame();
+        RefPtr<LocalFrame> mainFrame = m_page->mainFrame();
         bool preventedDefault = false;
         if (mainFrame->view()) {
             // Sending an event can result in the destruction of the view and part.
-            RefPtr<Clipboard> clipboard = createDraggingClipboard(ClipboardReadable, dragData);
+            RefPtrWillBeRawPtr<Clipboard> clipboard = createDraggingClipboard(ClipboardReadable, dragData);
             clipboard->setSourceOperation(dragData->draggingSourceOperationMask());
             preventedDefault = mainFrame->eventHandler().performDragAndDrop(createMouseEvent(dragData), clipboard.get());
             clipboard->setAccessPolicy(ClipboardNumb); // Invalidate clipboard here for security
         }
         if (preventedDefault) {
-            m_documentUnderMouse = 0;
+            m_documentUnderMouse = nullptr;
             return true;
         }
     }
 
     if ((m_dragDestinationAction & DragDestinationActionEdit) && concludeEditDrag(dragData)) {
-        m_documentUnderMouse = 0;
+        m_documentUnderMouse = nullptr;
         return true;
     }
 
-    m_documentUnderMouse = 0;
+    m_documentUnderMouse = nullptr;
 
     if (operationForLoad(dragData) == DragOperationNone)
         return false;
 
-    m_page->mainFrame()->loader().load(FrameLoadRequest(0, ResourceRequest(dragData->asURL())));
+    if (m_page->settings().navigateOnDragDrop())
+        m_page->mainFrame()->loader().load(FrameLoadRequest(0, ResourceRequest(dragData->asURL())));
     return true;
 }
 
@@ -302,7 +303,7 @@
 {
     ASSERT(node);
     for (; node; node = node->shadowHost()) {
-        if (node->hasTagName(HTMLNames::inputTag) && toHTMLInputElement(node)->isFileUpload())
+        if (isHTMLInputElement(*node) && toHTMLInputElement(node)->isFileUpload())
             return toHTMLInputElement(node);
     }
     return 0;
@@ -311,7 +312,7 @@
 // This can return null if an empty document is loaded.
 static Element* elementUnderMouse(Document* documentUnderMouse, const IntPoint& p)
 {
-    Frame* frame = documentUnderMouse->frame();
+    LocalFrame* frame = documentUnderMouse->frame();
     float zoomFactor = frame ? frame->pageZoomFactor() : 1;
     LayoutPoint point = roundedLayoutPoint(FloatPoint(p.x() * zoomFactor, p.y() * zoomFactor));
 
@@ -377,7 +378,7 @@
         if (!m_fileInputElementUnderMouse)
             m_page->dragCaretController().setCaretPosition(m_documentUnderMouse->frame()->visiblePositionForPoint(point));
 
-        Frame* innerFrame = element->document().frame();
+        LocalFrame* innerFrame = element->document().frame();
         dragSession.operation = dragIsMove(innerFrame->selection(), dragData) ? DragOperationMove : DragOperationCopy;
         dragSession.mouseIsOverFileInput = m_fileInputElementUnderMouse;
         dragSession.numberOfItemsToBeAccepted = 0;
@@ -409,7 +410,7 @@
     m_page->dragCaretController().clear();
     if (m_fileInputElementUnderMouse)
         m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
-    m_fileInputElementUnderMouse = 0;
+    m_fileInputElementUnderMouse = nullptr;
     return false;
 }
 
@@ -423,22 +424,22 @@
     return dragOperation(dragData);
 }
 
-static bool setSelectionToDragCaret(Frame* frame, VisibleSelection& dragCaret, RefPtr<Range>& range, const IntPoint& point)
+static bool setSelectionToDragCaret(LocalFrame* frame, VisibleSelection& dragCaret, RefPtr<Range>& range, const IntPoint& point)
 {
     frame->selection().setSelection(dragCaret);
     if (frame->selection().isNone()) {
-        dragCaret = frame->visiblePositionForPoint(point);
+        dragCaret = VisibleSelection(frame->visiblePositionForPoint(point));
         frame->selection().setSelection(dragCaret);
         range = dragCaret.toNormalizedRange();
     }
     return !frame->selection().isNone() && frame->selection().isContentEditable();
 }
 
-bool DragController::dispatchTextInputEventFor(Frame* innerFrame, DragData* dragData)
+bool DragController::dispatchTextInputEventFor(LocalFrame* innerFrame, DragData* dragData)
 {
     ASSERT(m_page->dragCaretController().hasCaret());
     String text = m_page->dragCaretController().isContentRichlyEditable() ? "" : dragData->asPlainText();
-    Node* target = innerFrame->editor().findEventTargetFrom(m_page->dragCaretController().caretPosition());
+    Node* target = innerFrame->editor().findEventTargetFrom(VisibleSelection(m_page->dragCaretController().caretPosition()));
     return target->dispatchEvent(TextEvent::createForDrop(innerFrame->domWindow(), text), IGNORE_EXCEPTION);
 }
 
@@ -449,7 +450,7 @@
     RefPtr<HTMLInputElement> fileInput = m_fileInputElementUnderMouse;
     if (m_fileInputElementUnderMouse) {
         m_fileInputElementUnderMouse->setCanReceiveDroppedFiles(false);
-        m_fileInputElementUnderMouse = 0;
+        m_fileInputElementUnderMouse = nullptr;
     }
 
     if (!m_documentUnderMouse)
@@ -459,7 +460,7 @@
     Element* element = elementUnderMouse(m_documentUnderMouse.get(), point);
     if (!element)
         return false;
-    RefPtr<Frame> innerFrame = element->ownerDocument()->frame();
+    RefPtr<LocalFrame> innerFrame = element->ownerDocument()->frame();
     ASSERT(innerFrame);
 
     if (m_page->dragCaretController().hasCaret() && !dispatchTextInputEventFor(innerFrame.get(), dragData))
@@ -480,7 +481,7 @@
         return false;
     }
 
-    VisibleSelection dragCaret = m_page->dragCaretController().caretPosition();
+    VisibleSelection dragCaret(m_page->dragCaretController().caretPosition());
     m_page->dragCaretController().clear();
     RefPtr<Range> range = dragCaret.toNormalizedRange();
     RefPtr<Element> rootEditableElement = innerFrame->selection().rootEditableElement();
@@ -526,7 +527,7 @@
     }
 
     if (rootEditableElement) {
-        if (Frame* frame = rootEditableElement->document().frame())
+        if (LocalFrame* frame = rootEditableElement->document().frame())
             frame->eventHandler().updateDragStateAfterEditDragIfNeeded(rootEditableElement.get());
     }
 
@@ -589,13 +590,13 @@
 {
     ASSERT(dragData);
     ASSERT(m_documentUnderMouse);
-    RefPtr<Frame> mainFrame = m_page->mainFrame();
+    RefPtr<LocalFrame> mainFrame = m_page->mainFrame();
     RefPtr<FrameView> viewProtector = mainFrame->view();
     if (!viewProtector)
         return false;
 
     ClipboardAccessPolicy policy = m_documentUnderMouse->securityOrigin()->isLocal() ? ClipboardReadable : ClipboardTypesReadable;
-    RefPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
+    RefPtrWillBeRawPtr<Clipboard> clipboard = createDraggingClipboard(policy, dragData);
     DragOperation srcOpMask = dragData->draggingSourceOperationMask();
     clipboard->setSourceOperation(srcOpMask);
 
@@ -617,7 +618,7 @@
     return true;
 }
 
-Node* DragController::draggableNode(const Frame* src, Node* startNode, const IntPoint& dragOrigin, SelectionDragPolicy selectionDragPolicy, DragSourceAction& dragType) const
+Node* DragController::draggableNode(const LocalFrame* src, Node* startNode, const IntPoint& dragOrigin, SelectionDragPolicy selectionDragPolicy, DragSourceAction& dragType) const
 {
     if (src->selection().contains(dragOrigin)) {
         dragType = DragSourceActionSelection;
@@ -654,7 +655,7 @@
                 return node;
             }
             // Other draggable elements are considered unselectable.
-            if (node->hasTagName(HTMLNames::aTag) && toHTMLAnchorElement(node)->isLiveLink()) {
+            if (isHTMLAnchorElement(*node) && toHTMLAnchorElement(node)->isLiveLink()) {
                 candidateDragType = DragSourceActionLink;
                 break;
             }
@@ -710,7 +711,7 @@
         cachedImage->image() : 0;
 }
 
-static void prepareClipboardForImageDrag(Frame* source, Clipboard* clipboard, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
+static void prepareClipboardForImageDrag(LocalFrame* source, Clipboard* clipboard, Element* node, const KURL& linkURL, const KURL& imageURL, const String& label)
 {
     if (node->isContentRichlyEditable()) {
         RefPtr<Range> range = source->document()->createRange();
@@ -720,7 +721,7 @@
     clipboard->declareAndWriteDragImage(node, !linkURL.isEmpty() ? linkURL : imageURL, label);
 }
 
-bool DragController::populateDragClipboard(Frame* src, const DragState& state, const IntPoint& dragOrigin)
+bool DragController::populateDragClipboard(LocalFrame* src, const DragState& state, const IntPoint& dragOrigin)
 {
     ASSERT(dragTypeIsValid(state.m_dragType));
     ASSERT(src);
@@ -778,7 +779,7 @@
     return IntPoint(dragOrigin.x() - dragImageOffset.x(), dragOrigin.y() + yOffset);
 }
 
-static IntPoint dragLocationForSelectionDrag(Frame* sourceFrame)
+static IntPoint dragLocationForSelectionDrag(LocalFrame* sourceFrame)
 {
     IntRect draggingRect = enclosingIntRect(sourceFrame->selection().bounds());
     int xpos = draggingRect.maxX();
@@ -840,7 +841,7 @@
     return dragImage.release();
 }
 
-bool DragController::startDrag(Frame* src, const DragState& state, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin)
+bool DragController::startDrag(LocalFrame* src, const DragState& state, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin)
 {
     ASSERT(dragTypeIsValid(state.m_dragType));
     ASSERT(src);
@@ -922,12 +923,12 @@
     return true;
 }
 
-void DragController::doSystemDrag(DragImage* image, const IntPoint& dragLocation, const IntPoint& eventPos, Clipboard* clipboard, Frame* frame, bool forLink)
+void DragController::doSystemDrag(DragImage* image, const IntPoint& dragLocation, const IntPoint& eventPos, Clipboard* clipboard, LocalFrame* frame, bool forLink)
 {
     m_didInitiateDrag = true;
     m_dragInitiator = frame->document();
     // Protect this frame and view, as a load may occur mid drag and attempt to unload this frame
-    RefPtr<Frame> frameProtector = m_page->mainFrame();
+    RefPtr<LocalFrame> frameProtector = m_page->mainFrame();
     RefPtr<FrameView> viewProtector = frameProtector->view();
     m_client->startDrag(image, viewProtector->rootViewToContents(frame->view()->contentsToRootView(dragLocation)),
         viewProtector->rootViewToContents(frame->view()->contentsToRootView(eventPos)), clipboard, frameProtector.get(), forLink);
@@ -948,13 +949,14 @@
     return dragData->containsURL() && !m_didInitiateDrag ? DragOperationCopy : DragOperationNone;
 }
 
-bool DragController::isCopyKeyDown(DragData*)
+bool DragController::isCopyKeyDown(DragData* dragData)
 {
-    // FIXME: This should not be OS specific.  Delegate to the embedder instead.
-#if OS(WIN)
-    return ::GetAsyncKeyState(VK_CONTROL);
+    int keyState = dragData->modifierKeyState();
+
+#if OS(MACOSX)
+    return keyState & PlatformEvent::AltKey;
 #else
-    return false;
+    return keyState & PlatformEvent::CtrlKey;
 #endif
 }
 
@@ -963,4 +965,3 @@
 }
 
 } // namespace WebCore
-
diff --git a/Source/core/page/DragController.h b/Source/core/page/DragController.h
index f109837..e2c9579 100644
--- a/Source/core/page/DragController.h
+++ b/Source/core/page/DragController.h
@@ -39,9 +39,9 @@
     class DragData;
     class DragImage;
     struct DragSession;
-    struct DragState;
+    class DragState;
     class Element;
-    class Frame;
+    class LocalFrame;
     class FrameSelection;
     class HTMLInputElement;
     class Image;
@@ -67,11 +67,11 @@
             ImmediateSelectionDragResolution,
             DelayedSelectionDragResolution,
         };
-        Node* draggableNode(const Frame*, Node*, const IntPoint&, SelectionDragPolicy, DragSourceAction&) const;
+        Node* draggableNode(const LocalFrame*, Node*, const IntPoint&, SelectionDragPolicy, DragSourceAction&) const;
         void dragEnded();
 
-        bool populateDragClipboard(Frame* src, const DragState&, const IntPoint& dragOrigin);
-        bool startDrag(Frame* src, const DragState&, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin);
+        bool populateDragClipboard(LocalFrame* src, const DragState&, const IntPoint& dragOrigin);
+        bool startDrag(LocalFrame* src, const DragState&, const PlatformMouseEvent& dragEvent, const IntPoint& dragOrigin);
 
         static const int DragIconRightInset;
         static const int DragIconBottomInset;
@@ -79,7 +79,7 @@
     private:
         DragController(Page*, DragClient*);
 
-        bool dispatchTextInputEventFor(Frame*, DragData*);
+        bool dispatchTextInputEventFor(LocalFrame*, DragData*);
         bool canProcessDrag(DragData*);
         bool concludeEditDrag(DragData*);
         DragSession dragEnteredOrUpdated(DragData*);
@@ -93,7 +93,7 @@
 
         void mouseMovedIntoDocument(Document*);
 
-        void doSystemDrag(DragImage*, const IntPoint& dragLocation, const IntPoint& dragOrigin, Clipboard*, Frame*, bool forLink);
+        void doSystemDrag(DragImage*, const IntPoint& dragLocation, const IntPoint& dragOrigin, Clipboard*, LocalFrame*, bool forLink);
         void cleanupAfterSystemDrag();
 
         Page* m_page;
diff --git a/Source/core/page/DragData.cpp b/Source/core/page/DragData.cpp
index 4e1a477..789c462 100644
--- a/Source/core/page/DragData.cpp
+++ b/Source/core/page/DragData.cpp
@@ -32,7 +32,7 @@
 #include "core/dom/DocumentFragment.h"
 #include "core/dom/Range.h"
 #include "core/editing/markup.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "modules/filesystem/DraggedIsolatedFileSystem.h"
 #include "platform/FileMetadata.h"
 #include "platform/clipboard/ClipboardMimeTypes.h"
@@ -132,7 +132,7 @@
         || containsFiles();
 }
 
-PassRefPtr<DocumentFragment> DragData::asFragment(Frame* frame, PassRefPtr<Range>, bool, bool&) const
+PassRefPtr<DocumentFragment> DragData::asFragment(LocalFrame* frame, PassRefPtr<Range>, bool, bool&) const
 {
     /*
      * Order is richest format first. On OSX this is:
@@ -158,7 +158,7 @@
             return fragment.release();
     }
 
-    return 0;
+    return nullptr;
 }
 
 String DragData::droppedFileSystemId() const
diff --git a/Source/core/page/DragData.h b/Source/core/page/DragData.h
index 83a11b0..6bfab8b 100644
--- a/Source/core/page/DragData.h
+++ b/Source/core/page/DragData.h
@@ -37,7 +37,7 @@
 
 class DataObject;
 class DocumentFragment;
-class Frame;
+class LocalFrame;
 class KURL;
 class Range;
 
@@ -67,7 +67,7 @@
     String asURL(FilenameConversionPolicy filenamePolicy = ConvertFilenames, String* title = 0) const;
     String asPlainText() const;
     void asFilenames(Vector<String>&) const;
-    PassRefPtr<DocumentFragment> asFragment(Frame*, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) const;
+    PassRefPtr<DocumentFragment> asFragment(LocalFrame*, PassRefPtr<Range> context, bool allowPlainText, bool& chosePlainText) const;
     bool canSmartReplace() const;
     bool containsFiles() const;
     unsigned numberOfFiles() const;
diff --git a/Source/core/page/DragState.h b/Source/core/page/DragState.h
index 6b86657..ef2900b 100644
--- a/Source/core/page/DragState.h
+++ b/Source/core/page/DragState.h
@@ -35,14 +35,18 @@
 class Clipboard;
 class Node;
 
-struct DragState {
+class DragState : public NoBaseWillBeGarbageCollectedFinalized<DragState> {
     WTF_MAKE_NONCOPYABLE(DragState);
-    WTF_MAKE_FAST_ALLOCATED;
 public:
     DragState() { }
     RefPtr<Node> m_dragSrc; // element that may be a drag source, for the current mouse gesture
     DragSourceAction m_dragType;
-    RefPtr<Clipboard> m_dragClipboard; // used on only the source side of dragging
+    RefPtrWillBeMember<Clipboard> m_dragClipboard; // used on only the source side of dragging
+
+    void trace(Visitor* visitor)
+    {
+        visitor->trace(m_dragClipboard);
+    }
 };
 
 } // namespace WebCore
diff --git a/Source/core/page/EditorClient.h b/Source/core/page/EditorClient.h
index f7664b6..7d7e4fd 100644
--- a/Source/core/page/EditorClient.h
+++ b/Source/core/page/EditorClient.h
@@ -33,7 +33,7 @@
 namespace WebCore {
 
 class Element;
-class Frame;
+class LocalFrame;
 class UndoStep;
 
 class EditorClient {
@@ -43,8 +43,8 @@
     virtual void respondToChangedContents() = 0;
     virtual void respondToChangedSelection(SelectionType) = 0;
 
-    virtual bool canCopyCut(Frame*, bool defaultValue) const = 0;
-    virtual bool canPaste(Frame*, bool defaultValue) const = 0;
+    virtual bool canCopyCut(LocalFrame*, bool defaultValue) const = 0;
+    virtual bool canPaste(LocalFrame*, bool defaultValue) const = 0;
 
     virtual void didExecuteCommand(String) = 0;
     virtual bool handleKeyboardEvent() = 0;
diff --git a/Source/core/page/EventHandler.cpp b/Source/core/page/EventHandler.cpp
index acc91dc..5a64465 100644
--- a/Source/core/page/EventHandler.cpp
+++ b/Source/core/page/EventHandler.cpp
@@ -53,6 +53,8 @@
 #include "core/events/TouchEvent.h"
 #include "core/events/WheelEvent.h"
 #include "core/fetch/ImageResource.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLDialogElement.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLFrameSetElement.h"
@@ -67,9 +69,7 @@
 #include "core/page/DragState.h"
 #include "core/page/EditorClient.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
 #include "core/page/FrameTree.h"
-#include "core/frame/FrameView.h"
 #include "core/inspector/InspectorController.h"
 #include "core/page/MouseEventWithHitTestResults.h"
 #include "core/page/Page.h"
@@ -88,6 +88,7 @@
 #include "core/svg/SVGDocument.h"
 #include "core/svg/SVGElementInstance.h"
 #include "core/svg/SVGUseElement.h"
+#include "heap/Handle.h"
 #include "platform/PlatformGestureEvent.h"
 #include "platform/PlatformKeyboardEvent.h"
 #include "platform/PlatformTouchEvent.h"
@@ -263,10 +264,10 @@
     Node* targetNode = mev.targetNode();
     if (!targetNode || !targetNode->parentNode())
         return true;
-    return targetNode->isShadowRoot() && toShadowRoot(targetNode)->host()->hasTagName(inputTag);
+    return targetNode->isShadowRoot() && isHTMLInputElement(*toShadowRoot(targetNode)->host());
 }
 
-EventHandler::EventHandler(Frame* frame)
+EventHandler::EventHandler(LocalFrame* frame)
     : m_frame(frame)
     , m_mousePressed(false)
     , m_capturesDragging(false)
@@ -289,7 +290,7 @@
     , m_widgetIsLatched(false)
     , m_originatingTouchPointTargetKey(0)
     , m_touchPressed(false)
-    , m_scrollGestureHandlingNode(0)
+    , m_scrollGestureHandlingNode(nullptr)
     , m_lastHitTestResultOverWidget(false)
     , m_maxMouseMovedDuration(0)
     , m_baseEventType(PlatformEvent::NoType)
@@ -308,8 +309,13 @@
 
 DragState& EventHandler::dragState()
 {
+#if ENABLE(OILPAN)
+    DEFINE_STATIC_LOCAL(Persistent<DragState>, state, (new DragState()));
+    return *state;
+#else
     DEFINE_STATIC_LOCAL(DragState, state, ());
     return state;
+#endif
 }
 
 void EventHandler::clear()
@@ -319,34 +325,34 @@
     m_fakeMouseMoveEventTimer.stop();
     m_activeIntervalTimer.stop();
     m_resizeScrollableArea = 0;
-    m_nodeUnderMouse = 0;
-    m_lastNodeUnderMouse = 0;
-    m_instanceUnderMouse = 0;
-    m_lastInstanceUnderMouse = 0;
-    m_lastMouseMoveEventSubframe = 0;
-    m_lastScrollbarUnderMouse = 0;
+    m_nodeUnderMouse = nullptr;
+    m_lastNodeUnderMouse = nullptr;
+    m_instanceUnderMouse = nullptr;
+    m_lastInstanceUnderMouse = nullptr;
+    m_lastMouseMoveEventSubframe = nullptr;
+    m_lastScrollbarUnderMouse = nullptr;
     m_clickCount = 0;
-    m_clickNode = 0;
-    m_frameSetBeingResized = 0;
-    m_dragTarget = 0;
+    m_clickNode = nullptr;
+    m_frameSetBeingResized = nullptr;
+    m_dragTarget = nullptr;
     m_shouldOnlyFireDragOverEvent = false;
     m_mousePositionIsUnknown = true;
     m_lastKnownMousePosition = IntPoint();
     m_lastKnownMouseGlobalPosition = IntPoint();
     m_lastMouseDownUserGestureToken.clear();
-    m_mousePressNode = 0;
+    m_mousePressNode = nullptr;
     m_mousePressed = false;
     m_capturesDragging = false;
-    m_capturingMouseEventsNode = 0;
-    m_latchedWheelEventNode = 0;
-    m_previousWheelScrolledNode = 0;
+    m_capturingMouseEventsNode = nullptr;
+    m_latchedWheelEventNode = nullptr;
+    m_previousWheelScrolledNode = nullptr;
     m_originatingTouchPointTargets.clear();
     m_originatingTouchPointDocument.clear();
     m_originatingTouchPointTargetKey = 0;
-    m_scrollGestureHandlingNode = 0;
+    m_scrollGestureHandlingNode = nullptr;
     m_lastHitTestResultOverWidget = false;
-    m_previousGestureScrolledNode = 0;
-    m_scrollbarHandlingScrollGesture = 0;
+    m_previousGestureScrolledNode = nullptr;
+    m_scrollbarHandlingScrollGesture = nullptr;
     m_maxMouseMovedDuration = 0;
     m_baseEventType = PlatformEvent::NoType;
     m_didStartDrag = false;
@@ -354,7 +360,7 @@
     m_mouseDownMayStartSelect = false;
     m_mouseDownMayStartDrag = false;
     m_lastShowPressTimestamp = 0;
-    m_lastDeferredTapElement = 0;
+    m_lastDeferredTapElement = nullptr;
 }
 
 void EventHandler::nodeWillBeRemoved(Node& nodeToBeRemoved)
@@ -366,7 +372,7 @@
     } else {
         // We don't dispatch click events if the mousedown node is removed
         // before a mouseup event. It is compatible with IE and Firefox.
-        m_clickNode = 0;
+        m_clickNode = nullptr;
     }
 }
 
@@ -446,7 +452,7 @@
         Position start = pos.deepEquivalent();
         Position end = pos.deepEquivalent();
         if (pos.isNotNull()) {
-            Vector<DocumentMarker*> markers = innerNode->document().markers()->markersInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
+            Vector<DocumentMarker*> markers = innerNode->document().markers().markersInRange(makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers());
             if (markers.size() == 1) {
                 start.moveToOffset(markers[0]->startOffset());
                 end.moveToOffset(markers[0]->endOffset());
@@ -567,7 +573,7 @@
     TextGranularity granularity = CharacterGranularity;
 
     if (extendSelection && newSelection.isCaretOrRange()) {
-        VisibleSelection selectionInUserSelectAll = expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(pos));
+        VisibleSelection selectionInUserSelectAll(expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(VisiblePosition(pos))));
         if (selectionInUserSelectAll.isRange()) {
             if (comparePositions(selectionInUserSelectAll.start(), newSelection.start()) < 0)
                 pos = selectionInUserSelectAll.start();
@@ -576,16 +582,18 @@
         }
 
         if (!m_frame->editor().behavior().shouldConsiderSelectionAsDirectional()) {
-            // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
-            // was created right-to-left
-            Position start = newSelection.start();
-            Position end = newSelection.end();
-            int distanceToStart = textDistance(start, pos);
-            int distanceToEnd = textDistance(pos, end);
-            if (distanceToStart <= distanceToEnd)
-                newSelection = VisibleSelection(end, pos);
-            else
-                newSelection = VisibleSelection(start, pos);
+            if (pos.isNotNull()) {
+                // See <rdar://problem/3668157> REGRESSION (Mail): shift-click deselects when selection
+                // was created right-to-left
+                Position start = newSelection.start();
+                Position end = newSelection.end();
+                int distanceToStart = textDistance(start, pos);
+                int distanceToEnd = textDistance(pos, end);
+                if (distanceToStart <= distanceToEnd)
+                    newSelection = VisibleSelection(end, pos);
+                else
+                    newSelection = VisibleSelection(start, pos);
+            }
         } else
             newSelection.setExtent(pos);
 
@@ -593,8 +601,9 @@
             granularity = m_frame->selection().granularity();
             newSelection.expandUsingGranularity(m_frame->selection().granularity());
         }
-    } else
-        newSelection = expandSelectionToRespectUserSelectAll(innerNode, visiblePos);
+    } else {
+        newSelection = expandSelectionToRespectUserSelectAll(innerNode, VisibleSelection(visiblePos));
+    }
 
     bool handled = updateSelectionForMouseDownDispatchingSelectStart(innerNode, newSelection, granularity);
     return handled;
@@ -614,7 +623,7 @@
 bool EventHandler::handleMousePressEvent(const MouseEventWithHitTestResults& event)
 {
     // Reset drag state.
-    dragState().m_dragSrc = 0;
+    dragState().m_dragSrc = nullptr;
 
     cancelFakeMouseMoveEvent();
 
@@ -880,7 +889,7 @@
     // We always send hitTestResultAtPoint to the main frame if we have one,
     // otherwise we might hit areas that are obscured by higher frames.
     if (Page* page = m_frame->page()) {
-        Frame* mainFrame = page->mainFrame();
+        LocalFrame* mainFrame = page->mainFrame();
         if (m_frame != mainFrame) {
             FrameView* frameView = m_frame->view();
             FrameView* mainView = mainFrame->view();
@@ -971,7 +980,7 @@
     m_frame->document()->updateLayoutIgnorePendingStylesheets();
     if (scroll(direction, granularity, startingNode))
         return true;
-    Frame* frame = m_frame;
+    LocalFrame* frame = m_frame;
     FrameView* view = frame->view();
     if (view && view->scroll(direction, granularity))
         return true;
@@ -986,7 +995,7 @@
     return m_lastKnownMousePosition;
 }
 
-static Frame* subframeForTargetNode(Node* node)
+static LocalFrame* subframeForTargetNode(Node* node)
 {
     if (!node)
         return 0;
@@ -1002,7 +1011,7 @@
     return &toFrameView(widget)->frame();
 }
 
-static Frame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
+static LocalFrame* subframeForHitTestResult(const MouseEventWithHitTestResults& hitTestResult)
 {
     if (!hitTestResult.isOverWidget())
         return 0;
@@ -1011,11 +1020,11 @@
 
 static bool isSubmitImage(Node* node)
 {
-    return node && node->hasTagName(inputTag) && toHTMLInputElement(node)->isImageButton();
+    return isHTMLInputElement(node) && toHTMLInputElement(node)->isImageButton();
 }
 
 // Returns true if the node's editable block is not current focused for editing
-static bool nodeIsNotBeingEdited(Node* node, Frame* frame)
+static bool nodeIsNotBeingEdited(Node* node, LocalFrame* frame)
 {
     return frame->selection().rootEditableElement() != node->rootEditableElement();
 }
@@ -1267,7 +1276,7 @@
     return pointerCursor();
 }
 
-static LayoutPoint documentPointForWindowPoint(Frame* frame, const IntPoint& windowPoint)
+static LayoutPoint documentPointForWindowPoint(LocalFrame* frame, const IntPoint& windowPoint)
 {
     FrameView* view = frame->view();
     // FIXME: Is it really OK to use the wrong coordinates here when view is 0?
@@ -1288,7 +1297,7 @@
 
     cancelFakeMouseMoveEvent();
     if (m_eventHandlerWillResetCapturingMouseEventsNode)
-        m_capturingMouseEventsNode = 0;
+        m_capturingMouseEventsNode = nullptr;
     m_mousePressed = true;
     m_capturesDragging = true;
     setLastKnownMousePosition(mouseEvent);
@@ -1320,7 +1329,7 @@
 
     m_mousePressNode = mev.targetNode();
 
-    RefPtr<Frame> subframe = subframeForHitTestResult(mev);
+    RefPtr<LocalFrame> subframe = subframeForHitTestResult(mev);
     if (subframe && passMousePressEventToSubframe(mev, subframe.get())) {
         // Start capturing future events for this frame.  We only do this if we didn't clear
         // the m_mousePressed flag, which may happen if an AppKit widget entered a modal event loop.
@@ -1373,7 +1382,7 @@
         HitTestRequest request(HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
         mev = m_frame->document()->prepareMouseEvent(request, documentPoint, mouseEvent);
         if (wasLastScrollBar && mev.scrollbar() != m_lastScrollbarUnderMouse.get())
-            m_lastScrollbarUnderMouse = 0;
+            m_lastScrollbarUnderMouse = nullptr;
     }
 
     if (swallowEvent) {
@@ -1548,7 +1557,7 @@
     }
 
     bool swallowEvent = false;
-    RefPtr<Frame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
+    RefPtr<LocalFrame> newSubframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
 
     // We want mouseouts to happen first, from the inside out.  First send a move event to the last subframe so that it will fire mouseouts.
     if (m_lastMouseMoveEventSubframe && m_lastMouseMoveEventSubframe->tree().isDescendantOf(m_frame) && m_lastMouseMoveEventSubframe != newSubframe)
@@ -1589,7 +1598,7 @@
 void EventHandler::invalidateClick()
 {
     m_clickCount = 0;
-    m_clickNode = 0;
+    m_clickNode = nullptr;
 }
 
 static Node* parentForClickEvent(const Node& node)
@@ -1648,9 +1657,9 @@
         hitType |= HitTestRequest::ReadOnly;
     HitTestRequest request(hitType);
     MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseEvent);
-    Frame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
+    LocalFrame* subframe = m_capturingMouseEventsNode.get() ? subframeForTargetNode(m_capturingMouseEventsNode.get()) : subframeForHitTestResult(mev);
     if (m_eventHandlerWillResetCapturingMouseEventsNode)
-        m_capturingMouseEventsNode = 0;
+        m_capturingMouseEventsNode = nullptr;
     if (subframe && passMouseReleaseEventToSubframe(mev, subframe))
         return true;
 
@@ -1706,7 +1715,7 @@
 
     if (!m_frame->page())
         return false;
-    Frame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame();
+    LocalFrame* focusFrame = m_frame->page()->focusController().focusedOrMainFrame();
     // Do not paste here if the focus was moved somewhere else.
     if (m_frame == focusFrame && m_frame->editor().behavior().supportsGlobalSelection())
         return m_frame->editor().command("PasteGlobalSelection").execute();
@@ -1728,18 +1737,18 @@
         0, event.globalPosition().x(), event.globalPosition().y(), event.position().x(), event.position().y(),
         event.movementDelta().x(), event.movementDelta().y(),
         event.ctrlKey(), event.altKey(), event.shiftKey(), event.metaKey(),
-        0, 0, clipboard);
+        0, nullptr, clipboard);
 
     dragTarget->dispatchEvent(me.get(), IGNORE_EXCEPTION);
     return me->defaultPrevented();
 }
 
-static bool targetIsFrame(Node* target, Frame*& frame)
+static bool targetIsFrame(Node* target, LocalFrame*& frame)
 {
     if (!target)
         return false;
 
-    if (!target->hasTagName(frameTag) && !target->hasTagName(iframeTag))
+    if (!isHTMLFrameElement(*target) && !isHTMLIFrameElement(*target))
         return false;
 
     frame = toHTMLFrameElementBase(target)->contentFrame();
@@ -1806,7 +1815,7 @@
         // LayoutTests/fast/events/drag-in-frames.html.
         //
         // Moreover, this ordering conforms to section 7.9.4 of the HTML 5 spec. <http://dev.w3.org/html5/spec/Overview.html#drag-and-drop-processing-model>.
-        Frame* targetFrame;
+        LocalFrame* targetFrame;
         if (targetIsFrame(newTarget.get(), targetFrame)) {
             if (targetFrame)
                 accept = targetFrame->eventHandler().updateDragAndDrop(event, clipboard);
@@ -1833,7 +1842,7 @@
             m_shouldOnlyFireDragOverEvent = true;
         }
     } else {
-        Frame* targetFrame;
+        LocalFrame* targetFrame;
         if (targetIsFrame(newTarget.get(), targetFrame)) {
             if (targetFrame)
                 accept = targetFrame->eventHandler().updateDragAndDrop(event, clipboard);
@@ -1856,7 +1865,7 @@
 
 void EventHandler::cancelDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
 {
-    Frame* targetFrame;
+    LocalFrame* targetFrame;
     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
         if (targetFrame)
             targetFrame->eventHandler().cancelDragAndDrop(event, clipboard);
@@ -1870,7 +1879,7 @@
 
 bool EventHandler::performDragAndDrop(const PlatformMouseEvent& event, Clipboard* clipboard)
 {
-    Frame* targetFrame;
+    LocalFrame* targetFrame;
     bool preventedDefault = false;
     if (targetIsFrame(m_dragTarget.get(), targetFrame)) {
         if (targetFrame)
@@ -1884,8 +1893,8 @@
 void EventHandler::clearDragState()
 {
     stopAutoscroll();
-    m_dragTarget = 0;
-    m_capturingMouseEventsNode = 0;
+    m_dragTarget = nullptr;
+    m_capturingMouseEventsNode = nullptr;
     m_shouldOnlyFireDragOverEvent = false;
 }
 
@@ -1913,7 +1922,7 @@
         return 0;
 
     Element* shadowTreeParentElement = shadowRoot->host();
-    if (!shadowTreeParentElement || !shadowTreeParentElement->hasTagName(useTag))
+    if (!isSVGUseElement(shadowTreeParentElement))
         return 0;
 
     return toSVGUseElement(shadowTreeParentElement)->instanceForShadowTreeElement(referenceNode);
@@ -1973,7 +1982,7 @@
 
         if (m_lastNodeUnderMouse && (!m_nodeUnderMouse || m_nodeUnderMouse->document() != m_frame->document())) {
             // The mouse has moved between frames.
-            if (Frame* frame = m_lastNodeUnderMouse->document().frame()) {
+            if (LocalFrame* frame = m_lastNodeUnderMouse->document().frame()) {
                 if (FrameView* frameView = frame->view())
                     frameView->mouseExitedContentArea();
             }
@@ -1985,7 +1994,7 @@
 
         if (m_nodeUnderMouse && (!m_lastNodeUnderMouse || m_lastNodeUnderMouse->document() != m_frame->document())) {
             // The mouse has moved between frames.
-            if (Frame* frame = m_nodeUnderMouse->document().frame()) {
+            if (LocalFrame* frame = m_nodeUnderMouse->document().frame()) {
                 if (FrameView* frameView = frame->view())
                     frameView->mouseEnteredContentArea();
             }
@@ -1996,9 +2005,9 @@
         }
 
         if (m_lastNodeUnderMouse && m_lastNodeUnderMouse->document() != m_frame->document()) {
-            m_lastNodeUnderMouse = 0;
-            m_lastScrollbarUnderMouse = 0;
-            m_lastInstanceUnderMouse = 0;
+            m_lastNodeUnderMouse = nullptr;
+            m_lastScrollbarUnderMouse = nullptr;
+            m_lastInstanceUnderMouse = nullptr;
         }
 
         if (m_lastNodeUnderMouse != m_nodeUnderMouse) {
@@ -2150,9 +2159,9 @@
         isOverWidget = m_widgetIsLatched;
     } else {
         if (m_latchedWheelEventNode)
-            m_latchedWheelEventNode = 0;
+            m_latchedWheelEventNode = nullptr;
         if (m_previousWheelScrolledNode)
-            m_previousWheelScrolledNode = 0;
+            m_previousWheelScrolledNode = nullptr;
 
         isOverWidget = result.isOverWidget();
     }
@@ -2178,6 +2187,12 @@
             RETURN_WHEEL_EVENT_HANDLED();
     }
 
+    // Ctrl + scrollwheel is reserved for triggering zoom in/out actions in Chromium.
+    // When Ctrl is pressed and the event was not canceled by JavaScript code,
+    // return false to notify the caller that the scrollwheel event was not canceled.
+    if (e.ctrlKey())
+        return false;
+
 
     // We do another check on the frame view because the event handler can run JS which results in the frame getting destroyed.
     view = m_frame->view();
@@ -2194,6 +2209,10 @@
     if (!startNode || !wheelEvent)
         return;
 
+    // Ctrl + scrollwheel is reserved for triggering zoom in/out actions in Chromium.
+    if (wheelEvent->ctrlKey())
+        return;
+
     Node* stopNode = m_previousWheelScrolledNode.get();
     ScrollGranularity granularity = wheelGranularityToScrollGranularity(wheelEvent->deltaMode());
 
@@ -2233,7 +2252,7 @@
 bool EventHandler::handleGestureEvent(const PlatformGestureEvent& gestureEvent)
 {
     IntPoint adjustedPoint = gestureEvent.position();
-    RefPtr<Frame> subframe = 0;
+    RefPtr<LocalFrame> subframe = nullptr;
     switch (gestureEvent.type()) {
     case PlatformEvent::GestureScrollBegin:
     case PlatformEvent::GestureScrollUpdate:
@@ -2303,7 +2322,7 @@
 
         if (shouldKeepActiveForMinInterval) {
             m_lastDeferredTapElement = result.innerElement();
-            m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterval);
+            m_activeIntervalTimer.startOneShot(minimumActiveInterval - activeInterval, FROM_HERE);
         }
 
         eventTarget = result.targetNode();
@@ -2322,7 +2341,7 @@
         } else if (gestureEvent.type() == PlatformEvent::GestureScrollEnd
             || gestureEvent.type() == PlatformEvent::GestureFlingStart
             || !eventSwallowed) {
-            m_scrollbarHandlingScrollGesture = 0;
+            m_scrollbarHandlingScrollGesture = nullptr;
         }
 
         if (eventSwallowed)
@@ -2429,7 +2448,7 @@
         MouseEventWithHitTestResults mev = prepareMouseEvent(request, mouseDragEvent);
         m_didStartDrag = false;
         m_mouseDownMayStartDrag = true;
-        dragState().m_dragSrc = 0;
+        dragState().m_dragSrc = nullptr;
         m_mouseDownPos = m_frame->view()->windowToContents(mouseDragEvent.position());
         RefPtr<FrameView> protector(m_frame->view());
         handleDrag(mev, DontCheckDragHysteresis);
@@ -2550,7 +2569,7 @@
 
     m_lastHitTestResultOverWidget = result.isOverWidget();
     m_scrollGestureHandlingNode = result.innerNode();
-    m_previousGestureScrolledNode = 0;
+    m_previousGestureScrolledNode = nullptr;
 
     // If there's no renderer on the node, send the event to the nearest ancestor with a renderer.
     // Needed for <option> and <optgroup> elements so we can touch scroll <select>s
@@ -2639,7 +2658,7 @@
     return scrolledFrame;
 }
 
-Frame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent& gestureEvent)
+LocalFrame* EventHandler::getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent& gestureEvent)
 {
     PlatformMouseEvent mouseDown(touchAdjustedPoint, gestureEvent.globalPosition(), LeftButton, PlatformEvent::MousePressed, 1,
         gestureEvent.shiftKey(), gestureEvent.ctrlKey(), gestureEvent.altKey(), gestureEvent.metaKey(), gestureEvent.timestamp());
@@ -2650,8 +2669,8 @@
 
 void EventHandler::clearGestureScrollNodes()
 {
-    m_scrollGestureHandlingNode = 0;
-    m_previousGestureScrolledNode = 0;
+    m_scrollGestureHandlingNode = nullptr;
+    m_previousGestureScrolledNode = nullptr;
 }
 
 bool EventHandler::isScrollbarHandlingGestures() const
@@ -2666,7 +2685,6 @@
     return !event.area().isEmpty();
 }
 
-
 bool EventHandler::bestClickableNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode)
 {
     IntPoint hitTestPoint = m_frame->view()->windowToContents(touchCenter);
@@ -2687,8 +2705,9 @@
     // regression in touchadjustment/html-label.html. Some refinement is required to testing/internals to
     // handle targetNode being a shadow DOM node.
 
-    // FIXME: the explicit Vector conversion copies into a temporary and is
-    // wasteful.
+    // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
+    // FIXME: targetNode and success are only used by Internals functions. We should
+    // instead have dedicated test methods so we only do this work in tests.
     bool success = findBestClickableCandidate(targetNode, targetPoint, touchCenter, touchRect, Vector<RefPtr<Node> > (nodes));
     if (success && targetNode)
         targetNode = targetNode->deprecatedShadowAncestorNode();
@@ -2704,8 +2723,7 @@
     Vector<RefPtr<Node>, 11> nodes;
     copyToVector(result.rectBasedTestResult(), nodes);
 
-    // FIXME: the explicit Vector conversion copies into a temporary and is
-    // wasteful.
+    // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
     return findBestContextMenuCandidate(targetNode, targetPoint, touchCenter, touchRect, Vector<RefPtr<Node> >(nodes));
 }
 
@@ -2718,15 +2736,14 @@
     Vector<RefPtr<Node>, 11> nodes;
     copyToVector(result.rectBasedTestResult(), nodes);
 
-    // FIXME: the explicit Vector conversion copies into a temporary and is
-    // wasteful.
+    // FIXME: the explicit Vector conversion copies into a temporary and is wasteful.
     return findBestZoomableArea(targetNode, targetArea, touchCenter, touchRect, Vector<RefPtr<Node> >(nodes));
 }
 
-bool EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint)
+void EventHandler::adjustGesturePosition(const PlatformGestureEvent& gestureEvent, IntPoint& adjustedPoint)
 {
     if (!shouldApplyTouchAdjustment(gestureEvent))
-        return false;
+        return;
 
     Node* targetNode = 0;
     switch (gestureEvent.type()) {
@@ -2745,7 +2762,6 @@
         // FIXME: Implement handling for other types as needed.
         ASSERT_NOT_REACHED();
     }
-    return targetNode;
 }
 
 bool EventHandler::sendContextMenuEvent(const PlatformMouseEvent& event)
@@ -2852,7 +2868,8 @@
 
     PlatformMouseEvent mouseEvent(position, globalPosition, RightButton, eventType, 1, false, false, false, false, WTF::currentTime());
 
-    return !dispatchMouseEvent(EventTypeNames::contextmenu, targetNode, true, 0, mouseEvent, false);
+    handleMousePressEvent(mouseEvent);
+    return sendContextMenuEvent(mouseEvent);
 }
 
 bool EventHandler::sendContextMenuEventForGesture(const PlatformGestureEvent& event)
@@ -2877,13 +2894,13 @@
 void EventHandler::scheduleHoverStateUpdate()
 {
     if (!m_hoverTimer.isActive())
-        m_hoverTimer.startOneShot(0);
+        m_hoverTimer.startOneShot(0, FROM_HERE);
 }
 
 void EventHandler::scheduleCursorUpdate()
 {
     if (!m_cursorUpdateTimer.isActive())
-        m_cursorUpdateTimer.startOneShot(cursorUpdateInterval);
+        m_cursorUpdateTimer.startOneShot(cursorUpdateInterval, FROM_HERE);
 }
 
 void EventHandler::dispatchFakeMouseMoveEventSoon()
@@ -2905,10 +2922,10 @@
     if (m_maxMouseMovedDuration > fakeMouseMoveShortInterval) {
         if (m_fakeMouseMoveEventTimer.isActive())
             m_fakeMouseMoveEventTimer.stop();
-        m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval);
+        m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveLongInterval, FROM_HERE);
     } else {
         if (!m_fakeMouseMoveEventTimer.isActive())
-            m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval);
+            m_fakeMouseMoveEventTimer.startOneShot(fakeMouseMoveShortInterval, FROM_HERE);
     }
 }
 
@@ -3003,7 +3020,7 @@
         HitTestRequest request(HitTestRequest::TouchEvent | HitTestRequest::Release);
         m_frame->document()->updateHoverActiveState(request, m_lastDeferredTapElement.get());
     }
-    m_lastDeferredTapElement = 0;
+    m_lastDeferredTapElement = nullptr;
 }
 
 void EventHandler::notifyElementActivated()
@@ -3011,7 +3028,7 @@
     // Since another element has been set to active, stop current timer and clear reference.
     if (m_activeIntervalTimer.isActive())
         m_activeIntervalTimer.stop();
-    m_lastDeferredTapElement = 0;
+    m_lastDeferredTapElement = nullptr;
 }
 
 bool EventHandler::handleAccessKey(const PlatformKeyboardEvent& evt)
@@ -3054,7 +3071,8 @@
 {
     RefPtr<FrameView> protector(m_frame->view());
 
-    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(m_frame->document())) {
+    ASSERT(m_frame->document());
+    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(*m_frame->document())) {
         if (fullscreen->webkitIsFullScreen() && !isKeyEventAllowedInFullScreen(fullscreen, initialKeyEvent))
             return false;
     }
@@ -3235,7 +3253,7 @@
         dispatchDragSrcEvent(EventTypeNames::dragend, event);
     }
     freeClipboard();
-    dragState().m_dragSrc = 0;
+    dragState().m_dragSrc = nullptr;
     // In case the drag was ended due to an escape key press we need to ensure
     // that consecutive mousemove events don't reinitiate the drag and drop.
     m_mouseDownMayStartDrag = false;
@@ -3284,7 +3302,7 @@
                 : DragController::ImmediateSelectionDragResolution;
             dragState().m_dragSrc = m_frame->page()->dragController().draggableNode(m_frame, node, m_mouseDownPos, selectionDragPolicy, dragState().m_dragType);
         } else {
-            dragState().m_dragSrc = 0;
+            dragState().m_dragSrc = nullptr;
         }
 
         if (!dragState().m_dragSrc)
@@ -3307,7 +3325,7 @@
     if (!tryStartDrag(event)) {
         // Something failed to start the drag, clean up.
         freeClipboard();
-        dragState().m_dragSrc = 0;
+        dragState().m_dragSrc = nullptr;
     }
 
     m_mouseDownMayStartDrag = false;
@@ -3544,7 +3562,7 @@
     }
 }
 
-HitTestResult EventHandler::hitTestResultInFrame(Frame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
+HitTestResult EventHandler::hitTestResultInFrame(LocalFrame* frame, const LayoutPoint& point, HitTestRequest::HitTestRequestType hitType)
 {
     HitTestResult result(point);
 
@@ -3566,18 +3584,18 @@
     // for an overview of how these lists fit together.
 
     // Holds the complete set of touches on the screen and will be used as the 'touches' list in the JS event.
-    RefPtr<TouchList> touches = TouchList::create();
+    RefPtrWillBeRawPtr<TouchList> touches = TouchList::create();
 
     // A different view on the 'touches' list above, filtered and grouped by event target. Used for the
     // 'targetTouches' list in the JS event.
-    typedef HashMap<EventTarget*, RefPtr<TouchList> > TargetTouchesMap;
-    TargetTouchesMap touchesByTarget;
+    typedef WillBeHeapHashMap<EventTarget*, RefPtrWillBeMember<TouchList> > TargetTouchesHeapMap;
+    TargetTouchesHeapMap touchesByTarget;
 
     // Array of touches per state, used to assemble the 'changedTouches' list in the JS event.
     typedef HashSet<RefPtr<EventTarget> > EventTargetSet;
     struct {
         // The touches corresponding to the particular change state this struct instance represents.
-        RefPtr<TouchList> m_touches;
+        RefPtrWillBeRawPtr<TouchList> m_touches;
         // Set of targets involved in m_touches.
         EventTargetSet m_targets;
     } changedTouches[PlatformTouchPoint::TouchStateEnd];
@@ -3662,8 +3680,7 @@
             m_originatingTouchPointTargets.set(touchPointTargetKey, node);
             touchTarget = node;
 
-            // FIXME(rbyers): Should really be doing a second hit test that ignores inline elements - crbug.com/319479.
-            TouchAction effectiveTouchAction = computeEffectiveTouchAction(*node);
+            TouchAction effectiveTouchAction = computeEffectiveTouchAction(pagePoint);
             if (effectiveTouchAction != TouchActionAuto)
                 m_frame->page()->chrome().client().setTouchAction(effectiveTouchAction);
 
@@ -3680,7 +3697,7 @@
         Document& doc = touchTarget->toNode()->document();
         if (!doc.hasTouchEventHandlers())
             continue;
-        Frame* targetFrame = doc.frame();
+        LocalFrame* targetFrame = doc.frame();
         if (!targetFrame)
             continue;
 
@@ -3696,14 +3713,14 @@
         int adjustedRadiusX = lroundf(point.radiusX() / scaleFactor);
         int adjustedRadiusY = lroundf(point.radiusY() / scaleFactor);
 
-        RefPtr<Touch> touch = Touch::create(targetFrame, touchTarget.get(), point.id(),
+        RefPtrWillBeRawPtr<Touch> touch = Touch::create(targetFrame, touchTarget.get(), point.id(),
                                             point.screenPos().x(), point.screenPos().y(),
                                             adjustedPageX, adjustedPageY,
                                             adjustedRadiusX, adjustedRadiusY,
                                             point.rotationAngle(), point.force());
 
         // Ensure this target's touch list exists, even if it ends up empty, so it can always be passed to TouchEvent::Create below.
-        TargetTouchesMap::iterator targetTouchesIterator = touchesByTarget.find(touchTarget.get());
+        TargetTouchesHeapMap::iterator targetTouchesIterator = touchesByTarget.find(touchTarget.get());
         if (targetTouchesIterator == touchesByTarget.end()) {
             touchesByTarget.set(touchTarget.get(), TouchList::create());
             targetTouchesIterator = touchesByTarget.find(touchTarget.get());
@@ -3736,20 +3753,20 @@
 
     // Now iterate the changedTouches list and m_targets within it, sending events to the targets as required.
     bool swallowedEvent = false;
-    RefPtr<TouchList> emptyList = TouchList::create();
+    RefPtrWillBeRawPtr<TouchList> emptyList = TouchList::create();
     for (unsigned state = 0; state != PlatformTouchPoint::TouchStateEnd; ++state) {
         if (!changedTouches[state].m_touches)
             continue;
 
         // When sending a touch cancel event, use empty touches and targetTouches lists.
         bool isTouchCancelEvent = (state == PlatformTouchPoint::TouchCancelled);
-        RefPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches);
+        RefPtrWillBeRawPtr<TouchList>& effectiveTouches(isTouchCancelEvent ? emptyList : touches);
         const AtomicString& stateName(eventNameForTouchPointState(static_cast<PlatformTouchPoint::State>(state)));
         const EventTargetSet& targetsForState = changedTouches[state].m_targets;
 
         for (EventTargetSet::const_iterator it = targetsForState.begin(); it != targetsForState.end(); ++it) {
             EventTarget* touchEventTarget = it->get();
-            RefPtr<TouchList> targetTouches(isTouchCancelEvent ? emptyList : touchesByTarget.get(touchEventTarget));
+            RefPtrWillBeRawPtr<TouchList> targetTouches(isTouchCancelEvent ? emptyList.get() : touchesByTarget.get(touchEventTarget));
             ASSERT(targetTouches);
 
             RefPtr<TouchEvent> touchEvent =
@@ -3896,19 +3913,24 @@
     return action1 & action2;
 }
 
-TouchAction EventHandler::computeEffectiveTouchAction(const Node& node)
+TouchAction EventHandler::computeEffectiveTouchAction(const LayoutPoint& point)
 {
     // Optimization to minimize risk of this new feature (behavior should be identical
     // since there's no way to get non-default touch-action values).
     if (!RuntimeEnabledFeatures::cssTouchActionEnabled())
         return TouchActionAuto;
 
+    HitTestResult taResult = hitTestResultAtPoint(point, HitTestRequest::TouchEvent | HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::TouchAction);
+    Node* node = taResult.innerNode();
+    if (!node)
+        return TouchActionAuto;
+
     // Start by permitting all actions, then walk the block level elements from
     // the target node up to the nearest scrollable ancestor and exclude any
     // prohibited actions. For now this is trivial, but when we add more types
     // of actions it'll get a little more complex.
     TouchAction effectiveTouchAction = TouchActionAuto;
-    for (const Node* curNode = &node; curNode; curNode = NodeRenderingTraversal::parent(curNode)) {
+    for (const Node* curNode = node; curNode; curNode = NodeRenderingTraversal::parent(curNode)) {
         // The spec says only block and SVG elements get touch-action.
         // FIXME(rbyers): Add correct support for SVG, crbug.com/247396.
         if (RenderObject* renderer = curNode->renderer()) {
@@ -3934,7 +3956,7 @@
     m_lastKnownMouseGlobalPosition = event.globalPosition();
 }
 
-bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+bool EventHandler::passMousePressEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe)
 {
     // If we're clicking into a frame that is selected, the frame will appear
     // greyed out even though we're clicking on the selection.  This looks
@@ -3952,7 +3974,7 @@
     return true;
 }
 
-bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe, HitTestResult* hoveredNode)
+bool EventHandler::passMouseMoveEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe, HitTestResult* hoveredNode)
 {
     if (m_mouseDownMayStartDrag && !m_mouseDownWasInSubframe)
         return false;
@@ -3960,7 +3982,7 @@
     return true;
 }
 
-bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, Frame* subframe)
+bool EventHandler::passMouseReleaseEventToSubframe(MouseEventWithHitTestResults& mev, LocalFrame* subframe)
 {
     subframe->eventHandler().handleMouseReleaseEvent(mev.event());
     return true;
@@ -3989,7 +4011,7 @@
     return false;
 }
 
-PassRefPtr<Clipboard> EventHandler::createDraggingClipboard() const
+PassRefPtrWillBeRawPtr<Clipboard> EventHandler::createDraggingClipboard() const
 {
     return Clipboard::create(Clipboard::DragAndDrop, ClipboardWritable, DataObject::create());
 }
diff --git a/Source/core/page/EventHandler.h b/Source/core/page/EventHandler.h
index 23316e2..7f025b2 100644
--- a/Source/core/page/EventHandler.h
+++ b/Source/core/page/EventHandler.h
@@ -32,6 +32,7 @@
 #include "core/page/FocusType.h"
 #include "core/rendering/HitTestRequest.h"
 #include "core/rendering/style/RenderStyleConstants.h"
+#include "heap/Handle.h"
 #include "platform/Cursor.h"
 #include "platform/PlatformMouseEvent.h"
 #include "platform/Timer.h"
@@ -53,7 +54,7 @@
 class FloatPoint;
 class FloatQuad;
 class FullscreenElementStack;
-class Frame;
+class LocalFrame;
 class HTMLFrameSetElement;
 class HitTestRequest;
 class HitTestResult;
@@ -78,7 +79,7 @@
 class WheelEvent;
 class Widget;
 
-struct DragState;
+class DragState;
 
 enum AppendTrailingWhitespace { ShouldAppendTrailingWhitespace, DontAppendTrailingWhitespace };
 enum CheckDragHysteresis { ShouldCheckDragHysteresis, DontCheckDragHysteresis };
@@ -86,7 +87,7 @@
 class EventHandler {
     WTF_MAKE_NONCOPYABLE(EventHandler);
 public:
-    explicit EventHandler(Frame*);
+    explicit EventHandler(LocalFrame*);
     ~EventHandler();
 
     void clear();
@@ -149,7 +150,7 @@
     bool bestContextMenuNodeForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntPoint& targetPoint, Node*& targetNode);
     bool bestZoomableAreaForTouchPoint(const IntPoint& touchCenter, const IntSize& touchRadius, IntRect& targetArea, Node*& targetNode);
 
-    bool adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
+    void adjustGesturePosition(const PlatformGestureEvent&, IntPoint& adjustedPoint);
 
     bool sendContextMenuEvent(const PlatformMouseEvent&);
     bool sendContextMenuEventForKey();
@@ -180,7 +181,7 @@
 private:
     static DragState& dragState();
 
-    PassRefPtr<Clipboard> createDraggingClipboard() const;
+    PassRefPtrWillBeRawPtr<Clipboard> createDraggingClipboard() const;
 
     bool updateSelectionForMouseDownDispatchingSelectStart(Node*, const VisibleSelection&, TextGranularity);
     void selectClosestWordFromHitTestResult(const HitTestResult&, AppendTrailingWhitespace);
@@ -244,11 +245,11 @@
     bool dispatchSyntheticTouchEventIfEnabled(const PlatformMouseEvent&);
 
     TouchAction intersectTouchAction(const TouchAction, const TouchAction);
-    TouchAction computeEffectiveTouchAction(const Node&);
+    TouchAction computeEffectiveTouchAction(const LayoutPoint&);
 
     bool handleMouseEventAsEmulatedGesture(const PlatformMouseEvent&);
     bool handleWheelEventAsEmulatedGesture(const PlatformWheelEvent&);
-    HitTestResult hitTestResultInFrame(Frame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
+    HitTestResult hitTestResultInFrame(LocalFrame*, const LayoutPoint&, HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent);
 
     void invalidateClick();
 
@@ -272,9 +273,9 @@
     bool dragHysteresisExceeded(const FloatPoint&) const;
     bool dragHysteresisExceeded(const IntPoint&) const;
 
-    bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
-    bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe, HitTestResult* hoveredNode = 0);
-    bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, Frame* subframe);
+    bool passMousePressEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
+    bool passMouseMoveEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe, HitTestResult* hoveredNode = 0);
+    bool passMouseReleaseEventToSubframe(MouseEventWithHitTestResults&, LocalFrame* subframe);
 
     bool passMousePressEventToScrollbar(MouseEventWithHitTestResults&, Scrollbar*);
 
@@ -305,13 +306,13 @@
     bool passGestureEventToWidget(const PlatformGestureEvent&, Widget*);
     bool passGestureEventToWidgetIfPossible(const PlatformGestureEvent&, RenderObject*);
     bool sendScrollEventToView(const PlatformGestureEvent&, const FloatSize&);
-    Frame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
+    LocalFrame* getSubFrameForGestureEvent(const IntPoint& touchAdjustedPoint, const PlatformGestureEvent&);
 
     AutoscrollController* autoscrollController() const;
     bool panScrollInProgress() const;
     void setLastKnownMousePosition(const PlatformMouseEvent&);
 
-    Frame* const m_frame;
+    LocalFrame* const m_frame;
 
     bool m_mousePressed;
     bool m_capturesDragging;
@@ -344,7 +345,7 @@
 
     RefPtr<Node> m_nodeUnderMouse;
     RefPtr<Node> m_lastNodeUnderMouse;
-    RefPtr<Frame> m_lastMouseMoveEventSubframe;
+    RefPtr<LocalFrame> m_lastMouseMoveEventSubframe;
     RefPtr<Scrollbar> m_lastScrollbarUnderMouse;
     Cursor m_currentMouseCursor;
 
diff --git a/Source/core/page/EventSource.cpp b/Source/core/page/EventSource.cpp
index 6fae815..695529a 100644
--- a/Source/core/page/EventSource.cpp
+++ b/Source/core/page/EventSource.cpp
@@ -42,9 +42,9 @@
 #include "core/dom/ExecutionContext.h"
 #include "core/events/Event.h"
 #include "core/events/MessageEvent.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/parser/TextResourceDecoder.h"
 #include "core/loader/ThreadableLoader.h"
 #include "platform/network/ResourceError.h"
@@ -72,17 +72,17 @@
     eventSourceInit.get("withCredentials", m_withCredentials);
 }
 
-PassRefPtr<EventSource> EventSource::create(ExecutionContext* context, const String& url, const Dictionary& eventSourceInit, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<EventSource> EventSource::create(ExecutionContext* context, const String& url, const Dictionary& eventSourceInit, ExceptionState& exceptionState)
 {
     if (url.isEmpty()) {
         exceptionState.throwDOMException(SyntaxError, "Cannot open an EventSource to an empty URL.");
-        return 0;
+        return nullptr;
     }
 
     KURL fullURL = context->completeURL(url);
     if (!fullURL.isValid()) {
         exceptionState.throwDOMException(SyntaxError, "Cannot open an EventSource to '" + url + "'. The URL is invalid.");
-        return 0;
+        return nullptr;
     }
 
     // FIXME: Convert this to check the isolated world's Content Security Policy once webkit.org/b/104520 is solved.
@@ -94,10 +94,10 @@
     if (!shouldBypassMainWorldContentSecurityPolicy && !context->contentSecurityPolicy()->allowConnectToSource(fullURL)) {
         // We can safely expose the URL to JavaScript, as this exception is generate synchronously before any redirects take place.
         exceptionState.throwSecurityError("Refused to connect to '" + fullURL.elidedString() + "' because it violates the document's Content Security Policy.");
-        return 0;
+        return nullptr;
     }
 
-    RefPtr<EventSource> source = adoptRef(new EventSource(context, fullURL, eventSourceInit));
+    RefPtrWillBeRawPtr<EventSource> source = adoptRefWillBeRefCountedGarbageCollected(new EventSource(context, fullURL, eventSourceInit));
 
     source->setPendingActivity(source.get());
     source->scheduleInitialConnect();
@@ -117,7 +117,7 @@
     ASSERT(m_state == CONNECTING);
     ASSERT(!m_requestInFlight);
 
-    m_connectTimer.startOneShot(0);
+    m_connectTimer.startOneShot(0, FROM_HERE);
 }
 
 void EventSource::connect()
@@ -166,7 +166,7 @@
 void EventSource::scheduleReconnect()
 {
     m_state = CONNECTING;
-    m_connectTimer.startOneShot(m_reconnectDelay / 1000.0);
+    m_connectTimer.startOneShot(m_reconnectDelay / 1000.0, FROM_HERE);
     dispatchEvent(Event::create(EventTypeNames::error));
 }
 
diff --git a/Source/core/page/EventSource.h b/Source/core/page/EventSource.h
index bf54cc4..81e7751 100644
--- a/Source/core/page/EventSource.h
+++ b/Source/core/page/EventSource.h
@@ -36,6 +36,7 @@
 #include "core/dom/ActiveDOMObject.h"
 #include "core/events/EventTarget.h"
 #include "core/loader/ThreadableLoaderClient.h"
+#include "heap/Handle.h"
 #include "platform/Timer.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/RefPtr.h"
@@ -50,11 +51,11 @@
 class TextResourceDecoder;
 class ThreadableLoader;
 
-class EventSource FINAL : public RefCounted<EventSource>, public ScriptWrappable, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject {
-    WTF_MAKE_FAST_ALLOCATED;
-    REFCOUNTED_EVENT_TARGET(EventSource);
+class EventSource FINAL : public RefCountedWillBeRefCountedGarbageCollected<EventSource>, public ScriptWrappable, public EventTargetWithInlineData, private ThreadableLoaderClient, public ActiveDOMObject {
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+    DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<EventSource>);
 public:
-    static PassRefPtr<EventSource> create(ExecutionContext*, const String& url, const Dictionary&, ExceptionState&);
+    static PassRefPtrWillBeRawPtr<EventSource> create(ExecutionContext*, const String& url, const Dictionary&, ExceptionState&);
     virtual ~EventSource();
 
     static const unsigned long long defaultReconnectDelay;
@@ -80,12 +81,14 @@
 
     // ActiveDOMObject
     //
-    // Note: suspend() is noop since PageGroupLoadDeferrer calls
+    // Note: suspend() is noop since ScopedPageLoadDeferrer calls
     // Page::setDefersLoading() and it defers delivery of events from the
     // loader, and therefore the methods of this class for receiving
     // asynchronous events from the loader won't be invoked.
     virtual void stop() OVERRIDE;
 
+    void trace(Visitor*) { }
+
 private:
     EventSource(ExecutionContext*, const KURL&, const Dictionary&);
 
diff --git a/Source/core/page/EventSource.idl b/Source/core/page/EventSource.idl
index 5e3efa8..aa3d6b2 100644
--- a/Source/core/page/EventSource.idl
+++ b/Source/core/page/EventSource.idl
@@ -30,6 +30,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     ActiveDOMObject,
     Constructor(DOMString url, optional Dictionary eventSourceInit),
     ConstructorCallWith=ExecutionContext,
diff --git a/Source/core/page/FocusController.cpp b/Source/core/page/FocusController.cpp
index 93a2193..4e3fe53 100644
--- a/Source/core/page/FocusController.cpp
+++ b/Source/core/page/FocusController.cpp
@@ -43,11 +43,11 @@
 #include "core/events/Event.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAreaElement.h"
 #include "core/html/HTMLImageElement.h"
-#include "core/html/shadow/HTMLShadowElement.h"
+#include "core/html/HTMLShadowElement.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
 #include "core/page/EventHandler.h"
@@ -87,7 +87,7 @@
         ShadowRoot* shadowRoot = toShadowRoot(root);
         return shadowRoot->isYoungest() ? shadowRoot->host() : shadowRoot->shadowInsertionPointOfYoungerShadowRoot();
     }
-    if (Frame* frame = root->document().frame())
+    if (LocalFrame* frame = root->document().frame())
         return frame->ownerElement();
     return 0;
 }
@@ -231,7 +231,7 @@
     return adoptPtr(new FocusController(page));
 }
 
-void FocusController::setFocusedFrame(PassRefPtr<Frame> frame)
+void FocusController::setFocusedFrame(PassRefPtr<LocalFrame> frame)
 {
     ASSERT(!frame || frame->page() == m_page);
     if (m_focusedFrame == frame || m_isChangingFocusedFrame)
@@ -239,8 +239,8 @@
 
     m_isChangingFocusedFrame = true;
 
-    RefPtr<Frame> oldFrame = m_focusedFrame;
-    RefPtr<Frame> newFrame = frame;
+    RefPtr<LocalFrame> oldFrame = m_focusedFrame;
+    RefPtr<LocalFrame> newFrame = frame;
 
     m_focusedFrame = newFrame;
 
@@ -256,11 +256,13 @@
     }
 
     m_isChangingFocusedFrame = false;
+
+    m_page->chrome().client().focusedFrameChanged(newFrame.get());
 }
 
-Frame* FocusController::focusedOrMainFrame() const
+LocalFrame* FocusController::focusedOrMainFrame() const
 {
-    if (Frame* frame = focusedFrame())
+    if (LocalFrame* frame = focusedFrame())
         return frame;
     return m_page->mainFrame();
 }
@@ -278,7 +280,9 @@
     if (!m_focusedFrame)
         setFocusedFrame(m_page->mainFrame());
 
-    if (m_focusedFrame->view()) {
+    // setFocusedFrame above might reject to update m_focusedFrame, or
+    // m_focusedFrame might be changed by blur/focus event handlers.
+    if (m_focusedFrame && m_focusedFrame->view()) {
         m_focusedFrame->selection().setFocused(focused);
         dispatchEventsOnWindowAndFocusedNode(m_focusedFrame->document(), focused);
     }
@@ -335,7 +339,7 @@
 
 bool FocusController::advanceFocusInDocumentOrder(FocusType type, bool initialFocus)
 {
-    Frame* frame = focusedOrMainFrame();
+    LocalFrame* frame = focusedOrMainFrame();
     ASSERT(frame);
     Document* document = frame->document();
 
@@ -353,8 +357,8 @@
     if (!node) {
         // We didn't find a node to focus, so we should try to pass focus to Chrome.
         if (!initialFocus && m_page->chrome().canTakeFocus(type)) {
-            document->setFocusedElement(0);
-            setFocusedFrame(0);
+            document->setFocusedElement(nullptr);
+            setFocusedFrame(nullptr);
             m_page->chrome().takeFocus(type);
             return true;
         }
@@ -385,7 +389,7 @@
         if (!owner->contentFrame())
             return false;
 
-        document->setFocusedElement(0);
+        document->setFocusedElement(nullptr);
         setFocusedFrame(owner->contentFrame());
         return true;
     }
@@ -397,7 +401,7 @@
 
     if (&newDocument != document) {
         // Focus is going away from this document, so clear the focused node.
-        document->setFocusedElement(0);
+        document->setFocusedElement(nullptr);
     }
 
     setFocusedFrame(newDocument.frame());
@@ -584,7 +588,7 @@
     return node->document().frame() && node->rootEditableElement();
 }
 
-static void clearSelectionIfNeeded(Frame* oldFocusedFrame, Frame* newFocusedFrame, Node* newFocusedNode)
+static void clearSelectionIfNeeded(LocalFrame* oldFocusedFrame, LocalFrame* newFocusedFrame, Node* newFocusedNode)
 {
     if (!oldFocusedFrame || !newFocusedFrame)
         return;
@@ -612,7 +616,7 @@
                 return;
 
             if (Node* shadowAncestorNode = root->deprecatedShadowAncestorNode()) {
-                if (!shadowAncestorNode->hasTagName(inputTag) && !shadowAncestorNode->hasTagName(textareaTag))
+                if (!isHTMLInputElement(*shadowAncestorNode) && !isHTMLTextAreaElement(*shadowAncestorNode))
                     return;
             }
         }
@@ -621,9 +625,9 @@
     selection.clear();
 }
 
-bool FocusController::setFocusedElement(Element* element, PassRefPtr<Frame> newFocusedFrame, FocusType type)
+bool FocusController::setFocusedElement(Element* element, PassRefPtr<LocalFrame> newFocusedFrame, FocusType type)
 {
-    RefPtr<Frame> oldFocusedFrame = focusedFrame();
+    RefPtr<LocalFrame> oldFocusedFrame = focusedFrame();
     RefPtr<Document> oldDocument = oldFocusedFrame ? oldFocusedFrame->document() : 0;
 
     Element* oldFocusedElement = oldDocument ? oldDocument->focusedElement() : 0;
@@ -648,10 +652,10 @@
     clearSelectionIfNeeded(oldFocusedFrame.get(), newFocusedFrame.get(), element);
 
     if (oldDocument && oldDocument != newDocument)
-        oldDocument->setFocusedElement(0);
+        oldDocument->setFocusedElement(nullptr);
 
     if (newFocusedFrame && !newFocusedFrame->page()) {
-        setFocusedFrame(0);
+        setFocusedFrame(nullptr);
         return false;
     }
     setFocusedFrame(newFocusedFrame);
@@ -674,12 +678,8 @@
 
     m_isActive = active;
 
-    if (FrameView* view = m_page->mainFrame()->view()) {
-        view->updateLayoutAndStyleIfNeededRecursive();
-        // https://code.google.com/p/chromium/issues/detail?id=343758
-        DisableCompositingQueryAsserts disabler;
+    if (FrameView* view = m_page->mainFrame()->view())
         view->updateControlTints();
-    }
 
     focusedOrMainFrame()->selection().pageActivationChanged();
 }
@@ -705,7 +705,7 @@
 
     contentAreaDidShowOrHide(view, containingWindowIsVisible);
 
-    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         FrameView* frameView = frame->view();
         if (!frameView)
             continue;
@@ -872,7 +872,7 @@
 
 bool FocusController::advanceFocusDirectionally(FocusType type)
 {
-    Frame* curFrame = focusedOrMainFrame();
+    LocalFrame* curFrame = focusedOrMainFrame();
     ASSERT(curFrame);
 
     Document* focusedDocument = curFrame->document();
@@ -891,9 +891,9 @@
         if (!hasOffscreenRect(focusedElement)) {
             container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(type, focusedElement);
             startingRect = nodeRectInAbsoluteCoordinates(focusedElement, true /* ignore border */);
-        } else if (focusedElement->hasTagName(areaTag)) {
-            HTMLAreaElement* area = toHTMLAreaElement(focusedElement);
-            container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(type, area->imageElement());
+        } else if (isHTMLAreaElement(*focusedElement)) {
+            HTMLAreaElement& area = toHTMLAreaElement(*focusedElement);
+            container = scrollableEnclosingBoxOrParentFrameForNodeInDirection(type, area.imageElement());
             startingRect = virtualRectForAreaElementAndDirection(area, type);
         }
     }
diff --git a/Source/core/page/FocusController.h b/Source/core/page/FocusController.h
index 0983fcd..b7d919c 100644
--- a/Source/core/page/FocusController.h
+++ b/Source/core/page/FocusController.h
@@ -37,7 +37,7 @@
 struct FocusCandidate;
 class Document;
 class Element;
-class Frame;
+class LocalFrame;
 class HTMLFrameOwnerElement;
 class HTMLShadowElement;
 class IntRect;
@@ -66,14 +66,14 @@
 public:
     static PassOwnPtr<FocusController> create(Page*);
 
-    void setFocusedFrame(PassRefPtr<Frame>);
-    Frame* focusedFrame() const { return m_focusedFrame.get(); }
-    Frame* focusedOrMainFrame() const;
+    void setFocusedFrame(PassRefPtr<LocalFrame>);
+    LocalFrame* focusedFrame() const { return m_focusedFrame.get(); }
+    LocalFrame* focusedOrMainFrame() const;
 
     bool setInitialFocus(FocusType);
     bool advanceFocus(FocusType type) { return advanceFocus(type, false); }
 
-    bool setFocusedElement(Element*, PassRefPtr<Frame>, FocusType = FocusTypeNone);
+    bool setFocusedElement(Element*, PassRefPtr<LocalFrame>, FocusType = FocusTypeNone);
 
     void setActive(bool);
     bool isActive() const { return m_isActive; }
@@ -115,7 +115,7 @@
     void findFocusCandidateInContainer(Node& container, const LayoutRect& startingRect, FocusType, FocusCandidate& closest);
 
     Page* m_page;
-    RefPtr<Frame> m_focusedFrame;
+    RefPtr<LocalFrame> m_focusedFrame;
     bool m_isActive;
     bool m_isFocused;
     bool m_isChangingFocusedFrame;
diff --git a/Source/core/page/FrameTree.cpp b/Source/core/page/FrameTree.cpp
index cc01cfb..eb28334 100644
--- a/Source/core/page/FrameTree.cpp
+++ b/Source/core/page/FrameTree.cpp
@@ -22,11 +22,10 @@
 #include "core/page/FrameTree.h"
 
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoaderClient.h"
 #include "core/page/Page.h"
-#include "core/page/PageGroup.h"
 #include "wtf/Vector.h"
 #include "wtf/text/CString.h"
 #include "wtf/text/StringBuilder.h"
@@ -41,7 +40,7 @@
 
 } // namespace
 
-FrameTree::FrameTree(Frame* thisFrame)
+FrameTree::FrameTree(LocalFrame* thisFrame)
     : m_thisFrame(thisFrame)
     , m_scopedChildCount(invalidChildCount)
 {
@@ -49,9 +48,9 @@
 
 FrameTree::~FrameTree()
 {
-    // FIXME: Why is this here? Doesn't this parallel what we already do in ~Frame?
-    for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
-        child->setView(0);
+    // FIXME: Why is this here? Doesn't this parallel what we already do in ~LocalFrame?
+    for (LocalFrame* child = firstChild(); child; child = child->tree().nextSibling())
+        child->setView(nullptr);
 }
 
 void FrameTree::setName(const AtomicString& name)
@@ -65,50 +64,56 @@
     m_uniqueName = parent()->tree().uniqueChildName(name);
 }
 
-Frame* FrameTree::parent() const
+LocalFrame* FrameTree::parent() const
 {
     if (!m_thisFrame->loader().client())
         return 0;
-    return m_thisFrame->loader().client()->parent();
+    // FIXME: Temporary hack to stage converting locations that really should be Frame.
+    return toLocalFrame(m_thisFrame->loader().client()->parent());
 }
 
-Frame* FrameTree::top() const
+LocalFrame* FrameTree::top() const
 {
     // FIXME: top() should never return null, so here are some hacks to deal
     // with EmptyFrameLoaderClient and cases where the frame is detached
     // already...
     if (!m_thisFrame->loader().client())
         return m_thisFrame;
-    Frame* candidate = m_thisFrame->loader().client()->top();
+    // FIXME: Temporary hack to stage converting locations that really should be Frame.
+    LocalFrame* candidate = toLocalFrame(m_thisFrame->loader().client()->top());
     return candidate ? candidate : m_thisFrame;
 }
 
-Frame* FrameTree::previousSibling() const
+LocalFrame* FrameTree::previousSibling() const
 {
     if (!m_thisFrame->loader().client())
         return 0;
-    return m_thisFrame->loader().client()->previousSibling();
+    // FIXME: Temporary hack to stage converting locations that really should be Frame.
+    return toLocalFrame(m_thisFrame->loader().client()->previousSibling());
 }
 
-Frame* FrameTree::nextSibling() const
+LocalFrame* FrameTree::nextSibling() const
 {
     if (!m_thisFrame->loader().client())
         return 0;
-    return m_thisFrame->loader().client()->nextSibling();
+    // FIXME: Temporary hack to stage converting locations that really should be Frame.
+    return toLocalFrame(m_thisFrame->loader().client()->nextSibling());
 }
 
-Frame* FrameTree::firstChild() const
+LocalFrame* FrameTree::firstChild() const
 {
     if (!m_thisFrame->loader().client())
         return 0;
-    return m_thisFrame->loader().client()->firstChild();
+    // FIXME: Temporary hack to stage converting locations that really should be Frame.
+    return toLocalFrame(m_thisFrame->loader().client()->firstChild());
 }
 
-Frame* FrameTree::lastChild() const
+LocalFrame* FrameTree::lastChild() const
 {
     if (!m_thisFrame->loader().client())
         return 0;
-    return m_thisFrame->loader().client()->lastChild();
+    // FIXME: Temporary hack to stage converting locations that really should be Frame.
+    return toLocalFrame(m_thisFrame->loader().client()->lastChild());
 }
 
 AtomicString FrameTree::uniqueChildName(const AtomicString& requestedName) const
@@ -128,8 +133,8 @@
     const int framePathSuffixLength = 3;
 
     // Find the nearest parent that has a frame with a path in it.
-    Vector<Frame*, 16> chain;
-    Frame* frame;
+    Vector<LocalFrame*, 16> chain;
+    LocalFrame* frame;
     for (frame = m_thisFrame; frame; frame = frame->tree().parent()) {
         if (frame->tree().uniqueName().startsWith(framePathPrefix))
             break;
@@ -154,14 +159,14 @@
     return name.toAtomicString();
 }
 
-Frame* FrameTree::scopedChild(unsigned index) const
+LocalFrame* FrameTree::scopedChild(unsigned index) const
 {
     TreeScope* scope = m_thisFrame->document();
     if (!scope)
         return 0;
 
     unsigned scopedIndex = 0;
-    for (Frame* result = firstChild(); result; result = result->tree().nextSibling()) {
+    for (LocalFrame* result = firstChild(); result; result = result->tree().nextSibling()) {
         if (result->inScope(scope)) {
             if (scopedIndex == index)
                 return result;
@@ -172,13 +177,13 @@
     return 0;
 }
 
-Frame* FrameTree::scopedChild(const AtomicString& name) const
+LocalFrame* FrameTree::scopedChild(const AtomicString& name) const
 {
     TreeScope* scope = m_thisFrame->document();
     if (!scope)
         return 0;
 
-    for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
+    for (LocalFrame* child = firstChild(); child; child = child->tree().nextSibling())
         if (child->tree().uniqueName() == name && child->inScope(scope))
             return child;
     return 0;
@@ -190,7 +195,7 @@
         return 0;
 
     unsigned scopedCount = 0;
-    for (Frame* result = firstChild(); result; result = result->tree().nextSibling()) {
+    for (LocalFrame* result = firstChild(); result; result = result->tree().nextSibling()) {
         if (result->inScope(scope))
             scopedCount++;
     }
@@ -213,20 +218,20 @@
 unsigned FrameTree::childCount() const
 {
     unsigned count = 0;
-    for (Frame* result = firstChild(); result; result = result->tree().nextSibling())
+    for (LocalFrame* result = firstChild(); result; result = result->tree().nextSibling())
         ++count;
     return count;
 }
 
-Frame* FrameTree::child(const AtomicString& name) const
+LocalFrame* FrameTree::child(const AtomicString& name) const
 {
-    for (Frame* child = firstChild(); child; child = child->tree().nextSibling())
+    for (LocalFrame* child = firstChild(); child; child = child->tree().nextSibling())
         if (child->tree().uniqueName() == name)
             return child;
     return 0;
 }
 
-Frame* FrameTree::find(const AtomicString& name) const
+LocalFrame* FrameTree::find(const AtomicString& name) const
 {
     if (name == "_self" || name == "_current" || name.isEmpty())
         return m_thisFrame;
@@ -242,7 +247,7 @@
         return 0;
 
     // Search subtree starting with this frame first.
-    for (Frame* frame = m_thisFrame; frame; frame = frame->tree().traverseNext(m_thisFrame))
+    for (LocalFrame* frame = m_thisFrame; frame; frame = frame->tree().traverseNext(m_thisFrame))
         if (frame->tree().uniqueName() == name)
             return frame;
 
@@ -253,18 +258,18 @@
     if (!page)
         return 0;
 
-    for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
+    for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
         if (frame->tree().uniqueName() == name)
             return frame;
 
     // Search the entire tree of each of the other pages in this namespace.
     // FIXME: Is random order OK?
-    const HashSet<Page*>& pages = page->group().pages();
+    const HashSet<Page*>& pages = Page::ordinaryPages();
     HashSet<Page*>::const_iterator end = pages.end();
     for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
         Page* otherPage = *it;
         if (otherPage != page) {
-            for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            for (LocalFrame* frame = otherPage->mainFrame(); frame; frame = frame->tree().traverseNext()) {
                 if (frame->tree().uniqueName() == name)
                     return frame;
             }
@@ -274,7 +279,7 @@
     return 0;
 }
 
-bool FrameTree::isDescendantOf(const Frame* ancestor) const
+bool FrameTree::isDescendantOf(const LocalFrame* ancestor) const
 {
     if (!ancestor)
         return false;
@@ -282,15 +287,15 @@
     if (m_thisFrame->page() != ancestor->page())
         return false;
 
-    for (Frame* frame = m_thisFrame; frame; frame = frame->tree().parent())
+    for (LocalFrame* frame = m_thisFrame; frame; frame = frame->tree().parent())
         if (frame == ancestor)
             return true;
     return false;
 }
 
-Frame* FrameTree::traverseNext(const Frame* stayWithin) const
+LocalFrame* FrameTree::traverseNext(const LocalFrame* stayWithin) const
 {
-    Frame* child = firstChild();
+    LocalFrame* child = firstChild();
     if (child) {
         ASSERT(!stayWithin || child->tree().isDescendantOf(stayWithin));
         return child;
@@ -299,13 +304,13 @@
     if (m_thisFrame == stayWithin)
         return 0;
 
-    Frame* sibling = nextSibling();
+    LocalFrame* sibling = nextSibling();
     if (sibling) {
         ASSERT(!stayWithin || sibling->tree().isDescendantOf(stayWithin));
         return sibling;
     }
 
-    Frame* frame = m_thisFrame;
+    LocalFrame* frame = m_thisFrame;
     while (!sibling && (!stayWithin || frame->tree().parent() != stayWithin)) {
         frame = frame->tree().parent();
         if (!frame)
@@ -321,9 +326,9 @@
     return 0;
 }
 
-Frame* FrameTree::traverseNextWithWrap(bool wrap) const
+LocalFrame* FrameTree::traverseNextWithWrap(bool wrap) const
 {
-    if (Frame* result = traverseNext())
+    if (LocalFrame* result = traverseNext())
         return result;
 
     if (wrap)
@@ -332,13 +337,13 @@
     return 0;
 }
 
-Frame* FrameTree::traversePreviousWithWrap(bool wrap) const
+LocalFrame* FrameTree::traversePreviousWithWrap(bool wrap) const
 {
     // FIXME: besides the wrap feature, this is just the traversePreviousNode algorithm
 
-    if (Frame* prevSibling = previousSibling())
+    if (LocalFrame* prevSibling = previousSibling())
         return prevSibling->tree().deepLastChild();
-    if (Frame* parentFrame = parent())
+    if (LocalFrame* parentFrame = parent())
         return parentFrame;
 
     // no siblings, no parent, self==top
@@ -349,10 +354,10 @@
     return 0;
 }
 
-Frame* FrameTree::deepLastChild() const
+LocalFrame* FrameTree::deepLastChild() const
 {
-    Frame* result = m_thisFrame;
-    for (Frame* last = lastChild(); last; last = last->tree().lastChild())
+    LocalFrame* result = m_thisFrame;
+    for (LocalFrame* last = lastChild(); last; last = last->tree().lastChild())
         result = last;
 
     return result;
@@ -368,7 +373,7 @@
         printf("    ");
 }
 
-static void printFrames(const WebCore::Frame* frame, const WebCore::Frame* targetFrame, int indent)
+static void printFrames(const WebCore::LocalFrame* frame, const WebCore::LocalFrame* targetFrame, int indent)
 {
     if (frame == targetFrame) {
         printf("--> ");
@@ -377,7 +382,7 @@
         printIndent(indent);
 
     WebCore::FrameView* view = frame->view();
-    printf("Frame %p %dx%d\n", frame, view ? view->width() : 0, view ? view->height() : 0);
+    printf("LocalFrame %p %dx%d\n", frame, view ? view->width() : 0, view ? view->height() : 0);
     printIndent(indent);
     printf("  ownerElement=%p\n", frame->ownerElement());
     printIndent(indent);
@@ -387,11 +392,11 @@
     printIndent(indent);
     printf("  uri=%s\n\n", frame->document()->url().string().utf8().data());
 
-    for (WebCore::Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
+    for (WebCore::LocalFrame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
         printFrames(child, targetFrame, indent + 1);
 }
 
-void showFrameTree(const WebCore::Frame* frame)
+void showFrameTree(const WebCore::LocalFrame* frame)
 {
     if (!frame) {
         printf("Null input frame\n");
diff --git a/Source/core/page/FrameTree.h b/Source/core/page/FrameTree.h
index 0ac7be3..563a74c 100644
--- a/Source/core/page/FrameTree.h
+++ b/Source/core/page/FrameTree.h
@@ -24,46 +24,46 @@
 
 namespace WebCore {
 
-    class Frame;
+    class LocalFrame;
     class TreeScope;
 
     class FrameTree {
         WTF_MAKE_NONCOPYABLE(FrameTree);
     public:
-        explicit FrameTree(Frame* thisFrame);
+        explicit FrameTree(LocalFrame* thisFrame);
         ~FrameTree();
 
         const AtomicString& name() const { return m_name; }
         const AtomicString& uniqueName() const { return m_uniqueName; }
         void setName(const AtomicString&);
 
-        Frame* parent() const;
-        Frame* top() const;
-        Frame* previousSibling() const;
-        Frame* nextSibling() const;
-        Frame* firstChild() const;
-        Frame* lastChild() const;
+        LocalFrame* parent() const;
+        LocalFrame* top() const;
+        LocalFrame* previousSibling() const;
+        LocalFrame* nextSibling() const;
+        LocalFrame* firstChild() const;
+        LocalFrame* lastChild() const;
 
-        bool isDescendantOf(const Frame* ancestor) const;
-        Frame* traversePreviousWithWrap(bool) const;
-        Frame* traverseNext(const Frame* stayWithin = 0) const;
-        Frame* traverseNextWithWrap(bool) const;
+        bool isDescendantOf(const LocalFrame* ancestor) const;
+        LocalFrame* traversePreviousWithWrap(bool) const;
+        LocalFrame* traverseNext(const LocalFrame* stayWithin = 0) const;
+        LocalFrame* traverseNextWithWrap(bool) const;
 
-        Frame* child(const AtomicString& name) const;
-        Frame* find(const AtomicString& name) const;
+        LocalFrame* child(const AtomicString& name) const;
+        LocalFrame* find(const AtomicString& name) const;
         unsigned childCount() const;
 
-        Frame* scopedChild(unsigned index) const;
-        Frame* scopedChild(const AtomicString& name) const;
+        LocalFrame* scopedChild(unsigned index) const;
+        LocalFrame* scopedChild(const AtomicString& name) const;
         unsigned scopedChildCount() const;
         void invalidateScopedChildCount();
 
     private:
-        Frame* deepLastChild() const;
+        LocalFrame* deepLastChild() const;
         AtomicString uniqueChildName(const AtomicString& requestedName) const;
         unsigned scopedChildCount(TreeScope*) const;
 
-        Frame* m_thisFrame;
+        LocalFrame* m_thisFrame;
 
         AtomicString m_name; // The actual frame name (may be empty).
         AtomicString m_uniqueName;
@@ -75,7 +75,7 @@
 
 #ifndef NDEBUG
 // Outside the WebCore namespace for ease of invocation from gdb.
-void showFrameTree(const WebCore::Frame*);
+void showFrameTree(const WebCore::LocalFrame*);
 #endif
 
 #endif // FrameTree_h
diff --git a/Source/core/page/HistoryController.cpp b/Source/core/page/HistoryController.cpp
index 9b246ab..14aecd7 100644
--- a/Source/core/page/HistoryController.cpp
+++ b/Source/core/page/HistoryController.cpp
@@ -31,7 +31,7 @@
 #include "config.h"
 #include "core/page/HistoryController.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoader.h"
 #include "core/page/FrameTree.h"
 #include "core/page/Page.h"
@@ -40,25 +40,25 @@
 
 namespace WebCore {
 
-PassOwnPtr<HistoryNode> HistoryNode::create(HistoryEntry* entry, HistoryItem* value)
+PassOwnPtr<HistoryNode> HistoryNode::create(HistoryEntry* entry, HistoryItem* value, int64_t frameID)
 {
-    return adoptPtr(new HistoryNode(entry, value));
+    return adoptPtr(new HistoryNode(entry, value, frameID));
 }
 
-HistoryNode* HistoryNode::addChild(PassRefPtr<HistoryItem> item)
+HistoryNode* HistoryNode::addChild(PassRefPtr<HistoryItem> item, int64_t frameID)
 {
-    m_children.append(HistoryNode::create(m_entry, item.get()));
+    m_children.append(HistoryNode::create(m_entry, item.get(), frameID));
     return m_children.last().get();
 }
 
-PassOwnPtr<HistoryNode> HistoryNode::cloneAndReplace(HistoryEntry* newEntry, HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Frame* currentFrame)
+PassOwnPtr<HistoryNode> HistoryNode::cloneAndReplace(HistoryEntry* newEntry, HistoryItem* newItem, bool clipAtTarget, LocalFrame* targetFrame, LocalFrame* currentFrame)
 {
     bool isNodeBeingNavigated = targetFrame == currentFrame;
     HistoryItem* itemForCreate = isNodeBeingNavigated ? newItem : m_value.get();
-    OwnPtr<HistoryNode> newHistoryNode = create(newEntry, itemForCreate);
+    OwnPtr<HistoryNode> newHistoryNode = create(newEntry, itemForCreate, currentFrame->frameID());
 
     if (!clipAtTarget || !isNodeBeingNavigated) {
-        for (Frame* child = currentFrame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+        for (LocalFrame* child = currentFrame->tree().firstChild(); child; child = child->tree().nextSibling()) {
             HistoryNode* childHistoryNode = m_entry->historyNodeForFrame(child);
             if (!childHistoryNode)
                 continue;
@@ -68,11 +68,12 @@
     return newHistoryNode.release();
 }
 
-HistoryNode::HistoryNode(HistoryEntry* entry, HistoryItem* value)
+HistoryNode::HistoryNode(HistoryEntry* entry, HistoryItem* value, int64_t frameID)
     : m_entry(entry)
     , m_value(value)
 {
-    m_entry->m_framesToItems.add(value->targetFrameID(), this);
+    if (frameID != -1)
+        m_entry->m_framesToItems.add(frameID, this);
     String target = value->target();
     if (target.isNull())
         target = emptyString();
@@ -99,24 +100,24 @@
     m_children.clear();
 }
 
-HistoryEntry::HistoryEntry(HistoryItem* root)
+HistoryEntry::HistoryEntry(HistoryItem* root, int64_t frameID)
 {
-    m_root = HistoryNode::create(this, root);
+    m_root = HistoryNode::create(this, root, frameID);
 }
 
-PassOwnPtr<HistoryEntry> HistoryEntry::create(HistoryItem* root)
+PassOwnPtr<HistoryEntry> HistoryEntry::create(HistoryItem* root, int64_t frameID)
 {
-    return adoptPtr(new HistoryEntry(root));
+    return adoptPtr(new HistoryEntry(root, frameID));
 }
 
-PassOwnPtr<HistoryEntry> HistoryEntry::cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Page* page)
+PassOwnPtr<HistoryEntry> HistoryEntry::cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, LocalFrame* targetFrame, Page* page)
 {
     OwnPtr<HistoryEntry> newEntry = adoptPtr(new HistoryEntry());
     newEntry->m_root = m_root->cloneAndReplace(newEntry.get(), newItem, clipAtTarget, targetFrame, page->mainFrame());
     return newEntry.release();
 }
 
-HistoryNode* HistoryEntry::historyNodeForFrame(Frame* frame)
+HistoryNode* HistoryEntry::historyNodeForFrame(LocalFrame* frame)
 {
     if (HistoryNode* historyNode = m_framesToItems.get(frame->frameID()))
         return historyNode;
@@ -126,7 +127,7 @@
     return m_uniqueNamesToItems.get(target);
 }
 
-HistoryItem* HistoryEntry::itemForFrame(Frame* frame)
+HistoryItem* HistoryEntry::itemForFrame(LocalFrame* frame)
 {
     if (HistoryNode* historyNode = historyNodeForFrame(frame))
         return historyNode->value();
@@ -135,8 +136,6 @@
 
 HistoryController::HistoryController(Page* page)
     : m_page(page)
-    , m_defersLoading(false)
-    , m_deferredCachePolicy(UseProtocolCachePolicy)
 {
 }
 
@@ -144,7 +143,7 @@
 {
 }
 
-void HistoryController::updateBackForwardListForFragmentScroll(Frame* frame, HistoryItem* item)
+void HistoryController::updateBackForwardListForFragmentScroll(LocalFrame* frame, HistoryItem* item)
 {
     createNewBackForwardItem(frame, item, false);
 }
@@ -178,7 +177,7 @@
     }
 }
 
-void HistoryController::recursiveGoToEntry(Frame* frame, HistoryFrameLoadSet& sameDocumentLoads, HistoryFrameLoadSet& differentDocumentLoads)
+void HistoryController::recursiveGoToEntry(LocalFrame* frame, HistoryFrameLoadSet& sameDocumentLoads, HistoryFrameLoadSet& differentDocumentLoads)
 {
     ASSERT(m_provisionalEntry);
     ASSERT(m_currentEntry);
@@ -195,19 +194,17 @@
         return;
     }
 
-    for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
+    for (LocalFrame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
         recursiveGoToEntry(child, sameDocumentLoads, differentDocumentLoads);
 }
 
 void HistoryController::goToItem(HistoryItem* targetItem, ResourceRequestCachePolicy cachePolicy)
 {
-    if (m_defersLoading) {
-        m_deferredItem = targetItem;
-        m_deferredCachePolicy = cachePolicy;
-        return;
-    }
-
-    OwnPtr<HistoryEntry> newEntry = HistoryEntry::create(targetItem);
+    // We don't have enough information to set a correct frame id here. This might be a restore from
+    // disk, and the frame ids might not match up if the state was saved from a different process.
+    // Ensure the HistoryEntry's main frame id matches the actual main frame id. Its subframe ids
+    // are invalid to ensure they don't accidentally match a potentially random frame.
+    OwnPtr<HistoryEntry> newEntry = HistoryEntry::create(targetItem, m_page->mainFrame()->frameID());
     Deque<HistoryNode*> historyNodes;
     historyNodes.append(newEntry->rootHistoryNode());
     while (!historyNodes.isEmpty()) {
@@ -217,7 +214,7 @@
         HistoryNode* historyNode = historyNodes.takeFirst();
         const HistoryItemVector& children = historyNode->value()->children();
         for (size_t i = 0; i < children.size(); i++) {
-            HistoryNode* childHistoryNode = historyNode->addChild(children[i].get());
+            HistoryNode* childHistoryNode = historyNode->addChild(children[i].get(), -1);
             historyNodes.append(childHistoryNode);
         }
         historyNode->value()->clearChildren();
@@ -225,17 +222,7 @@
     goToEntry(newEntry.release(), cachePolicy);
 }
 
-void HistoryController::setDefersLoading(bool defer)
-{
-    m_defersLoading = defer;
-    if (!defer && m_deferredItem) {
-        goToItem(m_deferredItem.get(), m_deferredCachePolicy);
-        m_deferredItem = 0;
-        m_deferredCachePolicy = UseProtocolCachePolicy;
-    }
-}
-
-void HistoryController::updateForInitialLoadInChildFrame(Frame* frame, HistoryItem* item)
+void HistoryController::updateForInitialLoadInChildFrame(LocalFrame* frame, HistoryItem* item)
 {
     ASSERT(frame->tree().parent());
     if (!m_currentEntry)
@@ -243,10 +230,10 @@
     if (HistoryNode* existingNode = m_currentEntry->historyNodeForFrame(frame))
         existingNode->updateValue(item);
     else if (HistoryNode* parentHistoryNode = m_currentEntry->historyNodeForFrame(frame->tree().parent()))
-        parentHistoryNode->addChild(item);
+        parentHistoryNode->addChild(item, frame->frameID());
 }
 
-void HistoryController::updateForCommit(Frame* frame, HistoryItem* item, HistoryCommitType commitType)
+void HistoryController::updateForCommit(LocalFrame* frame, HistoryItem* item, HistoryCommitType commitType)
 {
     if (commitType == BackForwardCommit) {
         if (!m_provisionalEntry)
@@ -278,23 +265,23 @@
 PassRefPtr<HistoryItem> HistoryController::currentItemForExport()
 {
     if (!m_currentEntry)
-        return 0;
+        return nullptr;
     return itemForExport(m_currentEntry->rootHistoryNode());
 }
 
 PassRefPtr<HistoryItem> HistoryController::previousItemForExport()
 {
     if (!m_previousEntry)
-        return 0;
+        return nullptr;
     return itemForExport(m_previousEntry->rootHistoryNode());
 }
 
-HistoryItem* HistoryController::itemForNewChildFrame(Frame* frame) const
+HistoryItem* HistoryController::itemForNewChildFrame(LocalFrame* frame) const
 {
     return m_currentEntry ? m_currentEntry->itemForFrame(frame) : 0;
 }
 
-void HistoryController::removeChildrenForRedirect(Frame* frame)
+void HistoryController::removeChildrenForRedirect(LocalFrame* frame)
 {
     if (!m_provisionalEntry)
         return;
@@ -302,11 +289,11 @@
         node->removeChildren();
 }
 
-void HistoryController::createNewBackForwardItem(Frame* targetFrame, HistoryItem* item, bool clipAtTarget)
+void HistoryController::createNewBackForwardItem(LocalFrame* targetFrame, HistoryItem* item, bool clipAtTarget)
 {
     RefPtr<HistoryItem> newItem = item;
     if (!m_currentEntry) {
-        m_currentEntry = HistoryEntry::create(newItem.get());
+        m_currentEntry = HistoryEntry::create(newItem.get(), targetFrame->frameID());
     } else {
         HistoryItem* oldItem = m_currentEntry->itemForFrame(targetFrame);
         if (!clipAtTarget && oldItem)
diff --git a/Source/core/page/HistoryController.h b/Source/core/page/HistoryController.h
index 433cea0..ec22dea 100644
--- a/Source/core/page/HistoryController.h
+++ b/Source/core/page/HistoryController.h
@@ -40,7 +40,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class HistoryEntry;
 class Page;
 
@@ -93,18 +93,18 @@
 
 class HistoryNode {
 public:
-    static PassOwnPtr<HistoryNode> create(HistoryEntry*, HistoryItem*);
+    static PassOwnPtr<HistoryNode> create(HistoryEntry*, HistoryItem*, int64_t frameID);
     ~HistoryNode() { }
 
-    HistoryNode* addChild(PassRefPtr<HistoryItem>);
-    PassOwnPtr<HistoryNode> cloneAndReplace(HistoryEntry*, HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Frame* currentFrame);
+    HistoryNode* addChild(PassRefPtr<HistoryItem>, int64_t frameID);
+    PassOwnPtr<HistoryNode> cloneAndReplace(HistoryEntry*, HistoryItem* newItem, bool clipAtTarget, LocalFrame* targetFrame, LocalFrame* currentFrame);
     HistoryItem* value() { return m_value.get(); }
     void updateValue(PassRefPtr<HistoryItem> item) { m_value = item; }
     const Vector<OwnPtr<HistoryNode> >& children() const { return m_children; }
     void removeChildren();
 
 private:
-    HistoryNode(HistoryEntry*, HistoryItem*);
+    HistoryNode(HistoryEntry*, HistoryItem*, int64_t frameID);
 
     HistoryEntry* m_entry;
     Vector<OwnPtr<HistoryNode> > m_children;
@@ -114,11 +114,11 @@
 
 class HistoryEntry {
 public:
-    static PassOwnPtr<HistoryEntry> create(HistoryItem* root);
-    PassOwnPtr<HistoryEntry> cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, Frame* targetFrame, Page*);
+    static PassOwnPtr<HistoryEntry> create(HistoryItem* root, int64_t frameID);
+    PassOwnPtr<HistoryEntry> cloneAndReplace(HistoryItem* newItem, bool clipAtTarget, LocalFrame* targetFrame, Page*);
 
-    HistoryNode* historyNodeForFrame(Frame*);
-    HistoryItem* itemForFrame(Frame*);
+    HistoryNode* historyNodeForFrame(LocalFrame*);
+    HistoryItem* itemForFrame(LocalFrame*);
     HistoryItem* root() const { return m_root->value(); }
     HistoryNode* rootHistoryNode() const { return m_root.get(); }
 
@@ -126,7 +126,7 @@
     friend class HistoryNode;
 
     HistoryEntry() { }
-    explicit HistoryEntry(HistoryItem* root);
+    explicit HistoryEntry(HistoryItem* root, int64_t frameID);
 
     OwnPtr<HistoryNode> m_root;
     HashMap<uint64_t, HistoryNode*> m_framesToItems;
@@ -143,33 +143,27 @@
     // navigation, call FrameLoaderClient::navigateBackForward().
     void goToItem(HistoryItem*, ResourceRequestCachePolicy);
 
-    void updateBackForwardListForFragmentScroll(Frame*, HistoryItem*);
-    void updateForCommit(Frame*, HistoryItem*, HistoryCommitType);
+    void updateBackForwardListForFragmentScroll(LocalFrame*, HistoryItem*);
+    void updateForCommit(LocalFrame*, HistoryItem*, HistoryCommitType);
 
     PassRefPtr<HistoryItem> currentItemForExport();
     PassRefPtr<HistoryItem> previousItemForExport();
-    HistoryItem* itemForNewChildFrame(Frame*) const;
-    void removeChildrenForRedirect(Frame*);
-
-    void setDefersLoading(bool);
+    HistoryItem* itemForNewChildFrame(LocalFrame*) const;
+    void removeChildrenForRedirect(LocalFrame*);
 
 private:
     void goToEntry(PassOwnPtr<HistoryEntry>, ResourceRequestCachePolicy);
-    typedef HashMap<RefPtr<Frame>, RefPtr<HistoryItem> > HistoryFrameLoadSet;
-    void recursiveGoToEntry(Frame*, HistoryFrameLoadSet& sameDocumentLoads, HistoryFrameLoadSet& differentDocumentLoads);
+    typedef HashMap<RefPtr<LocalFrame>, RefPtr<HistoryItem> > HistoryFrameLoadSet;
+    void recursiveGoToEntry(LocalFrame*, HistoryFrameLoadSet& sameDocumentLoads, HistoryFrameLoadSet& differentDocumentLoads);
 
-    void updateForInitialLoadInChildFrame(Frame*, HistoryItem*);
-    void createNewBackForwardItem(Frame*, HistoryItem*, bool doClip);
+    void updateForInitialLoadInChildFrame(LocalFrame*, HistoryItem*);
+    void createNewBackForwardItem(LocalFrame*, HistoryItem*, bool doClip);
 
     Page* m_page;
 
     OwnPtr<HistoryEntry> m_currentEntry;
     OwnPtr<HistoryEntry> m_previousEntry;
     OwnPtr<HistoryEntry> m_provisionalEntry;
-
-    bool m_defersLoading;
-    RefPtr<HistoryItem> m_deferredItem;
-    ResourceRequestCachePolicy m_deferredCachePolicy;
 };
 
 } // namespace WebCore
diff --git a/Source/core/page/InjectedStyleSheets.cpp b/Source/core/page/InjectedStyleSheets.cpp
index 561ecd6..80c971b 100644
--- a/Source/core/page/InjectedStyleSheets.cpp
+++ b/Source/core/page/InjectedStyleSheets.cpp
@@ -23,9 +23,8 @@
 
 #include "core/dom/Document.h"
 #include "core/dom/StyleEngine.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
-#include "core/page/PageGroup.h"
 #include "wtf/HashSet.h"
 
 namespace WebCore {
@@ -52,11 +51,11 @@
 void InjectedStyleSheets::invalidateInjectedStyleSheetCacheInAllFrames()
 {
     // Clear our cached sheets and have them just reparse.
-    const HashSet<Page*>& pages = PageGroup::sharedGroup()->pages();
+    const HashSet<Page*>& pages = Page::ordinaryPages();
 
     HashSet<Page*>::const_iterator end = pages.end();
     for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
-        for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
+        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
             frame->document()->styleEngine()->invalidateInjectedStyleSheetCache();
     }
 }
diff --git a/Source/core/page/Page.cpp b/Source/core/page/Page.cpp
index 2b964b3..7795209 100644
--- a/Source/core/page/Page.cpp
+++ b/Source/core/page/Page.cpp
@@ -31,9 +31,9 @@
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/DOMTimer.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/inspector/InspectorController.h"
 #include "core/inspector/InspectorInstrumentation.h"
@@ -47,7 +47,6 @@
 #include "core/page/DragController.h"
 #include "core/page/FocusController.h"
 #include "core/page/FrameTree.h"
-#include "core/page/PageGroup.h"
 #include "core/page/PageLifecycleNotifier.h"
 #include "core/page/PointerLockController.h"
 #include "core/page/StorageClient.h"
@@ -73,14 +72,22 @@
     return allPages;
 }
 
+// static
+HashSet<Page*>& Page::ordinaryPages()
+{
+    DEFINE_STATIC_LOCAL(HashSet<Page*>, ordinaryPages, ());
+    return ordinaryPages;
+}
+
+
 void Page::networkStateChanged(bool online)
 {
-    Vector<RefPtr<Frame> > frames;
+    Vector<RefPtr<LocalFrame> > frames;
 
     // Get all the frames of all the pages in all the page groups
     HashSet<Page*>::iterator end = allPages().end();
     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
-        for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
+        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
             frames.append(frame);
         InspectorInstrumentation::networkStateChanged(*it, online);
     }
@@ -90,7 +97,7 @@
         frames[i]->domWindow()->dispatchEvent(Event::create(eventName));
 }
 
-float deviceScaleFactor(Frame* frame)
+float deviceScaleFactor(LocalFrame* frame)
 {
     if (!frame)
         return 1;
@@ -102,6 +109,7 @@
 
 Page::Page(PageClients& pageClients)
     : SettingsDelegate(Settings::create())
+    , m_animator(this)
     , m_autoscrollController(AutoscrollController::create(*this))
     , m_chrome(Chrome::create(this, pageClients.chromeClient))
     , m_dragCaretController(DragCaretController::create())
@@ -124,7 +132,6 @@
     , m_defersLoading(false)
     , m_pageScaleFactor(1)
     , m_deviceScaleFactor(1)
-    , m_group(0)
     , m_timerAlignmentInterval(DOMTimer::visiblePageAlignmentInterval())
     , m_visibilityState(PageVisibilityStateVisible)
     , m_isCursorVisible(true)
@@ -145,17 +152,16 @@
 
 Page::~Page()
 {
-    m_mainFrame->setView(0);
-    clearPageGroup();
+    m_mainFrame->setView(nullptr);
     allPages().remove(this);
+    if (ordinaryPages().contains(this))
+        ordinaryPages().remove(this);
 
-    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
         frame->willDetachFrameHost();
         frame->detachFromFrameHost();
     }
 
-    m_inspectorController->inspectedPageDestroyed();
-
     if (m_scrollingCoordinator)
         m_scrollingCoordinator->pageDestroyed();
 
@@ -164,6 +170,12 @@
 #endif
 }
 
+void Page::makeOrdinary()
+{
+    ASSERT(!ordinaryPages().contains(this));
+    ordinaryPages().add(this);
+}
+
 ViewportDescription Page::viewportDescription() const
 {
     return mainFrame() && mainFrame()->document() ? mainFrame()->document()->viewportDescription() : ViewportDescription();
@@ -185,7 +197,7 @@
     return String();
 }
 
-PassRefPtr<ClientRectList> Page::nonFastScrollableRects(const Frame* frame)
+PassRefPtr<ClientRectList> Page::nonFastScrollableRects(const LocalFrame* frame)
 {
     if (Document* document = m_mainFrame->document())
         document->updateLayout();
@@ -200,7 +212,7 @@
     return ClientRectList::create(quads);
 }
 
-void Page::setMainFrame(PassRefPtr<Frame> mainFrame)
+void Page::setMainFrame(PassRefPtr<LocalFrame> mainFrame)
 {
     ASSERT(!m_mainFrame); // Should only be called during initialization
     m_mainFrame = mainFrame;
@@ -224,47 +236,23 @@
     m_openedByDOM = true;
 }
 
-void Page::clearPageGroup()
-{
-    if (!m_group)
-        return;
-    m_group->removePage(this);
-    m_group = 0;
-}
-
-void Page::setGroupType(PageGroupType type)
-{
-    clearPageGroup();
-
-    switch (type) {
-    case PrivatePageGroup:
-        m_group = PageGroup::create();
-        break;
-    case SharedPageGroup:
-        m_group = PageGroup::sharedGroup();
-        break;
-    }
-
-    m_group->addPage(this);
-}
-
 void Page::scheduleForcedStyleRecalcForAllPages()
 {
     HashSet<Page*>::iterator end = allPages().end();
     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it)
-        for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
+        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext())
             frame->document()->setNeedsStyleRecalc(SubtreeStyleChange);
 }
 
 void Page::setNeedsRecalcStyleInAllFrames()
 {
-    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
+    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
         frame->document()->styleResolverChanged(RecalcStyleDeferred);
 }
 
 void Page::setNeedsLayoutInAllFrames()
 {
-    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
         if (FrameView* view = frame->view()) {
             view->setNeedsLayout();
             view->scheduleRelayout();
@@ -279,7 +267,7 @@
 
     PluginData::refresh();
 
-    Vector<RefPtr<Frame> > framesNeedingReload;
+    Vector<RefPtr<LocalFrame> > framesNeedingReload;
 
     HashSet<Page*>::iterator end = allPages().end();
     for (HashSet<Page*>::iterator it = allPages().begin(); it != end; ++it) {
@@ -287,12 +275,12 @@
 
         // Clear out the page's plug-in data.
         if (page->m_pluginData)
-            page->m_pluginData = 0;
+            page->m_pluginData = nullptr;
 
         if (!reload)
             continue;
 
-        for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
             if (frame->document()->containsPlugins())
                 framesNeedingReload.append(frame);
         }
@@ -311,7 +299,7 @@
     return m_pluginData.get();
 }
 
-static Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
+static LocalFrame* incrementFrame(LocalFrame* curr, bool forward, bool wrapFlag)
 {
     return forward
         ? curr->tree().traverseNextWithWrap(wrapFlag)
@@ -323,9 +311,9 @@
     if (!mainFrame())
         return;
 
-    Frame* frame = mainFrame();
+    LocalFrame* frame = mainFrame();
     do {
-        frame->document()->markers()->removeMarkers(DocumentMarker::TextMatch);
+        frame->document()->markers().removeMarkers(DocumentMarker::TextMatch);
         frame = incrementFrame(frame, true, false);
     } while (frame);
 }
@@ -336,8 +324,7 @@
         return;
 
     m_defersLoading = defers;
-    m_historyController->setDefersLoading(defers);
-    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
+    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
         frame->loader().setDefersLoading(defers);
 }
 
@@ -355,7 +342,9 @@
         m_chrome->client().deviceOrPageScaleFactorChanged();
 
         if (view)
-            view->viewportConstrainedVisibleContentRectChanged(true, true);
+            view->viewportConstrainedVisibleContentSizeChanged(true, true);
+
+        mainFrame()->loader().saveScrollState();
     }
 
     if (view && view->scrollPosition() != origin)
@@ -378,24 +367,20 @@
 
 void Page::allVisitedStateChanged()
 {
-    HashSet<Page*>::iterator pagesEnd = allPages().end();
-    for (HashSet<Page*>::iterator it = allPages().begin(); it != pagesEnd; ++it) {
+    HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
+    for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
         Page* page = *it;
-        if (page->m_group != PageGroup::sharedGroup())
-            continue;
-        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
+        for (LocalFrame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
             frame->document()->visitedLinkState().invalidateStyleForAllLinks();
     }
 }
 
 void Page::visitedStateChanged(LinkHash linkHash)
 {
-    HashSet<Page*>::iterator pagesEnd = allPages().end();
-    for (HashSet<Page*>::iterator it = allPages().begin(); it != pagesEnd; ++it) {
+    HashSet<Page*>::iterator pagesEnd = ordinaryPages().end();
+    for (HashSet<Page*>::iterator it = ordinaryPages().begin(); it != pagesEnd; ++it) {
         Page* page = *it;
-        if (page->m_group != PageGroup::sharedGroup())
-            continue;
-        for (Frame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
+        for (LocalFrame* frame = page->m_mainFrame.get(); frame; frame = frame->tree().traverseNext())
             frame->document()->visitedLinkState().invalidateStyleForLink(linkHash);
     }
 }
@@ -413,7 +398,7 @@
         return;
 
     m_timerAlignmentInterval = interval;
-    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
+    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNextWithWrap(false)) {
         if (frame->document())
             frame->document()->didChangeTimerAlignmentInterval();
     }
@@ -430,7 +415,7 @@
     ASSERT(m_subframeCount >= 0);
 
     int subframeCount = 0;
-    for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
+    for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
         ++subframeCount;
 
     ASSERT(m_subframeCount + 1 == subframeCount);
@@ -485,7 +470,7 @@
         setNeedsRecalcStyleInAllFrames();
         break;
     case SettingsDelegate::DNSPrefetchingChange:
-        for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
+        for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
             frame->document()->initDNSPrefetch();
         break;
     case SettingsDelegate::MultisamplingChange: {
@@ -495,7 +480,7 @@
         break;
     }
     case SettingsDelegate::ImageLoadingChange:
-        for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
             frame->document()->fetcher()->setImagesEnabled(settings().imagesEnabled());
             frame->document()->fetcher()->setAutoLoadImages(settings().loadsImagesAutomatically());
         }
@@ -506,7 +491,7 @@
             setNeedsRecalcStyleInAllFrames();
         } else {
             // FIXME: I wonder if this needs to traverse frames like in WebViewImpl::resize, or whether there is only one document per Settings instance?
-            for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
+            for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext()) {
                 TextAutosizer* textAutosizer = frame->document()->textAutosizer();
                 if (textAutosizer)
                     textAutosizer->recalculateMultipliers();
@@ -520,14 +505,14 @@
         m_inspectorController->scriptsEnabled(settings().scriptEnabled());
         break;
     case SettingsDelegate::FontFamilyChange:
-        for (Frame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
+        for (LocalFrame* frame = mainFrame(); frame; frame = frame->tree().traverseNext())
             frame->document()->styleEngine()->updateGenericFontFamilySettings();
         setNeedsRecalcStyleInAllFrames();
         break;
     }
 }
 
-void Page::didCommitLoad(Frame* frame)
+void Page::didCommitLoad(LocalFrame* frame)
 {
     lifecycleNotifier().notifyDidCommitLoad(frame);
     if (m_mainFrame == frame) {
diff --git a/Source/core/page/Page.h b/Source/core/page/Page.h
index c043c36..c25fa8d 100644
--- a/Source/core/page/Page.h
+++ b/Source/core/page/Page.h
@@ -25,6 +25,7 @@
 #include "core/frame/SettingsDelegate.h"
 #include "core/frame/UseCounter.h"
 #include "core/page/HistoryController.h"
+#include "core/page/PageAnimator.h"
 #include "core/page/PageVisibilityState.h"
 #include "platform/LifecycleContext.h"
 #include "platform/Supplementable.h"
@@ -50,7 +51,7 @@
 class DragController;
 class EditorClient;
 class FocusController;
-class Frame;
+class LocalFrame;
 class FrameHost;
 class FrameSelection;
 class HaltablePlugin;
@@ -58,7 +59,6 @@
 class InspectorClient;
 class InspectorController;
 class Node;
-class PageGroup;
 class PageLifecycleNotifier;
 class PlatformMouseEvent;
 class PluginData;
@@ -80,7 +80,7 @@
 
 typedef uint64_t LinkHash;
 
-float deviceScaleFactor(Frame*);
+float deviceScaleFactor(LocalFrame*);
 
 class Page FINAL : public Supplementable<Page>, public LifecycleContext<Page>, public SettingsDelegate {
     WTF_MAKE_NONCOPYABLE(Page);
@@ -108,9 +108,13 @@
     explicit Page(PageClients&);
     virtual ~Page();
 
+    void makeOrdinary();
+
     // This method returns all pages, incl. private ones associated with
     // inspector overlay, popups, SVGImage, etc.
     static HashSet<Page*>& allPages();
+    // This method returns all ordinary pages.
+    static HashSet<Page*>& ordinaryPages();
 
     FrameHost& frameHost() { return *m_frameHost; }
 
@@ -127,29 +131,19 @@
 
     HistoryController& historyController() const { return *m_historyController; }
 
-    void setMainFrame(PassRefPtr<Frame>);
-    Frame* mainFrame() const { return m_mainFrame.get(); }
+    void setMainFrame(PassRefPtr<LocalFrame>);
+    LocalFrame* mainFrame() const { return m_mainFrame.get(); }
 
     void documentDetached(Document*);
 
     bool openedByDOM() const;
     void setOpenedByDOM();
 
-    // FIXME: PageGroup should probably just be removed, see comment in PageGroup.h
-    enum PageGroupType { PrivatePageGroup, SharedPageGroup };
-    void setGroupType(PageGroupType);
-    void clearPageGroup();
-    PageGroup& group()
-    {
-        if (!m_group)
-            setGroupType(PrivatePageGroup);
-        return *m_group;
-    }
-
     void incrementSubframeCount() { ++m_subframeCount; }
     void decrementSubframeCount() { ASSERT(m_subframeCount); --m_subframeCount; }
     int subframeCount() const { checkSubframeCountConsistency(); return m_subframeCount; }
 
+    PageAnimator& animator() { return m_animator; }
     Chrome& chrome() const { return *m_chrome; }
     AutoscrollController& autoscrollController() const { return *m_autoscrollController; }
     DragCaretController& dragCaretController() const { return *m_dragCaretController; }
@@ -164,7 +158,7 @@
     ScrollingCoordinator* scrollingCoordinator();
 
     String mainThreadScrollingReasonsAsText();
-    PassRefPtr<ClientRectList> nonFastScrollableRects(const Frame*);
+    PassRefPtr<ClientRectList> nonFastScrollableRects(const LocalFrame*);
 
     Settings& settings() const { return *m_settings; }
     ProgressTracker& progress() const { return *m_progress; }
@@ -222,7 +216,7 @@
     void addMultisamplingChangedObserver(MultisamplingChangedObserver*);
     void removeMultisamplingChangedObserver(MultisamplingChangedObserver*);
 
-    void didCommitLoad(Frame*);
+    void didCommitLoad(LocalFrame*);
 
     static void networkStateChanged(bool online);
     PassOwnPtr<LifecycleNotifier<Page> > createLifecycleNotifier();
@@ -246,6 +240,7 @@
     // SettingsDelegate overrides.
     virtual void settingsChanged(SettingsDelegate::ChangeType) OVERRIDE;
 
+    PageAnimator m_animator;
     const OwnPtr<AutoscrollController> m_autoscrollController;
     const OwnPtr<Chrome> m_chrome;
     const OwnPtr<DragCaretController> m_dragCaretController;
@@ -260,7 +255,7 @@
     const OwnPtr<ProgressTracker> m_progress;
     const OwnPtr<UndoStack> m_undoStack;
 
-    RefPtr<Frame> m_mainFrame;
+    RefPtr<LocalFrame> m_mainFrame;
 
     mutable RefPtr<PluginData> m_pluginData;
 
@@ -281,8 +276,6 @@
     float m_pageScaleFactor;
     float m_deviceScaleFactor;
 
-    RefPtr<PageGroup> m_group;
-
     OwnPtr<StorageNamespace> m_sessionStorage;
 
     double m_timerAlignmentInterval;
diff --git a/Source/core/page/PageAnimator.cpp b/Source/core/page/PageAnimator.cpp
new file mode 100644
index 0000000..8bca069
--- /dev/null
+++ b/Source/core/page/PageAnimator.cpp
@@ -0,0 +1,53 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/page/PageAnimator.h"
+
+#include "core/animation/DocumentAnimations.h"
+#include "core/dom/Document.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/page/Chrome.h"
+#include "core/page/ChromeClient.h"
+#include "core/page/Page.h"
+#include "core/svg/SVGDocumentExtensions.h"
+
+namespace WebCore {
+
+PageAnimator::PageAnimator(Page* page)
+    : m_page(page)
+    , m_animationFramePending(false)
+    , m_servicingAnimations(false)
+{
+}
+
+void PageAnimator::serviceScriptedAnimations(double monotonicAnimationStartTime)
+{
+    m_animationFramePending = false;
+    TemporaryChange<bool> servicing(m_servicingAnimations, true);
+
+    for (RefPtr<LocalFrame> frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        frame->view()->serviceScrollAnimations();
+        DocumentAnimations::updateAnimationTimingForAnimationFrame(*frame->document(), monotonicAnimationStartTime);
+        SVGDocumentExtensions::serviceOnAnimationFrame(*frame->document(), monotonicAnimationStartTime);
+    }
+
+    Vector<RefPtr<Document> > documents;
+    for (LocalFrame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext())
+        documents.append(frame->document());
+
+    for (size_t i = 0; i < documents.size(); ++i)
+        documents[i]->serviceScriptedAnimations(monotonicAnimationStartTime);
+}
+
+void PageAnimator::scheduleVisualUpdate()
+{
+    if (m_animationFramePending || m_servicingAnimations)
+        return;
+    m_page->chrome().scheduleAnimation();
+    ASSERT(m_animationFramePending);
+}
+
+}
diff --git a/Source/core/page/PageAnimator.h b/Source/core/page/PageAnimator.h
new file mode 100644
index 0000000..47a4b9c
--- /dev/null
+++ b/Source/core/page/PageAnimator.h
@@ -0,0 +1,30 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PageAnimator_h
+#define PageAnimator_h
+
+namespace WebCore {
+
+class Page;
+
+class PageAnimator {
+public:
+    explicit PageAnimator(Page*);
+
+    void scheduleVisualUpdate();
+    void serviceScriptedAnimations(double monotonicAnimationStartTime);
+
+    void setAnimationFramePending() { m_animationFramePending = true; }
+    bool isServicingAnimations() const { return m_servicingAnimations; }
+
+private:
+    Page* m_page;
+    bool m_animationFramePending;
+    bool m_servicingAnimations;
+};
+
+}
+
+#endif // PageAnimator_h
diff --git a/Source/core/page/PageGroup.cpp b/Source/core/page/PageGroup.cpp
deleted file mode 100644
index 2893355..0000000
--- a/Source/core/page/PageGroup.cpp
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/page/PageGroup.h"
-
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "wtf/StdLibExtras.h"
-
-namespace WebCore {
-
-PageGroup::PageGroup()
-{
-}
-
-PageGroup::~PageGroup()
-{
-}
-
-PageGroup* PageGroup::sharedGroup()
-{
-    DEFINE_STATIC_REF(PageGroup, staticSharedGroup, (create()));
-    return staticSharedGroup;
-}
-
-void PageGroup::addPage(Page* page)
-{
-    ASSERT(page);
-    ASSERT(!m_pages.contains(page));
-    m_pages.add(page);
-}
-
-void PageGroup::removePage(Page* page)
-{
-    ASSERT(page);
-    ASSERT(m_pages.contains(page));
-    m_pages.remove(page);
-}
-
-} // namespace WebCore
diff --git a/Source/core/page/PageGroup.h b/Source/core/page/PageGroup.h
deleted file mode 100644
index 4ce3bc9..0000000
--- a/Source/core/page/PageGroup.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PageGroup_h
-#define PageGroup_h
-
-#include "core/page/InjectedStyleSheets.h"
-#include "platform/Supplementable.h"
-#include "wtf/HashSet.h"
-#include "wtf/Noncopyable.h"
-#include "wtf/PassRefPtr.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-    class Page;
-
-    // FIXME: This is really more of a "Settings Group" than a Page Group.
-    // It has nothing to do with Page. There is one shared PageGroup
-    // in the renderer process, which all normal Pages belong to. There are also
-    // additional private PageGroups for SVGImage, Inspector Overlay, etc.
-    class PageGroup : public Supplementable<PageGroup>, public RefCounted<PageGroup> {
-        WTF_MAKE_NONCOPYABLE(PageGroup); WTF_MAKE_FAST_ALLOCATED;
-    public:
-        ~PageGroup();
-
-        static PassRefPtr<PageGroup> create() { return adoptRef(new PageGroup()); }
-        static PageGroup* sharedGroup();
-
-        const HashSet<Page*>& pages() const { return m_pages; }
-
-        void addPage(Page*);
-        void removePage(Page*);
-
-    private:
-        PageGroup();
-
-        HashSet<Page*> m_pages;
-    };
-
-} // namespace WebCore
-
-#endif // PageGroup_h
diff --git a/Source/core/page/PageGroupLoadDeferrer.cpp b/Source/core/page/PageGroupLoadDeferrer.cpp
deleted file mode 100644
index be7e7c2..0000000
--- a/Source/core/page/PageGroupLoadDeferrer.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
- * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/page/PageGroupLoadDeferrer.h"
-
-#include "core/dom/Document.h"
-#include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
-#include "core/page/Page.h"
-#include "core/page/PageGroup.h"
-#include "wtf/HashSet.h"
-
-namespace WebCore {
-
-using namespace std;
-
-PageGroupLoadDeferrer::PageGroupLoadDeferrer(Page* page, bool deferSelf)
-{
-    const HashSet<Page*>& pages = page->group().pages();
-
-    HashSet<Page*>::const_iterator end = pages.end();
-    for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
-        Page* otherPage = *it;
-        if ((deferSelf || otherPage != page)) {
-            if (!otherPage->defersLoading()) {
-                m_deferredFrames.append(otherPage->mainFrame());
-
-                // Ensure that we notify the client if the initial empty document is accessed before showing anything
-                // modal, to prevent spoofs while the modal window or sheet is visible.
-                otherPage->mainFrame()->loader().notifyIfInitialDocumentAccessed();
-
-                // This code is not logically part of load deferring, but we do not want JS code executed beneath modal
-                // windows or sheets, which is exactly when PageGroupLoadDeferrer is used.
-                for (Frame* frame = otherPage->mainFrame(); frame; frame = frame->tree().traverseNext())
-                    frame->document()->suspendScheduledTasks();
-            }
-        }
-    }
-
-    size_t count = m_deferredFrames.size();
-    for (size_t i = 0; i < count; ++i)
-        if (Page* page = m_deferredFrames[i]->page())
-            page->setDefersLoading(true);
-}
-
-PageGroupLoadDeferrer::~PageGroupLoadDeferrer()
-{
-    for (size_t i = 0; i < m_deferredFrames.size(); ++i) {
-        if (Page* page = m_deferredFrames[i]->page()) {
-            page->setDefersLoading(false);
-
-            for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
-                frame->document()->resumeScheduledTasks();
-        }
-    }
-}
-
-
-} // namespace WebCore
diff --git a/Source/core/page/PageLifecycleNotifier.h b/Source/core/page/PageLifecycleNotifier.h
index c910e29..0048320 100644
--- a/Source/core/page/PageLifecycleNotifier.h
+++ b/Source/core/page/PageLifecycleNotifier.h
@@ -34,14 +34,14 @@
 namespace WebCore {
 
 class Page;
-class Frame;
+class LocalFrame;
 
 class PageLifecycleNotifier FINAL : public LifecycleNotifier<Page> {
 public:
     static PassOwnPtr<PageLifecycleNotifier> create(Page*);
 
     void notifyPageVisibilityChanged();
-    void notifyDidCommitLoad(Frame*);
+    void notifyDidCommitLoad(LocalFrame*);
 
     virtual void addObserver(Observer*) OVERRIDE;
     virtual void removeObserver(Observer*) OVERRIDE;
@@ -65,7 +65,7 @@
         (*it)->pageVisibilityChanged();
 }
 
-inline void PageLifecycleNotifier::notifyDidCommitLoad(Frame* frame)
+inline void PageLifecycleNotifier::notifyDidCommitLoad(LocalFrame* frame)
 {
     TemporaryChange<IterationType> scope(this->m_iterating, IteratingOverPageObservers);
     for (PageObserverSet::iterator it = m_pageObservers.begin(); it != m_pageObservers.end(); ++it)
diff --git a/Source/core/page/PageLifecycleObserver.h b/Source/core/page/PageLifecycleObserver.h
index 86c0eb0..7b1133c 100644
--- a/Source/core/page/PageLifecycleObserver.h
+++ b/Source/core/page/PageLifecycleObserver.h
@@ -31,7 +31,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class Page;
 
 template<> void observerContext(Page*, LifecycleObserver<Page>*);
@@ -45,7 +45,7 @@
     Page* page() const;
 
     virtual void pageVisibilityChanged() { }
-    virtual void didCommitLoad(Frame*) { }
+    virtual void didCommitLoad(LocalFrame*) { }
 };
 
 } // namespace WebCore
diff --git a/Source/core/page/PagePopupController.cpp b/Source/core/page/PagePopupController.cpp
index 961d96e..d221c42 100644
--- a/Source/core/page/PagePopupController.cpp
+++ b/Source/core/page/PagePopupController.cpp
@@ -44,9 +44,9 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<PagePopupController> PagePopupController::create(PagePopupClient* client)
+PassRefPtrWillBeRawPtr<PagePopupController> PagePopupController::create(PagePopupClient* client)
 {
-    return adoptRef(new PagePopupController(client));
+    return adoptRefWillBeNoop(new PagePopupController(client));
 }
 
 void PagePopupController::setValueAndClosePopup(int numValue, const String& stringValue)
diff --git a/Source/core/page/PagePopupController.h b/Source/core/page/PagePopupController.h
index 7a4846f..1b24343 100644
--- a/Source/core/page/PagePopupController.h
+++ b/Source/core/page/PagePopupController.h
@@ -32,6 +32,7 @@
 #define PagePopupController_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 
@@ -39,9 +40,9 @@
 
 class PagePopupClient;
 
-class PagePopupController : public RefCounted<PagePopupController>, public ScriptWrappable {
+class PagePopupController : public RefCountedWillBeGarbageCollectedFinalized<PagePopupController>, public ScriptWrappable {
 public:
-    static PassRefPtr<PagePopupController> create(PagePopupClient*);
+    static PassRefPtrWillBeRawPtr<PagePopupController> create(PagePopupClient*);
     void setValueAndClosePopup(int numValue, const String& stringValue);
     void setValue(const String&);
     void closePopup();
@@ -51,6 +52,8 @@
     void clearPagePopupClient();
     void histogramEnumeration(const String& name, int sample, int boundaryValue);
 
+    void trace(Visitor*) { }
+
 private:
     explicit PagePopupController(PagePopupClient*);
 
diff --git a/Source/core/page/PagePopupController.idl b/Source/core/page/PagePopupController.idl
index 0a4fbd4..e2c88b2 100644
--- a/Source/core/page/PagePopupController.idl
+++ b/Source/core/page/PagePopupController.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,
     RuntimeEnabled=PagePopup
 ] interface PagePopupController {
diff --git a/Source/core/page/PageSerializer.cpp b/Source/core/page/PageSerializer.cpp
index ccf0a28..e0d3342 100644
--- a/Source/core/page/PageSerializer.cpp
+++ b/Source/core/page/PageSerializer.cpp
@@ -48,11 +48,12 @@
 #include "core/editing/MarkupAccumulator.h"
 #include "core/fetch/FontResource.h"
 #include "core/fetch/ImageResource.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLLinkElement.h"
+#include "core/html/HTMLMetaElement.h"
 #include "core/html/HTMLStyleElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/page/Page.h"
@@ -70,18 +71,17 @@
 
 static bool isCharsetSpecifyingNode(const Node& node)
 {
-    if (!node.isHTMLElement())
+    if (!isHTMLMetaElement(node))
         return false;
 
-    const HTMLElement& element = toHTMLElement(node);
-    if (!element.hasTagName(HTMLNames::metaTag))
-        return false;
+    const HTMLMetaElement& element = toHTMLMetaElement(node);
     HTMLAttributeList attributes;
     if (element.hasAttributes()) {
-        for (unsigned i = 0; i < element.attributeCount(); ++i) {
-            const Attribute* attribute = element.attributeItem(i);
+        unsigned attributeCount = element.attributeCount();
+        for (unsigned i = 0; i < attributeCount; ++i) {
+            const Attribute& attribute = element.attributeItem(i);
             // FIXME: We should deal appropriately with the attribute if they have a namespace.
-            attributes.append(std::make_pair(attribute->name().localName(), attribute->value().string()));
+            attributes.append(std::make_pair(attribute.name().localName(), attribute.value().string()));
         }
     }
     WTF::TextEncoding textEncoding = encodingFromMetaAttributes(attributes);
@@ -90,13 +90,13 @@
 
 static bool shouldIgnoreElement(const Element& element)
 {
-    return element.hasTagName(HTMLNames::scriptTag) || element.hasTagName(HTMLNames::noscriptTag) || isCharsetSpecifyingNode(element);
+    return isHTMLScriptElement(element) || isHTMLNoScriptElement(element) || isCharsetSpecifyingNode(element);
 }
 
 static const QualifiedName& frameOwnerURLAttributeName(const HTMLFrameOwnerElement& frameOwner)
 {
     // FIXME: We should support all frame owners including applets.
-    return frameOwner.hasTagName(HTMLNames::objectTag) ? HTMLNames::dataAttr : HTMLNames::srcAttr;
+    return isHTMLObjectElement(frameOwner) ? HTMLNames::dataAttr : HTMLNames::srcAttr;
 }
 
 class SerializerMarkupAccumulator FINAL : public MarkupAccumulator {
@@ -138,7 +138,7 @@
     if (!shouldIgnoreElement(element))
         MarkupAccumulator::appendElement(out, element, namespaces);
 
-    if (element.hasTagName(HTMLNames::headTag)) {
+    if (isHTMLHeadElement(element)) {
         out.append("<meta charset=\"");
         out.append(m_document.charset());
         out.append("\">");
@@ -153,7 +153,7 @@
         return;
 
     const HTMLFrameOwnerElement& frameOwner = toHTMLFrameOwnerElement(element);
-    Frame* frame = frameOwner.contentFrame();
+    LocalFrame* frame = frameOwner.contentFrame();
     if (!frame)
         return;
 
@@ -183,7 +183,7 @@
     serializeFrame(page->mainFrame());
 }
 
-void PageSerializer::serializeFrame(Frame* frame)
+void PageSerializer::serializeFrame(LocalFrame* frame)
 {
     ASSERT(frame->document());
     Document& document = *frame->document();
@@ -224,33 +224,33 @@
         if (element.isStyledElement())
             retrieveResourcesForProperties(element.inlineStyle(), document);
 
-        if (element.hasTagName(HTMLNames::imgTag)) {
+        if (isHTMLImageElement(element)) {
             HTMLImageElement& imageElement = toHTMLImageElement(element);
             KURL url = document.completeURL(imageElement.getAttribute(HTMLNames::srcAttr));
             ImageResource* cachedImage = imageElement.cachedImage();
             addImageToResources(cachedImage, imageElement.renderer(), url);
-        } else if (element.hasTagName(HTMLNames::inputTag)) {
+        } else if (isHTMLInputElement(element)) {
             HTMLInputElement& inputElement = toHTMLInputElement(element);
             if (inputElement.isImageButton() && inputElement.hasImageLoader()) {
                 KURL url = inputElement.src();
                 ImageResource* cachedImage = inputElement.imageLoader()->image();
                 addImageToResources(cachedImage, inputElement.renderer(), url);
             }
-        } else if (element.hasTagName(HTMLNames::linkTag)) {
+        } else if (isHTMLLinkElement(element)) {
             HTMLLinkElement& linkElement = toHTMLLinkElement(element);
             if (CSSStyleSheet* sheet = linkElement.sheet()) {
                 KURL url = document.completeURL(linkElement.getAttribute(HTMLNames::hrefAttr));
                 serializeCSSStyleSheet(sheet, url);
                 ASSERT(m_resourceURLs.contains(url));
             }
-        } else if (element.hasTagName(HTMLNames::styleTag)) {
+        } else if (isHTMLStyleElement(element)) {
             HTMLStyleElement& styleElement = toHTMLStyleElement(element);
             if (CSSStyleSheet* sheet = styleElement.sheet())
                 serializeCSSStyleSheet(sheet, KURL());
         }
     }
 
-    for (Frame* childFrame = frame->tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling())
+    for (LocalFrame* childFrame = frame->tree().firstChild(); childFrame; childFrame = childFrame->tree().nextSibling())
         serializeFrame(childFrame);
 }
 
@@ -275,9 +275,9 @@
                 continue;
             serializeCSSStyleSheet(importRule->styleSheet(), importURL);
         } else if (rule->type() == CSSRule::FONT_FACE_RULE) {
-            retrieveResourcesForProperties(toCSSFontFaceRule(rule)->styleRule()->properties(), document);
+            retrieveResourcesForProperties(&toCSSFontFaceRule(rule)->styleRule()->properties(), document);
         } else if (rule->type() == CSSRule::STYLE_RULE) {
-            retrieveResourcesForProperties(toCSSStyleRule(rule)->styleRule()->properties(), document);
+            retrieveResourcesForProperties(&toCSSStyleRule(rule)->styleRule()->properties(), document);
         }
     }
 
@@ -344,7 +344,7 @@
     // image properties there might be.
     unsigned propertyCount = styleDeclaration->propertyCount();
     for (unsigned i = 0; i < propertyCount; ++i) {
-        RefPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value();
+        RefPtrWillBeRawPtr<CSSValue> cssValue = styleDeclaration->propertyAt(i).value();
         retrieveResourcesForCSSValue(cssValue.get(), document);
     }
 }
@@ -373,9 +373,9 @@
     }
 }
 
-KURL PageSerializer::urlForBlankFrame(Frame* frame)
+KURL PageSerializer::urlForBlankFrame(LocalFrame* frame)
 {
-    HashMap<Frame*, KURL>::iterator iter = m_blankFrameURLs.find(frame);
+    HashMap<LocalFrame*, KURL>::iterator iter = m_blankFrameURLs.find(frame);
     if (iter != m_blankFrameURLs.end())
         return iter->value;
     String url = "wyciwyg://frame/" + String::number(m_blankFrameCounter++);
diff --git a/Source/core/page/PageSerializer.h b/Source/core/page/PageSerializer.h
index 05b5f32..6c390d5 100644
--- a/Source/core/page/PageSerializer.h
+++ b/Source/core/page/PageSerializer.h
@@ -44,7 +44,7 @@
 class CSSStyleSheet;
 class CSSValue;
 class Document;
-class Frame;
+class LocalFrame;
 class Page;
 class RenderObject;
 class Resource;
@@ -66,10 +66,10 @@
     // vector is the top frame serialized content.
     void serialize(Page*);
 
-    KURL urlForBlankFrame(Frame*);
+    KURL urlForBlankFrame(LocalFrame*);
 
 private:
-    void serializeFrame(Frame*);
+    void serializeFrame(LocalFrame*);
 
     // Serializes the stylesheet back to text and adds it to the resources if URL is not-empty.
     // It also adds any resources included in that stylesheet (including any imported stylesheets and their own resources).
@@ -86,7 +86,7 @@
 
     Vector<SerializedResource>* m_resources;
     ListHashSet<KURL> m_resourceURLs;
-    HashMap<Frame*, KURL> m_blankFrameURLs;
+    HashMap<LocalFrame*, KURL> m_blankFrameURLs;
     unsigned m_blankFrameCounter;
 };
 
diff --git a/Source/core/page/PointerLockController.cpp b/Source/core/page/PointerLockController.cpp
index 9866aa8..ab377a3 100644
--- a/Source/core/page/PointerLockController.cpp
+++ b/Source/core/page/PointerLockController.cpp
@@ -125,7 +125,7 @@
 {
     enqueueEvent(EventTypeNames::webkitpointerlockchange, m_element ? &m_element->document() : m_documentOfRemovedElementWhileWaitingForUnlock.get());
     clearElement();
-    m_documentOfRemovedElementWhileWaitingForUnlock = 0;
+    m_documentOfRemovedElementWhileWaitingForUnlock = nullptr;
 }
 
 void PointerLockController::dispatchLockedMouseEvent(const PlatformMouseEvent& event, const AtomicString& eventType)
@@ -143,7 +143,7 @@
 void PointerLockController::clearElement()
 {
     m_lockPending = false;
-    m_element = 0;
+    m_element = nullptr;
 }
 
 void PointerLockController::enqueueEvent(const AtomicString& type, Element* element)
diff --git a/Source/core/page/PrintContext.cpp b/Source/core/page/PrintContext.cpp
index cded884..c25100e 100644
--- a/Source/core/page/PrintContext.cpp
+++ b/Source/core/page/PrintContext.cpp
@@ -21,8 +21,8 @@
 #include "config.h"
 #include "core/page/PrintContext.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderView.h"
 #include "platform/graphics/GraphicsContext.h"
 
@@ -41,7 +41,7 @@
 // behavior matches MacIE and Mozilla, at least)
 const float printingMaximumShrinkFactor = 2;
 
-PrintContext::PrintContext(Frame* frame)
+PrintContext::PrintContext(LocalFrame* frame)
     : m_frame(frame)
     , m_isPrinting(false)
     , m_linkedDestinationsValid(false)
@@ -244,7 +244,7 @@
     if (!box)
         return -1;
 
-    Frame* frame = element->document().frame();
+    LocalFrame* frame = element->document().frame();
     FloatRect pageRect(FloatPoint(0, 0), pageSizeInPixels);
     PrintContext printContext(frame);
     printContext.begin(pageRect.width(), pageRect.height());
@@ -305,7 +305,7 @@
     }
 }
 
-String PrintContext::pageProperty(Frame* frame, const char* propertyName, int pageNumber)
+String PrintContext::pageProperty(LocalFrame* frame, const char* propertyName, int pageNumber)
 {
     Document* document = frame->document();
     PrintContext printContext(frame);
@@ -331,12 +331,12 @@
     return String("pageProperty() unimplemented for: ") + propertyName;
 }
 
-bool PrintContext::isPageBoxVisible(Frame* frame, int pageNumber)
+bool PrintContext::isPageBoxVisible(LocalFrame* frame, int pageNumber)
 {
     return frame->document()->isPageBoxVisible(pageNumber);
 }
 
-String PrintContext::pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
+String PrintContext::pageSizeAndMarginsInPixels(LocalFrame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft)
 {
     IntSize pageSize(width, height);
     frame->document()->pageSizeAndMarginsInPixels(pageNumber, pageSize, marginTop, marginRight, marginBottom, marginLeft);
@@ -345,7 +345,7 @@
            String::number(marginTop) + ' ' + String::number(marginRight) + ' ' + String::number(marginBottom) + ' ' + String::number(marginLeft);
 }
 
-int PrintContext::numberOfPages(Frame* frame, const FloatSize& pageSizeInPixels)
+int PrintContext::numberOfPages(LocalFrame* frame, const FloatSize& pageSizeInPixels)
 {
     frame->document()->updateLayout();
 
@@ -359,7 +359,7 @@
     return printContext.pageCount();
 }
 
-void PrintContext::spoolAllPagesWithBoundaries(Frame* frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
+void PrintContext::spoolAllPagesWithBoundaries(LocalFrame* frame, GraphicsContext& graphicsContext, const FloatSize& pageSizeInPixels)
 {
     if (!frame->document() || !frame->view() || !frame->document()->renderer())
         return;
diff --git a/Source/core/page/PrintContext.h b/Source/core/page/PrintContext.h
index d71a443..728498c 100644
--- a/Source/core/page/PrintContext.h
+++ b/Source/core/page/PrintContext.h
@@ -29,7 +29,7 @@
 namespace WebCore {
 
 class Element;
-class Frame;
+class LocalFrame;
 class FloatRect;
 class FloatSize;
 class GraphicsContext;
@@ -38,10 +38,10 @@
 
 class PrintContext {
 public:
-    explicit PrintContext(Frame*);
+    explicit PrintContext(LocalFrame*);
     ~PrintContext();
 
-    Frame* frame() const { return m_frame; }
+    LocalFrame* frame() const { return m_frame; }
 
     // Break up a page into rects without relayout.
     // FIXME: This means that CSS page breaks won't be on page boundary if the size is different than what was passed to begin(). That's probably not always desirable.
@@ -73,19 +73,19 @@
 
     // Used by layout tests.
     static int pageNumberForElement(Element*, const FloatSize& pageSizeInPixels); // Returns -1 if page isn't found.
-    static String pageProperty(Frame* frame, const char* propertyName, int pageNumber);
-    static bool isPageBoxVisible(Frame* frame, int pageNumber);
-    static String pageSizeAndMarginsInPixels(Frame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft);
-    static int numberOfPages(Frame*, const FloatSize& pageSizeInPixels);
+    static String pageProperty(LocalFrame* frame, const char* propertyName, int pageNumber);
+    static bool isPageBoxVisible(LocalFrame* frame, int pageNumber);
+    static String pageSizeAndMarginsInPixels(LocalFrame* frame, int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft);
+    static int numberOfPages(LocalFrame*, const FloatSize& pageSizeInPixels);
     // Draw all pages into a graphics context with lines which mean page boundaries.
     // The height of the graphics context should be
     // (pageSizeInPixels.height() + 1) * number-of-pages - 1
-    static void spoolAllPagesWithBoundaries(Frame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
+    static void spoolAllPagesWithBoundaries(LocalFrame*, GraphicsContext&, const FloatSize& pageSizeInPixels);
 
 protected:
     void outputLinkedDestinations(GraphicsContext&, Node*, const IntRect& pageRect);
 
-    Frame* m_frame;
+    LocalFrame* m_frame;
     Vector<IntRect> m_pageRects;
 
 private:
diff --git a/Source/core/page/ScopedPageLoadDeferrer.cpp b/Source/core/page/ScopedPageLoadDeferrer.cpp
new file mode 100644
index 0000000..4f22326
--- /dev/null
+++ b/Source/core/page/ScopedPageLoadDeferrer.cpp
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "core/page/ScopedPageLoadDeferrer.h"
+
+#include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
+#include "core/loader/FrameLoader.h"
+#include "core/page/Page.h"
+#include "wtf/HashSet.h"
+
+namespace WebCore {
+
+using namespace std;
+
+ScopedPageLoadDeferrer::ScopedPageLoadDeferrer(Page* exclusion)
+{
+    const HashSet<Page*>& pages = Page::ordinaryPages();
+
+    HashSet<Page*>::const_iterator end = pages.end();
+    for (HashSet<Page*>::const_iterator it = pages.begin(); it != end; ++it) {
+        Page* page = *it;
+        if (page == exclusion || page->defersLoading())
+            continue;
+
+        m_deferredFrames.append(page->mainFrame());
+
+        // Ensure that we notify the client if the initial empty document is accessed before
+        // showing anything modal, to prevent spoofs while the modal window or sheet is visible.
+        page->mainFrame()->loader().notifyIfInitialDocumentAccessed();
+
+        // This code is not logically part of load deferring, but we do not want JS code executed
+        // beneath modal windows or sheets, which is exactly when ScopedPageLoadDeferrer is used.
+        for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
+            frame->document()->suspendScheduledTasks();
+    }
+
+    size_t count = m_deferredFrames.size();
+    for (size_t i = 0; i < count; ++i) {
+        if (Page* page = m_deferredFrames[i]->page())
+            page->setDefersLoading(true);
+    }
+}
+
+ScopedPageLoadDeferrer::~ScopedPageLoadDeferrer()
+{
+    for (size_t i = 0; i < m_deferredFrames.size(); ++i) {
+        if (Page* page = m_deferredFrames[i]->page()) {
+            page->setDefersLoading(false);
+
+            for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext())
+                frame->document()->resumeScheduledTasks();
+        }
+    }
+}
+
+} // namespace WebCore
diff --git a/Source/core/page/PageGroupLoadDeferrer.h b/Source/core/page/ScopedPageLoadDeferrer.h
similarity index 70%
rename from Source/core/page/PageGroupLoadDeferrer.h
rename to Source/core/page/ScopedPageLoadDeferrer.h
index 180707e..3ec0f47 100644
--- a/Source/core/page/PageGroupLoadDeferrer.h
+++ b/Source/core/page/ScopedPageLoadDeferrer.h
@@ -17,26 +17,27 @@
  * Boston, MA 02110-1301, USA.
  */
 
-#ifndef PageGroupLoadDeferrer_h
-#define PageGroupLoadDeferrer_h
+#ifndef ScopedPageLoadDeferrer_h
+#define ScopedPageLoadDeferrer_h
 
 #include "wtf/RefPtr.h"
 #include "wtf/Vector.h"
 
 namespace WebCore {
 
-    class Frame;
-    class Page;
+class LocalFrame;
+class Page;
 
-    class PageGroupLoadDeferrer {
-        WTF_MAKE_NONCOPYABLE(PageGroupLoadDeferrer);
-    public:
-        PageGroupLoadDeferrer(Page*, bool deferSelf);
-        ~PageGroupLoadDeferrer();
+class ScopedPageLoadDeferrer {
+    WTF_MAKE_NONCOPYABLE(ScopedPageLoadDeferrer);
+public:
+    ScopedPageLoadDeferrer(Page* exclusion = 0);
+    ~ScopedPageLoadDeferrer();
 
-    private:
-        Vector<RefPtr<Frame>, 16> m_deferredFrames;
-    };
-}
+private:
+    Vector<RefPtr<LocalFrame>, 16> m_deferredFrames;
+};
 
-#endif // PageGroupLoadDeferrer_h
+} // namespace WebCore
+
+#endif // ScopedPageLoadDeferrer_h
diff --git a/Source/core/page/Selection.idl b/Source/core/page/Selection.idl
index 9c5b2d7..61efec7 100644
--- a/Source/core/page/Selection.idl
+++ b/Source/core/page/Selection.idl
@@ -30,6 +30,7 @@
 // This is based off of Mozilla's Selection interface
 // https://developer.mozilla.org/En/DOM/Selection
 [
+    WillBeGarbageCollected,
     ImplementedAs=DOMSelection
 ] interface Selection {
     readonly attribute Node anchorNode;
diff --git a/Source/core/page/SpatialNavigation.cpp b/Source/core/page/SpatialNavigation.cpp
index fc7bd00..77606dd 100644
--- a/Source/core/page/SpatialNavigation.cpp
+++ b/Source/core/page/SpatialNavigation.cpp
@@ -30,13 +30,13 @@
 #include "core/page/SpatialNavigation.h"
 
 #include "HTMLNames.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
 #include "core/html/HTMLAreaElement.h"
 #include "core/html/HTMLImageElement.h"
-#include "core/frame/Frame.h"
 #include "core/page/FrameTree.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
-#include "core/frame/Settings.h"
 #include "core/rendering/RenderLayer.h"
 #include "platform/geometry/IntRect.h"
 
@@ -50,7 +50,7 @@
 static bool areRectsMoreThanFullScreenApart(FocusType, const LayoutRect& curRect, const LayoutRect& targetRect, const LayoutSize& viewSize);
 static bool isRectInDirection(FocusType, const LayoutRect&, const LayoutRect&);
 static void deflateIfOverlapped(LayoutRect&, LayoutRect&);
-static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect&);
+static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const LayoutRect&);
 static void entryAndExitPointsForDirection(FocusType, const LayoutRect& startingRect, const LayoutRect& potentialRect, LayoutPoint& exitPoint, LayoutPoint& entryPoint);
 static bool isScrollableNode(const Node*);
 
@@ -68,9 +68,9 @@
     ASSERT(node);
     ASSERT(node->isElementNode());
 
-    if (node->hasTagName(areaTag)) {
-        HTMLAreaElement* area = toHTMLAreaElement(node);
-        HTMLImageElement* image = area->imageElement();
+    if (isHTMLAreaElement(*node)) {
+        HTMLAreaElement& area = toHTMLAreaElement(*node);
+        HTMLImageElement* image = area.imageElement();
         if (!image || !image->renderer())
             return;
 
@@ -89,7 +89,7 @@
     isOffscreenAfterScrolling = hasOffscreenRect(visibleNode, type);
 }
 
-bool isSpatialNavigationEnabled(const Frame* frame)
+bool isSpatialNavigationEnabled(const LocalFrame* frame)
 {
     return (frame && frame->settings() && frame->settings()->spatialNavigationEnabled());
 }
@@ -334,7 +334,7 @@
     return !containerViewportRect.intersects(rect);
 }
 
-bool scrollInDirection(Frame* frame, FocusType type)
+bool scrollInDirection(LocalFrame* frame, FocusType type)
 {
     ASSERT(frame);
 
@@ -427,7 +427,7 @@
         return false;
 
     if (RenderObject* renderer = node->renderer())
-        return renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea() && node->hasChildNodes();
+        return renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea() && node->hasChildren();
 
     return false;
 }
@@ -470,7 +470,7 @@
     }
 }
 
-bool canScrollInDirection(const Frame* frame, FocusType type)
+bool canScrollInDirection(const LocalFrame* frame, FocusType type)
 {
     if (!frame->view())
         return false;
@@ -483,7 +483,7 @@
         return false;
     LayoutSize size = frame->view()->contentsSize();
     LayoutSize offset = frame->view()->scrollOffset();
-    LayoutRect rect = frame->view()->visibleContentRect(ScrollableArea::IncludeScrollbars);
+    LayoutRect rect = frame->view()->visibleContentRect(IncludeScrollbars);
 
     switch (type) {
     case FocusTypeLeft:
@@ -500,10 +500,10 @@
     }
 }
 
-static LayoutRect rectToAbsoluteCoordinates(Frame* initialFrame, const LayoutRect& initialRect)
+static LayoutRect rectToAbsoluteCoordinates(LocalFrame* initialFrame, const LayoutRect& initialRect)
 {
     LayoutRect rect = initialRect;
-    for (Frame* frame = initialFrame; frame; frame = frame->tree().parent()) {
+    for (LocalFrame* frame = initialFrame; frame; frame = frame->tree().parent()) {
         if (Element* element = frame->ownerElement()) {
             do {
                 rect.move(element->offsetLeft(), element->offsetTop());
@@ -532,7 +532,7 @@
     return rect;
 }
 
-LayoutRect frameRectInAbsoluteCoordinates(Frame* frame)
+LayoutRect frameRectInAbsoluteCoordinates(LocalFrame* frame)
 {
     return rectToAbsoluteCoordinates(frame, frame->view()->visibleContentRect());
 }
@@ -605,7 +605,7 @@
     if (!firstCandidate.rect.intersects(secondCandidate.rect))
         return false;
 
-    if (firstCandidate.focusableNode->hasTagName(areaTag) || secondCandidate.focusableNode->hasTagName(areaTag))
+    if (isHTMLAreaElement(*firstCandidate.focusableNode) || isHTMLAreaElement(*secondCandidate.focusableNode))
         return false;
 
     if (!firstCandidate.visibleNode->renderer()->isRenderInline() || !secondCandidate.visibleNode->renderer()->isRenderInline())
@@ -722,13 +722,12 @@
     return virtualStartingRect;
 }
 
-LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement* area, FocusType type)
+LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement& area, FocusType type)
 {
-    ASSERT(area);
-    ASSERT(area->imageElement());
+    ASSERT(area.imageElement());
     // Area elements tend to overlap more than other focusable elements. We flatten the rect of the area elements
     // to minimize the effect of overlapping areas.
-    LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(area->document().frame(), area->computeRect(area->imageElement()->renderer())), 1);
+    LayoutRect rect = virtualRectForDirection(type, rectToAbsoluteCoordinates(area.document().frame(), area.computeRect(area.imageElement()->renderer())), 1);
     return rect;
 }
 
diff --git a/Source/core/page/SpatialNavigation.h b/Source/core/page/SpatialNavigation.h
index 616dada..5a9942e 100644
--- a/Source/core/page/SpatialNavigation.h
+++ b/Source/core/page/SpatialNavigation.h
@@ -31,7 +31,7 @@
 namespace WebCore {
 
 class Element;
-class Frame;
+class LocalFrame;
 class HTMLAreaElement;
 class IntRect;
 class RenderObject;
@@ -46,7 +46,7 @@
     return 2;
 }
 
-bool isSpatialNavigationEnabled(const Frame*);
+bool isSpatialNavigationEnabled(const LocalFrame*);
 
 // Spatially speaking, two given elements in a web page can be:
 // 1) Fully aligned: There is a full intersection between the rects, either
@@ -134,18 +134,18 @@
 };
 
 bool hasOffscreenRect(Node*, FocusType = FocusTypeNone);
-bool scrollInDirection(Frame*, FocusType);
+bool scrollInDirection(LocalFrame*, FocusType);
 bool scrollInDirection(Node* container, FocusType);
 bool canScrollInDirection(const Node* container, FocusType);
-bool canScrollInDirection(const Frame*, FocusType);
+bool canScrollInDirection(const LocalFrame*, FocusType);
 bool canBeScrolledIntoView(FocusType, const FocusCandidate&);
 bool areElementsOnSameLine(const FocusCandidate& firstCandidate, const FocusCandidate& secondCandidate);
 void distanceDataForNode(FocusType, const FocusCandidate& current, FocusCandidate&);
 Node* scrollableEnclosingBoxOrParentFrameForNodeInDirection(FocusType, Node*);
 LayoutRect nodeRectInAbsoluteCoordinates(Node*, bool ignoreBorder = false);
-LayoutRect frameRectInAbsoluteCoordinates(Frame*);
+LayoutRect frameRectInAbsoluteCoordinates(LocalFrame*);
 LayoutRect virtualRectForDirection(FocusType, const LayoutRect& startingRect, LayoutUnit width = 0);
-LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement*, FocusType);
+LayoutRect virtualRectForAreaElementAndDirection(HTMLAreaElement&, FocusType);
 HTMLFrameOwnerElement* frameOwnerElement(FocusCandidate&);
 
 } // namspace WebCore
diff --git a/Source/core/page/StorageClient.h b/Source/core/page/StorageClient.h
index 331d23c..7017df0 100644
--- a/Source/core/page/StorageClient.h
+++ b/Source/core/page/StorageClient.h
@@ -17,7 +17,7 @@
     virtual ~StorageClient() { }
 
     virtual PassOwnPtr<StorageNamespace> createSessionStorageNamespace() = 0;
-    virtual bool canAccessStorage(Frame*, StorageType) const = 0;
+    virtual bool canAccessStorage(LocalFrame*, StorageType) const = 0;
 };
 
 } // namespace WebCore
diff --git a/Source/core/page/TouchAdjustment.cpp b/Source/core/page/TouchAdjustment.cpp
index be85ae4..e61824a 100644
--- a/Source/core/page/TouchAdjustment.cpp
+++ b/Source/core/page/TouchAdjustment.cpp
@@ -26,9 +26,9 @@
 #include "core/dom/NodeRenderStyle.h"
 #include "core/dom/Text.h"
 #include "core/editing/Editor.h"
-#include "core/html/HTMLFrameOwnerElement.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLFrameOwnerElement.h"
 #include "core/rendering/RenderBox.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/RenderText.h"
diff --git a/Source/core/page/TouchDisambiguation.cpp b/Source/core/page/TouchDisambiguation.cpp
index 9d9b8c0..56ff16c 100644
--- a/Source/core/page/TouchDisambiguation.cpp
+++ b/Source/core/page/TouchDisambiguation.cpp
@@ -38,9 +38,10 @@
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/NodeTraversal.h"
-#include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLHtmlElement.h"
+#include "core/page/EventHandler.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/RenderBlock.h"
 
@@ -87,7 +88,7 @@
     float score;
 };
 
-void findGoodTouchTargets(const IntRect& touchBox, Frame* mainFrame, Vector<IntRect>& goodTargets, Vector<Node*>& highlightNodes)
+void findGoodTouchTargets(const IntRect& touchBox, LocalFrame* mainFrame, Vector<IntRect>& goodTargets, Vector<Node*>& highlightNodes)
 {
     goodTargets.clear();
 
@@ -125,7 +126,7 @@
         for (Node* node = it->get(); node; node = node->parentNode()) {
             if (blackList.contains(node))
                 continue;
-            if (node->isDocumentNode() || node->hasTagName(HTMLNames::htmlTag) || node->hasTagName(HTMLNames::bodyTag))
+            if (node->isDocumentNode() || isHTMLHtmlElement(*node) || isHTMLBodyElement(*node))
                 break;
             if (node->willRespondToMouseClickEvents()) {
                 TouchTargetData& targetData = touchTargets.add(node, TouchTargetData()).storedValue->value;
diff --git a/Source/core/page/TouchDisambiguation.h b/Source/core/page/TouchDisambiguation.h
index 36352a9..8741cdc 100644
--- a/Source/core/page/TouchDisambiguation.h
+++ b/Source/core/page/TouchDisambiguation.h
@@ -35,11 +35,11 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class IntRect;
 class Node;
 
-void findGoodTouchTargets(const IntRect& touchBox, Frame* mainFrame, Vector<IntRect>& goodTargets, Vector<Node*>& highlightNodes);
+void findGoodTouchTargets(const IntRect& touchBox, LocalFrame* mainFrame, Vector<IntRect>& goodTargets, Vector<Node*>& highlightNodes);
 
 } // namespace WebCore
 
diff --git a/Source/core/page/scrolling/ScrollingCoordinator.cpp b/Source/core/page/scrolling/ScrollingCoordinator.cpp
index 76571fb..c09c01c 100644
--- a/Source/core/page/scrolling/ScrollingCoordinator.cpp
+++ b/Source/core/page/scrolling/ScrollingCoordinator.cpp
@@ -32,8 +32,8 @@
 #include "core/dom/Node.h"
 #include "core/dom/WheelController.h"
 #include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "platform/TraceEvent.h"
@@ -48,10 +48,10 @@
 #include "platform/scroll/ScrollAnimator.h"
 #include "platform/scroll/ScrollbarTheme.h"
 #include "core/plugins/PluginView.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/RenderGeometryMap.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "public/platform/Platform.h"
 #include "public/platform/WebCompositorSupport.h"
 #include "public/platform/WebLayerPositionConstraint.h"
@@ -66,29 +66,17 @@
 using blink::WebScrollbarLayer;
 using blink::WebVector;
 
+namespace {
+
+WebLayer* toWebLayer(WebCore::GraphicsLayer* layer)
+{
+    return layer ? layer->platformLayer() : 0;
+}
+
+} // namespace
 
 namespace WebCore {
 
-static WebLayer* scrollingWebLayerForGraphicsLayer(GraphicsLayer* layer)
-{
-    return layer->platformLayer();
-}
-
-WebLayer* ScrollingCoordinator::scrollingWebLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
-    GraphicsLayer* graphicsLayer = scrollLayerForScrollableArea(scrollableArea);
-    return graphicsLayer ? scrollingWebLayerForGraphicsLayer(graphicsLayer) : 0;
-}
-
-WebLayer* ScrollingCoordinator::containerWebLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
-    GraphicsLayer* graphicsLayer = scrollLayerForScrollableArea(scrollableArea);
-    if (!graphicsLayer)
-        return 0;
-    graphicsLayer = graphicsLayer->parent();
-    return graphicsLayer ? graphicsLayer->platformLayer() : 0;
-}
-
 PassOwnPtr<ScrollingCoordinator> ScrollingCoordinator::create(Page* page)
 {
     return adoptPtr(new ScrollingCoordinator(page));
@@ -123,7 +111,7 @@
 
 void ScrollingCoordinator::setShouldHandleScrollGestureOnMainThreadRegion(const Region& region)
 {
-    if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(m_page->mainFrame()->view())) {
+    if (WebLayer* scrollLayer = toWebLayer(m_page->mainFrame()->view()->layerForScrolling())) {
         Vector<IntRect> rects = region.rects();
         WebVector<WebRect> webRects(rects.size());
         for (size_t i = 0; i < rects.size(); ++i)
@@ -172,26 +160,26 @@
 
     // The mainFrame view doesn't get included in the FrameTree below, so we
     // update its size separately.
-    if (WebLayer* scrollingWebLayer = frameView ? scrollingWebLayerForScrollableArea(frameView) : 0)
+    if (WebLayer* scrollingWebLayer = frameView ? toWebLayer(frameView->layerForScrolling()) : 0)
         scrollingWebLayer->setBounds(frameView->contentsSize());
 
     const FrameTree& tree = m_page->mainFrame()->tree();
-    for (const Frame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
-        if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(child->view()))
+    for (const LocalFrame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
+        if (WebLayer* scrollLayer = toWebLayer(child->view()->layerForScrolling()))
             scrollLayer->setBounds(child->view()->contentsSize());
     }
 }
 
 void ScrollingCoordinator::setLayerIsContainerForFixedPositionLayers(GraphicsLayer* layer, bool enable)
 {
-    if (WebLayer* scrollableLayer = scrollingWebLayerForGraphicsLayer(layer))
+    if (WebLayer* scrollableLayer = toWebLayer(layer))
         scrollableLayer->setIsContainerForFixedPositionLayers(enable);
 }
 
 static void clearPositionConstraintExceptForLayer(GraphicsLayer* layer, GraphicsLayer* except)
 {
-    if (layer && layer != except && scrollingWebLayerForGraphicsLayer(layer))
-        scrollingWebLayerForGraphicsLayer(layer)->setPositionConstraint(WebLayerPositionConstraint());
+    if (layer && layer != except && toWebLayer(layer))
+        toWebLayer(layer)->setPositionConstraint(WebLayerPositionConstraint());
 }
 
 static WebLayerPositionConstraint computePositionConstraint(const RenderLayer* layer)
@@ -223,7 +211,7 @@
     clearPositionConstraintExceptForLayer(compositedLayerMapping->ancestorClippingLayer(), mainLayer);
     clearPositionConstraintExceptForLayer(compositedLayerMapping->mainGraphicsLayer(), mainLayer);
 
-    if (WebLayer* scrollableLayer = scrollingWebLayerForGraphicsLayer(mainLayer))
+    if (WebLayer* scrollableLayer = toWebLayer(mainLayer))
         scrollableLayer->setPositionConstraint(computePositionConstraint(layer));
 }
 
@@ -314,7 +302,10 @@
     if (!isMainFrame && platformSupportsMainFrameOnly)
         return;
 
-    GraphicsLayer* scrollbarGraphicsLayer = orientation == HorizontalScrollbar ? horizontalScrollbarLayerForScrollableArea(scrollableArea) : verticalScrollbarLayerForScrollableArea(scrollableArea);
+    GraphicsLayer* scrollbarGraphicsLayer = orientation == HorizontalScrollbar
+        ? scrollableArea->layerForHorizontalScrollbar()
+        : scrollableArea->layerForVerticalScrollbar();
+
     if (scrollbarGraphicsLayer) {
         Scrollbar* scrollbar = orientation == HorizontalScrollbar ? scrollableArea->horizontalScrollbar() : scrollableArea->verticalScrollbar();
         if (scrollbar->isCustomScrollbar()) {
@@ -343,8 +334,8 @@
             scrollbarGraphicsLayer->setContentsOpaque(isMainFrame && isOpaqueScrollbar);
         scrollbarLayer->layer()->setOpaque(scrollbarGraphicsLayer->contentsOpaque());
 
-        WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(scrollableArea);
-        WebLayer* containerLayer = containerWebLayerForScrollableArea(scrollableArea);
+        WebLayer* scrollLayer = toWebLayer(scrollableArea->layerForScrolling());
+        WebLayer* containerLayer = toWebLayer(scrollableArea->layerForContainer());
         setupScrollbarLayer(scrollbarGraphicsLayer, scrollbarLayer, scrollLayer, containerLayer);
     } else
         removeWebScrollbarLayer(scrollableArea, orientation);
@@ -352,14 +343,15 @@
 
 bool ScrollingCoordinator::scrollableAreaScrollLayerDidChange(ScrollableArea* scrollableArea)
 {
-    GraphicsLayer* scrollLayer = scrollLayerForScrollableArea(scrollableArea);
+    GraphicsLayer* scrollLayer = scrollableArea->layerForScrolling();
+
     if (scrollLayer) {
         bool isMainFrame = isForMainFrame(scrollableArea);
         scrollLayer->setScrollableArea(scrollableArea, isMainFrame);
     }
 
-    WebLayer* webLayer = scrollingWebLayerForScrollableArea(scrollableArea);
-    WebLayer* containerLayer = containerWebLayerForScrollableArea(scrollableArea);
+    WebLayer* webLayer = toWebLayer(scrollableArea->layerForScrolling());
+    WebLayer* containerLayer = toWebLayer(scrollableArea->layerForContainer());
     if (webLayer) {
         webLayer->setScrollClipLayer(containerLayer);
         webLayer->setScrollPosition(IntPoint(scrollableArea->scrollPosition() - scrollableArea->minimumScrollPosition()));
@@ -369,12 +361,12 @@
         webLayer->setUserScrollable(canScrollX, canScrollY);
     }
     if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, HorizontalScrollbar)) {
-        GraphicsLayer* horizontalScrollbarLayer = horizontalScrollbarLayerForScrollableArea(scrollableArea);
+        GraphicsLayer* horizontalScrollbarLayer = scrollableArea->layerForHorizontalScrollbar();
         if (horizontalScrollbarLayer)
             setupScrollbarLayer(horizontalScrollbarLayer, scrollbarLayer, webLayer, containerLayer);
     }
     if (WebScrollbarLayer* scrollbarLayer = getWebScrollbarLayer(scrollableArea, VerticalScrollbar)) {
-        GraphicsLayer* verticalScrollbarLayer = verticalScrollbarLayerForScrollableArea(scrollableArea);
+        GraphicsLayer* verticalScrollbarLayer = scrollableArea->layerForVerticalScrollbar();
         if (verticalScrollbarLayer)
             setupScrollbarLayer(verticalScrollbarLayer, scrollbarLayer, webLayer, containerLayer);
     }
@@ -386,16 +378,16 @@
 // RenderLayers have child frames inside of them. This computes a mapping for the
 // current frame which we can consult while walking the layers of that frame.
 // Whenever we descend into a new frame, a new map will be created.
-typedef HashMap<const RenderLayer*, Vector<const Frame*> > LayerFrameMap;
-static void makeLayerChildFrameMap(const Frame* currentFrame, LayerFrameMap* map)
+typedef HashMap<const RenderLayer*, Vector<const LocalFrame*> > LayerFrameMap;
+static void makeLayerChildFrameMap(const LocalFrame* currentFrame, LayerFrameMap* map)
 {
     map->clear();
     const FrameTree& tree = currentFrame->tree();
-    for (const Frame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
+    for (const LocalFrame* child = tree.firstChild(); child; child = child->tree().nextSibling()) {
         const RenderLayer* containingLayer = child->ownerRenderer()->enclosingLayer();
         LayerFrameMap::iterator iter = map->find(containingLayer);
         if (iter == map->end())
-            map->add(containingLayer, Vector<const Frame*>()).storedValue->value.append(child);
+            map->add(containingLayer, Vector<const LocalFrame*>()).storedValue->value.append(child);
         else
             iter->value.append(child);
     }
@@ -465,7 +457,7 @@
     LayerFrameMap::iterator mapIter = layerChildFrameMap.find(curLayer);
     if (mapIter != layerChildFrameMap.end()) {
         for (size_t i = 0; i < mapIter->value.size(); i++) {
-            const Frame* childFrame = mapIter->value[i];
+            const LocalFrame* childFrame = mapIter->value[i];
             const RenderLayer* childLayer = childFrame->view()->renderView()->layer();
             if (layersWithRects.contains(childLayer)) {
                 LayerFrameMap newLayerChildFrameMap;
@@ -478,7 +470,7 @@
     }
 }
 
-static void convertLayerRectsToEnclosingCompositedLayer(Frame* mainFrame, const LayerHitTestRects& layerRects, LayerHitTestRects& compositorRects)
+static void convertLayerRectsToEnclosingCompositedLayer(LocalFrame* mainFrame, const LayerHitTestRects& layerRects, LayerHitTestRects& compositorRects)
 {
     TRACE_EVENT0("input", "ScrollingCoordinator::convertLayerRectsToEnclosingCompositedLayer");
     bool touchHandlerInChildFrame = false;
@@ -606,7 +598,7 @@
 {
     WebLayer* scrollParentWebLayer = 0;
     if (parent && parent->hasCompositedLayerMapping())
-        scrollParentWebLayer = scrollingWebLayerForGraphicsLayer(parent->compositedLayerMapping()->parentForSublayers());
+        scrollParentWebLayer = toWebLayer(parent->compositedLayerMapping()->parentForSublayers());
 
     child->setScrollParent(scrollParentWebLayer);
 }
@@ -615,7 +607,7 @@
 {
     WebLayer* clipParentWebLayer = 0;
     if (parent && parent->hasCompositedLayerMapping())
-        clipParentWebLayer = scrollingWebLayerForGraphicsLayer(parent->compositedLayerMapping()->parentForSublayers());
+        clipParentWebLayer = toWebLayer(parent->compositedLayerMapping()->parentForSublayers());
 
     child->setClipParent(clipParentWebLayer);
 }
@@ -627,7 +619,7 @@
 
 void ScrollingCoordinator::setWheelEventHandlerCount(unsigned count)
 {
-    if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(m_page->mainFrame()->view()))
+    if (WebLayer* scrollLayer = toWebLayer(m_page->mainFrame()->view()->layerForScrolling()))
         scrollLayer->setHaveWheelEventHandlers(count > 0);
 }
 
@@ -638,7 +630,7 @@
 
 void ScrollingCoordinator::setShouldUpdateScrollLayerPositionOnMainThread(MainThreadScrollingReasons reasons)
 {
-    if (WebLayer* scrollLayer = scrollingWebLayerForScrollableArea(m_page->mainFrame()->view())) {
+    if (WebLayer* scrollLayer = toWebLayer(m_page->mainFrame()->view()->layerForScrolling())) {
         m_lastMainThreadScrollingReasons = reasons;
         scrollLayer->setShouldScrollOnMainThread(reasons);
     }
@@ -666,7 +658,7 @@
     return renderView->usesCompositing();
 }
 
-Region ScrollingCoordinator::computeShouldHandleScrollGestureOnMainThreadRegion(const Frame* frame, const IntPoint& frameLocation) const
+Region ScrollingCoordinator::computeShouldHandleScrollGestureOnMainThreadRegion(const LocalFrame* frame, const IntPoint& frameLocation) const
 {
     Region shouldHandleScrollGestureOnMainThreadRegion;
     FrameView* frameView = frame->view();
@@ -714,7 +706,7 @@
     }
 
     const FrameTree& tree = frame->tree();
-    for (Frame* subFrame = tree.firstChild(); subFrame; subFrame = subFrame->tree().nextSibling())
+    for (LocalFrame* subFrame = tree.firstChild(); subFrame; subFrame = subFrame->tree().nextSibling())
         shouldHandleScrollGestureOnMainThreadRegion.unite(computeShouldHandleScrollGestureOnMainThreadRegion(subFrame, offset));
 
     return shouldHandleScrollGestureOnMainThreadRegion;
@@ -797,9 +789,9 @@
 {
     unsigned wheelEventHandlerCount = 0;
 
-    for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = m_page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         if (frame->document())
-            wheelEventHandlerCount += WheelController::from(frame->document())->wheelEventHandlerCount();
+            wheelEventHandlerCount += WheelController::from(*frame->document())->wheelEventHandlerCount();
     }
 
     return wheelEventHandlerCount;
@@ -835,21 +827,6 @@
     m_shouldScrollOnMainThreadDirty = true;
 }
 
-GraphicsLayer* ScrollingCoordinator::scrollLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
-    return scrollableArea->layerForScrolling();
-}
-
-GraphicsLayer* ScrollingCoordinator::horizontalScrollbarLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
-    return scrollableArea->layerForHorizontalScrollbar();
-}
-
-GraphicsLayer* ScrollingCoordinator::verticalScrollbarLayerForScrollableArea(ScrollableArea* scrollableArea)
-{
-    return scrollableArea->layerForVerticalScrollbar();
-}
-
 bool ScrollingCoordinator::isForMainFrame(ScrollableArea* scrollableArea) const
 {
     return scrollableArea == m_page->mainFrame()->view();
@@ -967,7 +944,7 @@
     if (frameIsScrollable != m_wasFrameScrollable)
         return true;
 
-    if (WebLayer* scrollLayer = frameView ? scrollingWebLayerForScrollableArea(frameView) : 0)
+    if (WebLayer* scrollLayer = frameView ? toWebLayer(frameView->layerForScrolling()) : 0)
         return blink::WebSize(frameView->contentsSize()) != scrollLayer->bounds();
     return false;
 }
diff --git a/Source/core/page/scrolling/ScrollingCoordinator.h b/Source/core/page/scrolling/ScrollingCoordinator.h
index cad3ee5..2423b1d 100644
--- a/Source/core/page/scrolling/ScrollingCoordinator.h
+++ b/Source/core/page/scrolling/ScrollingCoordinator.h
@@ -42,7 +42,7 @@
 typedef unsigned MainThreadScrollingReasons;
 
 class Document;
-class Frame;
+class LocalFrame;
 class FrameView;
 class GraphicsLayer;
 class Page;
@@ -111,7 +111,7 @@
 
     static String mainThreadScrollingReasonsAsText(MainThreadScrollingReasons);
     String mainThreadScrollingReasonsAsText() const;
-    Region computeShouldHandleScrollGestureOnMainThreadRegion(const Frame*, const IntPoint& frameLocation) const;
+    Region computeShouldHandleScrollGestureOnMainThreadRegion(const LocalFrame*, const IntPoint& frameLocation) const;
 
     void updateTouchEventTargetRectsIfNeeded();
 
@@ -122,9 +122,6 @@
 protected:
     explicit ScrollingCoordinator(Page*);
 
-    static GraphicsLayer* scrollLayerForScrollableArea(ScrollableArea*);
-    static GraphicsLayer* horizontalScrollbarLayerForScrollableArea(ScrollableArea*);
-    static GraphicsLayer* verticalScrollbarLayerForScrollableArea(ScrollableArea*);
     bool isForMainFrame(ScrollableArea*) const;
 
     unsigned computeCurrentWheelEventHandlerCount();
@@ -144,9 +141,6 @@
 
     bool hasVisibleSlowRepaintViewportConstrainedObjects(FrameView*) const;
 
-    static blink::WebLayer* scrollingWebLayerForScrollableArea(ScrollableArea*);
-    static blink::WebLayer* containerWebLayerForScrollableArea(ScrollableArea*);
-
     bool touchHitTestingEnabled() const;
     void setShouldHandleScrollGestureOnMainThreadRegion(const Region&);
     void setTouchEventTargetRects(const LayerHitTestRects&);
diff --git a/Source/core/plugins/DOMMimeType.cpp b/Source/core/plugins/DOMMimeType.cpp
index 84b08e7..75b3210 100644
--- a/Source/core/plugins/DOMMimeType.cpp
+++ b/Source/core/plugins/DOMMimeType.cpp
@@ -19,17 +19,15 @@
 #include "config.h"
 #include "core/plugins/DOMMimeType.h"
 
+#include "core/frame/LocalFrame.h"
 #include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/plugins/DOMPlugin.h"
 #include "wtf/text/StringBuilder.h"
 
 namespace WebCore {
 
-DEFINE_GC_INFO(DOMMimeType);
-
-DOMMimeType::DOMMimeType(PassRefPtr<PluginData> pluginData, Frame* frame, unsigned index)
+DOMMimeType::DOMMimeType(PassRefPtr<PluginData> pluginData, LocalFrame* frame, unsigned index)
     : FrameDestructionObserver(frame)
     , m_pluginData(pluginData)
     , m_index(index)
@@ -70,7 +68,7 @@
     // to bounce through the page or mainframe or loader to get there.
     // Something like: m_frame->host()->client()->allowPlugins().
     if (!m_frame || !m_frame->page() || !m_frame->page()->mainFrame()->loader().allowPlugins(NotAboutToInstantiatePlugin))
-        return 0;
+        return nullptr;
 
     return DOMPlugin::create(m_pluginData.get(), m_frame, m_pluginData->mimePluginIndices()[m_index]);
 }
diff --git a/Source/core/plugins/DOMMimeType.h b/Source/core/plugins/DOMMimeType.h
index e0401be..eaf664f 100644
--- a/Source/core/plugins/DOMMimeType.h
+++ b/Source/core/plugins/DOMMimeType.h
@@ -32,12 +32,11 @@
 namespace WebCore {
 
 class DOMPlugin;
-class Frame;
+class LocalFrame;
 
 class DOMMimeType FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMMimeType>, public ScriptWrappable, public FrameDestructionObserver {
-    DECLARE_GC_INFO;
 public:
-    static PassRefPtrWillBeRawPtr<DOMMimeType> create(PassRefPtr<PluginData> pluginData, Frame* frame, unsigned index)
+    static PassRefPtrWillBeRawPtr<DOMMimeType> create(PassRefPtr<PluginData> pluginData, LocalFrame* frame, unsigned index)
     {
         return adoptRefWillBeNoop(new DOMMimeType(pluginData, frame, index));
     }
@@ -53,7 +52,7 @@
 private:
     const MimeClassInfo& mimeClassInfo() const { return m_pluginData->mimes()[m_index]; }
 
-    DOMMimeType(PassRefPtr<PluginData>, Frame*, unsigned index);
+    DOMMimeType(PassRefPtr<PluginData>, LocalFrame*, unsigned index);
     RefPtr<PluginData> m_pluginData;
     unsigned m_index;
 };
diff --git a/Source/core/plugins/DOMMimeTypeArray.cpp b/Source/core/plugins/DOMMimeTypeArray.cpp
index e2f948b..23e7085 100644
--- a/Source/core/plugins/DOMMimeTypeArray.cpp
+++ b/Source/core/plugins/DOMMimeTypeArray.cpp
@@ -20,16 +20,14 @@
 #include "config.h"
 #include "core/plugins/DOMMimeTypeArray.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 #include "platform/plugins/PluginData.h"
 #include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
-DEFINE_GC_INFO(DOMMimeTypeArray);
-
-DOMMimeTypeArray::DOMMimeTypeArray(Frame* frame)
+DOMMimeTypeArray::DOMMimeTypeArray(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
@@ -51,10 +49,10 @@
 {
     PluginData* data = getPluginData();
     if (!data)
-        return 0;
+        return nullptr;
     const Vector<MimeClassInfo>& mimes = data->mimes();
     if (index >= mimes.size())
-        return 0;
+        return nullptr;
     return DOMMimeType::create(data, m_frame, index).get();
 }
 
@@ -75,13 +73,13 @@
 {
     PluginData *data = getPluginData();
     if (!data)
-        return 0;
+        return nullptr;
     const Vector<MimeClassInfo>& mimes = data->mimes();
     for (unsigned i = 0; i < mimes.size(); ++i) {
         if (mimes[i].type == propertyName)
             return DOMMimeType::create(data, m_frame, i).get();
     }
-    return 0;
+    return nullptr;
 }
 
 PluginData* DOMMimeTypeArray::getPluginData() const
diff --git a/Source/core/plugins/DOMMimeTypeArray.h b/Source/core/plugins/DOMMimeTypeArray.h
index e65562b..6600fd0 100644
--- a/Source/core/plugins/DOMMimeTypeArray.h
+++ b/Source/core/plugins/DOMMimeTypeArray.h
@@ -32,13 +32,12 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class PluginData;
 
 class DOMMimeTypeArray FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMMimeTypeArray>, public ScriptWrappable, public DOMWindowProperty {
-    DECLARE_GC_INFO;
 public:
-    static PassRefPtrWillBeRawPtr<DOMMimeTypeArray> create(Frame* frame)
+    static PassRefPtrWillBeRawPtr<DOMMimeTypeArray> create(LocalFrame* frame)
     {
         return adoptRefWillBeNoop(new DOMMimeTypeArray(frame));
     }
@@ -52,7 +51,7 @@
     void trace(Visitor*) { }
 
 private:
-    explicit DOMMimeTypeArray(Frame*);
+    explicit DOMMimeTypeArray(LocalFrame*);
     PluginData* getPluginData() const;
 };
 
diff --git a/Source/core/plugins/DOMPlugin.cpp b/Source/core/plugins/DOMPlugin.cpp
index 67492d6..03fff43 100644
--- a/Source/core/plugins/DOMPlugin.cpp
+++ b/Source/core/plugins/DOMPlugin.cpp
@@ -24,9 +24,7 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(DOMPlugin);
-
-DOMPlugin::DOMPlugin(PluginData* pluginData, Frame* frame, unsigned index)
+DOMPlugin::DOMPlugin(PluginData* pluginData, LocalFrame* frame, unsigned index)
     : FrameDestructionObserver(frame)
     , m_pluginData(pluginData)
     , m_index(index)
@@ -61,7 +59,7 @@
 PassRefPtrWillBeRawPtr<DOMMimeType> DOMPlugin::item(unsigned index)
 {
     if (index >= pluginInfo().mimes.size())
-        return 0;
+        return nullptr;
 
     const MimeClassInfo& mime = pluginInfo().mimes[index];
 
@@ -70,7 +68,7 @@
         if (mimes[i] == mime && m_pluginData->mimePluginIndices()[i] == m_index)
             return DOMMimeType::create(m_pluginData.get(), m_frame, i).get();
     }
-    return 0;
+    return nullptr;
 }
 
 bool DOMPlugin::canGetItemsForName(const AtomicString& propertyName)
@@ -88,7 +86,7 @@
     for (unsigned i = 0; i < mimes.size(); ++i)
         if (mimes[i].type == propertyName)
             return DOMMimeType::create(m_pluginData.get(), m_frame, i).get();
-    return 0;
+    return nullptr;
 }
 
 } // namespace WebCore
diff --git a/Source/core/plugins/DOMPlugin.h b/Source/core/plugins/DOMPlugin.h
index 2e96015..c823872 100644
--- a/Source/core/plugins/DOMPlugin.h
+++ b/Source/core/plugins/DOMPlugin.h
@@ -34,9 +34,8 @@
 class PluginData;
 
 class DOMPlugin FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMPlugin>, public ScriptWrappable, public FrameDestructionObserver {
-    DECLARE_GC_INFO;
 public:
-    static PassRefPtrWillBeRawPtr<DOMPlugin> create(PluginData* pluginData, Frame* frame, unsigned index)
+    static PassRefPtrWillBeRawPtr<DOMPlugin> create(PluginData* pluginData, LocalFrame* frame, unsigned index)
     {
         return adoptRefWillBeNoop(new DOMPlugin(pluginData, frame, index));
     }
@@ -57,7 +56,7 @@
 private:
     const PluginInfo& pluginInfo() const { return m_pluginData->plugins()[m_index]; }
 
-    DOMPlugin(PluginData*, Frame*, unsigned index);
+    DOMPlugin(PluginData*, LocalFrame*, unsigned index);
     RefPtr<PluginData> m_pluginData;
     unsigned m_index;
 };
diff --git a/Source/core/plugins/DOMPluginArray.cpp b/Source/core/plugins/DOMPluginArray.cpp
index d865985..9975131 100644
--- a/Source/core/plugins/DOMPluginArray.cpp
+++ b/Source/core/plugins/DOMPluginArray.cpp
@@ -20,16 +20,14 @@
 #include "config.h"
 #include "core/plugins/DOMPluginArray.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 #include "platform/plugins/PluginData.h"
 #include "wtf/text/AtomicString.h"
 
 namespace WebCore {
 
-DEFINE_GC_INFO(DOMPluginArray);
-
-DOMPluginArray::DOMPluginArray(Frame* frame)
+DOMPluginArray::DOMPluginArray(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
@@ -51,10 +49,10 @@
 {
     PluginData* data = pluginData();
     if (!data)
-        return 0;
+        return nullptr;
     const Vector<PluginInfo>& plugins = data->plugins();
     if (index >= plugins.size())
-        return 0;
+        return nullptr;
     return DOMPlugin::create(data, m_frame, index).get();
 }
 
@@ -75,13 +73,13 @@
 {
     PluginData* data = pluginData();
     if (!data)
-        return 0;
+        return nullptr;
     const Vector<PluginInfo>& plugins = data->plugins();
     for (unsigned i = 0; i < plugins.size(); ++i) {
         if (plugins[i].name == propertyName)
             return DOMPlugin::create(data, m_frame, i).get();
     }
-    return 0;
+    return nullptr;
 }
 
 void DOMPluginArray::refresh(bool reload)
diff --git a/Source/core/plugins/DOMPluginArray.h b/Source/core/plugins/DOMPluginArray.h
index 2ea687a..1834cc3 100644
--- a/Source/core/plugins/DOMPluginArray.h
+++ b/Source/core/plugins/DOMPluginArray.h
@@ -32,13 +32,12 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class PluginData;
 
-class DOMPluginArray FINAL : public RefCountedWillBeGarbageCollected<DOMPluginArray>, public ScriptWrappable, public DOMWindowProperty {
-    DECLARE_GC_INFO;
+class DOMPluginArray FINAL : public RefCountedWillBeGarbageCollectedFinalized<DOMPluginArray>, public ScriptWrappable, public DOMWindowProperty {
 public:
-    static PassRefPtrWillBeRawPtr<DOMPluginArray> create(Frame* frame)
+    static PassRefPtrWillBeRawPtr<DOMPluginArray> create(LocalFrame* frame)
     {
         return adoptRefWillBeNoop(new DOMPluginArray(frame));
     }
@@ -54,7 +53,7 @@
     void trace(Visitor*) { }
 
 private:
-    explicit DOMPluginArray(Frame*);
+    explicit DOMPluginArray(LocalFrame*);
     PluginData* pluginData() const;
 };
 
diff --git a/Source/core/plugins/PluginOcclusionSupport.cpp b/Source/core/plugins/PluginOcclusionSupport.cpp
index 3fab5dc..d637996 100644
--- a/Source/core/plugins/PluginOcclusionSupport.cpp
+++ b/Source/core/plugins/PluginOcclusionSupport.cpp
@@ -33,10 +33,10 @@
 
 #include "HTMLNames.h"
 #include "core/dom/Element.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/rendering/RenderBox.h"
 #include "core/rendering/RenderObject.h"
 #include "platform/Widget.h"
@@ -179,7 +179,7 @@
 
         RenderObject* iframeRenderer = element->renderer();
 
-        if (element->hasTagName(HTMLNames::iframeTag) && intersectsRect(iframeRenderer, frameRect)) {
+        if (isHTMLIFrameElement(*element) && intersectsRect(iframeRenderer, frameRect)) {
             getObjectStack(iframeRenderer, &iframeZstack);
             if (iframeIsAbovePlugin(iframeZstack, pluginZstack))
                 addToOcclusions(toRenderBox(iframeRenderer), occlusions);
diff --git a/Source/core/rendering/AbstractInlineTextBox.cpp b/Source/core/rendering/AbstractInlineTextBox.cpp
index a14b4a0..6598e57 100644
--- a/Source/core/rendering/AbstractInlineTextBox.cpp
+++ b/Source/core/rendering/AbstractInlineTextBox.cpp
@@ -41,7 +41,7 @@
 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::getOrCreate(RenderText* renderText, InlineTextBox* inlineTextBox)
 {
     if (!inlineTextBox)
-        return 0;
+        return nullptr;
 
     if (!gAbstractInlineTextBoxMap)
         gAbstractInlineTextBoxMap = new InlineToAbstractInlineTextBoxHashMap();
@@ -76,7 +76,7 @@
 PassRefPtr<AbstractInlineTextBox> AbstractInlineTextBox::nextInlineTextBox() const
 {
     if (!m_inlineTextBox)
-        return 0;
+        return nullptr;
 
     return getOrCreate(m_renderText, m_inlineTextBox->nextTextBox());
 }
diff --git a/Source/core/rendering/AutoTableLayout.cpp b/Source/core/rendering/AutoTableLayout.cpp
index 2c290c6..cc84208 100644
--- a/Source/core/rendering/AutoTableLayout.cpp
+++ b/Source/core/rendering/AutoTableLayout.cpp
@@ -65,7 +65,7 @@
                 if (current.inColSpan || !cell)
                     continue;
 
-                bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding();
+                bool cellHasContent = cell->children()->firstChild() || cell->style()->hasBorder() || cell->style()->hasPadding() || cell->style()->hasBackground();
                 if (cellHasContent)
                     columnLayout.emptyCellsOnly = false;
 
diff --git a/Source/core/rendering/ClipRect.h b/Source/core/rendering/ClipRect.h
index 8fbcebf..a558243 100644
--- a/Source/core/rendering/ClipRect.h
+++ b/Source/core/rendering/ClipRect.h
@@ -179,6 +179,7 @@
 enum ClipRectsType {
     PaintingClipRects, // Relative to painting ancestor. Used for painting.
     RootRelativeClipRects, // Relative to the ancestor treated as the root (e.g. transformed layer). Used for hit testing.
+    CompositingClipRects, // Relative to the compositing ancestor. Used for updating graphics layer geometry.
     AbsoluteClipRects, // Relative to the RenderView's layer. Used for compositing overlap testing.
     NumCachedClipRectsTypes,
     AllClipRectTypes,
diff --git a/Source/core/rendering/EllipsisBox.cpp b/Source/core/rendering/EllipsisBox.cpp
index 5eb42de..9f3e026 100644
--- a/Source/core/rendering/EllipsisBox.cpp
+++ b/Source/core/rendering/EllipsisBox.cpp
@@ -27,7 +27,7 @@
 #include "core/rendering/RootInlineBox.h"
 #include "core/rendering/style/ShadowList.h"
 #include "platform/fonts/Font.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
 #include "platform/text/TextRun.h"
 
@@ -36,21 +36,20 @@
 void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
 {
     GraphicsContext* context = paintInfo.context;
-    RenderStyle* style = m_renderer->style(isFirstLineStyle());
+    RenderStyle* style = renderer().style(isFirstLineStyle());
 
     const Font& font = style->font();
     FloatPoint boxOrigin = locationIncludingFlipping();
-    LayoutPoint adjustedPaintOffset = paintOffset;
+    boxOrigin.moveBy(FloatPoint(paintOffset));
     if (!isHorizontal())
-        adjustedPaintOffset.move(0, -virtualLogicalHeight());
-    boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y());
+        boxOrigin.move(0, -virtualLogicalHeight());
     FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight()));
     GraphicsContextStateSaver stateSaver(*context);
     if (!isHorizontal())
         context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise));
     FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent());
 
-    Color styleTextColor = m_renderer->resolveColor(style, CSSPropertyWebkitTextFillColor);
+    Color styleTextColor = renderer().resolveColor(style, CSSPropertyWebkitTextFillColor);
     if (styleTextColor != context->fillColor())
         context->setFillColor(styleTextColor);
 
@@ -58,7 +57,7 @@
         paintSelection(context, boxOrigin, style, font);
 
         // Select the correct color for painting the text.
-        Color foreground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionForegroundColor();
+        Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor();
         if (foreground != styleTextColor)
             context->setFillColor(foreground);
     }
@@ -67,21 +66,20 @@
     const ShadowList* shadowList = context->printing() ? 0 : style->textShadow();
     bool hasShadow = shadowList;
     if (hasShadow) {
-        DrawLooper drawLooper;
+        OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
         for (size_t i = shadowList->shadows().size(); i--; ) {
             const ShadowData& shadow = shadowList->shadows()[i];
             float shadowX = isHorizontal() ? shadow.x() : shadow.y();
             float shadowY = isHorizontal() ? shadow.y() : -shadow.x();
             FloatSize offset(shadowX, shadowY);
-            drawLooper.addShadow(offset, shadow.blur(), shadow.color(),
-                DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
+            drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(),
+                DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
         }
-        drawLooper.addUnmodifiedContent();
-        context->setDrawLooper(drawLooper);
+        drawLooperBuilder->addUnmodifiedContent();
+        context->setDrawLooper(drawLooperBuilder.release());
     }
 
-    // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
-    TextRun textRun = RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion);
+    TextRun textRun = RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion);
     TextRunPaintInfo textRunPaintInfo(textRun);
     textRunPaintInfo.bounds = boxRect;
     context->drawText(font, textRunPaintInfo, textOrigin);
@@ -98,18 +96,18 @@
 
 InlineBox* EllipsisBox::markupBox() const
 {
-    if (!m_shouldPaintMarkupBox || !m_renderer->isRenderBlock())
+    if (!m_shouldPaintMarkupBox || !renderer().isRenderBlock())
         return 0;
 
-    RenderBlock* block = toRenderBlock(m_renderer);
-    RootInlineBox* lastLine = block->lineAtIndex(block->lineCount() - 1);
+    RenderBlock& block = toRenderBlock(renderer());
+    RootInlineBox* lastLine = block.lineAtIndex(block.lineCount() - 1);
     if (!lastLine)
         return 0;
 
     // If the last line-box on the last line of a block is a link, -webkit-line-clamp paints that box after the ellipsis.
     // It does not actually move the link.
     InlineBox* anchorBox = lastLine->lastChild();
-    if (!anchorBox || !anchorBox->renderer()->style()->isLink())
+    if (!anchorBox || !anchorBox->renderer().style()->isLink())
         return 0;
 
     return anchorBox;
@@ -123,22 +121,21 @@
 
     LayoutPoint adjustedPaintOffset = paintOffset;
     adjustedPaintOffset.move(x() + m_logicalWidth - markupBox->x(),
-        y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer()->style(isFirstLineStyle())->fontMetrics().ascent()));
+        y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics().ascent()));
     markupBox->paint(paintInfo, adjustedPaintOffset, lineTop, lineBottom);
 }
 
 IntRect EllipsisBox::selectionRect()
 {
-    RenderStyle* style = m_renderer->style(isFirstLineStyle());
+    RenderStyle* style = renderer().style(isFirstLineStyle());
     const Font& font = style->font();
-    // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
-    return enclosingIntRect(font.selectionRectForText(RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(logicalLeft(), logicalTop() + root()->selectionTopAdjustedForPrecedingBlock()), root()->selectionHeightAdjustedForPrecedingBlock()));
+    return enclosingIntRect(font.selectionRectForText(RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), IntPoint(logicalLeft(), logicalTop() + root().selectionTopAdjustedForPrecedingBlock()), root().selectionHeightAdjustedForPrecedingBlock()));
 }
 
 void EllipsisBox::paintSelection(GraphicsContext* context, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font)
 {
-    Color textColor = m_renderer->resolveColor(style, CSSPropertyColor);
-    Color c = m_renderer->selectionBackgroundColor();
+    Color textColor = renderer().resolveColor(style, CSSPropertyColor);
+    Color c = renderer().selectionBackgroundColor();
     if (!c.alpha())
         return;
 
@@ -148,16 +145,15 @@
         c = Color(0xff - c.red(), 0xff - c.green(), 0xff - c.blue());
 
     GraphicsContextStateSaver stateSaver(*context);
-    LayoutUnit selectionBottom = root()->selectionBottom();
-    LayoutUnit top = root()->selectionTop();
-    LayoutUnit h = root()->selectionHeight();
-    const int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - top);
+    LayoutUnit selectionBottom = root().selectionBottom();
+    LayoutUnit top = root().selectionTop();
+    LayoutUnit h = root().selectionHeight();
+    const int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - top);
     const FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
-    FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h));
+    FloatRect clipRect(localOrigin, FloatSize(m_logicalWidth, h.toFloat()));
     alignSelectionRectToDevicePixels(clipRect);
     context->clip(clipRect);
-    // FIXME: Why is this always LTR? Fix by passing correct text run flags below.
-    context->drawHighlightForText(font, RenderBlockFlow::constructTextRun(renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c);
+    context->drawHighlightForText(font, RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion), localOrigin, h, c);
 }
 
 bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
@@ -166,11 +162,11 @@
 
     // Hit test the markup box.
     if (InlineBox* markupBox = this->markupBox()) {
-        RenderStyle* style = m_renderer->style(isFirstLineStyle());
+        RenderStyle* style = renderer().style(isFirstLineStyle());
         LayoutUnit mtx = adjustedLocation.x() + m_logicalWidth - markupBox->x();
-        LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer()->style(isFirstLineStyle())->fontMetrics().ascent());
+        LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics().ascent());
         if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutPoint(mtx, mty), lineTop, lineBottom)) {
-            renderer()->updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty));
+            renderer().updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty));
             return true;
         }
     }
@@ -179,8 +175,8 @@
     boxOrigin.moveBy(accumulatedOffset);
     FloatRect boundsRect(boxOrigin, size());
     if (visibleToHitTestRequest(request) && boundsRect.intersects(HitTestLocation::rectForPoint(locationInContainer.point(), 0, 0, 0, 0))) {
-        renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
-        if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, boundsRect))
+        renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation));
+        if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, boundsRect))
             return true;
     }
 
diff --git a/Source/core/rendering/EllipsisBox.h b/Source/core/rendering/EllipsisBox.h
index 149a851..c97d375 100644
--- a/Source/core/rendering/EllipsisBox.h
+++ b/Source/core/rendering/EllipsisBox.h
@@ -29,7 +29,7 @@
 
 class EllipsisBox FINAL : public InlineBox {
 public:
-    EllipsisBox(RenderObject* obj, const AtomicString& ellipsisStr, InlineFlowBox* parent,
+    EllipsisBox(RenderObject& obj, const AtomicString& ellipsisStr, InlineFlowBox* parent,
         int width, int height, int x, int y, bool firstLine, bool isVertical, InlineBox* markupBox)
         : InlineBox(obj, FloatPoint(x, y), width, firstLine, true, false, false, isVertical, 0, 0, parent)
         , m_shouldPaintMarkupBox(markupBox)
diff --git a/Source/core/rendering/FastTextAutosizer.cpp b/Source/core/rendering/FastTextAutosizer.cpp
index 6b9d0df..2888f16 100644
--- a/Source/core/rendering/FastTextAutosizer.cpp
+++ b/Source/core/rendering/FastTextAutosizer.cpp
@@ -32,26 +32,227 @@
 #include "core/rendering/FastTextAutosizer.h"
 
 #include "core/dom/Document.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/page/Page.h"
 #include "core/rendering/InlineIterator.h"
 #include "core/rendering/RenderBlock.h"
 #include "core/rendering/RenderListItem.h"
 #include "core/rendering/RenderListMarker.h"
+#include "core/rendering/RenderTableCell.h"
 #include "core/rendering/RenderView.h"
-#include "core/rendering/TextAutosizer.h"
 
 using namespace std;
 
 namespace WebCore {
 
+static const RenderObject* parentElementRenderer(const RenderObject* renderer)
+{
+    // At style recalc, the renderer's parent may not be attached,
+    // so we need to obtain this from the DOM tree.
+
+    const Node* node = renderer->node();
+    if (!node)
+        return 0;
+
+    while ((node = node->parentNode())) {
+        if (node->isElementNode())
+            return node->renderer();
+    }
+    return 0;
+}
+
+static const Vector<QualifiedName>& formInputTags()
+{
+    // Returns the tags for the form input elements.
+    DEFINE_STATIC_LOCAL(Vector<QualifiedName>, formInputTags, ());
+    if (formInputTags.isEmpty()) {
+        formInputTags.append(HTMLNames::inputTag);
+        formInputTags.append(HTMLNames::buttonTag);
+        formInputTags.append(HTMLNames::selectTag);
+    }
+    return formInputTags;
+}
+
+static bool isAutosizingContainer(const RenderObject* renderer)
+{
+    // "Autosizing containers" are the smallest unit for which we can
+    // enable/disable Text Autosizing.
+    // - Must not be inline, as different multipliers on one line looks terrible.
+    //   Exceptions are inline-block and alike elements (inline-table, -webkit-inline-*),
+    //   as they often contain entire multi-line columns of text.
+    // - Must not be list items, as items in the same list should look consistent (*).
+    // - Must not be normal list items, as items in the same list should look
+    //   consistent, unless they are floating or position:absolute/fixed.
+    Node* node = renderer->generatingNode();
+    if ((node && !node->hasChildren())
+        || !renderer->isRenderBlock()
+        || (renderer->isInline() && !renderer->style()->isDisplayReplacedType()))
+        return false;
+    if (renderer->isListItem())
+        return renderer->isFloating() || renderer->isOutOfFlowPositioned();
+    // Avoid creating containers for text within text controls, buttons, or <select> buttons.
+    Node* parentNode = renderer->parent() ? renderer->parent()->generatingNode() : 0;
+    if (parentNode && parentNode->isElementNode() && formInputTags().contains(toElement(parentNode)->tagQName()))
+        return false;
+
+    return true;
+}
+
+static RenderObject* nextInPreOrderSkippingDescendantsOfContainers(const RenderObject* current, const RenderObject* stayWithin)
+{
+    if (current == stayWithin || !isAutosizingContainer(current))
+        return current->nextInPreOrder(stayWithin);
+    return current->nextInPreOrderAfterChildren(stayWithin);
+}
+
+static bool isIndependentDescendant(const RenderBlock* renderer)
+{
+    ASSERT(isAutosizingContainer(renderer));
+
+    // "Autosizing clusters" are special autosizing containers within which we
+    // want to enforce a uniform text size multiplier, in the hopes of making
+    // the major sections of the page look internally consistent.
+    // All their descendants (including other autosizing containers) must share
+    // the same multiplier, except for subtrees which are themselves clusters,
+    // and some of their descendant containers might not be autosized at all
+    // (for example if their height is constrained).
+    // Additionally, clusterShouldBeAutosized requires each cluster to contain a
+    // minimum amount of text, without which it won't be autosized.
+    //
+    // Clusters are chosen using very similar criteria to CSS flow roots, aka
+    // block formatting contexts (http://w3.org/TR/css3-box/#flow-root), since
+    // flow roots correspond to box containers that behave somewhat
+    // independently from their parent (for example they don't overlap floats).
+    // The definition of a flow root also conveniently includes most of the
+    // ways that a box and its children can have significantly different width
+    // from the box's parent (we want to avoid having significantly different
+    // width blocks within a cluster, since the narrower blocks would end up
+    // larger than would otherwise be necessary).
+    RenderBlock* containingBlock = renderer->containingBlock();
+    return renderer->isRenderView()
+        || renderer->isFloating()
+        || renderer->isOutOfFlowPositioned()
+        || renderer->isTableCell()
+        || renderer->isTableCaption()
+        || renderer->isFlexibleBoxIncludingDeprecated()
+        || renderer->hasColumns()
+        || (containingBlock && containingBlock->isHorizontalWritingMode() != renderer->isHorizontalWritingMode())
+        || renderer->style()->isDisplayReplacedType()
+        || renderer->isTextArea()
+        || renderer->style()->userModify() != READ_ONLY;
+    // FIXME: Tables need special handling to multiply all their columns by
+    // the same amount even if they're different widths; so do hasColumns()
+    // containers, and probably flexboxes...
+}
+
+static bool containerIsRowOfLinks(const RenderObject* container)
+{
+    // A "row of links" is a container for which holds:
+    //  1. it should not contain non-link text elements longer than 3 characters
+    //  2. it should contain min. 3 inline links and all links should
+    //     have the same specified font size
+    //  3. it should not contain <br> elements
+    //  4. it should contain only inline elements unless they are containers,
+    //     children of link elements or children of sub-containers.
+    int linkCount = 0;
+    RenderObject* renderer = container->nextInPreOrder(container);
+    float matchingFontSize = -1;
+
+    while (renderer) {
+        if (!isAutosizingContainer(renderer)) {
+            if (renderer->isText() && toRenderText(renderer)->text().impl()->stripWhiteSpace()->length() > 3)
+                return false;
+            if (!renderer->isInline())
+                return false;
+            if (renderer->isBR())
+                return false;
+        }
+        if (renderer->style()->isLink()) {
+            if (matchingFontSize < 0) {
+                matchingFontSize = renderer->style()->specifiedFontSize();
+            } else {
+                if (matchingFontSize != renderer->style()->specifiedFontSize())
+                    return false;
+            }
+
+            linkCount++;
+            // Skip traversing descendants of the link.
+            renderer = renderer->nextInPreOrderAfterChildren(container);
+        } else {
+            renderer = nextInPreOrderSkippingDescendantsOfContainers(renderer, container);
+        }
+    }
+
+    return (linkCount >= 3);
+}
+
+static bool contentHeightIsConstrained(const RenderBlock* container)
+{
+    // FIXME: Propagate constrainedness down the tree, to avoid inefficiently walking back up from each box.
+    // FIXME: This code needs to take into account vertical writing modes.
+    // FIXME: Consider additional heuristics, such as ignoring fixed heights if the content is already overflowing before autosizing kicks in.
+    for (; container; container = container->containingBlock()) {
+        RenderStyle* style = container->style();
+        if (style->overflowY() >= OSCROLL)
+            return false;
+        if (style->height().isSpecified() || style->maxHeight().isSpecified() || container->isOutOfFlowPositioned()) {
+            // Some sites (e.g. wikipedia) set their html and/or body elements to height:100%,
+            // without intending to constrain the height of the content within them.
+            return !container->isRoot() && !container->isBody();
+        }
+        if (container->isFloating())
+            return false;
+    }
+    return false;
+}
+
+static bool containerContainsOneOfTags(const RenderBlock* container, const Vector<QualifiedName>& tags)
+{
+    const RenderObject* renderer = container;
+    while (renderer) {
+        const Node* rendererNode = renderer->node();
+        if (rendererNode && rendererNode->isElementNode()) {
+            if (tags.contains(toElement(rendererNode)->tagQName()))
+                return true;
+        }
+        renderer = nextInPreOrderSkippingDescendantsOfContainers(renderer, container);
+    }
+
+    return false;
+}
+
+static bool containerShouldBeAutosized(const RenderBlock* container)
+{
+    if (containerContainsOneOfTags(container, formInputTags()))
+        return false;
+
+    if (containerIsRowOfLinks(container))
+        return false;
+
+    // Don't autosize block-level text that can't wrap (as it's likely to
+    // expand sideways and break the page's layout).
+    if (!container->style()->autoWrap())
+        return false;
+
+    return !contentHeightIsConstrained(container);
+}
+
 FastTextAutosizer::FastTextAutosizer(const Document* document)
     : m_document(document)
+    , m_frameWidth(0)
+    , m_layoutWidth(0)
+    , m_baseMultiplier(0)
+    , m_pageAutosizingStatus(PageAutosizingStatusUnknown)
+    , m_firstBlock(0)
 #ifndef NDEBUG
     , m_renderViewInfoPrepared(false)
+    , m_blocksThatHaveBegunLayout()
 #endif
+    , m_superclusters()
+    , m_clusterStack()
+    , m_fingerprintMapper()
 {
 }
 
@@ -65,11 +266,8 @@
     if (!isFingerprintingCandidate(block))
         return;
 
-    AtomicString fingerprint = computeFingerprint(block);
-    if (fingerprint.isNull())
-        return;
-
-    m_fingerprintMapper.add(block, fingerprint);
+    if (Fingerprint fingerprint = computeFingerprint(block))
+        m_fingerprintMapper.addTentativeClusterRoot(block, fingerprint);
 }
 
 void FastTextAutosizer::destroy(const RenderBlock* block)
@@ -81,40 +279,51 @@
     m_fingerprintMapper.remove(block);
 }
 
-bool FastTextAutosizer::isLayoutRoot(const RenderBlock* block) const
+void FastTextAutosizer::prepareClusterStack(const RenderObject* renderer)
 {
-    RenderObject* layoutRoot = m_document->view()->layoutRoot(true);
-    if (!layoutRoot)
-        layoutRoot = m_document->renderer();
-    return block == layoutRoot;
+    if (!renderer)
+        return;
+    prepareClusterStack(renderer->parent());
+
+    if (renderer->isRenderBlock()) {
+        const RenderBlock* block = toRenderBlock(renderer);
+#ifndef NDEBUG
+        m_blocksThatHaveBegunLayout.add(block);
+#endif
+        if (Cluster* cluster = maybeCreateCluster(block))
+            m_clusterStack.append(adoptPtr(cluster));
+    }
 }
 
 void FastTextAutosizer::beginLayout(RenderBlock* block)
 {
-    ASSERT(enabled());
+    ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing);
 #ifndef NDEBUG
     m_blocksThatHaveBegunLayout.add(block);
 #endif
-    ASSERT(m_clusterStack.isEmpty() == isLayoutRoot(block));
 
-    if (isLayoutRoot(block)) {
-        prepareRenderViewInfo();
+    if (!m_firstBlock)  {
+        m_firstBlock = block;
+        prepareClusterStack(block->parent());
     } else if (block == currentCluster()->m_root) {
         // Ignore beginLayout on the same block twice.
         // This can happen with paginated overflow.
         return;
     }
 
-    if (Cluster* cluster = maybeCreateCluster(block))
+    if (Cluster* cluster = maybeCreateCluster(block)) {
         m_clusterStack.append(adoptPtr(cluster));
+        if (block->isTable())
+            inflateTable(toRenderTable(block));
+    }
 
-    if (block->childrenInline())
+    if (block->childrenInline() && block->firstChild())
         inflate(block);
 }
 
 void FastTextAutosizer::inflateListItem(RenderListItem* listItem, RenderListMarker* listItemMarker)
 {
-    if (!enabled())
+    if (!enabled() || m_pageAutosizingStatus != PageNeedsAutosizing)
         return;
     ASSERT(listItem && listItemMarker);
 #ifndef NDEBUG
@@ -129,20 +338,67 @@
     applyMultiplier(listItemMarker, multiplier);
 }
 
+void FastTextAutosizer::inflateTable(RenderTable* table)
+{
+    ASSERT(table);
+    ASSERT(table->containingBlock());
+
+    Cluster* cluster = currentCluster();
+    ASSERT(cluster->m_root->isTable());
+
+    // Pre-inflate cells that have enough text so that their inflated preferred widths will be used
+    // for column sizing.
+    // The multiplier used for cell descendants represents the maximum we can ever inflate
+    // descendants without overflowing the cell width computed by the table layout. Therefore,
+    // descendants of cells cannot use a multiplier higher than the table's multiplier.
+    float multiplier = clusterMultiplier(cluster);
+    for (RenderObject* section = table->firstChild(); section; section = section->nextSibling()) {
+        if (!section->isTableSection())
+            continue;
+        for (RenderObject* row = section->firstChild(); row; row = row->nextSibling()) {
+            if (!row->isTableRow())
+                continue;
+            for (RenderObject* cell = row->firstChild(); cell; cell = cell->nextSibling()) {
+                if (!cell->isTableCell())
+                    continue;
+                RenderTableCell* renderTableCell = toRenderTableCell(cell);
+
+                bool shouldAutosize;
+                if (!containerShouldBeAutosized(renderTableCell))
+                    shouldAutosize = false;
+                else if (Supercluster* supercluster = getSupercluster(renderTableCell))
+                    shouldAutosize = anyClusterHasEnoughTextToAutosize(supercluster->m_roots, table);
+                else
+                    shouldAutosize = clusterWouldHaveEnoughTextToAutosize(renderTableCell, table);
+
+                if (shouldAutosize) {
+                    for (RenderObject* child = cell; child; child = child->nextInPreOrder(cell)) {
+                        if (child->isText()) {
+                            applyMultiplier(child, multiplier);
+                            applyMultiplier(child->parent(), multiplier); // Parent handles line spacing.
+                        }
+                    }
+                }
+            }
+        }
+    }
+}
+
 void FastTextAutosizer::endLayout(RenderBlock* block)
 {
-    ASSERT(enabled());
-    if (isLayoutRoot(block)) {
+    ASSERT(enabled() && m_pageAutosizingStatus == PageNeedsAutosizing);
+
+    if (block == m_firstBlock) {
+        m_firstBlock = 0;
+        m_pageAutosizingStatus = PageAutosizingStatusUnknown;
+        m_clusterStack.clear();
         m_superclusters.clear();
 #ifndef NDEBUG
         m_blocksThatHaveBegunLayout.clear();
 #endif
-    }
-
-    if (currentCluster()->m_root == block)
+    } else if (currentCluster()->m_root == block) {
         m_clusterStack.removeLast();
-
-    ASSERT(m_clusterStack.isEmpty() == isLayoutRoot(block));
+    }
 }
 
 void FastTextAutosizer::inflate(RenderBlock* block)
@@ -169,15 +425,15 @@
     return m_document->settings()->textAutosizingEnabled();
 }
 
-void FastTextAutosizer::prepareRenderViewInfo()
+void FastTextAutosizer::updateRenderViewInfo()
 {
     RenderView* renderView = toRenderView(m_document->renderer());
     bool horizontalWritingMode = isHorizontalWritingMode(renderView->style()->writingMode());
 
-    Frame* mainFrame = m_document->page()->mainFrame();
+    LocalFrame* mainFrame = m_document->page()->mainFrame();
     IntSize frameSize = m_document->settings()->textAutosizingWindowSizeOverride();
     if (frameSize.isEmpty())
-        frameSize = mainFrame->view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
+        frameSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollbars);
     m_frameWidth = horizontalWritingMode ? frameSize.width() : frameSize.height();
 
     IntSize layoutSize = m_document->page()->mainFrame()->view()->layoutSize();
@@ -191,6 +447,10 @@
         float deviceScaleAdjustment = m_document->settings()->deviceScaleAdjustment();
         m_baseMultiplier *= deviceScaleAdjustment;
     }
+
+    m_pageAutosizingStatus = m_frameWidth && (m_baseMultiplier * (static_cast<float>(m_layoutWidth) / m_frameWidth) > 1.0f)
+        ? PageNeedsAutosizing : PageDoesNotNeedAutosizing;
+
 #ifndef NDEBUG
     m_renderViewInfoPrepared = true;
 #endif
@@ -200,76 +460,139 @@
 {
     // FIXME: move the logic out of TextAutosizer.cpp into this class.
     return block->isRenderView()
-        || (TextAutosizer::isAutosizingContainer(block)
-            && TextAutosizer::isIndependentDescendant(block));
+        || (isAutosizingContainer(block)
+            && (isIndependentDescendant(block)
+                || mightBeWiderOrNarrowerDescendant(block)));
 }
 
-bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root)
+bool FastTextAutosizer::clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider)
 {
     Cluster hypotheticalCluster(root, true, 0);
-    return clusterHasEnoughTextToAutosize(&hypotheticalCluster);
+    return clusterHasEnoughTextToAutosize(&hypotheticalCluster, widthProvider);
 }
 
-bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster)
+bool FastTextAutosizer::clusterHasEnoughTextToAutosize(Cluster* cluster, const RenderBlock* widthProvider)
 {
+    if (cluster->m_hasEnoughTextToAutosize != UnknownAmountOfText)
+        return cluster->m_hasEnoughTextToAutosize == HasEnoughText;
+
     const RenderBlock* root = cluster->m_root;
+    if (!widthProvider)
+        widthProvider = clusterWidthProvider(root);
 
     // TextAreas and user-modifiable areas get a free pass to autosize regardless of text content.
-    if (root->isTextArea() || (root->style() && root->style()->userModify() != READ_ONLY))
+    if (root->isTextArea() || (root->style() && root->style()->userModify() != READ_ONLY)) {
+        cluster->m_hasEnoughTextToAutosize = HasEnoughText;
         return true;
+    }
 
-    static const float minLinesOfText = 4;
-    if (textLength(cluster) >= root->contentLogicalWidth() * minLinesOfText)
-        return true;
+    if (!containerShouldBeAutosized(root)) {
+        cluster->m_hasEnoughTextToAutosize = NotEnoughText;
+        return false;
+    }
 
-    return false;
-}
-
-float FastTextAutosizer::textLength(Cluster* cluster)
-{
-    if (cluster->m_textLength >= 0)
-        return cluster->m_textLength;
+    // 4 lines of text is considered enough to autosize.
+    float minimumTextLengthToAutosize = widthFromBlock(widthProvider) * 4;
 
     float length = 0;
-    const RenderBlock* root = cluster->m_root;
-    bool measureLocalText = TextAutosizer::containerShouldBeAutosized(root);
     RenderObject* descendant = root->nextInPreOrder(root);
     while (descendant) {
-        // FIXME: We should skip over text from descendant clusters (see:
-        //        clusters-sufficient-text-except-in-root.html). This currently includes text
-        //        from descendant clusters.
-
-        if (measureLocalText && descendant->isText()) {
+        if (descendant->isRenderBlock()) {
+            RenderBlock* block = toRenderBlock(descendant);
+            if (isAutosizingContainer(block)) {
+                // Note: Ideally we would check isWiderOrNarrowerDescendant here but we only know that
+                //       after the block has entered layout, which may not be the case.
+                bool isAutosizingClusterRoot = isIndependentDescendant(block) || block->isTable();
+                if ((isAutosizingClusterRoot && !block->isTableCell())
+                    || !containerShouldBeAutosized(block)) {
+                    descendant = descendant->nextInPreOrderAfterChildren(root);
+                    continue;
+                }
+            }
+        } else if (descendant->isText()) {
             // Note: Using text().stripWhiteSpace().length() instead of renderedTextLength() because
             // the lineboxes will not be built until layout. These values can be different.
+            // Note: This is an approximation assuming each character is 1em wide.
             length += toRenderText(descendant)->text().stripWhiteSpace().length() * descendant->style()->specifiedFontSize();
+
+            if (length >= minimumTextLengthToAutosize) {
+                cluster->m_hasEnoughTextToAutosize = HasEnoughText;
+                return true;
+            }
         }
         descendant = descendant->nextInPreOrder(root);
     }
 
-    return cluster->m_textLength = length;
+    cluster->m_hasEnoughTextToAutosize = NotEnoughText;
+    return false;
 }
 
-AtomicString FastTextAutosizer::computeFingerprint(const RenderBlock* block)
+FastTextAutosizer::Fingerprint FastTextAutosizer::getFingerprint(const RenderObject* renderer)
 {
-    // FIXME(crbug.com/322340): Implement a fingerprinting algorithm.
-    return nullAtom;
+    Fingerprint result = m_fingerprintMapper.get(renderer);
+    if (!result) {
+        result = computeFingerprint(renderer);
+        m_fingerprintMapper.add(renderer, result);
+    }
+    return result;
+}
+
+FastTextAutosizer::Fingerprint FastTextAutosizer::computeFingerprint(const RenderObject* renderer)
+{
+    Node* node = renderer->generatingNode();
+    if (!node || !node->isElementNode())
+        return 0;
+
+    FingerprintSourceData data;
+
+    // FIXME: Instead of computing and caching parent fingerprints on demand,
+    // consider maintaining a fingerprint stack during the style recalc
+    // tree walk (similar to the cluster stack used during layout).
+
+    if (const RenderObject* parent = parentElementRenderer(renderer))
+        data.m_parentHash = getFingerprint(parent);
+
+    data.m_qualifiedNameHash = QualifiedNameHash::hash(toElement(node)->tagQName());
+
+    if (RenderStyle* style = renderer->style()) {
+        data.m_packedStyleProperties = style->direction();
+        data.m_packedStyleProperties |= (style->position() << 1);
+        data.m_packedStyleProperties |= (style->floating() << 4);
+        data.m_packedStyleProperties |= (style->display() << 6);
+        data.m_packedStyleProperties |= (style->width().type() << 11);
+        // packedStyleProperties effectively using 15 bits now.
+
+        // consider for adding: writing mode, padding.
+
+        data.m_width = style->width().getFloatValue();
+    }
+
+    // Use nodeIndex as a rough approximation of column number
+    // (it's too early to call RenderTableCell::col).
+    // FIXME: account for colspan
+    if (renderer->isTableCell())
+        data.m_column = renderer->node()->nodeIndex();
+
+    return StringHasher::computeHash<UChar>(
+        static_cast<const UChar*>(static_cast<const void*>(&data)),
+        sizeof data / sizeof(UChar));
 }
 
 FastTextAutosizer::Cluster* FastTextAutosizer::maybeCreateCluster(const RenderBlock* block)
 {
-    if (!TextAutosizer::isAutosizingContainer(block))
+    if (!isAutosizingContainer(block))
         return 0;
 
     Cluster* parentCluster = m_clusterStack.isEmpty() ? 0 : currentCluster();
-    ASSERT(parentCluster || isLayoutRoot(block));
+    ASSERT(parentCluster || block->isRenderView());
 
     // Create clusters to suppress / unsuppress autosizing based on containerShouldBeAutosized.
-    bool containerCanAutosize = TextAutosizer::containerShouldBeAutosized(block);
+    bool containerCanAutosize = containerShouldBeAutosized(block);
     bool parentClusterCanAutosize = parentCluster && parentCluster->m_autosize;
-    bool createClusterThatMightAutosize = isLayoutRoot(block)
+    bool createClusterThatMightAutosize = block->isRenderView()
         || mightBeWiderOrNarrowerDescendant(block)
-        || TextAutosizer::isIndependentDescendant(block);
+        || isIndependentDescendant(block)
+        || block->isTable();
 
     // If the container would not alter the m_autosize bit, it doesn't need to be a cluster.
     if (!createClusterThatMightAutosize && containerCanAutosize == parentClusterCanAutosize)
@@ -280,12 +603,12 @@
 
 FastTextAutosizer::Supercluster* FastTextAutosizer::getSupercluster(const RenderBlock* block)
 {
-    AtomicString fingerprint = m_fingerprintMapper.get(block);
-    if (fingerprint.isNull())
+    Fingerprint fingerprint = m_fingerprintMapper.get(block);
+    if (!fingerprint)
         return 0;
 
-    BlockSet* roots = &m_fingerprintMapper.getBlocks(fingerprint);
-    if (roots->size() < 2)
+    BlockSet* roots = &m_fingerprintMapper.getTentativeClusterRoots(fingerprint);
+    if (!roots || roots->size() < 2 || !roots->contains(block))
         return 0;
 
     SuperclusterMap::AddResult addResult = m_superclusters.add(fingerprint, PassOwnPtr<Supercluster>());
@@ -318,16 +641,17 @@
 {
     ASSERT(m_renderViewInfoPrepared);
     if (!cluster->m_multiplier) {
-
-        if (isLayoutRoot(cluster->m_root)
-            || TextAutosizer::isIndependentDescendant(cluster->m_root)
-            || isWiderDescendant(cluster)
-            || isNarrowerDescendant(cluster)) {
+        if (cluster->m_root->isTable()
+            || isIndependentDescendant(cluster->m_root)
+            || isWiderOrNarrowerDescendant(cluster)) {
 
             if (cluster->m_supercluster) {
-                cluster->m_multiplier = superclusterMultiplier(cluster->m_supercluster);
+                cluster->m_multiplier = superclusterMultiplier(cluster);
             } else if (clusterHasEnoughTextToAutosize(cluster)) {
-                cluster->m_multiplier = multiplierFromBlock(deepestBlockContainingAllText(cluster));
+                cluster->m_multiplier = multiplierFromBlock(clusterWidthProvider(cluster->m_root));
+                // Do not inflate table descendants above the table's multiplier. See inflateTable(...) for details.
+                if (cluster->m_hasTableAncestor)
+                    cluster->m_multiplier = min(cluster->m_multiplier, clusterMultiplier(cluster->m_parent));
             } else {
                 cluster->m_multiplier = 1.0f;
             }
@@ -339,23 +663,58 @@
     return cluster->m_multiplier;
 }
 
-float FastTextAutosizer::superclusterMultiplier(Supercluster* supercluster)
+bool FastTextAutosizer::anyClusterHasEnoughTextToAutosize(const BlockSet* roots, const RenderBlock* widthProvider)
 {
+    for (BlockSet::iterator it = roots->begin(); it != roots->end(); ++it) {
+        if (clusterWouldHaveEnoughTextToAutosize(*it, widthProvider))
+            return true;
+    }
+    return false;
+}
+
+float FastTextAutosizer::superclusterMultiplier(Cluster* cluster)
+{
+    Supercluster* supercluster = cluster->m_supercluster;
     if (!supercluster->m_multiplier) {
         const BlockSet* roots = supercluster->m_roots;
-        // Set of the deepest block containing all text (DBCAT) of every cluster.
-        BlockSet dbcats;
-        for (BlockSet::iterator it = roots->begin(); it != roots->end(); ++it) {
-            dbcats.add(deepestBlockContainingAllText(*it));
-            supercluster->m_anyClusterHasEnoughText |= clusterWouldHaveEnoughTextToAutosize(*it);
+        const RenderBlock* widthProvider;
+
+        if (cluster->m_root->isTableCell()) {
+            widthProvider = clusterWidthProvider(cluster->m_root);
+        } else {
+            BlockSet widthProviders;
+            for (BlockSet::iterator it = roots->begin(); it != roots->end(); ++it)
+                widthProviders.add(clusterWidthProvider(*it));
+            widthProvider = deepestCommonAncestor(widthProviders);
         }
-        supercluster->m_multiplier = supercluster->m_anyClusterHasEnoughText
-            ? multiplierFromBlock(deepestCommonAncestor(dbcats)) : 1.0f;
+
+        supercluster->m_multiplier = anyClusterHasEnoughTextToAutosize(roots, widthProvider)
+            ? multiplierFromBlock(widthProvider) : 1.0f;
     }
     ASSERT(supercluster->m_multiplier);
     return supercluster->m_multiplier;
 }
 
+const RenderBlock* FastTextAutosizer::clusterWidthProvider(const RenderBlock* root)
+{
+    if (root->isTable() || root->isTableCell())
+        return root;
+
+    return deepestBlockContainingAllText(root);
+}
+
+float FastTextAutosizer::widthFromBlock(const RenderBlock* block)
+{
+    if (block->isTable()) {
+        RenderBlock* containingBlock = block->containingBlock();
+        ASSERT(block->containingBlock());
+        if (block->style()->logicalWidth().isSpecified())
+            return floatValueForLength(block->style()->logicalWidth(), containingBlock->contentLogicalWidth().toFloat());
+        return containingBlock->contentLogicalWidth().toFloat();
+    }
+    return block->contentLogicalWidth().toFloat();
+}
+
 float FastTextAutosizer::multiplierFromBlock(const RenderBlock* block)
 {
     // If block->needsLayout() is false, it does not need to be in m_blocksThatHaveBegunLayout.
@@ -364,8 +723,8 @@
     ASSERT(m_blocksThatHaveBegunLayout.contains(block) || !block->needsLayout());
 
     // Block width, in CSS pixels.
-    float textBlockWidth = block->contentLogicalWidth();
-    float multiplier = min(textBlockWidth, static_cast<float>(m_layoutWidth)) / m_frameWidth;
+    float blockWidth = widthFromBlock(block);
+    float multiplier = m_frameWidth ? min(blockWidth, static_cast<float>(m_layoutWidth)) / m_frameWidth : 1.0f;
 
     return max(m_baseMultiplier * multiplier, 1.0f);
 }
@@ -437,7 +796,7 @@
     while (child) {
         // Note: At this point clusters may not have been created for these blocks so we cannot rely
         //       on m_clusters. Instead, we use a best-guess about whether the block will become a cluster.
-        if (!TextAutosizer::isAutosizingContainer(child) || !TextAutosizer::isIndependentDescendant(toRenderBlock(child))) {
+        if (!isAutosizingContainer(child) || !isIndependentDescendant(toRenderBlock(child))) {
             const RenderObject* leaf = findTextLeaf(child, depth, firstOrLast);
             if (leaf)
                 return leaf;
@@ -470,40 +829,30 @@
     return block->style() && block->style()->width().isSpecified();
 }
 
-bool FastTextAutosizer::isWiderDescendant(Cluster* cluster)
+bool FastTextAutosizer::isWiderOrNarrowerDescendant(Cluster* cluster)
 {
     if (!cluster->m_parent || !mightBeWiderOrNarrowerDescendant(cluster->m_root))
         return true;
+
     const RenderBlock* parentDeepestBlockContainingAllText = deepestBlockContainingAllText(cluster->m_parent);
     ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root));
     ASSERT(m_blocksThatHaveBegunLayout.contains(parentDeepestBlockContainingAllText));
 
+    float contentWidth = cluster->m_root->contentLogicalWidth().toFloat();
+    float clusterTextWidth = parentDeepestBlockContainingAllText->contentLogicalWidth().toFloat();
+
     // Clusters with a root that is wider than the deepestBlockContainingAllText of their parent
-    // autosize independently of their parent. Otherwise, they fall back to their parent's multiplier.
-    float contentWidth = cluster->m_root->contentLogicalWidth();
-    float clusterTextWidth = parentDeepestBlockContainingAllText->contentLogicalWidth();
-    return contentWidth > clusterTextWidth;
-}
-
-bool FastTextAutosizer::isNarrowerDescendant(Cluster* cluster)
-{
-    static float narrowWidthDifference = 200;
-
-    if (!cluster->m_parent || !mightBeWiderOrNarrowerDescendant(cluster->m_root))
+    // autosize independently of their parent.
+    if (contentWidth > clusterTextWidth)
         return true;
 
-    const RenderBlock* parentDeepestBlockContainingAllText = deepestBlockContainingAllText(cluster->m_parent);
-    ASSERT(m_blocksThatHaveBegunLayout.contains(cluster->m_root));
-    ASSERT(m_blocksThatHaveBegunLayout.contains(parentDeepestBlockContainingAllText));
-
     // Clusters with a root that is significantly narrower than the deepestBlockContainingAllText of
-    // their parent autosize independently of their parent. Otherwise, they fall back to their
-    // parent's multiplier.
-    float contentWidth = cluster->m_root->contentLogicalWidth();
-    float clusterTextWidth = parentDeepestBlockContainingAllText->contentLogicalWidth();
-    float widthDifference = clusterTextWidth - contentWidth;
+    // their parent autosize independently of their parent.
+    static float narrowWidthDifference = 200;
+    if (clusterTextWidth - contentWidth > narrowWidthDifference)
+        return true;
 
-    return widthDifference > narrowWidthDifference;
+    return false;
 }
 
 FastTextAutosizer::Cluster* FastTextAutosizer::currentCluster() const
@@ -512,35 +861,71 @@
     return m_clusterStack.last().get();
 }
 
-void FastTextAutosizer::FingerprintMapper::add(const RenderBlock* block, AtomicString fingerprint)
+#ifndef NDEBUG
+void FastTextAutosizer::FingerprintMapper::assertMapsAreConsistent()
 {
-    m_fingerprints.set(block, fingerprint);
+    // For each fingerprint -> block mapping in m_blocksForFingerprint we should have an associated
+    // map from block -> fingerprint in m_fingerprints.
+    ReverseFingerprintMap::iterator end = m_blocksForFingerprint.end();
+    for (ReverseFingerprintMap::iterator fingerprintIt = m_blocksForFingerprint.begin(); fingerprintIt != end; ++fingerprintIt) {
+        Fingerprint fingerprint = fingerprintIt->key;
+        BlockSet* blocks = fingerprintIt->value.get();
+        for (BlockSet::iterator blockIt = blocks->begin(); blockIt != blocks->end(); ++blockIt) {
+            const RenderBlock* block = (*blockIt);
+            ASSERT(m_fingerprints.get(block) == fingerprint);
+        }
+    }
+}
+#endif
+
+void FastTextAutosizer::FingerprintMapper::add(const RenderObject* renderer, Fingerprint fingerprint)
+{
+    remove(renderer);
+
+    m_fingerprints.set(renderer, fingerprint);
+#ifndef NDEBUG
+    assertMapsAreConsistent();
+#endif
+}
+
+void FastTextAutosizer::FingerprintMapper::addTentativeClusterRoot(const RenderBlock* block, Fingerprint fingerprint)
+{
+    add(block, fingerprint);
 
     ReverseFingerprintMap::AddResult addResult = m_blocksForFingerprint.add(fingerprint, PassOwnPtr<BlockSet>());
     if (addResult.isNewEntry)
         addResult.storedValue->value = adoptPtr(new BlockSet);
     addResult.storedValue->value->add(block);
+#ifndef NDEBUG
+    assertMapsAreConsistent();
+#endif
 }
 
-void FastTextAutosizer::FingerprintMapper::remove(const RenderBlock* block)
+void FastTextAutosizer::FingerprintMapper::remove(const RenderObject* renderer)
 {
-    AtomicString fingerprint = m_fingerprints.take(block);
-    if (fingerprint.isNull())
+    Fingerprint fingerprint = m_fingerprints.take(renderer);
+    if (!fingerprint || !renderer->isRenderBlock())
         return;
 
     ReverseFingerprintMap::iterator blocksIter = m_blocksForFingerprint.find(fingerprint);
+    if (blocksIter == m_blocksForFingerprint.end())
+        return;
+
     BlockSet& blocks = *blocksIter->value;
-    blocks.remove(block);
+    blocks.remove(toRenderBlock(renderer));
     if (blocks.isEmpty())
         m_blocksForFingerprint.remove(blocksIter);
+#ifndef NDEBUG
+    assertMapsAreConsistent();
+#endif
 }
 
-AtomicString FastTextAutosizer::FingerprintMapper::get(const RenderBlock* block)
+FastTextAutosizer::Fingerprint FastTextAutosizer::FingerprintMapper::get(const RenderObject* renderer)
 {
-    return m_fingerprints.get(block);
+    return m_fingerprints.get(renderer);
 }
 
-FastTextAutosizer::BlockSet& FastTextAutosizer::FingerprintMapper::getBlocks(AtomicString fingerprint)
+FastTextAutosizer::BlockSet& FastTextAutosizer::FingerprintMapper::getTentativeClusterRoots(Fingerprint fingerprint)
 {
     return *m_blocksForFingerprint.get(fingerprint);
 }
@@ -552,4 +937,31 @@
     return current->nextInPreOrderAfterChildren(stayWithin);
 }
 
+FastTextAutosizer::LayoutScope::LayoutScope(RenderBlock* block)
+    : m_textAutosizer(block->document().fastTextAutosizer())
+    , m_block(block)
+{
+    if (!m_textAutosizer)
+        return;
+
+    if (!m_textAutosizer->enabled()) {
+        m_textAutosizer = 0;
+        return;
+    }
+
+    if (m_textAutosizer->m_pageAutosizingStatus == PageAutosizingStatusUnknown)
+        m_textAutosizer->updateRenderViewInfo();
+
+    if (m_textAutosizer->m_pageAutosizingStatus == PageNeedsAutosizing)
+        m_textAutosizer->beginLayout(m_block);
+    else
+        m_textAutosizer = 0;
+}
+
+FastTextAutosizer::LayoutScope::~LayoutScope()
+{
+    if (m_textAutosizer)
+        m_textAutosizer->endLayout(m_block);
+}
+
 } // namespace WebCore
diff --git a/Source/core/rendering/FastTextAutosizer.h b/Source/core/rendering/FastTextAutosizer.h
index 50ba1bd..37a5447 100644
--- a/Source/core/rendering/FastTextAutosizer.h
+++ b/Source/core/rendering/FastTextAutosizer.h
@@ -32,13 +32,12 @@
 #define FastTextAutosizer_h
 
 #include "core/rendering/RenderObject.h"
-#include "core/rendering/TextAutosizer.h"
+#include "core/rendering/RenderTable.h"
 #include "wtf/HashMap.h"
 #include "wtf/HashSet.h"
 #include "wtf/Noncopyable.h"
 #include "wtf/OwnPtr.h"
 #include "wtf/PassOwnPtr.h"
-#include "wtf/text/AtomicStringHash.h"
 
 namespace WebCore {
 
@@ -67,24 +66,8 @@
 
     class LayoutScope {
     public:
-        explicit LayoutScope(Document& document, RenderBlock* block)
-        {
-            m_textAutosizer = document.fastTextAutosizer();
-            if (m_textAutosizer) {
-                if (!m_textAutosizer->enabled()) {
-                    m_textAutosizer = 0;
-                    return;
-                }
-                m_block = block;
-                m_textAutosizer->beginLayout(m_block);
-            }
-        }
-
-        ~LayoutScope()
-        {
-            if (m_textAutosizer)
-                m_textAutosizer->endLayout(m_block);
-        }
+        explicit LayoutScope(RenderBlock*);
+        ~LayoutScope();
     private:
         FastTextAutosizer* m_textAutosizer;
         RenderBlock* m_block;
@@ -93,6 +76,18 @@
 private:
     typedef HashSet<const RenderBlock*> BlockSet;
 
+    enum HasEnoughTextToAutosize {
+        UnknownAmountOfText,
+        HasEnoughText,
+        NotEnoughText
+    };
+
+    enum PageAutosizingStatus {
+        PageAutosizingStatusUnknown,
+        PageNeedsAutosizing,
+        PageDoesNotNeedAutosizing
+    };
+
     // A supercluster represents autosizing information about a set of two or
     // more blocks that all have the same fingerprint. Clusters whose roots
     // belong to a supercluster will share a common multiplier and
@@ -101,13 +96,11 @@
         explicit Supercluster(const BlockSet* roots)
             : m_roots(roots)
             , m_multiplier(0)
-            , m_anyClusterHasEnoughText(false)
         {
         }
 
         const BlockSet* const m_roots;
         float m_multiplier;
-        bool m_anyClusterHasEnoughText;
     };
 
     struct Cluster {
@@ -117,8 +110,9 @@
             , m_parent(parent)
             , m_autosize(autosize)
             , m_multiplier(0)
-            , m_textLength(-1)
+            , m_hasEnoughTextToAutosize(UnknownAmountOfText)
             , m_supercluster(supercluster)
+            , m_hasTableAncestor(root->isTableCell() || (m_parent && m_parent->m_hasTableAncestor))
         {
         }
 
@@ -133,11 +127,10 @@
         // m_blocksThatHaveBegunLayout assertions cover this). Note: the multiplier is still
         // calculated when m_autosize is false because child clusters may depend on this multiplier.
         float m_multiplier;
-        // Text length is computed lazily (see: textLength). This is an approximation and characters
-        // are assumed to be 1em wide. Negative values indicate the length has not been computed.
-        int m_textLength;
+        HasEnoughTextToAutosize m_hasEnoughTextToAutosize;
         // A set of blocks that are similar to this block.
         Supercluster* m_supercluster;
+        bool m_hasTableAncestor;
     };
 
     enum TextLeafSearch {
@@ -145,47 +138,82 @@
         Last
     };
 
-    typedef HashMap<AtomicString, OwnPtr<Supercluster> > SuperclusterMap;
+    struct FingerprintSourceData {
+        FingerprintSourceData()
+            : m_parentHash(0)
+            , m_qualifiedNameHash(0)
+            , m_packedStyleProperties(0)
+            , m_column(0)
+            , m_width(0)
+        {
+        }
+
+        unsigned m_parentHash;
+        unsigned m_qualifiedNameHash;
+        // Style specific selection of signals
+        unsigned m_packedStyleProperties;
+        unsigned m_column;
+        float m_width;
+    };
+    // Ensures efficient hashing using StringHasher.
+    COMPILE_ASSERT(!(sizeof(FingerprintSourceData) % sizeof(UChar)),
+        Sizeof_FingerprintSourceData_must_be_multiple_of_UChar);
+
+    typedef unsigned Fingerprint;
+    typedef HashMap<Fingerprint, OwnPtr<Supercluster> > SuperclusterMap;
     typedef Vector<OwnPtr<Cluster> > ClusterStack;
 
     // Fingerprints are computed during style recalc, for (some subset of)
     // blocks that will become cluster roots.
     class FingerprintMapper {
     public:
-        void add(const RenderBlock*, AtomicString);
-        void remove(const RenderBlock*);
-        AtomicString get(const RenderBlock*);
-        BlockSet& getBlocks(AtomicString);
+        void add(const RenderObject*, Fingerprint);
+        void addTentativeClusterRoot(const RenderBlock*, Fingerprint);
+        void remove(const RenderObject*);
+        Fingerprint get(const RenderObject*);
+        BlockSet& getTentativeClusterRoots(Fingerprint);
     private:
-        typedef HashMap<const RenderBlock*, AtomicString> FingerprintMap;
-        typedef HashMap<AtomicString, OwnPtr<BlockSet> > ReverseFingerprintMap;
+        typedef HashMap<const RenderObject*, Fingerprint> FingerprintMap;
+        typedef HashMap<Fingerprint, OwnPtr<BlockSet> > ReverseFingerprintMap;
 
         FingerprintMap m_fingerprints;
         ReverseFingerprintMap m_blocksForFingerprint;
+#ifndef NDEBUG
+        void assertMapsAreConsistent();
+#endif
     };
 
     explicit FastTextAutosizer(const Document*);
 
     void beginLayout(RenderBlock*);
     void endLayout(RenderBlock*);
+    void inflateTable(RenderTable*);
     void inflate(RenderBlock*);
     bool enabled();
-    void prepareRenderViewInfo();
+    void updateRenderViewInfo();
+    void prepareClusterStack(const RenderObject*);
     bool isFingerprintingCandidate(const RenderBlock*);
-    bool clusterHasEnoughTextToAutosize(Cluster*);
-    bool clusterWouldHaveEnoughTextToAutosize(const RenderBlock*);
-    float textLength(Cluster*);
-    AtomicString computeFingerprint(const RenderBlock*);
+    bool clusterHasEnoughTextToAutosize(Cluster*, const RenderBlock* widthProvider = 0);
+    bool anyClusterHasEnoughTextToAutosize(const BlockSet* roots, const RenderBlock* widthProvider = 0);
+    bool clusterWouldHaveEnoughTextToAutosize(const RenderBlock* root, const RenderBlock* widthProvider = 0);
+    Fingerprint getFingerprint(const RenderObject*);
+    Fingerprint computeFingerprint(const RenderObject*);
     Cluster* maybeCreateCluster(const RenderBlock*);
     Supercluster* getSupercluster(const RenderBlock*);
     const RenderBlock* deepestCommonAncestor(BlockSet&);
     float clusterMultiplier(Cluster*);
-    float superclusterMultiplier(Supercluster*);
+    float superclusterMultiplier(Cluster*);
+    // A cluster's width provider is typically the deepest block containing all text.
+    // There are exceptions, such as tables and table cells which use the table itself for width.
+    const RenderBlock* clusterWidthProvider(const RenderBlock*);
+    // Typically this returns a block's computed width. In the case of tables layout, this
+    // width is not yet known so the fixed width is used if it's available, or the containing
+    // block's width otherwise.
+    float widthFromBlock(const RenderBlock*);
     float multiplierFromBlock(const RenderBlock*);
     void applyMultiplier(RenderObject*, float);
     bool mightBeWiderOrNarrowerDescendant(const RenderBlock*);
-    bool isWiderDescendant(Cluster*);
-    bool isNarrowerDescendant(Cluster*);
+    bool isWiderOrNarrowerDescendant(Cluster*);
     bool isLayoutRoot(const RenderBlock*) const;
 
     Cluster* currentCluster() const;
@@ -200,9 +228,11 @@
     const RenderObject* findTextLeaf(const RenderObject*, size_t&, TextLeafSearch);
 
     const Document* m_document;
-    int m_frameWidth; // Frame width in density-independent pixels (DIPs).
+    int m_frameWidth; // LocalFrame width in density-independent pixels (DIPs).
     int m_layoutWidth; // Layout width in CSS pixels.
     float m_baseMultiplier; // Includes accessibility font scale factor and device scale adjustment.
+    PageAutosizingStatus m_pageAutosizingStatus;
+    const RenderBlock* m_firstBlock; // First block to receive beginLayout.
 #ifndef NDEBUG
     bool m_renderViewInfoPrepared;
     BlockSet m_blocksThatHaveBegunLayout; // Used to ensure we don't compute properties of a block before beginLayout() is called on it.
diff --git a/Source/core/rendering/FilterEffectRenderer.cpp b/Source/core/rendering/FilterEffectRenderer.cpp
index 9b10d69..0c8d5e4 100644
--- a/Source/core/rendering/FilterEffectRenderer.cpp
+++ b/Source/core/rendering/FilterEffectRenderer.cpp
@@ -66,14 +66,6 @@
     parameters.append(0);
 }
 
-inline bool isFilterSizeValid(FloatRect rect)
-{
-    if (rect.width() < 0 || rect.width() > kMaxFilterSize
-        || rect.height() < 0 || rect.height() > kMaxFilterSize)
-        return false;
-    return true;
-}
-
 FilterEffectRenderer::FilterEffectRenderer()
     : Filter(AffineTransform())
     , m_graphicsBufferAttached(false)
@@ -99,9 +91,11 @@
 
     // Inverse zoom the pre-zoomed CSS shorthand filters, so that they are in the same zoom as the unzoomed reference filters.
     const RenderStyle* style = renderer->style();
-    // FIXME: The effects now contain high dpi information, but the software path doesn't (yet) scale its backing.
-    //        When the proper dpi dependant backing size is allocated, we should remove deviceScaleFactor(...) here.
+#ifdef BLINK_SCALE_FILTERS_AT_RECORD_TIME
     float invZoom = 1.0f / ((style ? style->effectiveZoom() : 1.0f) * deviceScaleFactor(renderer->frame()));
+#else
+    float invZoom = style ? 1.0f / style->effectiveZoom() : 1.0f;
+#endif
 
     RefPtr<FilterEffect> previousEffect = m_sourceGraphic;
     for (size_t i = 0; i < operations.operations().size(); ++i) {
@@ -266,7 +260,7 @@
 bool FilterEffectRenderer::updateBackingStoreRect(const FloatRect& floatFilterRect)
 {
     IntRect filterRect = enclosingIntRect(floatFilterRect);
-    if (!filterRect.isEmpty() && isFilterSizeValid(filterRect)) {
+    if (!filterRect.isEmpty() && FilterEffect::isFilterSizeValid(filterRect)) {
         FloatRect currentSourceRect = sourceImageRect();
         if (filterRect != currentSourceRect) {
             setSourceImageRect(filterRect);
@@ -340,7 +334,8 @@
     // Prepare a transformation that brings the coordinates into the space
     // filter coordinates are defined in.
     AffineTransform absoluteTransform;
-    absoluteTransform.translate(filterBoxRect.x(), filterBoxRect.y());
+    // FIXME: Should these really be upconverted to doubles and not rounded? crbug.com/350474
+    absoluteTransform.translate(filterBoxRect.x().toDouble(), filterBoxRect.y().toDouble());
     absoluteTransform.scale(zoom, zoom);
 
     FilterEffectRenderer* filter = renderLayer->filterRenderer();
@@ -377,7 +372,7 @@
     filter->allocateBackingStoreIfNeeded();
     // Paint into the context that represents the SourceGraphic of the filter.
     GraphicsContext* sourceGraphicsContext = filter->inputContext();
-    if (!sourceGraphicsContext || !isFilterSizeValid(filter->absoluteFilterRegion())) {
+    if (!sourceGraphicsContext || !FilterEffect::isFilterSizeValid(filter->absoluteFilterRegion())) {
         // Disable the filters and continue.
         m_haveFilterEffect = false;
         return oldContext;
diff --git a/Source/core/rendering/FloatingObjects.cpp b/Source/core/rendering/FloatingObjects.cpp
index 7f202d3..d272077 100644
--- a/Source/core/rendering/FloatingObjects.cpp
+++ b/Source/core/rendering/FloatingObjects.cpp
@@ -112,16 +112,16 @@
     {
     }
 
+    virtual ~ComputeFloatOffsetAdapter() { }
+
     int lowValue() const { return m_lineTop; }
     int highValue() const { return m_lineBottom; }
     void collectIfNeeded(const IntervalType&);
 
     LayoutUnit offset() const { return m_offset; }
-    LayoutUnit shapeOffset() const;
-    LayoutUnit heightRemaining() const;
 
-private:
-    bool updateOffsetIfNeeded(const FloatingObject*);
+protected:
+    virtual bool updateOffsetIfNeeded(const FloatingObject*) = 0;
 
     const RenderBlockFlow* m_renderer;
     int m_lineTop;
@@ -130,6 +130,36 @@
     const FloatingObject* m_outermostFloat;
 };
 
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForFloatLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+    ComputeFloatOffsetForFloatLayoutAdapter(const RenderBlockFlow* renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+        : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+    {
+    }
+
+    virtual ~ComputeFloatOffsetForFloatLayoutAdapter() { }
+
+    LayoutUnit heightRemaining() const;
+
+protected:
+    virtual bool updateOffsetIfNeeded(const FloatingObject*) OVERRIDE FINAL;
+};
+
+template <FloatingObject::Type FloatTypeValue>
+class ComputeFloatOffsetForLineLayoutAdapter : public ComputeFloatOffsetAdapter<FloatTypeValue> {
+public:
+    ComputeFloatOffsetForLineLayoutAdapter(const RenderBlockFlow* renderer, LayoutUnit lineTop, LayoutUnit lineBottom, LayoutUnit offset)
+        : ComputeFloatOffsetAdapter<FloatTypeValue>(renderer, lineTop, lineBottom, offset)
+    {
+    }
+
+    virtual ~ComputeFloatOffsetForLineLayoutAdapter() { }
+
+protected:
+    virtual bool updateOffsetIfNeeded(const FloatingObject*) OVERRIDE FINAL;
+};
+
 
 FloatingObjects::~FloatingObjects()
 {
@@ -146,17 +176,6 @@
     }
 }
 
-template<>
-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
-{
-    LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
-    if (logicalRight > m_offset) {
-        m_offset = logicalRight;
-        return true;
-    }
-    return false;
-}
-
 FloatingObjects::FloatingObjects(const RenderBlockFlow* renderer, bool horizontalWritingMode)
     : m_placedFloatsTree(UninitializedTree)
     , m_leftObjectsCount(0)
@@ -357,40 +376,10 @@
     }
 }
 
-static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject* floatingObject, const RenderBlockFlow* containingBlock, LayoutUnit lineTop, LayoutUnit lineBottom)
-{
-    if (floatingObject) {
-        if (ShapeOutsideInfo* shapeOutside = floatingObject->renderer()->shapeOutsideInfo()) {
-            shapeOutside->updateDeltasForContainingBlockLine(containingBlock, floatingObject, lineTop, lineBottom - lineTop);
-            return shapeOutside;
-        }
-    }
-
-    return 0;
-}
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatLeft>::shapeOffset() const
-{
-    if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
-        return m_offset + shapeOutside->rightMarginBoxDelta();
-
-    return m_offset;
-}
-
-template<>
-inline LayoutUnit ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::shapeOffset() const
-{
-    if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(m_outermostFloat, m_renderer, m_lineTop, m_lineBottom))
-        return m_offset + shapeOutside->leftMarginBoxDelta();
-
-    return m_offset;
-}
-
 LayoutUnit FloatingObjects::logicalLeftOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
 {
     int logicalTopAsInt = roundToInt(logicalTop);
-    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
+    ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
     if (heightRemaining)
@@ -402,7 +391,7 @@
 LayoutUnit FloatingObjects::logicalRightOffsetForPositioningFloat(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit *heightRemaining)
 {
     int logicalTopAsInt = roundToInt(logicalTop);
-    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
+    ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, logicalTopAsInt, logicalTopAsInt, fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
     if (heightRemaining)
@@ -413,18 +402,18 @@
 
 LayoutUnit FloatingObjects::logicalLeftOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatLeft> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
+    ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
-    return adapter.shapeOffset();
+    return adapter.offset();
 }
 
 LayoutUnit FloatingObjects::logicalRightOffset(LayoutUnit fixedOffset, LayoutUnit logicalTop, LayoutUnit logicalHeight)
 {
-    ComputeFloatOffsetAdapter<FloatingObject::FloatRight> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
+    ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight> adapter(m_renderer, roundToInt(logicalTop), roundToInt(logicalTop + logicalHeight), fixedOffset);
     placedFloatsTree().allOverlapsWithAdapter(adapter);
 
-    return min(fixedOffset, adapter.shapeOffset());
+    return min(fixedOffset, adapter.offset());
 }
 
 FloatingObjects::FloatBottomCachedValue::FloatBottomCachedValue()
@@ -454,7 +443,18 @@
 }
 
 template<>
-inline bool ComputeFloatOffsetAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+    LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
+    if (logicalRight > m_offset) {
+        m_offset = logicalRight;
+        return true;
+    }
+    return false;
+}
+
+template<>
+inline bool ComputeFloatOffsetForFloatLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
 {
     LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
     if (logicalLeft < m_offset) {
@@ -465,6 +465,12 @@
 }
 
 template <FloatingObject::Type FloatTypeValue>
+LayoutUnit ComputeFloatOffsetForFloatLayoutAdapter<FloatTypeValue>::heightRemaining() const
+{
+    return this->m_outermostFloat ? this->m_renderer->logicalBottomForFloat(this->m_outermostFloat) - this->m_lineTop : LayoutUnit(1);
+}
+
+template <FloatingObject::Type FloatTypeValue>
 inline void ComputeFloatOffsetAdapter<FloatTypeValue>::collectIfNeeded(const IntervalType& interval)
 {
     const FloatingObject* floatingObject = interval.data();
@@ -481,10 +487,52 @@
         m_outermostFloat = floatingObject;
 }
 
-template <FloatingObject::Type FloatTypeValue>
-LayoutUnit ComputeFloatOffsetAdapter<FloatTypeValue>::heightRemaining() const
+static inline ShapeOutsideInfo* shapeInfoForFloat(const FloatingObject& floatingObject, const RenderBlockFlow& containingBlock, LayoutUnit lineTop, LayoutUnit lineBottom)
 {
-    return m_outermostFloat ? m_renderer->logicalBottomForFloat(m_outermostFloat) - m_lineTop : LayoutUnit(1);
+    if (ShapeOutsideInfo* shapeOutside = floatingObject.renderer()->shapeOutsideInfo()) {
+        shapeOutside->updateDeltasForContainingBlockLine(containingBlock, floatingObject, lineTop, lineBottom - lineTop);
+        return shapeOutside;
+    }
+
+    return 0;
+}
+
+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatLeft>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+    ASSERT(floatingObject);
+    LayoutUnit logicalRight = m_renderer->logicalRightForFloat(floatingObject);
+    if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(*floatingObject, *m_renderer, m_lineTop, m_lineBottom)) {
+        if (!shapeOutside->lineOverlapsShape())
+            return false;
+
+        logicalRight += shapeOutside->rightMarginBoxDelta();
+    }
+    if (logicalRight > m_offset) {
+        m_offset = logicalRight;
+        return true;
+    }
+
+    return false;
+}
+
+template<>
+inline bool ComputeFloatOffsetForLineLayoutAdapter<FloatingObject::FloatRight>::updateOffsetIfNeeded(const FloatingObject* floatingObject)
+{
+    ASSERT(floatingObject);
+    LayoutUnit logicalLeft = m_renderer->logicalLeftForFloat(floatingObject);
+    if (ShapeOutsideInfo* shapeOutside = shapeInfoForFloat(*floatingObject, *m_renderer, m_lineTop, m_lineBottom)) {
+        if (!shapeOutside->lineOverlapsShape())
+            return false;
+
+        logicalLeft += shapeOutside->leftMarginBoxDelta();
+    }
+    if (logicalLeft < m_offset) {
+        m_offset = logicalLeft;
+        return true;
+    }
+
+    return false;
 }
 
 #ifndef NDEBUG
diff --git a/Source/core/rendering/HitTestLocation.h b/Source/core/rendering/HitTestLocation.h
index 828cf29..c4d26fb 100644
--- a/Source/core/rendering/HitTestLocation.h
+++ b/Source/core/rendering/HitTestLocation.h
@@ -34,7 +34,7 @@
 namespace WebCore {
 
 class Element;
-class Frame;
+class LocalFrame;
 class Image;
 class KURL;
 class Node;
diff --git a/Source/core/rendering/HitTestRequest.h b/Source/core/rendering/HitTestRequest.h
index 97dfa51..44fd6e4 100644
--- a/Source/core/rendering/HitTestRequest.h
+++ b/Source/core/rendering/HitTestRequest.h
@@ -40,7 +40,8 @@
         AllowFrameScrollbars = 1 << 9,
         AllowChildFrameContent = 1 << 10,
         ChildFrameHitTest = 1 << 11,
-        IgnorePointerEventsNone = 1 << 12
+        IgnorePointerEventsNone = 1 << 12,
+        TouchAction = 1 << 13, // Hit testing for touch-action considers only block-level elements
     };
 
     typedef unsigned HitTestRequestType;
@@ -63,6 +64,7 @@
     bool allowsChildFrameContent() const { return m_requestType & AllowChildFrameContent; }
     bool isChildFrameHitTest() const { return m_requestType & ChildFrameHitTest; }
     bool ignorePointerEventsNone() const { return m_requestType & IgnorePointerEventsNone; }
+    bool touchAction() const { return m_requestType & TouchAction; }
 
     // Convenience functions
     bool touchMove() const { return move() && touchEvent(); }
diff --git a/Source/core/rendering/HitTestResult.cpp b/Source/core/rendering/HitTestResult.cpp
index ac573ea..1b15d9c 100644
--- a/Source/core/rendering/HitTestResult.cpp
+++ b/Source/core/rendering/HitTestResult.cpp
@@ -30,15 +30,16 @@
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/editing/FrameSelection.h"
 #include "core/fetch/ImageResource.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLMediaElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
-#include "core/frame/Frame.h"
 #include "core/page/FrameTree.h"
 #include "core/rendering/RenderImage.h"
 #include "core/rendering/RenderTextFragment.h"
+#include "core/svg/SVGElement.h"
 #include "platform/scroll/Scrollbar.h"
 
 namespace WebCore {
@@ -179,7 +180,7 @@
     m_scrollbar = s;
 }
 
-Frame* HitTestResult::innerNodeFrame() const
+LocalFrame* HitTestResult::innerNodeFrame() const
 {
     if (m_innerNonSharedNode)
         return m_innerNonSharedNode->document().frame();
@@ -193,7 +194,7 @@
     if (!m_innerNonSharedNode)
         return false;
 
-    if (Frame* frame = m_innerNonSharedNode->document().frame())
+    if (LocalFrame* frame = m_innerNonSharedNode->document().frame())
         return frame->selection().contains(m_hitTestLocation.point());
     return false;
 }
@@ -206,7 +207,7 @@
     if (!m_innerNonSharedNode)
         return String();
 
-    DocumentMarker* marker = m_innerNonSharedNode->document().markers()->markerContainingPoint(m_hitTestLocation.point(), DocumentMarker::Grammar);
+    DocumentMarker* marker = m_innerNonSharedNode->document().markers().markerContainingPoint(m_hitTestLocation.point(), DocumentMarker::Grammar);
     if (!marker)
         return String();
 
@@ -238,14 +239,14 @@
     if (!m_innerNonSharedNode)
         return nullAtom;
 
-    if (m_innerNonSharedNode->hasTagName(imgTag)) {
-        HTMLImageElement* image = toHTMLImageElement(m_innerNonSharedNode);
-        return image->getAttribute(altAttr);
+    if (isHTMLImageElement(*m_innerNonSharedNode)) {
+        HTMLImageElement& image = toHTMLImageElement(*m_innerNonSharedNode);
+        return image.getAttribute(altAttr);
     }
 
-    if (m_innerNonSharedNode->hasTagName(inputTag)) {
-        HTMLInputElement* input = toHTMLInputElement(m_innerNonSharedNode);
-        return input->alt();
+    if (isHTMLInputElement(*m_innerNonSharedNode)) {
+        HTMLInputElement& input = toHTMLInputElement(*m_innerNonSharedNode);
+        return input.alt();
     }
 
     return nullAtom;
@@ -282,13 +283,13 @@
         return KURL();
 
     AtomicString urlString;
-    if (m_innerNonSharedNode->hasTagName(embedTag)
-        || m_innerNonSharedNode->hasTagName(imgTag)
-        || m_innerNonSharedNode->hasTagName(inputTag)
-        || m_innerNonSharedNode->hasTagName(objectTag)
-        || m_innerNonSharedNode->hasTagName(SVGNames::imageTag)
+    if (isHTMLEmbedElement(*m_innerNonSharedNode)
+        || isHTMLImageElement(*m_innerNonSharedNode)
+        || isHTMLInputElement(*m_innerNonSharedNode)
+        || isHTMLObjectElement(*m_innerNonSharedNode)
+        || isSVGImageElement(*m_innerNonSharedNode)
        ) {
-        urlString = toElement(m_innerNonSharedNode)->imageSourceURL();
+        urlString = toElement(*m_innerNonSharedNode).imageSourceURL();
     } else
         return KURL();
 
@@ -321,9 +322,9 @@
         return KURL();
 
     AtomicString urlString;
-    if (m_innerURLElement->hasTagName(aTag) || m_innerURLElement->hasTagName(areaTag) || m_innerURLElement->hasTagName(linkTag))
+    if (isHTMLAnchorElement(*m_innerURLElement) || isHTMLAreaElement(*m_innerURLElement) || isHTMLLinkElement(*m_innerURLElement))
         urlString = m_innerURLElement->getAttribute(hrefAttr);
-    else if (m_innerURLElement->hasTagName(SVGNames::aTag))
+    else if (isSVGAElement(*m_innerURLElement))
         urlString = m_innerURLElement->getAttribute(XLinkNames::hrefAttr);
     else
         return KURL();
@@ -336,10 +337,10 @@
     if (!m_innerURLElement)
         return false;
 
-    if (m_innerURLElement->hasTagName(aTag))
+    if (isHTMLAnchorElement(*m_innerURLElement))
         return toHTMLAnchorElement(m_innerURLElement)->isLiveLink();
 
-    if (m_innerURLElement->hasTagName(SVGNames::aTag))
+    if (isSVGAElement(*m_innerURLElement))
         return m_innerURLElement->isLink();
 
     return false;
@@ -347,12 +348,12 @@
 
 bool HitTestResult::isMisspelled() const
 {
-    if (!targetNode())
+    if (!targetNode() || !targetNode()->renderer())
         return false;
     VisiblePosition pos(targetNode()->renderer()->positionForPoint(localPoint()));
     if (pos.isNull())
         return false;
-    return m_innerNonSharedNode->document().markers()->markersInRange(
+    return m_innerNonSharedNode->document().markers().markersInRange(
         makeRange(pos, pos).get(), DocumentMarker::MisspellingMarkers()).size() > 0;
 }
 
@@ -385,11 +386,11 @@
     if (!m_innerNonSharedNode)
         return false;
 
-    if (m_innerNonSharedNode->hasTagName(textareaTag))
+    if (isHTMLTextAreaElement(*m_innerNonSharedNode))
         return true;
 
-    if (m_innerNonSharedNode->hasTagName(inputTag))
-        return toHTMLInputElement(m_innerNonSharedNode)->isTextField();
+    if (isHTMLInputElement(*m_innerNonSharedNode))
+        return toHTMLInputElement(*m_innerNonSharedNode).isTextField();
 
     return m_innerNonSharedNode->rendererIsEditable();
 }
diff --git a/Source/core/rendering/HitTestResult.h b/Source/core/rendering/HitTestResult.h
index 39cadf3..f72054e 100644
--- a/Source/core/rendering/HitTestResult.h
+++ b/Source/core/rendering/HitTestResult.h
@@ -36,7 +36,7 @@
 namespace WebCore {
 
 class Element;
-class Frame;
+class LocalFrame;
 class HTMLMediaElement;
 class Image;
 class KURL;
@@ -75,7 +75,7 @@
     // The hit-tested point in the coordinates of the innerNode frame, the frame containing innerNode.
     const LayoutPoint& pointInInnerNodeFrame() const { return m_pointInInnerNodeFrame; }
     IntPoint roundedPointInInnerNodeFrame() const { return roundedIntPoint(pointInInnerNodeFrame()); }
-    Frame* innerNodeFrame() const;
+    LocalFrame* innerNodeFrame() const;
 
     // The hit-tested point in the coordinates of the inner node.
     const LayoutPoint& localPoint() const { return m_localPoint; }
diff --git a/Source/core/rendering/ImageQualityController.cpp b/Source/core/rendering/ImageQualityController.cpp
index ef4c23b..c9bdae7 100644
--- a/Source/core/rendering/ImageQualityController.cpp
+++ b/Source/core/rendering/ImageQualityController.cpp
@@ -31,8 +31,8 @@
 #include "config.h"
 #include "core/rendering/ImageQualityController.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "platform/graphics/GraphicsContext.h"
 
 namespace WebCore {
@@ -109,7 +109,7 @@
     m_animatedResizeIsActive = false;
 
     for (ObjectLayerSizeMap::iterator it = m_objectLayerSizeMap.begin(); it != m_objectLayerSizeMap.end(); ++it) {
-        if (Frame* frame = it->key->document().frame()) {
+        if (LocalFrame* frame = it->key->document().frame()) {
             // If this renderer's containing FrameView is in live resize, punt the timer and hold back for now.
             if (frame->view() && frame->view()->inLiveResize()) {
                 restartTimer();
@@ -124,7 +124,7 @@
 
 void ImageQualityController::restartTimer()
 {
-    m_timer.startOneShot(cLowQualityTimeThreshold);
+    m_timer.startOneShot(cLowQualityTimeThreshold, FROM_HERE);
 }
 
 bool ImageQualityController::shouldPaintAtLowQuality(GraphicsContext* context, RenderObject* object, Image* image, const void *layer, const LayoutSize& layoutSize)
@@ -137,6 +137,10 @@
     if (object->style()->imageRendering() == ImageRenderingOptimizeContrast)
         return true;
 
+    // For images that are potentially animated we paint them at low quality.
+    if (image->maybeAnimated())
+        return true;
+
     // Look ourselves up in the hashtables.
     ObjectLayerSizeMap::iterator i = m_objectLayerSizeMap.find(object);
     LayerSizeMap* innerMap = i != m_objectLayerSizeMap.end() ? &i->value : 0;
@@ -159,7 +163,7 @@
     LayoutSize scaledLayoutSize = currentTransform.mapSize(roundedIntSize(layoutSize));
 
     // If the containing FrameView is being resized, paint at low quality until resizing is finished.
-    if (Frame* frame = object->document().frame()) {
+    if (LocalFrame* frame = object->document().frame()) {
         bool frameViewIsCurrentlyInLiveResize = frame->view() && frame->view()->inLiveResize();
         if (frameViewIsCurrentlyInLiveResize) {
             set(object, innerMap, layer, scaledLayoutSize);
diff --git a/Source/core/rendering/InlineBox.cpp b/Source/core/rendering/InlineBox.cpp
index 0e1e21e..b8b870c 100644
--- a/Source/core/rendering/InlineBox.cpp
+++ b/Source/core/rendering/InlineBox.cpp
@@ -82,14 +82,12 @@
 
 void InlineBox::showTreeForThis() const
 {
-    if (m_renderer)
-        m_renderer->showTreeForThis();
+    renderer().showTreeForThis();
 }
 
 void InlineBox::showLineTreeForThis() const
 {
-    if (m_renderer)
-        m_renderer->containingBlock()->showLineTreeAndMark(this, "*");
+    renderer().containingBlock()->showLineTreeAndMark(this, "*");
 }
 
 void InlineBox::showLineTreeAndMark(const InlineBox* markedBox1, const char* markedLabel1, const InlineBox* markedBox2, const char* markedLabel2, const RenderObject* obj, int depth) const
@@ -99,7 +97,7 @@
         printedCharacters += fprintf(stderr, "%s", markedLabel1);
     if (this == markedBox2)
         printedCharacters += fprintf(stderr, "%s", markedLabel2);
-    if (renderer() == obj)
+    if (&renderer() == obj)
         printedCharacters += fprintf(stderr, "*");
     for (; printedCharacters < depth * 2; printedCharacters++)
         fputc(' ', stderr);
@@ -112,7 +110,7 @@
     printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this);
     for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
         fputc(' ', stderr);
-    fprintf(stderr, "\t%s %p\n", renderer() ? renderer()->renderName() : "No Renderer", renderer());
+    fprintf(stderr, "\t%s %p\n", renderer().renderName(), &renderer());
 }
 #endif
 
@@ -121,14 +119,14 @@
     if (hasVirtualLogicalHeight())
         return virtualLogicalHeight();
 
-    if (renderer()->isText())
-        return m_bitfields.isText() ? renderer()->style(isFirstLineStyle())->fontMetrics().height() : 0;
-    if (renderer()->isBox() && parent())
-        return isHorizontal() ? toRenderBox(m_renderer)->height() : toRenderBox(m_renderer)->width();
+    if (renderer().isText())
+        return m_bitfields.isText() ? renderer().style(isFirstLineStyle())->fontMetrics().height() : 0;
+    if (renderer().isBox() && parent())
+        return isHorizontal() ? toRenderBox(renderer()).height().toFloat() : toRenderBox(renderer()).width().toFloat();
 
     ASSERT(isInlineFlowBox());
     RenderBoxModelObject* flowObject = boxModelObject();
-    const FontMetrics& fontMetrics = renderer()->style(isFirstLineStyle())->fontMetrics();
+    const FontMetrics& fontMetrics = renderer().style(isFirstLineStyle())->fontMetrics();
     float result = fontMetrics.height();
     if (parent())
         result += flowObject->borderAndPaddingLogicalHeight();
@@ -147,12 +145,12 @@
 
 int InlineBox::caretMinOffset() const
 {
-    return m_renderer->caretMinOffset();
+    return renderer().caretMinOffset();
 }
 
 int InlineBox::caretMaxOffset() const
 {
-    return m_renderer->caretMaxOffset();
+    return renderer().caretMaxOffset();
 }
 
 void InlineBox::dirtyLineBoxes()
@@ -164,43 +162,43 @@
 
 void InlineBox::deleteLine()
 {
-    if (!m_bitfields.extracted() && m_renderer->isBox())
-        toRenderBox(m_renderer)->setInlineBoxWrapper(0);
+    if (!m_bitfields.extracted() && renderer().isBox())
+        toRenderBox(renderer()).setInlineBoxWrapper(0);
     destroy();
 }
 
 void InlineBox::extractLine()
 {
     m_bitfields.setExtracted(true);
-    if (m_renderer->isBox())
-        toRenderBox(m_renderer)->setInlineBoxWrapper(0);
+    if (renderer().isBox())
+        toRenderBox(renderer()).setInlineBoxWrapper(0);
 }
 
 void InlineBox::attachLine()
 {
     m_bitfields.setExtracted(false);
-    if (m_renderer->isBox())
-        toRenderBox(m_renderer)->setInlineBoxWrapper(this);
+    if (renderer().isBox())
+        toRenderBox(renderer()).setInlineBoxWrapper(this);
 }
 
 void InlineBox::adjustPosition(float dx, float dy)
 {
     m_topLeft.move(dx, dy);
 
-    if (m_renderer->isReplaced())
-        toRenderBox(m_renderer)->move(dx, dy);
+    if (renderer().isReplaced())
+        toRenderBox(renderer()).move(dx, dy);
 }
 
 void InlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
 {
-    if (!paintInfo.shouldPaintWithinRoot(renderer()) || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
+    if (!paintInfo.shouldPaintWithinRoot(&renderer()) || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
         return;
 
     LayoutPoint childPoint = paintOffset;
-    if (parent()->renderer()->style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
-        childPoint = renderer()->containingBlock()->flipForWritingModeForChild(toRenderBox(renderer()), childPoint);
+    if (parent()->renderer().style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
+        childPoint = renderer().containingBlock()->flipForWritingModeForChild(&toRenderBox(renderer()), childPoint);
 
-    RenderBlock::paintAsInlineBlock(renderer(), paintInfo, childPoint);
+    RenderBlock::paintAsInlineBlock(&renderer(), paintInfo, childPoint);
 }
 
 bool InlineBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
@@ -209,26 +207,26 @@
     // own stacking context.  (See Appendix E.2, section 6.4 on inline block/table elements in the CSS2.1
     // specification.)
     LayoutPoint childPoint = accumulatedOffset;
-    if (parent()->renderer()->style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
-        childPoint = renderer()->containingBlock()->flipForWritingModeForChild(toRenderBox(renderer()), childPoint);
+    if (parent()->renderer().style()->isFlippedBlocksWritingMode()) // Faster than calling containingBlock().
+        childPoint = renderer().containingBlock()->flipForWritingModeForChild(&toRenderBox(renderer()), childPoint);
 
-    return renderer()->hitTest(request, result, locationInContainer, childPoint);
+    return renderer().hitTest(request, result, locationInContainer, childPoint);
 }
 
-const RootInlineBox* InlineBox::root() const
+const RootInlineBox& InlineBox::root() const
 {
     if (m_parent)
         return m_parent->root();
     ASSERT(isRootInlineBox());
-    return static_cast<const RootInlineBox*>(this);
+    return static_cast<const RootInlineBox&>(*this);
 }
 
-RootInlineBox* InlineBox::root()
+RootInlineBox& InlineBox::root()
 {
     if (m_parent)
         return m_parent->root();
     ASSERT(isRootInlineBox());
-    return static_cast<RootInlineBox*>(this);
+    return static_cast<RootInlineBox&>(*this);
 }
 
 bool InlineBox::nextOnLineExists() const
@@ -284,13 +282,13 @@
 
 RenderObject::SelectionState InlineBox::selectionState()
 {
-    return renderer()->selectionState();
+    return renderer().selectionState();
 }
 
 bool InlineBox::canAccommodateEllipsis(bool ltr, int blockEdge, int ellipsisWidth) const
 {
     // Non-replaced elements can always accommodate an ellipsis.
-    if (!m_renderer || !m_renderer->isReplaced())
+    if (!renderer().isReplaced())
         return true;
 
     IntRect boxRect(left(), 0, m_logicalWidth, 10);
@@ -314,41 +312,41 @@
 
 FloatPoint InlineBox::locationIncludingFlipping()
 {
-    if (!renderer()->style()->isFlippedBlocksWritingMode())
+    if (!renderer().style()->isFlippedBlocksWritingMode())
         return FloatPoint(x(), y());
-    RenderBlockFlow* block = root()->block();
-    if (block->style()->isHorizontalWritingMode())
-        return FloatPoint(x(), block->height() - height() - y());
-    else
-        return FloatPoint(block->width() - width() - x(), y());
+    RenderBlockFlow& block = root().block();
+    if (block.style()->isHorizontalWritingMode())
+        return FloatPoint(x(), block.height() - height() - y());
+
+    return FloatPoint(block.width() - width() - x(), y());
 }
 
 void InlineBox::flipForWritingMode(FloatRect& rect)
 {
-    if (!renderer()->style()->isFlippedBlocksWritingMode())
+    if (!renderer().style()->isFlippedBlocksWritingMode())
         return;
-    root()->block()->flipForWritingMode(rect);
+    root().block().flipForWritingMode(rect);
 }
 
 FloatPoint InlineBox::flipForWritingMode(const FloatPoint& point)
 {
-    if (!renderer()->style()->isFlippedBlocksWritingMode())
+    if (!renderer().style()->isFlippedBlocksWritingMode())
         return point;
-    return root()->block()->flipForWritingMode(point);
+    return root().block().flipForWritingMode(point);
 }
 
 void InlineBox::flipForWritingMode(LayoutRect& rect)
 {
-    if (!renderer()->style()->isFlippedBlocksWritingMode())
+    if (!renderer().style()->isFlippedBlocksWritingMode())
         return;
-    root()->block()->flipForWritingMode(rect);
+    root().block().flipForWritingMode(rect);
 }
 
 LayoutPoint InlineBox::flipForWritingMode(const LayoutPoint& point)
 {
-    if (!renderer()->style()->isFlippedBlocksWritingMode())
+    if (!renderer().style()->isFlippedBlocksWritingMode())
         return point;
-    return root()->block()->flipForWritingMode(point);
+    return root().block().flipForWritingMode(point);
 }
 
 } // namespace WebCore
diff --git a/Source/core/rendering/InlineBox.h b/Source/core/rendering/InlineBox.h
index 5803cd1..8f2a4ff 100644
--- a/Source/core/rendering/InlineBox.h
+++ b/Source/core/rendering/InlineBox.h
@@ -33,8 +33,9 @@
 // InlineBox represents a rectangle that occurs on a line.  It corresponds to
 // some RenderObject (i.e., it represents a portion of that RenderObject).
 class InlineBox {
+    WTF_MAKE_NONCOPYABLE(InlineBox);
 public:
-    InlineBox(RenderObject* obj)
+    InlineBox(RenderObject& obj)
         : m_next(0)
         , m_prev(0)
         , m_parent(0)
@@ -46,7 +47,7 @@
     {
     }
 
-    InlineBox(RenderObject* obj, FloatPoint topLeft, float logicalWidth, bool firstLine, bool constructed,
+    InlineBox(RenderObject& obj, FloatPoint topLeft, float logicalWidth, bool firstLine, bool constructed,
               bool dirty, bool extracted, bool isHorizontal, InlineBox* next, InlineBox* prev, InlineFlowBox* parent)
         : m_next(next)
         , m_prev(prev)
@@ -173,7 +174,7 @@
     InlineBox* nextLeafChildIgnoringLineBreak() const;
     InlineBox* prevLeafChildIgnoringLineBreak() const;
 
-    RenderObject* renderer() const { return m_renderer; }
+    RenderObject& renderer() const { return m_renderer; }
 
     InlineFlowBox* parent() const
     {
@@ -182,8 +183,8 @@
     }
     void setParent(InlineFlowBox* par) { m_parent = par; }
 
-    const RootInlineBox* root() const;
-    RootInlineBox* root();
+    const RootInlineBox& root() const;
+    RootInlineBox& root();
 
     // x() is the left side of the box in the containing block's coordinate system.
     void setX(float x) { m_topLeft.setX(x); }
@@ -270,15 +271,21 @@
 
     int expansion() const { return m_bitfields.expansion(); }
 
-    bool visibleToHitTestRequest(const HitTestRequest& request) const { return renderer()->visibleToHitTestRequest(request); }
+    bool visibleForTouchAction() const { return false; }
+    bool visibleToHitTestRequest(const HitTestRequest& request) const
+    {
+        if (request.touchAction() && !visibleForTouchAction())
+            return false;
+        return renderer().visibleToHitTestRequest(request);
+    }
 
-    EVerticalAlign verticalAlign() const { return renderer()->style(m_bitfields.firstLine())->verticalAlign(); }
+    EVerticalAlign verticalAlign() const { return renderer().style(m_bitfields.firstLine())->verticalAlign(); }
 
     // Use with caution! The type is not checked!
     RenderBoxModelObject* boxModelObject() const
     {
-        if (!m_renderer->isText())
-            return toRenderBoxModelObject(m_renderer);
+        if (!renderer().isText())
+            return toRenderBoxModelObject(&renderer());
         return 0;
     }
 
@@ -377,6 +384,7 @@
     InlineBox* m_prev; // The previous element on the same line as us.
 
     InlineFlowBox* m_parent; // The box that contains us.
+    RenderObject& m_renderer;
 
 protected:
     // For RootInlineBox
@@ -398,8 +406,6 @@
     // For InlineFlowBox and InlineTextBox
     bool extracted() const { return m_bitfields.extracted(); }
 
-    RenderObject* m_renderer;
-
     FloatPoint m_topLeft;
     float m_logicalWidth;
 
@@ -427,6 +433,14 @@
 #define DEFINE_INLINE_BOX_TYPE_CASTS(typeName) \
     DEFINE_TYPE_CASTS(typeName, InlineBox, box, box->is##typeName(), box.is##typeName())
 
+// Allow equality comparisons of InlineBox's by reference or pointer, interchangeably.
+inline bool operator==(const InlineBox& a, const InlineBox& b) { return &a == &b; }
+inline bool operator==(const InlineBox& a, const InlineBox* b) { return &a == b; }
+inline bool operator==(const InlineBox* a, const InlineBox& b) { return a == &b; }
+inline bool operator!=(const InlineBox& a, const InlineBox& b) { return !(a == b); }
+inline bool operator!=(const InlineBox& a, const InlineBox* b) { return !(a == b); }
+inline bool operator!=(const InlineBox* a, const InlineBox& b) { return !(a == b); }
+
 } // namespace WebCore
 
 #ifndef NDEBUG
diff --git a/Source/core/rendering/InlineFlowBox.cpp b/Source/core/rendering/InlineFlowBox.cpp
index 66e89f3..b1814ad 100644
--- a/Source/core/rendering/InlineFlowBox.cpp
+++ b/Source/core/rendering/InlineFlowBox.cpp
@@ -109,7 +109,7 @@
     child->setFirstLineStyleBit(isFirstLineStyle());
     child->setIsHorizontal(isHorizontal());
     if (child->isText()) {
-        if (child->renderer()->parent() == renderer())
+        if (child->renderer().parent() == renderer())
             m_hasTextChildren = true;
         setHasTextDescendantsOnAncestors(this);
     } else if (child->isInlineFlowBox()) {
@@ -117,14 +117,14 @@
             setHasTextDescendantsOnAncestors(this);
     }
 
-    if (descendantsHaveSameLineHeightAndBaseline() && !child->renderer()->isOutOfFlowPositioned()) {
-        RenderStyle* parentStyle = renderer()->style(isFirstLineStyle());
-        RenderStyle* childStyle = child->renderer()->style(isFirstLineStyle());
+    if (descendantsHaveSameLineHeightAndBaseline() && !child->renderer().isOutOfFlowPositioned()) {
+        RenderStyle* parentStyle = renderer().style(isFirstLineStyle());
+        RenderStyle* childStyle = child->renderer().style(isFirstLineStyle());
         bool shouldClearDescendantsHaveSameLineHeightAndBaseline = false;
-        if (child->renderer()->isReplaced())
+        if (child->renderer().isReplaced())
             shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
         else if (child->isText()) {
-            if (child->renderer()->isBR() || child->renderer()->parent() != renderer()) {
+            if (child->renderer().isBR() || child->renderer().parent() != renderer()) {
                 if (!parentStyle->font().fontMetrics().hasIdenticalAscentDescentAndLineGap(childStyle->font().fontMetrics())
                     || parentStyle->lineHeight() != childStyle->lineHeight()
                     || (parentStyle->verticalAlign() != BASELINE && !isRootInlineBox()) || childStyle->verticalAlign() != BASELINE)
@@ -133,7 +133,7 @@
             if (childStyle->hasTextCombine() || childStyle->textEmphasisMark() != TextEmphasisMarkNone)
                 shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
         } else {
-            if (child->renderer()->isBR()) {
+            if (child->renderer().isBR()) {
                 // FIXME: This is dumb. We only turn off because current layout test results expect the <br> to be 0-height on the baseline.
                 // Other than making a zillion tests have to regenerate results, there's no reason to ditch the optimization here.
                 shouldClearDescendantsHaveSameLineHeightAndBaseline = true;
@@ -154,19 +154,21 @@
             clearDescendantsHaveSameLineHeightAndBaseline();
     }
 
-    if (!child->renderer()->isOutOfFlowPositioned()) {
+    if (!child->renderer().isOutOfFlowPositioned()) {
         if (child->isText()) {
-            RenderStyle* childStyle = child->renderer()->style(isFirstLineStyle());
+            RenderStyle* childStyle = child->renderer().style(isFirstLineStyle());
             if (childStyle->letterSpacing() < 0 || childStyle->textShadow() || childStyle->textEmphasisMark() != TextEmphasisMarkNone || childStyle->textStrokeWidth())
                 child->clearKnownToHaveNoOverflow();
-        } else if (child->renderer()->isReplaced()) {
-            RenderBox* box = toRenderBox(child->renderer());
-            if (box->hasRenderOverflow() || box->hasSelfPaintingLayer())
+        } else if (child->renderer().isReplaced()) {
+            RenderBox& box = toRenderBox(child->renderer());
+            if (box.hasRenderOverflow() || box.hasSelfPaintingLayer())
                 child->clearKnownToHaveNoOverflow();
-        } else if (!child->renderer()->isBR() && (child->renderer()->style(isFirstLineStyle())->boxShadow() || child->boxModelObject()->hasSelfPaintingLayer()
-                   || (child->renderer()->isListMarker() && !toRenderListMarker(child->renderer())->isInside())
-                   || child->renderer()->style(isFirstLineStyle())->hasBorderImageOutsets()))
+        } else if (!child->renderer().isBR() && (child->renderer().style(isFirstLineStyle())->boxShadow() || child->boxModelObject()->hasSelfPaintingLayer()
+            || (child->renderer().isListMarker() && !toRenderListMarker(child->renderer()).isInside())
+            || child->renderer().style(isFirstLineStyle())->hasBorderImageOutsets())) {
+
             child->clearKnownToHaveNoOverflow();
+        }
 
         if (knownToHaveNoOverflow() && child->isInlineFlowBox() && !toInlineFlowBox(child)->knownToHaveNoOverflow())
             clearKnownToHaveNoOverflow();
@@ -182,7 +184,7 @@
     if (!isDirty())
         dirtyLineBoxes();
 
-    root()->childRemoved(child);
+    root().childRemoved(child);
 
     if (child == m_firstChild)
         m_firstChild = child->nextOnLine();
@@ -222,7 +224,7 @@
 
 void InlineFlowBox::removeLineBoxFromRenderObject()
 {
-    toRenderInline(renderer())->lineBoxes()->removeLineBox(this);
+    rendererLineBoxes()->removeLineBox(this);
 }
 
 void InlineFlowBox::extractLine()
@@ -235,7 +237,7 @@
 
 void InlineFlowBox::extractLineBoxFromRenderObject()
 {
-    toRenderInline(renderer())->lineBoxes()->extractLineBox(this);
+    rendererLineBoxes()->extractLineBox(this);
 }
 
 void InlineFlowBox::attachLine()
@@ -248,7 +250,7 @@
 
 void InlineFlowBox::attachLineBoxToRenderObject()
 {
-    toRenderInline(renderer())->lineBoxes()->attachLineBox(this);
+    rendererLineBoxes()->attachLineBox(this);
 }
 
 void InlineFlowBox::adjustPosition(float dx, float dy)
@@ -262,7 +264,7 @@
 
 RenderLineBoxList* InlineFlowBox::rendererLineBoxes() const
 {
-    return toRenderInline(renderer())->lineBoxes();
+    return toRenderInline(renderer()).lineBoxes();
 }
 
 static inline bool isLastChildForRenderer(RenderObject* ancestor, RenderObject* child)
@@ -308,13 +310,13 @@
 
     // The root inline box never has borders/margins/padding.
     if (parent()) {
-        bool ltr = renderer()->style()->isLeftToRightDirection();
+        bool ltr = renderer().style()->isLeftToRightDirection();
 
         // Check to see if all initial lines are unconstructed.  If so, then
         // we know the inline began on this line (unless we are a continuation).
         RenderLineBoxList* lineBoxList = rendererLineBoxes();
-        if (!lineBoxList->firstLineBox()->isConstructed() && !renderer()->isInlineElementContinuation()) {
-            if (renderer()->style()->boxDecorationBreak() == DCLONE)
+        if (!lineBoxList->firstLineBox()->isConstructed() && !renderer().isInlineElementContinuation()) {
+            if (renderer().style()->boxDecorationBreak() == DCLONE)
                 includeLeftEdge = includeRightEdge = true;
             else if (ltr && lineBoxList->firstLineBox() == this)
                 includeLeftEdge = true;
@@ -323,23 +325,23 @@
         }
 
         if (!lineBoxList->lastLineBox()->isConstructed()) {
-            RenderInline* inlineFlow = toRenderInline(renderer());
-            bool isLastObjectOnLine = !isAnsectorAndWithinBlock(renderer(), logicallyLastRunRenderer) || (isLastChildForRenderer(renderer(), logicallyLastRunRenderer) && !isLogicallyLastRunWrapped);
+            RenderInline& inlineFlow = toRenderInline(renderer());
+            bool isLastObjectOnLine = !isAnsectorAndWithinBlock(&renderer(), logicallyLastRunRenderer) || (isLastChildForRenderer(&renderer(), logicallyLastRunRenderer) && !isLogicallyLastRunWrapped);
 
             // We include the border under these conditions:
             // (1) The next line was not created, or it is constructed. We check the previous line for rtl.
             // (2) The logicallyLastRun is not a descendant of this renderer.
             // (3) The logicallyLastRun is a descendant of this renderer, but it is the last child of this renderer and it does not wrap to the next line.
             // (4) The decoration break is set to clone therefore there will be borders on every sides.
-            if (renderer()->style()->boxDecorationBreak() == DCLONE)
+            if (renderer().style()->boxDecorationBreak() == DCLONE)
                 includeLeftEdge = includeRightEdge = true;
             else if (ltr) {
                 if (!nextLineBox()
-                    && ((lastLine || isLastObjectOnLine) && !inlineFlow->continuation()))
+                    && ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation()))
                     includeRightEdge = true;
             } else {
                 if ((!prevLineBox() || prevLineBox()->isConstructed())
-                    && ((lastLine || isLastObjectOnLine) && !inlineFlow->continuation()))
+                    && ((lastLine || isLastObjectOnLine) && !inlineFlow.continuation()))
                     includeLeftEdge = true;
             }
         }
@@ -377,13 +379,13 @@
 float InlineFlowBox::placeBoxRangeInInlineDirection(InlineBox* firstChild, InlineBox* lastChild, float& logicalLeft, float& minLogicalLeft, float& maxLogicalRight, bool& needsWordSpacing, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
 {
     for (InlineBox* curr = firstChild; curr && curr != lastChild; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isText()) {
+        if (curr->renderer().isText()) {
             InlineTextBox* text = toInlineTextBox(curr);
-            RenderText* rt = toRenderText(text->renderer());
-            if (rt->textLength()) {
-                if (needsWordSpacing && isSpaceOrNewline(rt->characterAt(text->start())))
-                    logicalLeft += rt->style(isFirstLineStyle())->font().fontDescription().wordSpacing();
-                needsWordSpacing = !isSpaceOrNewline(rt->characterAt(text->end()));
+            RenderText& rt = toRenderText(text->renderer());
+            if (rt.textLength()) {
+                if (needsWordSpacing && isSpaceOrNewline(rt.characterAt(text->start())))
+                    logicalLeft += rt.style(isFirstLineStyle())->font().fontDescription().wordSpacing();
+                needsWordSpacing = !isSpaceOrNewline(rt.characterAt(text->end()));
             }
             text->setLogicalLeft(logicalLeft);
             if (knownToHaveNoOverflow())
@@ -392,17 +394,18 @@
             if (knownToHaveNoOverflow())
                 maxLogicalRight = max(logicalLeft, maxLogicalRight);
         } else {
-            if (curr->renderer()->isOutOfFlowPositioned()) {
-                if (curr->renderer()->parent()->style()->isLeftToRightDirection())
+            if (curr->renderer().isOutOfFlowPositioned()) {
+                if (curr->renderer().parent()->style()->isLeftToRightDirection()) {
                     curr->setLogicalLeft(logicalLeft);
-                else
+                } else {
                     // Our offset that we cache needs to be from the edge of the right border box and
                     // not the left border box.  We have to subtract |x| from the width of the block
                     // (which can be obtained from the root line box).
-                    curr->setLogicalLeft(root()->block()->logicalWidth() - logicalLeft);
+                    curr->setLogicalLeft(root().block().logicalWidth() - logicalLeft);
+                }
                 continue; // The positioned object has no effect on the width.
             }
-            if (curr->renderer()->isRenderInline()) {
+            if (curr->renderer().isRenderInline()) {
                 InlineFlowBox* flow = toInlineFlowBox(curr);
                 logicalLeft += flow->marginLogicalLeft();
                 if (knownToHaveNoOverflow())
@@ -411,7 +414,7 @@
                 if (knownToHaveNoOverflow())
                     maxLogicalRight = max(logicalLeft, maxLogicalRight);
                 logicalLeft += flow->marginLogicalRight();
-            } else if (!curr->renderer()->isListMarker() || toRenderListMarker(curr->renderer())->isInside()) {
+            } else if (!curr->renderer().isListMarker() || toRenderListMarker(curr->renderer()).isInside()) {
                 // The box can have a different writing-mode than the overall line, so this is a bit complicated.
                 // Just get all the physical margin and overflow values by hand based off |isVertical|.
                 LayoutUnit logicalLeftMargin = isHorizontal() ? curr->boxModelObject()->marginLeft() : curr->boxModelObject()->marginTop();
@@ -438,19 +441,19 @@
     if (isHorizontal())
         return false;
 
-    if (renderer()->style(isFirstLineStyle())->fontDescription().nonCJKGlyphOrientation() == NonCJKGlyphOrientationUpright
-        || renderer()->style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
+    if (renderer().style(isFirstLineStyle())->fontDescription().nonCJKGlyphOrientation() == NonCJKGlyphOrientationUpright
+        || renderer().style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
         return true;
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
 
         if (curr->isInlineFlowBox()) {
             if (toInlineFlowBox(curr)->requiresIdeographicBaseline(textBoxDataMap))
                 return true;
         } else {
-            if (curr->renderer()->style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
+            if (curr->renderer().style(isFirstLineStyle())->font().primaryFont()->hasVerticalGlyphs())
                 return true;
 
             const Vector<const SimpleFontData*>* usedFonts = 0;
@@ -476,7 +479,7 @@
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
         // The computed lineheight needs to be extended for the
         // positioned elements
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
         if (curr->verticalAlign() == TOP || curr->verticalAlign() == BOTTOM) {
             int lineHeight = curr->lineHeight();
@@ -543,7 +546,7 @@
         return;
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
 
         InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox(curr) : 0;
@@ -554,7 +557,7 @@
         // The verticalPositionForBox function returns the distance between the child box's baseline
         // and the root box's baseline.  The value is negative if the child box's baseline is above the
         // root box's baseline, and it is positive if the child box's baseline is below the root box's baseline.
-        curr->setLogicalTop(rootBox->verticalPositionForBox(curr, verticalPositionCache));
+        curr->setLogicalTop(rootBox->verticalPositionForBox(curr, verticalPositionCache).toFloat());
 
         int ascent = 0;
         int descent = 0;
@@ -600,7 +603,7 @@
 {
     bool isRootBox = isRootInlineBox();
     if (isRootBox) {
-        const FontMetrics& fontMetrics = renderer()->style(isFirstLineStyle())->fontMetrics();
+        const FontMetrics& fontMetrics = renderer().style(isFirstLineStyle())->fontMetrics();
         // RootInlineBoxes are always placed on at pixel boundaries in their logical y direction. Not doing
         // so results in incorrect rendering of text decorations, most notably underlines.
         setLogicalTop(roundToInt(top + maxAscent - fontMetrics.ascent(baselineType)));
@@ -614,20 +617,20 @@
     }
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
 
         if (descendantsHaveSameLineHeightAndBaseline()) {
-            curr->adjustBlockDirectionPosition(adjustmentForChildrenWithSameLineHeightAndBaseline);
+            curr->adjustBlockDirectionPosition(adjustmentForChildrenWithSameLineHeightAndBaseline.toFloat());
             continue;
         }
 
         InlineFlowBox* inlineFlowBox = curr->isInlineFlowBox() ? toInlineFlowBox(curr) : 0;
         bool childAffectsTopBottomPos = true;
         if (curr->verticalAlign() == TOP)
-            curr->setLogicalTop(top);
+            curr->setLogicalTop(top.toFloat());
         else if (curr->verticalAlign() == BOTTOM)
-            curr->setLogicalTop(top + maxHeight - curr->lineHeight());
+            curr->setLogicalTop((top + maxHeight - curr->lineHeight()).toFloat());
         else {
             if (!strictMode && inlineFlowBox && !inlineFlowBox->hasTextChildren() && !curr->boxModelObject()->hasInlineDirectionBordersOrPadding()
                 && !(inlineFlowBox->descendantsHaveSameLineHeightAndBaseline() && inlineFlowBox->hasTextDescendants()))
@@ -642,48 +645,48 @@
         LayoutUnit boxHeightIncludingMargins = boxHeight;
 
         if (curr->isText() || curr->isInlineFlowBox()) {
-            const FontMetrics& fontMetrics = curr->renderer()->style(isFirstLineStyle())->fontMetrics();
+            const FontMetrics& fontMetrics = curr->renderer().style(isFirstLineStyle())->fontMetrics();
             newLogicalTop += curr->baselinePosition(baselineType) - fontMetrics.ascent(baselineType);
             if (curr->isInlineFlowBox()) {
-                RenderBoxModelObject* boxObject = toRenderBoxModelObject(curr->renderer());
-                newLogicalTop -= boxObject->style(isFirstLineStyle())->isHorizontalWritingMode() ? boxObject->borderTop() + boxObject->paddingTop() :
-                                 boxObject->borderRight() + boxObject->paddingRight();
+                RenderBoxModelObject& boxObject = toRenderBoxModelObject(curr->renderer());
+                newLogicalTop -= boxObject.style(isFirstLineStyle())->isHorizontalWritingMode() ? boxObject.borderTop() + boxObject.paddingTop() :
+                    boxObject.borderRight() + boxObject.paddingRight();
             }
             newLogicalTopIncludingMargins = newLogicalTop;
-        } else if (!curr->renderer()->isBR()) {
-            RenderBox* box = toRenderBox(curr->renderer());
+        } else if (!curr->renderer().isBR()) {
+            RenderBox& box = toRenderBox(curr->renderer());
             newLogicalTopIncludingMargins = newLogicalTop;
-            LayoutUnit overSideMargin = curr->isHorizontal() ? box->marginTop() : box->marginRight();
-            LayoutUnit underSideMargin = curr->isHorizontal() ? box->marginBottom() : box->marginLeft();
+            LayoutUnit overSideMargin = curr->isHorizontal() ? box.marginTop() : box.marginRight();
+            LayoutUnit underSideMargin = curr->isHorizontal() ? box.marginBottom() : box.marginLeft();
             newLogicalTop += overSideMargin;
             boxHeightIncludingMargins += overSideMargin + underSideMargin;
         }
 
-        curr->setLogicalTop(newLogicalTop);
+        curr->setLogicalTop(newLogicalTop.toFloat());
 
         if (childAffectsTopBottomPos) {
-            if (curr->renderer()->isRubyRun()) {
+            if (curr->renderer().isRubyRun()) {
                 // Treat the leading on the first and last lines of ruby runs as not being part of the overall lineTop/lineBottom.
                 // Really this is a workaround hack for the fact that ruby should have been done as line layout and not done using
                 // inline-block.
-                if (renderer()->style()->isFlippedLinesWritingMode() == (curr->renderer()->style()->rubyPosition() == RubyPositionAfter))
+                if (renderer().style()->isFlippedLinesWritingMode() == (curr->renderer().style()->rubyPosition() == RubyPositionAfter))
                     hasAnnotationsBefore = true;
                 else
                     hasAnnotationsAfter = true;
 
-                RenderRubyRun* rubyRun = toRenderRubyRun(curr->renderer());
-                if (RenderRubyBase* rubyBase = rubyRun->rubyBase()) {
+                RenderRubyRun& rubyRun = toRenderRubyRun(curr->renderer());
+                if (RenderRubyBase* rubyBase = rubyRun.rubyBase()) {
                     LayoutUnit bottomRubyBaseLeading = (curr->logicalHeight() - rubyBase->logicalBottom()) + rubyBase->logicalHeight() - (rubyBase->lastRootBox() ? rubyBase->lastRootBox()->lineBottom() : LayoutUnit());
                     LayoutUnit topRubyBaseLeading = rubyBase->logicalTop() + (rubyBase->firstRootBox() ? rubyBase->firstRootBox()->lineTop() : LayoutUnit());
-                    newLogicalTop += !renderer()->style()->isFlippedLinesWritingMode() ? topRubyBaseLeading : bottomRubyBaseLeading;
+                    newLogicalTop += !renderer().style()->isFlippedLinesWritingMode() ? topRubyBaseLeading : bottomRubyBaseLeading;
                     boxHeight -= (topRubyBaseLeading + bottomRubyBaseLeading);
                 }
             }
             if (curr->isInlineTextBox()) {
                 TextEmphasisPosition emphasisMarkPosition;
-                if (toInlineTextBox(curr)->getEmphasisMarkPosition(curr->renderer()->style(isFirstLineStyle()), emphasisMarkPosition)) {
+                if (toInlineTextBox(curr)->getEmphasisMarkPosition(curr->renderer().style(isFirstLineStyle()), emphasisMarkPosition)) {
                     bool emphasisMarkIsOver = emphasisMarkPosition == TextEmphasisPositionOver;
-                    if (emphasisMarkIsOver != curr->renderer()->style(isFirstLineStyle())->isFlippedLinesWritingMode())
+                    if (emphasisMarkIsOver != curr->renderer().style(isFirstLineStyle())->isFlippedLinesWritingMode())
                         hasAnnotationsBefore = true;
                     else
                         hasAnnotationsAfter = true;
@@ -723,7 +726,7 @@
             lineBottomIncludingMargins = max(lineBottom, lineBottomIncludingMargins);
         }
 
-        if (renderer()->style()->isFlippedLinesWritingMode())
+        if (renderer().style()->isFlippedLinesWritingMode())
             flipLinesInBlockDirection(lineTopIncludingMargins, lineBottomIncludingMargins);
     }
 }
@@ -731,7 +734,7 @@
 void InlineFlowBox::computeMaxLogicalTop(float& maxLogicalTop) const
 {
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
 
         if (descendantsHaveSameLineHeightAndBaseline())
@@ -751,7 +754,7 @@
     setLogicalTop(lineBottom - (logicalTop() - lineTop) - logicalHeight());
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders aren't affected here.
 
         if (curr->isInlineFlowBox())
@@ -767,7 +770,7 @@
     if (!parent())
         return;
 
-    RenderStyle* style = renderer()->style(isFirstLineStyle());
+    RenderStyle* style = renderer().style(isFirstLineStyle());
     if (!style->boxShadow())
         return;
 
@@ -800,7 +803,7 @@
     if (!parent())
         return;
 
-    RenderStyle* style = renderer()->style(isFirstLineStyle());
+    RenderStyle* style = renderer().style(isFirstLineStyle());
     if (!style->hasBorderImageOutsets())
         return;
 
@@ -834,7 +837,7 @@
     if (textBox->knownToHaveNoOverflow())
         return;
 
-    RenderStyle* style = textBox->renderer()->style(isFirstLineStyle());
+    RenderStyle* style = textBox->renderer().style(isFirstLineStyle());
 
     GlyphOverflowAndFallbackFontsMap::iterator it = textBoxDataMap.find(textBox);
     GlyphOverflow* glyphOverflow = it == textBoxDataMap.end() ? 0 : &it->value.second;
@@ -891,13 +894,13 @@
 
 inline void InlineFlowBox::addReplacedChildOverflow(const InlineBox* inlineBox, LayoutRect& logicalLayoutOverflow, LayoutRect& logicalVisualOverflow)
 {
-    RenderBox* box = toRenderBox(inlineBox->renderer());
+    RenderBox& box = toRenderBox(inlineBox->renderer());
 
     // Visual overflow only propagates if the box doesn't have a self-painting layer.  This rectangle does not include
     // transforms or relative positioning (since those objects always have self-painting layers), but it does need to be adjusted
     // for writing-mode differences.
-    if (!box->hasSelfPaintingLayer()) {
-        LayoutRect childLogicalVisualOverflow = box->logicalVisualOverflowRectForPropagation(renderer()->style());
+    if (!box.hasSelfPaintingLayer()) {
+        LayoutRect childLogicalVisualOverflow = box.logicalVisualOverflowRectForPropagation(renderer().style());
         childLogicalVisualOverflow.move(inlineBox->logicalLeft(), inlineBox->logicalTop());
         logicalVisualOverflow.unite(childLogicalVisualOverflow);
     }
@@ -905,7 +908,7 @@
     // Layout overflow internal to the child box only propagates if the child box doesn't have overflow clip set.
     // Otherwise the child border box propagates as layout overflow.  This rectangle must include transforms and relative positioning
     // and be adjusted for writing-mode differences.
-    LayoutRect childLogicalLayoutOverflow = box->logicalLayoutOverflowRectForPropagation(renderer()->style());
+    LayoutRect childLogicalLayoutOverflow = box.logicalLayoutOverflowRectForPropagation(renderer().style());
     childLogicalLayoutOverflow.move(inlineBox->logicalLeft(), inlineBox->logicalTop());
     logicalLayoutOverflow.unite(childLogicalLayoutOverflow);
 }
@@ -913,8 +916,13 @@
 void InlineFlowBox::computeOverflow(LayoutUnit lineTop, LayoutUnit lineBottom, GlyphOverflowAndFallbackFontsMap& textBoxDataMap)
 {
     // If we know we have no overflow, we can just bail.
-    if (knownToHaveNoOverflow())
+    if (knownToHaveNoOverflow()) {
+        ASSERT(!m_overflow);
         return;
+    }
+
+    if (m_overflow)
+        m_overflow.clear();
 
     // Visual overflow just includes overflow for stuff we need to repaint ourselves.  Self-painting layers are ignored.
     // Layout overflow is used to determine scrolling extent, so it still includes child layers and also factors in
@@ -926,18 +934,18 @@
     addBorderOutsetVisualOverflow(logicalVisualOverflow);
 
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
 
-        if (curr->renderer()->isText()) {
+        if (curr->renderer().isText()) {
             InlineTextBox* text = toInlineTextBox(curr);
-            RenderText* rt = toRenderText(text->renderer());
-            if (rt->isBR())
+            RenderText& rt = toRenderText(text->renderer());
+            if (rt.isBR())
                 continue;
             LayoutRect textBoxOverflow(enclosingLayoutRect(text->logicalFrameRect()));
             addTextBoxVisualOverflow(text, textBoxDataMap, textBoxOverflow);
             logicalVisualOverflow.unite(textBoxOverflow);
-        } else  if (curr->renderer()->isRenderInline()) {
+        } else if (curr->renderer().isRenderInline()) {
             InlineFlowBox* flow = toInlineFlowBox(curr);
             flow->computeOverflow(lineTop, lineBottom, textBoxDataMap);
             if (!flow->boxModelObject()->hasSelfPaintingLayer())
@@ -945,16 +953,16 @@
             LayoutRect childLayoutOverflow = flow->logicalLayoutOverflowRect(lineTop, lineBottom);
             childLayoutOverflow.move(flow->boxModelObject()->relativePositionLogicalOffset());
             logicalLayoutOverflow.unite(childLayoutOverflow);
-        } else
+        } else {
             addReplacedChildOverflow(curr, logicalLayoutOverflow, logicalVisualOverflow);
+        }
     }
 
     setOverflowFromLogicalRects(logicalLayoutOverflow, logicalVisualOverflow, lineTop, lineBottom);
 }
 
-void InlineFlowBox::setLayoutOverflow(const LayoutRect& rect, LayoutUnit lineTop, LayoutUnit lineBottom)
+void InlineFlowBox::setLayoutOverflow(const LayoutRect& rect, const LayoutRect& frameBox)
 {
-    LayoutRect frameBox = enclosingLayoutRect(frameRectIncludingLineHeight(lineTop, lineBottom));
     if (frameBox.contains(rect) || rect.isEmpty())
         return;
 
@@ -964,9 +972,8 @@
     m_overflow->setLayoutOverflow(rect);
 }
 
-void InlineFlowBox::setVisualOverflow(const LayoutRect& rect, LayoutUnit lineTop, LayoutUnit lineBottom)
+void InlineFlowBox::setVisualOverflow(const LayoutRect& rect, const LayoutRect& frameBox)
 {
-    LayoutRect frameBox = enclosingLayoutRect(frameRectIncludingLineHeight(lineTop, lineBottom));
     if (frameBox.contains(rect) || rect.isEmpty())
         return;
 
@@ -978,11 +985,13 @@
 
 void InlineFlowBox::setOverflowFromLogicalRects(const LayoutRect& logicalLayoutOverflow, const LayoutRect& logicalVisualOverflow, LayoutUnit lineTop, LayoutUnit lineBottom)
 {
+    LayoutRect frameBox = enclosingLayoutRect(frameRectIncludingLineHeight(lineTop, lineBottom));
+
     LayoutRect layoutOverflow(isHorizontal() ? logicalLayoutOverflow : logicalLayoutOverflow.transposedRect());
-    setLayoutOverflow(layoutOverflow, lineTop, lineBottom);
+    setLayoutOverflow(layoutOverflow, frameBox);
 
     LayoutRect visualOverflow(isHorizontal() ? logicalVisualOverflow : logicalVisualOverflow.transposedRect());
-    setVisualOverflow(visualOverflow, lineTop, lineBottom);
+    setVisualOverflow(visualOverflow, frameBox);
 }
 
 bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
@@ -997,11 +1006,11 @@
     // We need to account for culled inline parents of the hit-tested nodes, so that they may also get included in area-based hit-tests.
     RenderObject* culledParent = 0;
     for (InlineBox* curr = lastChild(); curr; curr = curr->prevOnLine()) {
-        if (curr->renderer()->isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) {
+        if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer()) {
             RenderObject* newParent = 0;
             // Culled parents are only relevant for area-based hit-tests, so ignore it in point-based ones.
             if (locationInContainer.isRectBasedTest()) {
-                newParent = curr->renderer()->parent();
+                newParent = curr->renderer().parent();
                 if (newParent == renderer())
                     newParent = 0;
             }
@@ -1018,7 +1027,7 @@
                 culledParent = newParent;
             }
             if (curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom)) {
-                renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
+                renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
                 return true;
             }
         }
@@ -1038,13 +1047,13 @@
     LayoutUnit height = frameRect.height();
 
     // Constrain our hit testing to the line top and bottom if necessary.
-    bool noQuirksMode = renderer()->document().inNoQuirksMode();
+    bool noQuirksMode = renderer().document().inNoQuirksMode();
     if (!noQuirksMode && !hasTextChildren() && !(descendantsHaveSameLineHeightAndBaseline() && hasTextDescendants())) {
-        RootInlineBox* rootBox = root();
+        RootInlineBox& rootBox = root();
         LayoutUnit& top = isHorizontal() ? minY : minX;
         LayoutUnit& logicalHeight = isHorizontal() ? height : width;
-        LayoutUnit bottom = min(rootBox->lineBottom(), top + logicalHeight);
-        top = max(rootBox->lineTop(), top);
+        LayoutUnit bottom = min(rootBox.lineBottom(), top + logicalHeight);
+        top = max(rootBox.lineTop(), top);
         logicalHeight = bottom - top;
     }
 
@@ -1054,8 +1063,8 @@
     rect.moveBy(accumulatedOffset);
 
     if (visibleToHitTestRequest(request) && locationInContainer.intersects(rect)) {
-        renderer()->updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset))); // Don't add in m_x or m_y here, we want coords in the containing block's space.
-        if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, rect))
+        renderer().updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset))); // Don't add in m_x or m_y here, we want coords in the containing block's space.
+        if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, rect))
             return true;
     }
 
@@ -1065,7 +1074,7 @@
 void InlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
 {
     LayoutRect overflowRect(visualOverflowRect(lineTop, lineBottom));
-    overflowRect.inflate(renderer()->maximalOutlineSize(paintInfo.phase));
+    overflowRect.inflate(renderer().maximalOutlineSize(paintInfo.phase));
     flipForWritingMode(overflowRect);
     overflowRect.moveBy(paintOffset);
 
@@ -1076,16 +1085,16 @@
         if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) {
             // Add ourselves to the paint info struct's list of inlines that need to paint their
             // outlines.
-            if (renderer()->style()->visibility() == VISIBLE && renderer()->hasOutline() && !isRootInlineBox()) {
-                RenderInline* inlineFlow = toRenderInline(renderer());
+            if (renderer().style()->visibility() == VISIBLE && renderer().hasOutline() && !isRootInlineBox()) {
+                RenderInline& inlineFlow = toRenderInline(renderer());
 
                 RenderBlock* cb = 0;
-                bool containingBlockPaintsContinuationOutline = inlineFlow->continuation() || inlineFlow->isInlineElementContinuation();
+                bool containingBlockPaintsContinuationOutline = inlineFlow.continuation() || inlineFlow.isInlineElementContinuation();
                 if (containingBlockPaintsContinuationOutline) {
                     // FIXME: See https://bugs.webkit.org/show_bug.cgi?id=54690. We currently don't reconnect inline continuations
                     // after a child removal. As a result, those merged inlines do not get seperated and hence not get enclosed by
                     // anonymous blocks. In this case, it is better to bail out and paint it ourself.
-                    RenderBlock* enclosingAnonymousBlock = renderer()->containingBlock();
+                    RenderBlock* enclosingAnonymousBlock = renderer().containingBlock();
                     if (!enclosingAnonymousBlock->isAnonymousBlock())
                         containingBlockPaintsContinuationOutline = false;
                     else {
@@ -1102,9 +1111,9 @@
                 if (containingBlockPaintsContinuationOutline) {
                     // Add ourselves to the containing block of the entire continuation so that it can
                     // paint us atomically.
-                    cb->addContinuationWithOutline(toRenderInline(renderer()->node()->renderer()));
-                } else if (!inlineFlow->isInlineElementContinuation()) {
-                    paintInfo.outlineObjects()->add(inlineFlow);
+                    cb->addContinuationWithOutline(toRenderInline(renderer().node()->renderer()));
+                } else if (!inlineFlow.isInlineElementContinuation()) {
+                    paintInfo.outlineObjects()->add(&inlineFlow);
                 }
             }
         } else if (paintInfo.phase == PaintPhaseMask) {
@@ -1122,12 +1131,12 @@
     PaintPhase paintPhase = paintInfo.phase == PaintPhaseChildOutlines ? PaintPhaseOutline : paintInfo.phase;
     PaintInfo childInfo(paintInfo);
     childInfo.phase = paintPhase;
-    childInfo.updatePaintingRootForChildren(renderer());
+    childInfo.updatePaintingRootForChildren(&renderer());
 
     // Paint our children.
     if (paintPhase != PaintPhaseSelfOutline) {
         for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-            if (curr->renderer()->isText() || !curr->boxModelObject()->hasSelfPaintingLayer())
+            if (curr->renderer().isText() || !curr->boxModelObject()->hasSelfPaintingLayer())
                 curr->paint(childInfo, paintOffset, lineTop, lineBottom);
         }
     }
@@ -1146,17 +1155,17 @@
     // The checks here match how paintFillLayer() decides whether to clip (if it does, the shadow
     // would be clipped out, so it has to be drawn separately).
     StyleImage* image = lastBackgroundLayer.image();
-    bool hasFillImage = image && image->canRender(renderer(), renderer()->style()->effectiveZoom());
-    return (!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent();
+    bool hasFillImage = image && image->canRender(&renderer(), renderer().style()->effectiveZoom());
+    return (!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent();
 }
 
 void InlineFlowBox::paintFillLayer(const PaintInfo& paintInfo, const Color& c, const FillLayer* fillLayer, const LayoutRect& rect, CompositeOperator op)
 {
     StyleImage* img = fillLayer->image();
-    bool hasFillImage = img && img->canRender(renderer(), renderer()->style()->effectiveZoom());
-    if ((!hasFillImage && !renderer()->style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent())
+    bool hasFillImage = img && img->canRender(&renderer(), renderer().style()->effectiveZoom());
+    if ((!hasFillImage && !renderer().style()->hasBorderRadius()) || (!prevLineBox() && !nextLineBox()) || !parent()) {
         boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect, BackgroundBleedNone, this, rect.size(), op);
-    else if (renderer()->style()->boxDecorationBreak() == DCLONE) {
+    } else if (renderer().style()->boxDecorationBreak() == DCLONE) {
         GraphicsContextStateSaver stateSaver(*paintInfo.context);
         paintInfo.context->clip(LayoutRect(rect.x(), rect.y(), width(), height()));
         boxModelObject()->paintFillLayerExtended(paintInfo, c, fillLayer, rect, BackgroundBleedNone, this, rect.size(), op);
@@ -1169,7 +1178,7 @@
         // the previous line left off.
         LayoutUnit logicalOffsetOnLine = 0;
         LayoutUnit totalLogicalWidth;
-        if (renderer()->style()->direction() == LTR) {
+        if (renderer().style()->direction() == LTR) {
             for (InlineFlowBox* curr = prevLineBox(); curr; curr = curr->prevLineBox())
                 logicalOffsetOnLine += curr->logicalWidth();
             totalLogicalWidth = logicalOffsetOnLine;
@@ -1206,13 +1215,13 @@
 
 void InlineFlowBox::constrainToLineTopAndBottomIfNeeded(LayoutRect& rect) const
 {
-    bool noQuirksMode = renderer()->document().inNoQuirksMode();
+    bool noQuirksMode = renderer().document().inNoQuirksMode();
     if (!noQuirksMode && !hasTextChildren() && !(descendantsHaveSameLineHeightAndBaseline() && hasTextDescendants())) {
-        const RootInlineBox* rootBox = root();
+        const RootInlineBox& rootBox = root();
         LayoutUnit logicalTop = isHorizontal() ? rect.y() : rect.x();
         LayoutUnit logicalHeight = isHorizontal() ? rect.height() : rect.width();
-        LayoutUnit bottom = min(rootBox->lineBottom(), logicalTop + logicalHeight);
-        logicalTop = max(rootBox->lineTop(), logicalTop);
+        LayoutUnit bottom = min(rootBox.lineBottom(), logicalTop + logicalHeight);
+        logicalTop = max(rootBox.lineTop(), logicalTop);
         logicalHeight = bottom - logicalTop;
         if (isHorizontal()) {
             rect.setY(logicalTop);
@@ -1227,7 +1236,7 @@
 static LayoutRect clipRectForNinePieceImageStrip(InlineFlowBox* box, const NinePieceImage& image, const LayoutRect& paintRect)
 {
     LayoutRect clipRect(paintRect);
-    RenderStyle* style = box->renderer()->style();
+    RenderStyle* style = box->renderer().style();
     LayoutBoxExtent outsets = style->imageOutsets(image);
     if (box->isHorizontal()) {
         clipRect.setY(paintRect.y() - outsets.top());
@@ -1253,7 +1262,7 @@
 
 void InlineFlowBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
-    if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
+    if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
         return;
 
     // Pixel snap background/border painting.
@@ -1270,30 +1279,30 @@
 
     // You can use p::first-line to specify a background. If so, the root line boxes for
     // a line may actually have to paint a background.
-    RenderStyle* styleToUse = renderer()->style(isFirstLineStyle());
-    if ((!parent() && isFirstLineStyle() && styleToUse != renderer()->style()) || (parent() && renderer()->hasBoxDecorations())) {
+    RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
+    if ((!parent() && isFirstLineStyle() && styleToUse != renderer().style()) || (parent() && renderer().hasBoxDecorations())) {
         LayoutRect paintRect = LayoutRect(adjustedPaintoffset, frameRect.size());
         // Shadow comes first and is behind the background and border.
         if (!boxModelObject()->boxShadowShouldBeAppliedToBackground(BackgroundBleedNone, this))
             paintBoxShadow(paintInfo, styleToUse, Normal, paintRect);
 
-        Color c = renderer()->resolveColor(styleToUse, CSSPropertyBackgroundColor);
+        Color c = renderer().resolveColor(styleToUse, CSSPropertyBackgroundColor);
         paintFillLayers(paintInfo, c, styleToUse->backgroundLayers(), paintRect);
         paintBoxShadow(paintInfo, styleToUse, Inset, paintRect);
 
         // :first-line cannot be used to put borders on a line. Always paint borders with our
         // non-first-line style.
-        if (parent() && renderer()->style()->hasBorder()) {
-            const NinePieceImage& borderImage = renderer()->style()->borderImage();
+        if (parent() && renderer().style()->hasBorder()) {
+            const NinePieceImage& borderImage = renderer().style()->borderImage();
             StyleImage* borderImageSource = borderImage.image();
-            bool hasBorderImage = borderImageSource && borderImageSource->canRender(renderer(), styleToUse->effectiveZoom());
+            bool hasBorderImage = borderImageSource && borderImageSource->canRender(&renderer(), styleToUse->effectiveZoom());
             if (hasBorderImage && !borderImageSource->isLoaded())
                 return; // Don't paint anything while we wait for the image to load.
 
             // The simple case is where we either have no border image or we are the only box for this object.  In those
             // cases only a single call to draw is required.
             if (!hasBorderImage || (!prevLineBox() && !nextLineBox()))
-                boxModelObject()->paintBorder(paintInfo, paintRect, renderer()->style(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
+                boxModelObject()->paintBorder(paintInfo, paintRect, renderer().style(isFirstLineStyle()), BackgroundBleedNone, includeLogicalLeftEdge(), includeLogicalRightEdge());
             else {
                 // We have a border image that spans multiple lines.
                 // We need to adjust tx and ty by the width of all previous lines.
@@ -1317,7 +1326,7 @@
                 LayoutRect clipRect = clipRectForNinePieceImageStrip(this, borderImage, paintRect);
                 GraphicsContextStateSaver stateSaver(*context);
                 context->clip(clipRect);
-                boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer()->style(isFirstLineStyle()));
+                boxModelObject()->paintBorder(paintInfo, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(isFirstLineStyle()));
             }
         }
     }
@@ -1325,7 +1334,7 @@
 
 void InlineFlowBox::paintMask(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
-    if (!paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
+    if (!paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask)
         return;
 
     // Pixel snap mask painting.
@@ -1338,16 +1347,16 @@
     flipForWritingMode(localRect);
     LayoutPoint adjustedPaintOffset = paintOffset + localRect.location();
 
-    const NinePieceImage& maskNinePieceImage = renderer()->style()->maskBoxImage();
-    StyleImage* maskBoxImage = renderer()->style()->maskBoxImage().image();
+    const NinePieceImage& maskNinePieceImage = renderer().style()->maskBoxImage();
+    StyleImage* maskBoxImage = renderer().style()->maskBoxImage().image();
 
     // Figure out if we need to push a transparency layer to render our mask.
     bool pushTransparencyLayer = false;
-    bool compositedMask = renderer()->hasLayer() && boxModelObject()->layer()->hasCompositedMask();
-    bool flattenCompositingLayers = renderer()->view()->frameView() && renderer()->view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
+    bool compositedMask = renderer().hasLayer() && boxModelObject()->layer()->hasCompositedMask();
+    bool flattenCompositingLayers = renderer().view()->frameView() && renderer().view()->frameView()->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
     CompositeOperator compositeOp = CompositeSourceOver;
     if (!compositedMask || flattenCompositingLayers) {
-        if ((maskBoxImage && renderer()->style()->maskLayers()->hasImage()) || renderer()->style()->maskLayers()->next())
+        if ((maskBoxImage && renderer().style()->maskLayers()->hasImage()) || renderer().style()->maskLayers()->next())
             pushTransparencyLayer = true;
 
         compositeOp = CompositeDestinationIn;
@@ -1359,9 +1368,9 @@
     }
 
     LayoutRect paintRect = LayoutRect(adjustedPaintOffset, frameRect.size());
-    paintFillLayers(paintInfo, Color::transparent, renderer()->style()->maskLayers(), paintRect, compositeOp);
+    paintFillLayers(paintInfo, Color::transparent, renderer().style()->maskLayers(), paintRect, compositeOp);
 
-    bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(renderer(), renderer()->style()->effectiveZoom());
+    bool hasBoxImage = maskBoxImage && maskBoxImage->canRender(&renderer(), renderer().style()->effectiveZoom());
     if (!hasBoxImage || !maskBoxImage->isLoaded()) {
         if (pushTransparencyLayer)
             paintInfo.context->endLayer();
@@ -1371,7 +1380,7 @@
     // The simple case is where we are the only box for this object.  In those
     // cases only a single call to draw is required.
     if (!prevLineBox() && !nextLineBox()) {
-        boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(adjustedPaintOffset, frameRect.size()), renderer()->style(), maskNinePieceImage, compositeOp);
+        boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(adjustedPaintOffset, frameRect.size()), renderer().style(), maskNinePieceImage, compositeOp);
     } else {
         // We have a mask image that spans multiple lines.
         // We need to adjust _tx and _ty by the width of all previous lines.
@@ -1389,7 +1398,7 @@
         LayoutRect clipRect = clipRectForNinePieceImageStrip(this, maskNinePieceImage, paintRect);
         GraphicsContextStateSaver stateSaver(*paintInfo.context);
         paintInfo.context->clip(clipRect);
-        boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer()->style(), maskNinePieceImage, compositeOp);
+        boxModelObject()->paintNinePieceImage(paintInfo.context, LayoutRect(stripX, stripY, stripWidth, stripHeight), renderer().style(), maskNinePieceImage, compositeOp);
     }
 
     if (pushTransparencyLayer)
@@ -1466,19 +1475,19 @@
 {
     LayoutUnit result = 0;
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
 
         if (curr->isInlineFlowBox())
             result = max(result, toInlineFlowBox(curr)->computeOverAnnotationAdjustment(allowedPosition));
 
-        if (curr->renderer()->isReplaced() && curr->renderer()->isRubyRun() && curr->renderer()->style()->rubyPosition() == RubyPositionBefore) {
-            RenderRubyRun* rubyRun = toRenderRubyRun(curr->renderer());
-            RenderRubyText* rubyText = rubyRun->rubyText();
+        if (curr->renderer().isReplaced() && curr->renderer().isRubyRun() && curr->renderer().style()->rubyPosition() == RubyPositionBefore) {
+            RenderRubyRun& rubyRun = toRenderRubyRun(curr->renderer());
+            RenderRubyText* rubyText = rubyRun.rubyText();
             if (!rubyText)
                 continue;
 
-            if (!rubyRun->style()->isFlippedLinesWritingMode()) {
+            if (!rubyRun.style()->isFlippedLinesWritingMode()) {
                 LayoutUnit topOfFirstRubyTextLine = rubyText->logicalTop() + (rubyText->firstRootBox() ? rubyText->firstRootBox()->lineTop() : LayoutUnit());
                 if (topOfFirstRubyTextLine >= 0)
                     continue;
@@ -1494,7 +1503,7 @@
         }
 
         if (curr->isInlineTextBox()) {
-            RenderStyle* style = curr->renderer()->style(isFirstLineStyle());
+            RenderStyle* style = curr->renderer().style(isFirstLineStyle());
             TextEmphasisPosition emphasisMarkPosition;
             if (style->textEmphasisMark() != TextEmphasisMarkNone && toInlineTextBox(curr)->getEmphasisMarkPosition(style, emphasisMarkPosition) && emphasisMarkPosition == TextEmphasisPositionOver) {
                 if (!style->isFlippedLinesWritingMode()) {
@@ -1514,19 +1523,19 @@
 {
     LayoutUnit result = 0;
     for (InlineBox* curr = firstChild(); curr; curr = curr->nextOnLine()) {
-        if (curr->renderer()->isOutOfFlowPositioned())
+        if (curr->renderer().isOutOfFlowPositioned())
             continue; // Positioned placeholders don't affect calculations.
 
         if (curr->isInlineFlowBox())
             result = max(result, toInlineFlowBox(curr)->computeUnderAnnotationAdjustment(allowedPosition));
 
-        if (curr->renderer()->isReplaced() && curr->renderer()->isRubyRun() && curr->renderer()->style()->rubyPosition() == RubyPositionAfter) {
-            RenderRubyRun* rubyRun = toRenderRubyRun(curr->renderer());
-            RenderRubyText* rubyText = rubyRun->rubyText();
+        if (curr->renderer().isReplaced() && curr->renderer().isRubyRun() && curr->renderer().style()->rubyPosition() == RubyPositionAfter) {
+            RenderRubyRun& rubyRun = toRenderRubyRun(curr->renderer());
+            RenderRubyText* rubyText = rubyRun.rubyText();
             if (!rubyText)
                 continue;
 
-            if (rubyRun->style()->isFlippedLinesWritingMode()) {
+            if (rubyRun.style()->isFlippedLinesWritingMode()) {
                 LayoutUnit topOfFirstRubyTextLine = rubyText->logicalTop() + (rubyText->firstRootBox() ? rubyText->firstRootBox()->lineTop() : LayoutUnit());
                 if (topOfFirstRubyTextLine >= 0)
                     continue;
@@ -1542,7 +1551,7 @@
         }
 
         if (curr->isInlineTextBox()) {
-            RenderStyle* style = curr->renderer()->style(isFirstLineStyle());
+            RenderStyle* style = curr->renderer().style(isFirstLineStyle());
             if (style->textEmphasisMark() != TextEmphasisMarkNone && style->textEmphasisPosition() == TextEmphasisPositionUnder) {
                 if (!style->isFlippedLinesWritingMode()) {
                     LayoutUnit bottomOfEmphasisMark = curr->logicalBottom() + style->font().emphasisMarkHeight(style->textEmphasisMarkString());
@@ -1573,7 +1582,7 @@
         leafBoxesInLogicalOrder.append(leaf);
     }
 
-    if (renderer()->style()->rtlOrdering() == VisualOrder)
+    if (renderer().style()->rtlOrdering() == VisualOrder)
         return;
 
     // Reverse of reordering of the line (L2 according to Bidi spec):
diff --git a/Source/core/rendering/InlineFlowBox.h b/Source/core/rendering/InlineFlowBox.h
index e5478fe..7e68384 100644
--- a/Source/core/rendering/InlineFlowBox.h
+++ b/Source/core/rendering/InlineFlowBox.h
@@ -40,7 +40,7 @@
 
 class InlineFlowBox : public InlineBox {
 public:
-    InlineFlowBox(RenderObject* obj)
+    InlineFlowBox(RenderObject& obj)
         : InlineBox(obj)
         , m_firstChild(0)
         , m_lastChild(0)
@@ -61,7 +61,7 @@
         // an invisible marker exists.  The side effect of having an invisible marker is that the quirks mode behavior of shrinking lines with no
         // text children must not apply.  This change also means that gaps will exist between image bullet list items.  Even when the list bullet
         // is an image, the line is still considered to be immune from the quirk.
-        m_hasTextChildren = obj->style()->display() == LIST_ITEM;
+        m_hasTextChildren = obj.style()->display() == LIST_ITEM;
         m_hasTextDescendants = m_hasTextChildren;
     }
 
@@ -140,13 +140,13 @@
     {
         if (!includeLogicalLeftEdge())
             return 0;
-        return isHorizontal() ? renderer()->style(isFirstLineStyle())->borderLeftWidth() : renderer()->style(isFirstLineStyle())->borderTopWidth();
+        return isHorizontal() ? renderer().style(isFirstLineStyle())->borderLeftWidth() : renderer().style(isFirstLineStyle())->borderTopWidth();
     }
     int borderLogicalRight() const
     {
         if (!includeLogicalRightEdge())
             return 0;
-        return isHorizontal() ? renderer()->style(isFirstLineStyle())->borderRightWidth() : renderer()->style(isFirstLineStyle())->borderBottomWidth();
+        return isHorizontal() ? renderer().style(isFirstLineStyle())->borderRightWidth() : renderer().style(isFirstLineStyle())->borderBottomWidth();
     }
     int paddingLogicalLeft() const
     {
@@ -244,7 +244,7 @@
     LayoutRect logicalLayoutOverflowRect(LayoutUnit lineTop, LayoutUnit lineBottom) const
     {
         LayoutRect result = layoutOverflowRect(lineTop, lineBottom);
-        if (!renderer()->isHorizontalWritingMode())
+        if (!renderer().isHorizontalWritingMode())
             result = result.transposedRect();
         return result;
     }
@@ -270,25 +270,23 @@
     LayoutRect logicalVisualOverflowRect(LayoutUnit lineTop, LayoutUnit lineBottom) const
     {
         LayoutRect result = visualOverflowRect(lineTop, lineBottom);
-        if (!renderer()->isHorizontalWritingMode())
+        if (!renderer().isHorizontalWritingMode())
             result = result.transposedRect();
         return result;
     }
 
     void setOverflowFromLogicalRects(const LayoutRect& logicalLayoutOverflow, const LayoutRect& logicalVisualOverflow, LayoutUnit lineTop, LayoutUnit lineBottom);
-    void setLayoutOverflow(const LayoutRect&, LayoutUnit lineTop, LayoutUnit lineBottom);
-    void setVisualOverflow(const LayoutRect&, LayoutUnit lineTop, LayoutUnit lineBottom);
 
     FloatRect frameRectIncludingLineHeight(LayoutUnit lineTop, LayoutUnit lineBottom) const
     {
         if (isHorizontal())
-            return FloatRect(m_topLeft.x(), lineTop, width(), lineBottom - lineTop);
-        return FloatRect(lineTop, m_topLeft.y(), lineBottom - lineTop, height());
+            return FloatRect(m_topLeft.x(), lineTop.toFloat(), width(), (lineBottom - lineTop).toFloat());
+        return FloatRect(lineTop.toFloat(), m_topLeft.y(), (lineBottom - lineTop).toFloat(), height());
     }
 
     FloatRect logicalFrameRectIncludingLineHeight(LayoutUnit lineTop, LayoutUnit lineBottom) const
     {
-        return FloatRect(logicalLeft(), lineTop, logicalWidth(), lineBottom - lineTop);
+        return FloatRect(logicalLeft(), lineTop.toFloat(), logicalWidth(), (lineBottom - lineTop).toFloat());
     }
 
     bool descendantsHaveSameLineHeightAndBaseline() const { return m_descendantsHaveSameLineHeightAndBaseline; }
@@ -306,6 +304,9 @@
     void addReplacedChildOverflow(const InlineBox*, LayoutRect& logicalLayoutOverflow, LayoutRect& logicalVisualOverflow);
     void constrainToLineTopAndBottomIfNeeded(LayoutRect&) const;
 
+    void setLayoutOverflow(const LayoutRect&, const LayoutRect&);
+    void setVisualOverflow(const LayoutRect&, const LayoutRect&);
+
 protected:
     OwnPtr<RenderOverflow> m_overflow;
 
diff --git a/Source/core/rendering/InlineTextBox.cpp b/Source/core/rendering/InlineTextBox.cpp
index d36b8b4..dcb093c 100644
--- a/Source/core/rendering/InlineTextBox.cpp
+++ b/Source/core/rendering/InlineTextBox.cpp
@@ -29,7 +29,7 @@
 #include "core/dom/Text.h"
 #include "core/editing/Editor.h"
 #include "core/editing/InputMethodController.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/AbstractInlineTextBox.h"
@@ -46,7 +46,7 @@
 #include "core/rendering/svg/SVGTextRunRenderingContext.h"
 #include "platform/fonts/FontCache.h"
 #include "platform/fonts/WidthIterator.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
 #include "wtf/Vector.h"
 #include "wtf/text/CString.h"
@@ -106,35 +106,35 @@
 {
     if (!isText() || !parent())
         return 0;
-    if (parent()->renderer() == renderer()->parent())
+    if (parent()->renderer() == renderer().parent())
         return parent()->baselinePosition(baselineType);
-    return toRenderBoxModelObject(renderer()->parent())->baselinePosition(baselineType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
+    return toRenderBoxModelObject(renderer().parent())->baselinePosition(baselineType, isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
 }
 
 LayoutUnit InlineTextBox::lineHeight() const
 {
-    if (!isText() || !renderer()->parent())
+    if (!isText() || !renderer().parent())
         return 0;
-    if (m_renderer->isBR())
-        return toRenderBR(m_renderer)->lineHeight(isFirstLineStyle());
-    if (parent()->renderer() == renderer()->parent())
+    if (renderer().isBR())
+        return toRenderBR(renderer()).lineHeight(isFirstLineStyle());
+    if (parent()->renderer() == renderer().parent())
         return parent()->lineHeight();
-    return toRenderBoxModelObject(renderer()->parent())->lineHeight(isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
+    return toRenderBoxModelObject(renderer().parent())->lineHeight(isFirstLineStyle(), isHorizontal() ? HorizontalLine : VerticalLine, PositionOnContainingLine);
 }
 
 LayoutUnit InlineTextBox::selectionTop()
 {
-    return root()->selectionTop();
+    return root().selectionTop();
 }
 
 LayoutUnit InlineTextBox::selectionBottom()
 {
-    return root()->selectionBottom();
+    return root().selectionBottom();
 }
 
 LayoutUnit InlineTextBox::selectionHeight()
 {
-    return root()->selectionHeight();
+    return root().selectionHeight();
 }
 
 bool InlineTextBox::isSelected(int startPos, int endPos) const
@@ -148,16 +148,16 @@
 
 RenderObject::SelectionState InlineTextBox::selectionState()
 {
-    RenderObject::SelectionState state = renderer()->selectionState();
+    RenderObject::SelectionState state = renderer().selectionState();
     if (state == RenderObject::SelectionStart || state == RenderObject::SelectionEnd || state == RenderObject::SelectionBoth) {
         int startPos, endPos;
-        renderer()->selectionStartEnd(startPos, endPos);
+        renderer().selectionStartEnd(startPos, endPos);
         // The position after a hard line break is considered to be past its end.
         // See the corresponding code in InlineTextBox::isSelected.
         int lastSelectable = start() + len() - (isLineBreak() ? 1 : 0);
 
         // FIXME: Remove -webkit-line-break: LineBreakAfterWhiteSpace.
-        int endOfLineAdjustmentForCSSLineBreak = renderer()->style()->lineBreak() == LineBreakAfterWhiteSpace ? -1 : 0;
+        int endOfLineAdjustmentForCSSLineBreak = renderer().style()->lineBreak() == LineBreakAfterWhiteSpace ? -1 : 0;
         bool start = (state != RenderObject::SelectionEnd && startPos >= m_start && startPos <= m_start + m_len + endOfLineAdjustmentForCSSLineBreak);
         bool end = (state != RenderObject::SelectionStart && endPos > m_start && endPos <= lastSelectable);
         if (start && end)
@@ -174,8 +174,8 @@
     }
 
     // If there are ellipsis following, make sure their selection is updated.
-    if (m_truncation != cNoTruncation && root()->ellipsisBox()) {
-        EllipsisBox* ellipsis = root()->ellipsisBox();
+    if (m_truncation != cNoTruncation && root().ellipsisBox()) {
+        EllipsisBox* ellipsis = root().ellipsisBox();
         if (state != RenderObject::SelectionNone) {
             int start, end;
             selectionStartEnd(start, end);
@@ -202,22 +202,21 @@
 
     FontCachePurgePreventer fontCachePurgePreventer;
 
-    RenderText* textObj = textRenderer();
     LayoutUnit selTop = selectionTop();
     LayoutUnit selHeight = selectionHeight();
-    RenderStyle* styleToUse = textObj->style(isFirstLineStyle());
+    RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle());
     const Font& font = styleToUse->font();
 
     StringBuilder charactersWithHyphen;
     bool respectHyphen = ePos == m_len && hasHyphen();
     TextRun textRun = constructTextRun(styleToUse, font, respectHyphen ? &charactersWithHyphen : 0);
 
-    FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop);
+    FloatPoint startingPoint = FloatPoint(logicalLeft(), selTop.toFloat());
     LayoutRect r;
     if (sPos || ePos != static_cast<int>(m_len))
         r = enclosingIntRect(font.selectionRectForText(textRun, startingPoint, selHeight, sPos, ePos));
     else // Avoid computing the font width when the entire line box is selected as an optimization.
-        r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight)));
+        r = enclosingIntRect(FloatRect(startingPoint, FloatSize(m_logicalWidth, selHeight.toFloat())));
 
     LayoutUnit logicalWidth = r.width();
     if (r.x() > logicalRight())
@@ -234,7 +233,7 @@
 
 void InlineTextBox::deleteLine()
 {
-    toRenderText(renderer())->removeTextBox(this);
+    toRenderText(renderer()).removeTextBox(this);
     destroy();
 }
 
@@ -243,7 +242,7 @@
     if (extracted())
         return;
 
-    toRenderText(renderer())->extractTextBox(this);
+    toRenderText(renderer()).extractTextBox(this);
 }
 
 void InlineTextBox::attachLine()
@@ -251,7 +250,7 @@
     if (!extracted())
         return;
 
-    toRenderText(renderer())->attachTextBox(this);
+    toRenderText(renderer()).attachTextBox(this);
 }
 
 float InlineTextBox::placeEllipsisBox(bool flowIsLTR, float visibleLeftEdge, float visibleRightEdge, float ellipsisWidth, float &truncatedWidth, bool& foundBox)
@@ -305,7 +304,7 @@
 
         // If we got here that means that we were only partially truncated and we need to return the pixel offset at which
         // to place the ellipsis.
-        float widthOfVisibleText = toRenderText(renderer())->width(m_start, offset, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle());
+        float widthOfVisibleText = toRenderText(renderer()).width(m_start, offset, textPos(), flowIsLTR ? LTR : RTL, isFirstLineStyle());
 
         // The ellipsis needs to be placed just after the last visible character.
         // Where "after" is defined by the flow directionality, not the inline
@@ -367,7 +366,7 @@
 
 bool InlineTextBox::isLineBreak() const
 {
-    return renderer()->isBR() || (renderer()->style()->preserveNewline() && len() == 1 && (*textRenderer()->text().impl())[start()] == '\n');
+    return renderer().isBR() || (renderer().style()->preserveNewline() && len() == 1 && (*textRenderer().text().impl())[start()] == '\n');
 }
 
 bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/)
@@ -379,15 +378,15 @@
     boxOrigin.moveBy(accumulatedOffset);
     FloatRect rect(boxOrigin, size());
     if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && locationInContainer.intersects(rect)) {
-        renderer()->updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset)));
-        if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, rect))
+        renderer().updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset)));
+        if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, rect))
             return true;
     }
     return false;
 }
 
 static void paintTextWithShadows(GraphicsContext* context,
-    const RenderObject* renderer, const Font& font, const TextRun& textRun,
+    const RenderObject& renderer, const Font& font, const TextRun& textRun,
     const AtomicString& emphasisMark, int emphasisMarkOffset,
     int startOffset, int endOffset, int truncationPoint,
     const FloatPoint& textOrigin, const FloatRect& boxRect,
@@ -397,17 +396,17 @@
     bool hasShadow = shadowList && !context->printing();
 
     if (hasShadow) {
-        DrawLooper drawLooper;
+        OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
         for (size_t i = shadowList->shadows().size(); i--; ) {
             const ShadowData& shadow = shadowList->shadows()[i];
             float shadowX = horizontal ? shadow.x() : shadow.y();
             float shadowY = horizontal ? shadow.y() : -shadow.x();
             FloatSize offset(shadowX, shadowY);
-            drawLooper.addShadow(offset, shadow.blur(), shadow.color(),
-                DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
+            drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(),
+                DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
         }
-        drawLooper.addUnmodifiedContent();
-        context->setDrawLooper(drawLooper);
+        drawLooperBuilder->addUnmodifiedContent();
+        context->setDrawLooper(drawLooperBuilder.release());
     }
 
     TextRunPaintInfo textRunPaintInfo(textRun);
@@ -452,7 +451,7 @@
     if (emphasisPosition == TextEmphasisPositionUnder)
         return true; // Ruby text is always over, so it cannot suppress emphasis marks under.
 
-    RenderBlock* containingBlock = renderer()->containingBlock();
+    RenderBlock* containingBlock = renderer().containingBlock();
     if (!containingBlock->isRubyBase())
         return true; // This text is not inside a ruby base, so it does not have ruby text over it.
 
@@ -467,8 +466,8 @@
 
 void InlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit /*lineTop*/, LayoutUnit /*lineBottom*/)
 {
-    if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(renderer()) || renderer()->style()->visibility() != VISIBLE ||
-        m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len)
+    if (isLineBreak() || !paintInfo.shouldPaintWithinRoot(&renderer()) || renderer().style()->visibility() != VISIBLE
+        || m_truncation == cFullTruncation || paintInfo.phase == PaintPhaseOutline || !m_len)
         return;
 
     ASSERT(paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseChildOutlines);
@@ -486,7 +485,7 @@
     if (logicalStart >= paintEnd || logicalStart + logicalExtent <= paintStart)
         return;
 
-    bool isPrinting = textRenderer()->document().printing();
+    bool isPrinting = textRenderer().document().printing();
 
     // Determine whether or not we're selected.
     bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone;
@@ -495,7 +494,7 @@
         return;
 
     if (m_truncation != cNoTruncation) {
-        if (renderer()->containingBlock()->style()->isLeftToRightDirection() != isLeftToRightDirection()) {
+        if (renderer().containingBlock()->style()->isLeftToRightDirection() != isLeftToRightDirection()) {
             // Make the visible fragment of text hug the edge closest to the rest of the run by moving the origin
             // at which we start drawing text.
             // e.g. In the case of LTR text truncated in an RTL Context, the correct behavior is:
@@ -504,7 +503,7 @@
             // farther to the right.
             // NOTE: WebKit's behavior differs from that of IE which appears to just overlay the ellipsis on top of the
             // truncated string i.e.  |Hello|CBA| -> |...lo|CBA|
-            LayoutUnit widthOfVisibleText = toRenderText(renderer())->width(m_start, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
+            LayoutUnit widthOfVisibleText = toRenderText(renderer()).width(m_start, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
             LayoutUnit widthOfHiddenText = m_logicalWidth - widthOfVisibleText;
             // FIXME: The hit testing logic also needs to take this translation into account.
             LayoutSize truncationOffset(isLeftToRightDirection() ? widthOfHiddenText : -widthOfHiddenText, 0);
@@ -514,24 +513,25 @@
 
     GraphicsContext* context = paintInfo.context;
 
-    RenderObject* rendererToUse = renderer();
-    RenderStyle* styleToUse = rendererToUse->style(isFirstLineStyle());
+    RenderObject& rendererToUse = renderer();
+    RenderStyle* styleToUse = rendererToUse.style(isFirstLineStyle());
 
     adjustedPaintOffset.move(0, styleToUse->isHorizontalWritingMode() ? 0 : -logicalHeight());
 
     FloatPoint boxOrigin = locationIncludingFlipping();
-    boxOrigin.move(adjustedPaintOffset.x(), adjustedPaintOffset.y());
+    // FIXME: Shouldn't these offsets be rounded?
+    boxOrigin.move(adjustedPaintOffset.x().toFloat(), adjustedPaintOffset.y().toFloat());
     FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), logicalHeight()));
 
-    RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRenderer()->isCombineText() && toRenderCombineText(textRenderer())->isCombined() ? toRenderCombineText(textRenderer()) : 0;
+    RenderCombineText* combinedText = styleToUse->hasTextCombine() && textRenderer().isCombineText() && toRenderCombineText(textRenderer()).isCombined() ? &toRenderCombineText(textRenderer()) : 0;
 
     bool shouldRotate = !isHorizontal() && !combinedText;
     if (shouldRotate)
         context->concatCTM(rotation(boxRect, Clockwise));
 
     // Determine whether or not we have composition underlines to draw.
-    bool containsComposition = renderer()->node() && renderer()->frame()->inputMethodController().compositionNode() == renderer()->node();
-    bool useCustomUnderlines = containsComposition && renderer()->frame()->inputMethodController().compositionUsesCustomUnderlines();
+    bool containsComposition = renderer().node() && renderer().frame()->inputMethodController().compositionNode() == renderer().node();
+    bool useCustomUnderlines = containsComposition && renderer().frame()->inputMethodController().compositionUsesCustomUnderlines();
 
     // Determine the text colors and selection colors.
     Color textFillColor;
@@ -547,13 +547,13 @@
         textStrokeColor = Color::black;
         emphasisMarkColor = Color::black;
     } else {
-        textFillColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWebkitTextFillColor);
+        textFillColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextFillColor);
 
         bool forceBackgroundToWhite = false;
         if (isPrinting) {
             if (styleToUse->printColorAdjust() == PrintColorAdjustEconomy)
                 forceBackgroundToWhite = true;
-            if (textRenderer()->document().settings() && textRenderer()->document().settings()->shouldPrintBackgrounds())
+            if (textRenderer().document().settings() && textRenderer().document().settings()->shouldPrintBackgrounds())
                 forceBackgroundToWhite = false;
         }
 
@@ -561,13 +561,13 @@
         if (forceBackgroundToWhite)
             textFillColor = correctedTextColor(textFillColor, Color::white);
 
-        textStrokeColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWebkitTextStrokeColor);
+        textStrokeColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextStrokeColor);
 
         // Make the text stroke color legible against a white background
         if (forceBackgroundToWhite)
             textStrokeColor = correctedTextColor(textStrokeColor, Color::white);
 
-        emphasisMarkColor = rendererToUse->resolveColor(styleToUse, CSSPropertyWebkitTextEmphasisColor);
+        emphasisMarkColor = rendererToUse.resolveColor(styleToUse, CSSPropertyWebkitTextEmphasisColor);
 
         // Make the text stroke color legible against a white background
         if (forceBackgroundToWhite)
@@ -584,21 +584,21 @@
     const ShadowList* selectionShadow = textShadow;
     if (haveSelection) {
         // Check foreground color first.
-        Color foreground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionForegroundColor();
+        Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor();
         if (foreground != selectionFillColor) {
             if (!paintSelectedTextOnly)
                 paintSelectedTextSeparately = true;
             selectionFillColor = foreground;
         }
 
-        Color emphasisMarkForeground = paintInfo.forceBlackText() ? Color::black : renderer()->selectionEmphasisMarkColor();
+        Color emphasisMarkForeground = paintInfo.forceBlackText() ? Color::black : renderer().selectionEmphasisMarkColor();
         if (emphasisMarkForeground != selectionEmphasisMarkColor) {
             if (!paintSelectedTextOnly)
                 paintSelectedTextSeparately = true;
             selectionEmphasisMarkColor = emphasisMarkForeground;
         }
 
-        if (RenderStyle* pseudoStyle = renderer()->getCachedPseudoStyle(SELECTION)) {
+        if (RenderStyle* pseudoStyle = renderer().getCachedPseudoStyle(SELECTION)) {
             // Text shadows are disabled when printing. http://crbug.com/258321
             const ShadowList* shadow = (context->printing() || paintInfo.forceBlackText()) ? 0 : pseudoStyle->textShadow();
             if (shadow != selectionShadow) {
@@ -614,7 +614,7 @@
                 selectionStrokeWidth = strokeWidth;
             }
 
-            Color stroke = paintInfo.forceBlackText() ? Color::black : rendererToUse->resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor);
+            Color stroke = paintInfo.forceBlackText() ? Color::black : rendererToUse.resolveColor(pseudoStyle, CSSPropertyWebkitTextStrokeColor);
             if (stroke != selectionStrokeColor) {
                 if (!paintSelectedTextOnly)
                     paintSelectedTextSeparately = true;
@@ -637,8 +637,8 @@
 
         if (containsComposition && !useCustomUnderlines) {
             paintCompositionBackground(context, boxOrigin, styleToUse, font,
-                renderer()->frame()->inputMethodController().compositionStart(),
-                renderer()->frame()->inputMethodController().compositionEnd());
+                renderer().frame()->inputMethodController().compositionStart(),
+                renderer().frame()->inputMethodController().compositionEnd());
         }
 
         paintDocumentMarkers(context, boxOrigin, styleToUse, font, true);
@@ -652,10 +652,10 @@
     int maximumLength;
     StringView string;
     if (!combinedText) {
-        string = textRenderer()->text().createView();
+        string = textRenderer().text().createView();
         if (static_cast<unsigned>(length) != string.length() || m_start)
             string.narrow(m_start, length);
-        maximumLength = textRenderer()->textLength() - m_start;
+        maximumLength = textRenderer().textLength() - m_start;
     } else {
         combinedText->getStringToRender(m_start, string, length);
         maximumLength = length;
@@ -706,12 +706,19 @@
             if (combinedText)
                 context->concatCTM(rotation(boxRect, Clockwise));
 
-            if (!paintSelectedTextSeparately || ePos <= sPos) {
-                // FIXME: Truncate right-to-left text correctly.
-                paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, 0, length, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
-            } else {
-                paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, ePos, sPos, length, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
+            int startOffset = 0;
+            int endOffset = length;
+            int paintRunLength = length;
+            if (combinedText) {
+                startOffset = 0;
+                endOffset = objectReplacementCharacterTextRun.length();
+                paintRunLength = endOffset;
+            } else if (paintSelectedTextSeparately && ePos > sPos) {
+                startOffset = ePos;
+                endOffset = sPos;
             }
+            // FIXME: Truncate right-to-left text correctly.
+            paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, startOffset, endOffset, paintRunLength, emphasisMarkTextOrigin, boxRect, textShadow, textStrokeWidth > 0, isHorizontal());
 
             if (combinedText)
                 context->concatCTM(rotation(boxRect, Counterclockwise));
@@ -733,7 +740,10 @@
             if (combinedText)
                 context->concatCTM(rotation(boxRect, Clockwise));
 
-            paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, sPos, ePos, length, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal());
+            int startOffset = combinedText ? 0 : sPos;
+            int endOffset = combinedText ? objectReplacementCharacterTextRun.length() : ePos;
+            int paintRunLength = combinedText ? endOffset : length;
+            paintTextWithShadows(context, rendererToUse, combinedText ? combinedText->originalFont() : font, emphasisMarkTextRun, emphasisMark, emphasisMarkOffset, startOffset, endOffset, paintRunLength, emphasisMarkTextOrigin, boxRect, selectionShadow, selectionStrokeWidth > 0, isHorizontal());
 
             if (combinedText)
                 context->concatCTM(rotation(boxRect, Counterclockwise));
@@ -746,7 +756,7 @@
         updateGraphicsContext(context, textFillColor, textStrokeColor, textStrokeWidth);
         if (combinedText)
             context->concatCTM(rotation(boxRect, Clockwise));
-        paintDecoration(context, boxOrigin, textDecorations, styleToUse->textDecorationStyle(), textShadow);
+        paintDecoration(context, boxOrigin, textDecorations, textShadow);
         if (combinedText)
             context->concatCTM(rotation(boxRect, Counterclockwise));
     }
@@ -755,7 +765,7 @@
         paintDocumentMarkers(context, boxOrigin, styleToUse, font, false);
 
         if (useCustomUnderlines) {
-            const Vector<CompositionUnderline>& underlines = renderer()->frame()->inputMethodController().customCompositionUnderlines();
+            const Vector<CompositionUnderline>& underlines = renderer().frame()->inputMethodController().customCompositionUnderlines();
             size_t numUnderlines = underlines.size();
 
             for (size_t index = 0; index < numUnderlines; ++index) {
@@ -787,14 +797,14 @@
 void InlineTextBox::selectionStartEnd(int& sPos, int& ePos)
 {
     int startPos, endPos;
-    if (renderer()->selectionState() == RenderObject::SelectionInside) {
+    if (renderer().selectionState() == RenderObject::SelectionInside) {
         startPos = 0;
-        endPos = textRenderer()->textLength();
+        endPos = textRenderer().textLength();
     } else {
-        textRenderer()->selectionStartEnd(startPos, endPos);
-        if (renderer()->selectionState() == RenderObject::SelectionStart)
-            endPos = textRenderer()->textLength();
-        else if (renderer()->selectionState() == RenderObject::SelectionEnd)
+        textRenderer().selectionStartEnd(startPos, endPos);
+        if (renderer().selectionState() == RenderObject::SelectionStart)
+            endPos = textRenderer().textLength();
+        else if (renderer().selectionState() == RenderObject::SelectionEnd)
             startPos = 0;
     }
 
@@ -820,7 +830,7 @@
     if (sPos >= ePos)
         return;
 
-    Color c = renderer()->selectionBackgroundColor();
+    Color c = renderer().selectionBackgroundColor();
     if (!c.alpha())
         return;
 
@@ -835,21 +845,21 @@
     // If the text is truncated, let the thing being painted in the truncation
     // draw its own highlight.
     int length = m_truncation != cNoTruncation ? m_truncation : m_len;
-    StringView string = textRenderer()->text().createView();
+    StringView string = textRenderer().text().createView();
 
     if (string.length() != static_cast<unsigned>(length) || m_start)
         string.narrow(m_start, length);
 
     StringBuilder charactersWithHyphen;
     bool respectHyphen = ePos == length && hasHyphen();
-    TextRun textRun = constructTextRun(style, font, string, textRenderer()->textLength() - m_start, respectHyphen ? &charactersWithHyphen : 0);
+    TextRun textRun = constructTextRun(style, font, string, textRenderer().textLength() - m_start, respectHyphen ? &charactersWithHyphen : 0);
     if (respectHyphen)
         ePos = textRun.length();
 
-    LayoutUnit selectionBottom = root()->selectionBottom();
-    LayoutUnit selectionTop = root()->selectionTopAdjustedForPrecedingBlock();
+    LayoutUnit selectionBottom = root().selectionBottom();
+    LayoutUnit selectionTop = root().selectionTopAdjustedForPrecedingBlock();
 
-    int deltaY = roundToInt(renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - selectionTop);
+    int deltaY = roundToInt(renderer().style()->isFlippedLinesWritingMode() ? selectionBottom - logicalBottom() : logicalTop() - selectionTop);
     int selHeight = max(0, roundToInt(selectionBottom - selectionTop));
 
     FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
@@ -876,7 +886,7 @@
 
     updateGraphicsContext(context, c, c, 0); // Don't draw text at all!
 
-    int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
+    int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     int selHeight = selectionHeight();
     FloatPoint localOrigin(boxOrigin.x(), boxOrigin.y() - deltaY);
     context->drawHighlightForText(font, constructTextRun(style, font), localOrigin, selHeight, c, sPos, ePos);
@@ -918,7 +928,7 @@
         return fontMetrics.ascent() + gap; // Position underline near the alphabetic baseline.
     case TextUnderlinePositionUnder: {
         // Position underline relative to the under edge of the lowest element's content box.
-        const float offset = inlineTextBox->root()->maxLogicalTop() - inlineTextBox->logicalTop();
+        const float offset = inlineTextBox->root().maxLogicalTop() - inlineTextBox->logicalTop();
         if (offset > 0)
             return inlineTextBox->logicalHeight() + gap + offset;
         return inlineTextBox->logicalHeight() + gap;
@@ -974,7 +984,7 @@
  *             |-----------|
  *                 step
  */
-static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint& p1, FloatPoint& p2, float strokeThickness)
+static void strokeWavyTextDecoration(GraphicsContext* context, FloatPoint p1, FloatPoint p2, float strokeThickness)
 {
     context->adjustLineToPixelBoundaries(p1, p2, strokeThickness, context->strokeStyle());
 
@@ -1051,7 +1061,39 @@
     context->strokePath(path);
 }
 
-void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, TextDecorationStyle decorationStyle, const ShadowList* shadowList)
+static bool shouldSetDecorationAntialias(TextDecorationStyle decorationStyle)
+{
+    return decorationStyle == TextDecorationStyleDotted || decorationStyle == TextDecorationStyleDashed;
+}
+
+static bool shouldSetDecorationAntialias(TextDecorationStyle underline, TextDecorationStyle overline, TextDecorationStyle linethrough)
+{
+    return shouldSetDecorationAntialias(underline) || shouldSetDecorationAntialias(overline) || shouldSetDecorationAntialias(linethrough);
+}
+
+static void paintAppliedDecoration(GraphicsContext* context, FloatPoint start, float width, float doubleOffset, int wavyOffsetFactor,
+    RenderObject::AppliedTextDecoration decoration, float thickness, bool antialiasDecoration, bool isPrinting)
+{
+    context->setStrokeStyle(textDecorationStyleToStrokeStyle(decoration.style));
+    context->setStrokeColor(decoration.color);
+
+    switch (decoration.style) {
+    case TextDecorationStyleWavy:
+        strokeWavyTextDecoration(context, start + FloatPoint(0, doubleOffset * wavyOffsetFactor), start + FloatPoint(width, doubleOffset * wavyOffsetFactor), thickness);
+        break;
+    case TextDecorationStyleDotted:
+    case TextDecorationStyleDashed:
+        context->setShouldAntialias(antialiasDecoration);
+        // Fall through
+    default:
+        context->drawLineForText(start, width, isPrinting);
+
+        if (decoration.style == TextDecorationStyleDouble)
+            context->drawLineForText(start + FloatPoint(0, doubleOffset), width, isPrinting);
+    }
+}
+
+void InlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoint& boxOrigin, TextDecoration deco, const ShadowList* shadowList)
 {
     GraphicsContextStateSaver stateSaver(*context);
 
@@ -1062,23 +1104,24 @@
 
     float width = m_logicalWidth;
     if (m_truncation != cNoTruncation) {
-        width = toRenderText(renderer())->width(m_start, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
+        width = toRenderText(renderer()).width(m_start, m_truncation, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
         if (!isLeftToRightDirection())
             localOrigin.move(m_logicalWidth - width, 0);
     }
 
     // Get the text decoration colors.
-    Color underline(Color::transparent), overline(Color::transparent), linethrough(Color::transparent);
-    renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true);
+    RenderObject::AppliedTextDecoration underline, overline, linethrough;
+
+    renderer().getTextDecorations(deco, underline, overline, linethrough, true);
     if (isFirstLineStyle())
-        renderer()->getTextDecorationColors(deco, underline, overline, linethrough, true, true);
+        renderer().getTextDecorations(deco, underline, overline, linethrough, true, true);
 
     // Use a special function for underlines to get the positioning exactly right.
-    bool isPrinting = textRenderer()->document().printing();
+    bool isPrinting = textRenderer().document().printing();
 
-    bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || underline.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.alpha() == 255);
+    bool linesAreOpaque = !isPrinting && (!(deco & TextDecorationUnderline) || underline.color.alpha() == 255) && (!(deco & TextDecorationOverline) || overline.color.alpha() == 255) && (!(deco & TextDecorationLineThrough) || linethrough.color.alpha() == 255);
 
-    RenderStyle* styleToUse = renderer()->style(isFirstLineStyle());
+    RenderStyle* styleToUse = renderer().style(isFirstLineStyle());
     int baseline = styleToUse->fontMetrics().ascent();
 
     size_t shadowCount = shadowList ? shadowList->shadows().size() : 0;
@@ -1093,6 +1136,9 @@
 
     context->setStrokeThickness(textDecorationThickness);
 
+    bool antialiasDecoration = shouldSetDecorationAntialias(overline.style, underline.style, linethrough.style)
+        && RenderBoxModelObject::shouldAntialiasLines(context);
+
     float extraOffset = 0;
     if (!linesAreOpaque && shadowCount > 1) {
         FloatRect clipRect(localOrigin, FloatSize(width, baseline + 2));
@@ -1127,53 +1173,17 @@
 
         // Offset between lines - always non-zero, so lines never cross each other.
         float doubleOffset = textDecorationThickness + 1.f;
-        context->setStrokeStyle(textDecorationStyleToStrokeStyle(decorationStyle));
-        if (deco & TextDecorationUnderline) {
-            context->setStrokeColor(underline);
-            const int underlineOffset = computeUnderlineOffset(styleToUse->textUnderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness);
-            switch (decorationStyle) {
-            case TextDecorationStyleWavy: {
-                FloatPoint start(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset);
-                FloatPoint end(localOrigin.x() + width, localOrigin.y() + underlineOffset + doubleOffset);
-                strokeWavyTextDecoration(context, start, end, textDecorationThickness);
-                break;
-            }
-            default:
-                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset), width, isPrinting);
 
-                if (decorationStyle == TextDecorationStyleDouble)
-                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + underlineOffset + doubleOffset), width, isPrinting);
-            }
+        if (deco & TextDecorationUnderline) {
+            const int underlineOffset = computeUnderlineOffset(styleToUse->textUnderlinePosition(), styleToUse->fontMetrics(), this, textDecorationThickness);
+            paintAppliedDecoration(context, localOrigin + FloatPoint(0, underlineOffset), width, doubleOffset, 1, underline, textDecorationThickness, antialiasDecoration, isPrinting);
         }
         if (deco & TextDecorationOverline) {
-            context->setStrokeColor(overline);
-            switch (decorationStyle) {
-            case TextDecorationStyleWavy: {
-                FloatPoint start(localOrigin.x(), localOrigin.y() - doubleOffset);
-                FloatPoint end(localOrigin.x() + width, localOrigin.y() - doubleOffset);
-                strokeWavyTextDecoration(context, start, end, textDecorationThickness);
-                break;
-            }
-            default:
-                context->drawLineForText(localOrigin, width, isPrinting);
-                if (decorationStyle == TextDecorationStyleDouble)
-                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() - doubleOffset), width, isPrinting);
-            }
+            paintAppliedDecoration(context, localOrigin, width, -doubleOffset, 1, overline, textDecorationThickness, antialiasDecoration, isPrinting);
         }
         if (deco & TextDecorationLineThrough) {
-            context->setStrokeColor(linethrough);
-            switch (decorationStyle) {
-            case TextDecorationStyleWavy: {
-                FloatPoint start(localOrigin.x(), localOrigin.y() + 2 * baseline / 3);
-                FloatPoint end(localOrigin.x() + width, localOrigin.y() + 2 * baseline / 3);
-                strokeWavyTextDecoration(context, start, end, textDecorationThickness);
-                break;
-            }
-            default:
-                context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + 2 * baseline / 3), width, isPrinting);
-                if (decorationStyle == TextDecorationStyleDouble)
-                    context->drawLineForText(FloatPoint(localOrigin.x(), localOrigin.y() + doubleOffset + 2 * baseline / 3), width, isPrinting);
-            }
+            const float lineThroughOffset = 2 * baseline / 3;
+            paintAppliedDecoration(context, localOrigin + FloatPoint(0, lineThroughOffset), width, doubleOffset, 0, linethrough, textDecorationThickness, antialiasDecoration, isPrinting);
         }
     }
 }
@@ -1194,7 +1204,7 @@
 void InlineTextBox::paintDocumentMarker(GraphicsContext* pt, const FloatPoint& boxOrigin, DocumentMarker* marker, RenderStyle* style, const Font& font, bool grammar)
 {
     // Never print spelling/grammar markers (5327887)
-    if (textRenderer()->document().printing())
+    if (textRenderer().document().printing())
         return;
 
     if (m_truncation == cFullTruncation)
@@ -1220,7 +1230,7 @@
             endPosition = min<int>(endPosition, m_truncation);
 
         // Calculate start & width
-        int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
+        int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
         int selHeight = selectionHeight();
         FloatPoint startPoint(boxOrigin.x(), boxOrigin.y() - deltaY);
         TextRun run = constructTextRun(style, font);
@@ -1234,7 +1244,7 @@
         // display a toolTip. We don't do this for misspelling markers.
         if (grammar) {
             markerRect.move(-boxOrigin.x(), -boxOrigin.y());
-            markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
+            markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
             toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
         }
     }
@@ -1246,7 +1256,7 @@
     // So, we generally place the underline at the bottom of the text, but in larger fonts that's not so good so
     // we pin to two pixels under the baseline.
     int lineThickness = misspellingLineThickness;
-    int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent();
+    int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();
     int descent = logicalHeight() - baseline;
     int underlineOffset;
     if (descent <= (2 + lineThickness)) {
@@ -1263,7 +1273,7 @@
 {
     // Use same y positioning and height as for selection, so that when the selection and this highlight are on
     // the same word there are no pieces sticking out.
-    int deltaY = renderer()->style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
+    int deltaY = renderer().style()->isFlippedLinesWritingMode() ? selectionBottom() - logicalBottom() : logicalTop() - selectionTop();
     int selHeight = selectionHeight();
 
     int sPos = max(marker->startOffset() - m_start, (unsigned)0);
@@ -1272,11 +1282,11 @@
 
     // Always compute and store the rect associated with this marker. The computed rect is in absolute coordinates.
     IntRect markerRect = enclosingIntRect(font.selectionRectForText(run, IntPoint(x(), selectionTop()), selHeight, sPos, ePos));
-    markerRect = renderer()->localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
+    markerRect = renderer().localToAbsoluteQuad(FloatRect(markerRect)).enclosingBoundingBox();
     toRenderedDocumentMarker(marker)->setRenderedRect(markerRect);
 
     // Optionally highlight the text
-    if (renderer()->frame()->editor().markedTextMatchesAreHighlighted()) {
+    if (renderer().frame()->editor().markedTextMatchesAreHighlighted()) {
         Color color = marker->activeMatch() ?
             RenderTheme::theme().platformActiveTextSearchHighlightColor() :
             RenderTheme::theme().platformInactiveTextSearchHighlightColor();
@@ -1289,10 +1299,10 @@
 
 void InlineTextBox::paintDocumentMarkers(GraphicsContext* pt, const FloatPoint& boxOrigin, RenderStyle* style, const Font& font, bool background)
 {
-    if (!renderer()->node())
+    if (!renderer().node())
         return;
 
-    Vector<DocumentMarker*> markers = renderer()->document().markers()->markersFor(renderer()->node());
+    Vector<DocumentMarker*> markers = renderer().document().markers().markersFor(renderer().node());
     Vector<DocumentMarker*>::const_iterator markerIt = markers.begin();
 
     // Give any document markers that touch this run a chance to draw before the text has been drawn.
@@ -1355,7 +1365,7 @@
     if (paintStart <= underline.startOffset) {
         paintStart = underline.startOffset;
         useWholeWidth = false;
-        start = toRenderText(renderer())->width(m_start, paintStart - m_start, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
+        start = toRenderText(renderer()).width(m_start, paintStart - m_start, textPos(), isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
     }
     if (paintEnd != underline.endOffset) {      // end points at the last char, not past it
         paintEnd = min(paintEnd, (unsigned)underline.endOffset);
@@ -1366,14 +1376,14 @@
         useWholeWidth = false;
     }
     if (!useWholeWidth) {
-        width = toRenderText(renderer())->width(paintStart, paintEnd - paintStart, textPos() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
+        width = toRenderText(renderer()).width(paintStart, paintEnd - paintStart, textPos() + start, isLeftToRightDirection() ? LTR : RTL, isFirstLineStyle());
     }
 
     // Thick marked text underlines are 2px thick as long as there is room for the 2px line under the baseline.
     // All other marked text underlines are 1px thick.
     // If there's not enough space the underline will touch or overlap characters.
     int lineThickness = 1;
-    int baseline = renderer()->style(isFirstLineStyle())->fontMetrics().ascent();
+    int baseline = renderer().style(isFirstLineStyle())->fontMetrics().ascent();
     if (underline.thick && logicalHeight() - baseline >= 2)
         lineThickness = 2;
 
@@ -1384,7 +1394,7 @@
 
     ctx->setStrokeColor(underline.color);
     ctx->setStrokeThickness(lineThickness);
-    ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer()->document().printing());
+    ctx->drawLineForText(FloatPoint(boxOrigin.x() + start, boxOrigin.y() + logicalHeight() - lineThickness), width, textRenderer().document().printing());
 }
 
 int InlineTextBox::caretMinOffset() const
@@ -1403,7 +1413,7 @@
     // from the containing block edge in its measurement. textPos() should be consistent so the text are rendered in the same width.
     if (logicalLeft() == 0)
         return 0;
-    return logicalLeft() - root()->logicalLeft();
+    return logicalLeft() - root().logicalLeft();
 }
 
 int InlineTextBox::offsetForPosition(float lineOffset, bool includePartialGlyphs) const
@@ -1418,8 +1428,8 @@
 
     FontCachePurgePreventer fontCachePurgePreventer;
 
-    RenderText* text = toRenderText(renderer());
-    RenderStyle* style = text->style(isFirstLineStyle());
+    RenderText& text = toRenderText(renderer());
+    RenderStyle* style = text.style(isFirstLineStyle());
     const Font& font = style->font();
     return font.offsetForPosition(constructTextRun(style, font), lineOffset - logicalLeft(), includePartialGlyphs);
 }
@@ -1434,8 +1444,8 @@
 
     FontCachePurgePreventer fontCachePurgePreventer;
 
-    RenderText* text = toRenderText(renderer());
-    RenderStyle* styleToUse = text->style(isFirstLineStyle());
+    RenderText& text = toRenderText(renderer());
+    RenderStyle* styleToUse = text.style(isFirstLineStyle());
     ASSERT(styleToUse);
     const Font& font = styleToUse->font();
     int from = !isLeftToRightDirection() ? offset - m_start : 0;
@@ -1472,8 +1482,7 @@
 {
     FontCachePurgePreventer fontCachePurgePreventer;
 
-    RenderText* textObj = textRenderer();
-    RenderStyle* styleToUse = textObj->style(isFirstLineStyle());
+    RenderStyle* styleToUse = textRenderer().style(isFirstLineStyle());
     const Font& font = styleToUse->font();
 
     TextRun textRun = constructTextRun(styleToUse, font);
@@ -1492,28 +1501,22 @@
 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, StringBuilder* charactersWithHyphen) const
 {
     ASSERT(style);
+    ASSERT(textRenderer().text());
 
-    RenderText* textRenderer = this->textRenderer();
-    ASSERT(textRenderer);
-    ASSERT(textRenderer->text());
-
-    StringView string = textRenderer->text().createView();
+    StringView string = textRenderer().text().createView();
     unsigned startPos = start();
     unsigned length = len();
 
     if (string.length() != length || startPos)
         string.narrow(startPos, length);
 
-    return constructTextRun(style, font, string, textRenderer->textLength() - startPos, charactersWithHyphen);
+    return constructTextRun(style, font, string, textRenderer().textLength() - startPos, charactersWithHyphen);
 }
 
 TextRun InlineTextBox::constructTextRun(RenderStyle* style, const Font& font, StringView string, int maximumLength, StringBuilder* charactersWithHyphen) const
 {
     ASSERT(style);
 
-    RenderText* textRenderer = this->textRenderer();
-    ASSERT(textRenderer);
-
     if (charactersWithHyphen) {
         const AtomicString& hyphenString = style->hyphenString();
         charactersWithHyphen->reserveCapacity(string.length() + hyphenString.length());
@@ -1525,11 +1528,11 @@
 
     ASSERT(maximumLength >= static_cast<int>(string.length()));
 
-    TextRun run(string, textPos(), expansion(), expansionBehavior(), direction(), dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer->canUseSimpleFontCodePath());
+    TextRun run(string, textPos(), expansion(), expansionBehavior(), direction(), dirOverride() || style->rtlOrdering() == VisualOrder, !textRenderer().canUseSimpleFontCodePath());
     run.setTabSize(!style->collapseWhiteSpace(), style->tabSize());
-    run.setCharacterScanForCodePath(!textRenderer->canUseSimpleFontCodePath());
+    run.setCharacterScanForCodePath(!textRenderer().canUseSimpleFontCodePath());
     if (textRunNeedsRenderingContext(font))
-        run.setRenderingContext(SVGTextRunRenderingContext::create(textRenderer));
+        run.setRenderingContext(SVGTextRunRenderingContext::create(&textRenderer()));
 
     // Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring.
     run.setCharactersLength(maximumLength);
@@ -1551,15 +1554,15 @@
 
 void InlineTextBox::showBox(int printedCharacters) const
 {
-    const RenderText* obj = toRenderText(renderer());
-    String value = obj->text();
+    const RenderText& obj = toRenderText(renderer());
+    String value = obj.text();
     value = value.substring(start(), len());
     value.replaceWithLiteral('\\', "\\\\");
     value.replaceWithLiteral('\n', "\\n");
     printedCharacters += fprintf(stderr, "%s\t%p", boxName(), this);
     for (; printedCharacters < showTreeCharacterOffset; printedCharacters++)
         fputc(' ', stderr);
-    printedCharacters = fprintf(stderr, "\t%s %p", obj->renderName(), obj);
+    printedCharacters = fprintf(stderr, "\t%s %p", obj.renderName(), &obj);
     const int rendererCharacterOffset = 24;
     for (; printedCharacters < rendererCharacterOffset; printedCharacters++)
         fputc(' ', stderr);
diff --git a/Source/core/rendering/InlineTextBox.h b/Source/core/rendering/InlineTextBox.h
index 9292607..69b2a1d 100644
--- a/Source/core/rendering/InlineTextBox.h
+++ b/Source/core/rendering/InlineTextBox.h
@@ -43,7 +43,7 @@
 
 class InlineTextBox : public InlineBox {
 public:
-    InlineTextBox(RenderObject* obj)
+    InlineTextBox(RenderObject& obj)
         : InlineBox(obj)
         , m_prevTextBox(0)
         , m_nextTextBox(0)
@@ -122,7 +122,7 @@
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) OVERRIDE;
 
 public:
-    RenderText* textRenderer() const;
+    RenderText& textRenderer() const;
 
 private:
     virtual void deleteLine() OVERRIDE FINAL;
@@ -185,7 +185,7 @@
     virtual void paintTextMatchMarker(GraphicsContext*, const FloatPoint& boxOrigin, DocumentMarker*, RenderStyle*, const Font&);
 
 private:
-    void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, TextDecoration, TextDecorationStyle, const ShadowList*);
+    void paintDecoration(GraphicsContext*, const FloatPoint& boxOrigin, TextDecoration, const ShadowList*);
     void paintSelection(GraphicsContext*, const FloatPoint& boxOrigin, RenderStyle*, const Font&, Color textColor);
 
     TextRun::ExpansionBehavior expansionBehavior() const
@@ -197,7 +197,7 @@
 
 DEFINE_INLINE_BOX_TYPE_CASTS(InlineTextBox);
 
-inline RenderText* InlineTextBox::textRenderer() const
+inline RenderText& InlineTextBox::textRenderer() const
 {
     return toRenderText(renderer());
 }
diff --git a/Source/core/rendering/LayoutRepainter.cpp b/Source/core/rendering/LayoutRepainter.cpp
index fc06e0b..0e1f779 100644
--- a/Source/core/rendering/LayoutRepainter.cpp
+++ b/Source/core/rendering/LayoutRepainter.cpp
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "core/rendering/LayoutRepainter.h"
 
+#include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderObject.h"
 
 namespace WebCore {
@@ -40,7 +41,11 @@
 
     if (m_checkForRepaint) {
         m_repaintContainer = m_object.containerForRepaint();
-        m_oldBounds = m_object.clippedOverflowRectForRepaint(m_repaintContainer);
+        {
+            // Hits in compositing/video/video-controls-layer-creation.html
+            DisableCompositingQueryAsserts disabler;
+            m_oldBounds = m_object.clippedOverflowRectForRepaint(m_repaintContainer);
+        }
         m_oldOutlineBox = m_object.outlineBoundsForRepaint(m_repaintContainer);
     }
 }
@@ -50,6 +55,9 @@
     if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
         return false;
 
+    // Hits in compositing/video/video-controls-layer-creation.html
+    DisableCompositingQueryAsserts disabler;
+
     return m_checkForRepaint ? m_object.repaintAfterLayoutIfNeeded(m_repaintContainer, m_object.selfNeedsLayout(), m_oldBounds, m_oldOutlineBox) : false;
 }
 
diff --git a/Source/core/rendering/LayoutState.cpp b/Source/core/rendering/LayoutState.cpp
index 8c46caa..e9cb94b 100644
--- a/Source/core/rendering/LayoutState.cpp
+++ b/Source/core/rendering/LayoutState.cpp
@@ -33,26 +33,26 @@
 
 namespace WebCore {
 
-LayoutState::LayoutState(LayoutState* prev, RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo)
+LayoutState::LayoutState(LayoutState* prev, RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageLogicalHeight, bool pageLogicalHeightChanged, ColumnInfo* columnInfo)
     : m_columnInfo(columnInfo)
     , m_next(prev)
     , m_shapeInsideInfo(0)
 #ifndef NDEBUG
-    , m_renderer(renderer)
+    , m_renderer(&renderer)
 #endif
 {
     ASSERT(m_next);
 
-    bool fixed = renderer->isOutOfFlowPositioned() && renderer->style()->position() == FixedPosition;
+    bool fixed = renderer.isOutOfFlowPositioned() && renderer.style()->position() == FixedPosition;
     if (fixed) {
         // FIXME: This doesn't work correctly with transforms.
-        FloatPoint fixedOffset = renderer->view()->localToAbsolute(FloatPoint(), IsFixed);
+        FloatPoint fixedOffset = renderer.view()->localToAbsolute(FloatPoint(), IsFixed);
         m_paintOffset = LayoutSize(fixedOffset.x(), fixedOffset.y()) + offset;
     } else
         m_paintOffset = prev->m_paintOffset + offset;
 
-    if (renderer->isOutOfFlowPositioned() && !fixed) {
-        if (RenderObject* container = renderer->container()) {
+    if (renderer.isOutOfFlowPositioned() && !fixed) {
+        if (RenderObject* container = renderer.container()) {
             if (container->isInFlowPositioned() && container->isRenderInline())
                 m_paintOffset += toRenderInline(container)->offsetForInFlowPositionedInline(renderer);
         }
@@ -60,17 +60,17 @@
 
     m_layoutOffset = m_paintOffset;
 
-    if (renderer->isInFlowPositioned() && renderer->hasLayer())
-        m_paintOffset += renderer->layer()->offsetForInFlowPosition();
+    if (renderer.isInFlowPositioned() && renderer.hasLayer())
+        m_paintOffset += renderer.layer()->offsetForInFlowPosition();
 
     m_clipped = !fixed && prev->m_clipped;
     if (m_clipped)
         m_clipRect = prev->m_clipRect;
 
-    if (renderer->hasOverflowClip()) {
-        LayoutSize deltaSize = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : renderer->view()->layoutDelta();
+    if (renderer.hasOverflowClip()) {
+        LayoutSize deltaSize = RuntimeEnabledFeatures::repaintAfterLayoutEnabled() ? LayoutSize() : renderer.view()->layoutDelta();
 
-        LayoutRect clipRect(toPoint(m_paintOffset) + deltaSize, renderer->cachedSizeForOverflowClip());
+        LayoutRect clipRect(toPoint(m_paintOffset) + deltaSize, renderer.cachedSizeForOverflowClip());
         if (m_clipped)
             m_clipRect.intersect(clipRect);
         else {
@@ -78,16 +78,16 @@
             m_clipped = true;
         }
 
-        m_paintOffset -= renderer->scrolledContentOffset();
+        m_paintOffset -= renderer.scrolledContentOffset();
     }
 
     // If we establish a new page height, then cache the offset to the top of the first page.
     // We can compare this later on to figure out what part of the page we're actually on,
-    if (pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread()) {
+    if (pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread()) {
         m_pageLogicalHeight = pageLogicalHeight;
-        bool isFlipped = renderer->style()->isFlippedBlocksWritingMode();
-        m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer->borderLeft() + renderer->paddingLeft() : renderer->borderRight() + renderer->paddingRight()),
-                               m_layoutOffset.height() + (!isFlipped ? renderer->borderTop() + renderer->paddingTop() : renderer->borderBottom() + renderer->paddingBottom()));
+        bool isFlipped = renderer.style()->isFlippedBlocksWritingMode();
+        m_pageOffset = LayoutSize(m_layoutOffset.width() + (!isFlipped ? renderer.borderLeft() + renderer.paddingLeft() : renderer.borderRight() + renderer.paddingRight()),
+            m_layoutOffset.height() + (!isFlipped ? renderer.borderTop() + renderer.paddingTop() : renderer.borderBottom() + renderer.paddingBottom()));
         m_pageLogicalHeightChanged = pageLogicalHeightChanged;
     } else {
         // If we don't establish a new page height, then propagate the old page height and offset down.
@@ -97,17 +97,17 @@
 
         // Disable pagination for objects we don't support. For now this includes overflow:scroll/auto, inline blocks and
         // writing mode roots.
-        if (renderer->isUnsplittableForPagination())
+        if (renderer.isUnsplittableForPagination())
             m_pageLogicalHeight = 0;
     }
 
     if (!m_columnInfo)
         m_columnInfo = m_next->m_columnInfo;
 
-    if (renderer->isRenderBlock()) {
-        const RenderBlock* renderBlock = toRenderBlock(renderer);
-        m_shapeInsideInfo = renderBlock->shapeInsideInfo();
-        if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock->allowsShapeInsideInfoSharing(m_next->m_shapeInsideInfo->owner()))
+    if (renderer.isRenderBlock()) {
+        const RenderBlock& renderBlock = toRenderBlock(renderer);
+        m_shapeInsideInfo = renderBlock.shapeInsideInfo();
+        if (!m_shapeInsideInfo && m_next->m_shapeInsideInfo && renderBlock.allowsShapeInsideInfoSharing(&m_next->m_shapeInsideInfo->owner()))
             m_shapeInsideInfo = m_next->m_shapeInsideInfo;
     }
 
@@ -119,12 +119,12 @@
 #endif
     }
 
-    m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer->isRenderFlowThread();
+    m_isPaginated = m_pageLogicalHeight || m_columnInfo || renderer.isRenderFlowThread();
 
     // FIXME: <http://bugs.webkit.org/show_bug.cgi?id=13443> Apply control clip if present.
 }
 
-LayoutState::LayoutState(RenderObject* root)
+LayoutState::LayoutState(RenderObject& root)
     : m_clipped(false)
     , m_isPaginated(false)
     , m_pageLogicalHeightChanged(false)
@@ -137,10 +137,10 @@
     , m_shapeInsideInfo(0)
     , m_pageLogicalHeight(0)
 #ifndef NDEBUG
-    , m_renderer(root)
+    , m_renderer(&root)
 #endif
 {
-    RenderObject* container = root->container();
+    RenderObject* container = root.container();
     FloatPoint absContentPoint = container->localToAbsolute(FloatPoint(), UseTransforms);
     m_paintOffset = LayoutSize(absContentPoint.x(), absContentPoint.y());
 
@@ -169,14 +169,14 @@
     m_columnInfo = m_next->m_columnInfo;
 }
 
-LayoutUnit LayoutState::pageLogicalOffset(const RenderBox* child, LayoutUnit childLogicalOffset) const
+LayoutUnit LayoutState::pageLogicalOffset(const RenderBox& child, const LayoutUnit& childLogicalOffset) const
 {
-    if (child->isHorizontalWritingMode())
+    if (child.isHorizontalWritingMode())
         return m_layoutOffset.height() + childLogicalOffset - m_pageOffset.height();
     return m_layoutOffset.width() + childLogicalOffset - m_pageOffset.width();
 }
 
-void LayoutState::addForcedColumnBreak(RenderBox* child, LayoutUnit childLogicalOffset)
+void LayoutState::addForcedColumnBreak(const RenderBox& child, const LayoutUnit& childLogicalOffset)
 {
     if (!m_columnInfo || m_columnInfo->columnHeight())
         return;
diff --git a/Source/core/rendering/LayoutState.h b/Source/core/rendering/LayoutState.h
index bc38e74..19453de 100644
--- a/Source/core/rendering/LayoutState.h
+++ b/Source/core/rendering/LayoutState.h
@@ -60,8 +60,8 @@
     {
     }
 
-    LayoutState(LayoutState*, RenderBox*, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged, ColumnInfo*);
-    LayoutState(RenderObject*);
+    LayoutState(LayoutState*, RenderBox&, const LayoutSize& offset, LayoutUnit pageHeight, bool pageHeightChanged, ColumnInfo*);
+    explicit LayoutState(RenderObject&);
 
     // LayoutState is allocated out of the rendering partition.
     void* operator new(size_t);
@@ -73,9 +73,9 @@
 
     // The page logical offset is the object's offset from the top of the page in the page progression
     // direction (so an x-offset in vertical text and a y-offset for horizontal text).
-    LayoutUnit pageLogicalOffset(const RenderBox*, LayoutUnit childLogicalOffset) const;
+    LayoutUnit pageLogicalOffset(const RenderBox&, const LayoutUnit& childLogicalOffset) const;
 
-    void addForcedColumnBreak(RenderBox*, LayoutUnit childLogicalOffset);
+    void addForcedColumnBreak(const RenderBox&, const LayoutUnit& childLogicalOffset);
 
     LayoutUnit pageLogicalHeight() const { return m_pageLogicalHeight; }
     bool pageLogicalHeightChanged() const { return m_pageLogicalHeightChanged; }
diff --git a/Source/core/rendering/PartialLayoutState.h b/Source/core/rendering/PartialLayoutState.h
deleted file mode 100644
index 1ac7a32..0000000
--- a/Source/core/rendering/PartialLayoutState.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef PartialLayoutState_h
-#define PartialLayoutState_h
-
-#include "core/rendering/RenderObject.h"
-
-namespace WebCore {
-
-class PartialLayoutState {
-    friend class PartialLayoutDisabler;
-public:
-    PartialLayoutState()
-        : m_shouldStop(false)
-        , m_stopAtRenderer(0)
-        , m_disableCount(0)
-    {
-    }
-
-    // True if we plan to do a partial layout, or are in the process of stopping a partial layout.
-    bool isPartialLayout() const { return m_stopAtRenderer || m_shouldStop; }
-
-    bool isStopping() const { return m_shouldStop; }
-    bool checkPartialLayoutComplete(const RenderObject*);
-    void setStopAtRenderer(const RenderObject* renderer) { m_stopAtRenderer = renderer; }
-    void reset() { m_shouldStop = false; m_stopAtRenderer = 0; }
-
-private:
-    void disable() { ASSERT(!m_shouldStop); m_disableCount++; }
-    void enable() { ASSERT(m_disableCount > 0); m_disableCount--; }
-    const RenderObject* stopAtRenderer() const { return m_disableCount > 0 ? 0 : m_stopAtRenderer; }
-
-    bool m_shouldStop;
-    const RenderObject* m_stopAtRenderer;
-    int m_disableCount;
-};
-
-inline bool PartialLayoutState::checkPartialLayoutComplete(const RenderObject* renderer)
-{
-    if (m_shouldStop)
-        return true;
-
-    if (renderer == stopAtRenderer()) {
-        m_shouldStop = true;
-        m_stopAtRenderer = 0;
-        return true;
-    }
-
-    return false;
-}
-
-class PartialLayoutDisabler {
-    WTF_MAKE_NONCOPYABLE(PartialLayoutDisabler);
-public:
-    PartialLayoutDisabler(PartialLayoutState& partialLayout, bool disable = true)
-        : m_partialLayout(partialLayout)
-        , m_disable(disable)
-    {
-        if (m_disable)
-            m_partialLayout.disable();
-    }
-
-    ~PartialLayoutDisabler()
-    {
-        if (m_disable)
-            m_partialLayout.enable();
-    }
-private:
-    PartialLayoutState& m_partialLayout;
-    bool m_disable;
-};
-
-} // namespace WebCore
-
-#endif // PartialLayoutState_h
diff --git a/Source/core/rendering/RenderApplet.cpp b/Source/core/rendering/RenderApplet.cpp
index be4de73..38d0e4c 100644
--- a/Source/core/rendering/RenderApplet.cpp
+++ b/Source/core/rendering/RenderApplet.cpp
@@ -22,6 +22,7 @@
 #include "config.h"
 #include "core/rendering/RenderApplet.h"
 
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLAppletElement.h"
 
 namespace WebCore {
@@ -30,6 +31,7 @@
     : RenderEmbeddedObject(applet)
 {
     setInline(true);
+    UseCounter::count(document(), UseCounter::HTMLAppletElement);
 }
 
 RenderApplet::~RenderApplet()
diff --git a/Source/core/rendering/RenderBlock.cpp b/Source/core/rendering/RenderBlock.cpp
index bfefb11..5a02765 100644
--- a/Source/core/rendering/RenderBlock.cpp
+++ b/Source/core/rendering/RenderBlock.cpp
@@ -33,8 +33,8 @@
 #include "core/editing/Editor.h"
 #include "core/editing/FrameSelection.h"
 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/FastTextAutosizer.h"
@@ -217,7 +217,6 @@
 
 RenderBlock::~RenderBlock()
 {
-    ResourceLoadPriorityOptimizer::resourceLoadPriorityOptimizer()->removeRenderObject(this);
     if (hasColumns())
         gColumnInfoMap->take(this);
     if (gPercentHeightDescendantsMap)
@@ -1292,9 +1291,6 @@
     // layoutBlock().
     layoutBlock(false);
 
-    if (frameView()->partialLayout().isStopping())
-        return;
-
     // It's safe to check for control clip here, since controls can never be table cells.
     // If we have a lightweight clip, there can never be any overflow from children.
     if (hasControlClip() && m_overflow)
@@ -1401,8 +1397,8 @@
 
     ShapeValue* shapeValue = style()->shapeInside();
     if (shapeValue && shapeValue->image() && shapeValue->image()->data() == image) {
-        ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
-        shapeInsideInfo->dirtyShapeSize();
+        ShapeInsideInfo& shapeInsideInfo = ensureShapeInsideInfo();
+        shapeInsideInfo.markShapeAsDirty();
         markShapeInsideDescendantsForLayout();
     }
 }
@@ -1414,8 +1410,8 @@
         return;
 
     if (shapeInside) {
-        ShapeInsideInfo* shapeInsideInfo = ensureShapeInsideInfo();
-        shapeInsideInfo->dirtyShapeSize();
+        ShapeInsideInfo& shapeInsideInfo = ensureShapeInsideInfo();
+        shapeInsideInfo.markShapeAsDirty();
     } else {
         setShapeInsideInfo(nullptr);
         markShapeInsideDescendantsForLayout();
@@ -1426,7 +1422,7 @@
 {
     ShapeInsideInfo* info = block->shapeInsideInfo();
     if (info)
-        info->setNeedsLayout(info->shapeSizeDirty());
+        info->setNeedsLayout(info->isShapeDirty());
     else
         info = block->layoutShapeInsideInfo();
     return info && info->needsLayout();
@@ -1464,7 +1460,7 @@
         return;
 
     bool percentageLogicalHeightResolvable = percentageLogicalHeightIsResolvableFromBlock(this, false);
-    shapeInsideInfo->setShapeSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : LayoutUnit());
+    shapeInsideInfo->setReferenceBoxLogicalSize(LayoutSize(logicalWidth(), percentageLogicalHeightResolvable ? logicalHeight() : LayoutUnit()));
 }
 
 void RenderBlock::updateRegionsAndShapesAfterChildLayout(RenderFlowThread* flowThread, bool heightChanged)
@@ -1472,7 +1468,7 @@
     // A previous sibling has changed dimension, so we need to relayout the shape with the content
     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
     if (heightChanged && shapeInsideInfo)
-        shapeInsideInfo->dirtyShapeSize();
+        shapeInsideInfo->markShapeAsDirty();
 
     computeRegionRangeForBlock(flowThread);
 }
@@ -1593,51 +1589,6 @@
         || style()->specifiesColumns() || isTableCell() || isTableCaption() || isFieldset() || isWritingModeRoot() || isRoot() || style()->columnSpan();
 }
 
-void RenderBlock::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
-{
-    LayoutUnit startPosition = borderStart() + paddingStart();
-    if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
-        startPosition -= verticalScrollbarWidth();
-    LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
-
-    // Add in our start margin.
-    LayoutUnit childMarginStart = marginStartForChild(child);
-    LayoutUnit newPosition = startPosition + childMarginStart;
-
-    // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats.  They need
-    // to shift over as necessary to dodge any floats that might get in the way.
-    if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
-        newPosition += toRenderBlockFlow(this)->computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
-
-    setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
-}
-
-void RenderBlock::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
-{
-    if (isHorizontalWritingMode()) {
-        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
-            view()->addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
-        child->setX(logicalLeft);
-    } else {
-        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
-            view()->addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
-        child->setY(logicalLeft);
-    }
-}
-
-void RenderBlock::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
-{
-    if (isHorizontalWritingMode()) {
-        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
-            view()->addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
-        child->setY(logicalTop);
-    } else {
-        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
-            view()->addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
-        child->setX(logicalTop);
-    }
-}
-
 void RenderBlock::updateBlockChildDirtyBitsBeforeLayout(bool relayoutChildren, RenderBox* child)
 {
     // FIXME: Technically percentage height objects only need a relayout if their percentage isn't going to be turned into
@@ -1659,8 +1610,8 @@
             if (!o->isOutOfFlowPositioned() && (o->isReplaced() || o->isFloating())) {
                 o->layoutIfNeeded();
                 if (toRenderBox(o)->inlineBoxWrapper()) {
-                    RootInlineBox* box = toRenderBox(o)->inlineBoxWrapper()->root();
-                    lineBoxes.add(box);
+                    RootInlineBox& box = toRenderBox(o)->inlineBoxWrapper()->root();
+                    lineBoxes.add(&box);
                 }
             } else if (o->isText() || (o->isRenderInline() && !walker.atEndOfInline())) {
                 o->clearNeedsLayout();
@@ -1686,12 +1637,12 @@
     if ((!posChildNeedsLayout() && !needsSimplifiedNormalFlowLayout()) || normalChildNeedsLayout() || selfNeedsLayout())
         return false;
 
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     if (needsPositionedMovementLayout() && !tryLayoutDoingPositionedMovementOnly())
         return false;
 
-    FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(document(), this);
+    FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
 
     // Lay out positioned descendants or objects that just need to recompute overflow.
     if (needsSimplifiedNormalFlowLayout())
@@ -1709,7 +1660,7 @@
     // are statically positioned and thus need to move with their absolute ancestors.
     bool canContainFixedPosObjects = canContainFixedPositionObjects();
     if (posChildNeedsLayout() || canContainFixedPosObjects)
-        layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects);
+        layoutPositionedObjects(false, !posChildNeedsLayout() && canContainFixedPosObjects ? LayoutOnlyFixedPositionedObjects : DefaultLayout);
 
     // Recompute our overflow information.
     // FIXME: We could do better here by computing a temporary overflow object from layoutPositionedObjects and only
@@ -1749,9 +1700,10 @@
 
     RenderBox* box = toRenderBox(child);
     if (hasStaticInlinePosition) {
-        LayoutUnit oldLeft = box->logicalLeft();
-        box->updateLogicalWidth();
-        if (box->logicalLeft() != oldLeft)
+        LogicalExtentComputedValues computedValues;
+        box->computeLogicalWidth(computedValues);
+        LayoutUnit newLeft = computedValues.m_position;
+        if (newLeft != box->logicalLeft())
             layoutScope.setChildNeedsLayout(child);
     } else if (hasStaticBlockPosition) {
         LayoutUnit oldTop = box->logicalTop();
@@ -1776,7 +1728,7 @@
     return margin;
 }
 
-void RenderBlock::layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly)
+void RenderBlock::layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior info)
 {
     TrackedRendererListHashSet* positionedDescendants = positionedObjects();
     if (!positionedDescendants)
@@ -1795,7 +1747,7 @@
         // if this is a fixed position element, mark it for layout if it has an abspos ancestor and needs to move with that ancestor, i.e.
         // it has static position.
         markFixedPositionObjectForLayoutIfNeeded(r, layoutScope);
-        if (fixedPositionObjectsOnly) {
+        if (info == LayoutOnlyFixedPositionedObjects) {
             r->layoutIfNeeded();
             continue;
         }
@@ -1831,6 +1783,11 @@
             oldLogicalTop = logicalTopForChild(r);
         }
 
+        // FIXME: We should be able to do a r->setNeedsPositionedMovementLayout() here instead of a full layout. Need
+        // to investigate why it does not trigger the correct invalidations in that case. crbug.com/350756
+        if (info == ForcedLayoutAfterContainingBlockMoved)
+            r->setNeedsLayout();
+
         r->layoutIfNeeded();
 
         // Lay out again if our estimate was wrong.
@@ -1861,7 +1818,7 @@
     if (needsLayout())
         return;
 
-    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(this, logicalTop()) != pageLogicalOffset()))
+    if (view()->layoutState()->pageLogicalHeightChanged() || (view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(*this, logicalTop()) != pageLogicalOffset()))
         layoutScope.setChildNeedsLayout(this);
 }
 
@@ -3090,14 +3047,14 @@
     if (!box)
         return Position();
 
-    if (!box->renderer()->nonPseudoNode())
+    if (!box->renderer().nonPseudoNode())
         return createLegacyEditingPosition(nonPseudoNode(), start ? caretMinOffset() : caretMaxOffset());
 
     if (!box->isInlineTextBox())
-        return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? box->renderer()->caretMinOffset() : box->renderer()->caretMaxOffset());
+        return createLegacyEditingPosition(box->renderer().nonPseudoNode(), start ? box->renderer().caretMinOffset() : box->renderer().caretMaxOffset());
 
     InlineTextBox* textBox = toInlineTextBox(box);
-    return createLegacyEditingPosition(box->renderer()->nonPseudoNode(), start ? textBox->start() : textBox->start() + textBox->len());
+    return createLegacyEditingPosition(box->renderer().nonPseudoNode(), start ? textBox->start() : textBox->start() + textBox->len());
 }
 
 static inline bool isEditingBoundary(RenderObject* ancestor, RenderObject* child)
@@ -3209,12 +3166,12 @@
         }
 
         // pass the box a top position that is inside it
-        LayoutPoint point(pointInLogicalContents.x(), closestBox->root()->blockDirectionPointInLine());
+        LayoutPoint point(pointInLogicalContents.x(), closestBox->root().blockDirectionPointInLine());
         if (!isHorizontalWritingMode())
             point = point.transposedPoint();
-        if (closestBox->renderer()->isReplaced())
-            return positionForPointRespectingEditingBoundaries(this, toRenderBox(closestBox->renderer()), point);
-        return closestBox->renderer()->positionForPoint(point);
+        if (closestBox->renderer().isReplaced())
+            return positionForPointRespectingEditingBoundaries(this, &toRenderBox(closestBox->renderer()), point);
+        return closestBox->renderer().positionForPoint(point);
     }
 
     if (lastRootBoxWithChildren) {
@@ -3662,9 +3619,10 @@
 {
     if (childrenInline()) {
         // FIXME: Remove this const_cast.
-        const_cast<RenderBlock*>(this)->computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
-    } else
+        toRenderBlockFlow(const_cast<RenderBlock*>(this))->computeInlinePreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
+    } else {
         computeBlockPreferredLogicalWidths(minLogicalWidth, maxLogicalWidth);
+    }
 
     maxLogicalWidth = max(minLogicalWidth, maxLogicalWidth);
 
@@ -3728,9 +3686,6 @@
 
 void RenderBlock::adjustIntrinsicLogicalWidthsForColumns(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
 {
-    // FIXME: make this method virtual and move the code to RenderMultiColumnBlock once the old
-    // multicol code is gone.
-
     if (!style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth()) {
         // The min/max intrinsic widths calculated really tell how much space elements need when
         // laid out inside the columns. In order to eventually end up with the desired column width,
@@ -3753,429 +3708,6 @@
     }
 }
 
-struct InlineMinMaxIterator {
-/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
-   inline min/max width calculations.  Note the following about the way it walks:
-   (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
-   (2) We do not drill into the children of floats or replaced elements, since you can't break
-       in the middle of such an element.
-   (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
-       distinct borders/margin/padding that contribute to the min/max width.
-*/
-    RenderObject* parent;
-    RenderObject* current;
-    bool endOfInline;
-
-    InlineMinMaxIterator(RenderObject* p, bool end = false)
-        :parent(p), current(p), endOfInline(end) {}
-
-    RenderObject* next();
-};
-
-RenderObject* InlineMinMaxIterator::next()
-{
-    RenderObject* result = 0;
-    bool oldEndOfInline = endOfInline;
-    endOfInline = false;
-    while (current || current == parent) {
-        if (!oldEndOfInline &&
-            (current == parent ||
-             (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
-            result = current->firstChild();
-        if (!result) {
-            // We hit the end of our inline. (It was empty, e.g., <span></span>.)
-            if (!oldEndOfInline && current->isRenderInline()) {
-                result = current;
-                endOfInline = true;
-                break;
-            }
-
-            while (current && current != parent) {
-                result = current->nextSibling();
-                if (result) break;
-                current = current->parent();
-                if (current && current != parent && current->isRenderInline()) {
-                    result = current;
-                    endOfInline = true;
-                    break;
-                }
-            }
-        }
-
-        if (!result)
-            break;
-
-        if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
-             break;
-
-        current = result;
-        result = 0;
-    }
-
-    // Update our position.
-    current = result;
-    return current;
-}
-
-static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
-{
-    if (cssUnit.type() != Auto)
-        return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
-    return 0;
-}
-
-static LayoutUnit getBorderPaddingMargin(const RenderBoxModelObject* child, bool endOfInline)
-{
-    RenderStyle* childStyle = child->style();
-    if (endOfInline)
-        return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
-               getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
-               child->borderEnd();
-    return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
-               getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
-               child->borderStart();
-}
-
-static inline void stripTrailingSpace(float& inlineMax, float& inlineMin,
-                                      RenderObject* trailingSpaceChild)
-{
-    if (trailingSpaceChild && trailingSpaceChild->isText()) {
-        // Collapse away the trailing space at the end of a block.
-        RenderText* t = toRenderText(trailingSpaceChild);
-        const UChar space = ' ';
-        const Font& font = t->style()->font(); // FIXME: This ignores first-line.
-        float spaceWidth = font.width(RenderBlockFlow::constructTextRun(t, font, &space, 1, t->style(), LTR));
-        inlineMax -= spaceWidth + font.fontDescription().wordSpacing();
-        if (inlineMin > inlineMax)
-            inlineMin = inlineMax;
-    }
-}
-
-static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
-{
-    LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
-    preferredWidth = max(snappedResult, preferredWidth);
-}
-
-// When converting between floating point and LayoutUnits we risk losing precision
-// with each conversion. When this occurs while accumulating our preferred widths,
-// we can wind up with a line width that's larger than our maxPreferredWidth due to
-// pure float accumulation.
-static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
-{
-    return LayoutUnit::fromFloatCeil(value);
-}
-
-
-void RenderBlock::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
-{
-    float inlineMax = 0;
-    float inlineMin = 0;
-
-    RenderStyle* styleToUse = style();
-    RenderBlock* containingBlock = this->containingBlock();
-    LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
-
-    // If we are at the start of a line, we want to ignore all white-space.
-    // Also strip spaces if we previously had text that ended in a trailing space.
-    bool stripFrontSpaces = true;
-    RenderObject* trailingSpaceChild = 0;
-
-    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
-    // very specific cirucumstances (in order to match common WinIE renderings).
-    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
-    bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
-
-    bool autoWrap, oldAutoWrap;
-    autoWrap = oldAutoWrap = styleToUse->autoWrap();
-
-    InlineMinMaxIterator childIterator(this);
-
-    // Only gets added to the max preffered width once.
-    bool addedTextIndent = false;
-    // Signals the text indent was more negative than the min preferred width
-    bool hasRemainingNegativeTextIndent = false;
-
-    LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw);
-    RenderObject* prevFloat = 0;
-    bool isPrevChildInlineFlow = false;
-    bool shouldBreakLineAfterText = false;
-    while (RenderObject* child = childIterator.next()) {
-        autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
-            child->style()->autoWrap();
-
-        if (!child->isBR()) {
-            // Step One: determine whether or not we need to go ahead and
-            // terminate our current line.  Each discrete chunk can become
-            // the new min-width, if it is the widest chunk seen so far, and
-            // it can also become the max-width.
-
-            // Children fall into three categories:
-            // (1) An inline flow object.  These objects always have a min/max of 0,
-            // and are included in the iteration solely so that their margins can
-            // be added in.
-            //
-            // (2) An inline non-text non-flow object, e.g., an inline replaced element.
-            // These objects can always be on a line by themselves, so in this situation
-            // we need to go ahead and break the current line, and then add in our own
-            // margins and min/max width on its own line, and then terminate the line.
-            //
-            // (3) A text object.  Text runs can have breakable characters at the start,
-            // the middle or the end.  They may also lose whitespace off the front if
-            // we're already ignoring whitespace.  In order to compute accurate min-width
-            // information, we need three pieces of information.
-            // (a) the min-width of the first non-breakable run.  Should be 0 if the text string
-            // starts with whitespace.
-            // (b) the min-width of the last non-breakable run. Should be 0 if the text string
-            // ends with whitespace.
-            // (c) the min/max width of the string (trimmed for whitespace).
-            //
-            // If the text string starts with whitespace, then we need to go ahead and
-            // terminate our current line (unless we're already in a whitespace stripping
-            // mode.
-            //
-            // If the text string has a breakable character in the middle, but didn't start
-            // with whitespace, then we add the width of the first non-breakable run and
-            // then end the current line.  We then need to use the intermediate min/max width
-            // values (if any of them are larger than our current min/max).  We then look at
-            // the width of the last non-breakable run and use that to start a new line
-            // (unless we end in whitespace).
-            RenderStyle* childStyle = child->style();
-            float childMin = 0;
-            float childMax = 0;
-
-            if (!child->isText()) {
-                // Case (1) and (2).  Inline replaced and inline flow elements.
-                if (child->isRenderInline()) {
-                    // Add in padding/border/margin from the appropriate side of
-                    // the element.
-                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline);
-                    childMin += bpm;
-                    childMax += bpm;
-
-                    inlineMin += childMin;
-                    inlineMax += childMax;
-
-                    child->clearPreferredLogicalWidthsDirty();
-                } else {
-                    // Inline replaced elts add in their margins to their min/max values.
-                    LayoutUnit margins = 0;
-                    Length startMargin = childStyle->marginStart();
-                    Length endMargin = childStyle->marginEnd();
-                    if (startMargin.isFixed())
-                        margins += adjustFloatForSubPixelLayout(startMargin.value());
-                    if (endMargin.isFixed())
-                        margins += adjustFloatForSubPixelLayout(endMargin.value());
-                    childMin += margins.ceilToFloat();
-                    childMax += margins.ceilToFloat();
-                }
-            }
-
-            if (!child->isRenderInline() && !child->isText()) {
-                // Case (2). Inline replaced elements and floats.
-                // Go ahead and terminate the current line as far as
-                // minwidth is concerned.
-                LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
-                if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
-                    RenderBox* childBox = toRenderBox(child);
-                    LogicalExtentComputedValues computedValues;
-                    childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
-                    childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
-                } else {
-                    childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
-                    childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
-                }
-                childMin += childMinPreferredLogicalWidth.ceilToFloat();
-                childMax += childMaxPreferredLogicalWidth.ceilToFloat();
-
-                bool clearPreviousFloat;
-                if (child->isFloating()) {
-                    clearPreviousFloat = (prevFloat
-                        && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
-                            || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
-                    prevFloat = child;
-                } else
-                    clearPreviousFloat = false;
-
-                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
-                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
-                    updatePreferredWidth(minLogicalWidth, inlineMin);
-                    inlineMin = 0;
-                }
-
-                // If we're supposed to clear the previous float, then terminate maxwidth as well.
-                if (clearPreviousFloat) {
-                    updatePreferredWidth(maxLogicalWidth, inlineMax);
-                    inlineMax = 0;
-                }
-
-                // Add in text-indent.  This is added in only once.
-                if (!addedTextIndent && !child->isFloating()) {
-                    float ceiledTextIndent = textIndent.ceilToFloat();
-                    childMin += ceiledTextIndent;
-                    childMax += ceiledTextIndent;
-
-                    if (childMin < 0)
-                        textIndent = adjustFloatForSubPixelLayout(childMin);
-                    else
-                        addedTextIndent = true;
-                }
-
-                // Add our width to the max.
-                inlineMax += max<float>(0, childMax);
-
-                if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
-                    if (child->isFloating())
-                        updatePreferredWidth(minLogicalWidth, childMin);
-                    else
-                        inlineMin += childMin;
-                } else {
-                    // Now check our line.
-                    updatePreferredWidth(minLogicalWidth, childMin);
-
-                    // Now start a new line.
-                    inlineMin = 0;
-                }
-
-                if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
-                    updatePreferredWidth(minLogicalWidth, inlineMin);
-                    inlineMin = 0;
-                }
-
-                // We are no longer stripping whitespace at the start of
-                // a line.
-                if (!child->isFloating()) {
-                    stripFrontSpaces = false;
-                    trailingSpaceChild = 0;
-                }
-            } else if (child->isText()) {
-                // Case (3). Text.
-                RenderText* t = toRenderText(child);
-
-                if (t->isWordBreak()) {
-                    updatePreferredWidth(minLogicalWidth, inlineMin);
-                    inlineMin = 0;
-                    continue;
-                }
-
-                if (t->style()->hasTextCombine() && t->isCombineText())
-                    toRenderCombineText(t)->combineText();
-
-                // Determine if we have a breakable character.  Pass in
-                // whether or not we should ignore any spaces at the front
-                // of the string.  If those are going to be stripped out,
-                // then they shouldn't be considered in the breakable char
-                // check.
-                bool hasBreakableChar, hasBreak;
-                float firstLineMinWidth, lastLineMinWidth;
-                bool hasBreakableStart, hasBreakableEnd;
-                float firstLineMaxWidth, lastLineMaxWidth;
-                t->trimmedPrefWidths(inlineMax,
-                    firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
-                    hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
-                    childMin, childMax, stripFrontSpaces, styleToUse->direction());
-
-                // This text object will not be rendered, but it may still provide a breaking opportunity.
-                if (!hasBreak && childMax == 0) {
-                    if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
-                        updatePreferredWidth(minLogicalWidth, inlineMin);
-                        inlineMin = 0;
-                    }
-                    continue;
-                }
-
-                if (stripFrontSpaces)
-                    trailingSpaceChild = child;
-                else
-                    trailingSpaceChild = 0;
-
-                // Add in text-indent.  This is added in only once.
-                float ti = 0;
-                if (!addedTextIndent || hasRemainingNegativeTextIndent) {
-                    ti = textIndent.ceilToFloat();
-                    childMin += ti;
-                    firstLineMinWidth += ti;
-
-                    // It the text indent negative and larger than the child minimum, we re-use the remainder
-                    // in future minimum calculations, but using the negative value again on the maximum
-                    // will lead to under-counting the max pref width.
-                    if (!addedTextIndent) {
-                        childMax += ti;
-                        firstLineMaxWidth += ti;
-                        addedTextIndent = true;
-                    }
-
-                    if (childMin < 0) {
-                        textIndent = childMin;
-                        hasRemainingNegativeTextIndent = true;
-                    }
-                }
-
-                // If we have no breakable characters at all,
-                // then this is the easy case. We add ourselves to the current
-                // min and max and continue.
-                if (!hasBreakableChar) {
-                    inlineMin += childMin;
-                } else {
-                    if (hasBreakableStart) {
-                        updatePreferredWidth(minLogicalWidth, inlineMin);
-                    } else {
-                        inlineMin += firstLineMinWidth;
-                        updatePreferredWidth(minLogicalWidth, inlineMin);
-                        childMin -= ti;
-                    }
-
-                    inlineMin = childMin;
-
-                    if (hasBreakableEnd) {
-                        updatePreferredWidth(minLogicalWidth, inlineMin);
-                        inlineMin = 0;
-                        shouldBreakLineAfterText = false;
-                    } else {
-                        updatePreferredWidth(minLogicalWidth, inlineMin);
-                        inlineMin = lastLineMinWidth;
-                        shouldBreakLineAfterText = true;
-                    }
-                }
-
-                if (hasBreak) {
-                    inlineMax += firstLineMaxWidth;
-                    updatePreferredWidth(maxLogicalWidth, inlineMax);
-                    updatePreferredWidth(maxLogicalWidth, childMax);
-                    inlineMax = lastLineMaxWidth;
-                    addedTextIndent = true;
-                } else {
-                    inlineMax += max<float>(0, childMax);
-                }
-            }
-
-            // Ignore spaces after a list marker.
-            if (child->isListMarker())
-                stripFrontSpaces = true;
-        } else {
-            updatePreferredWidth(minLogicalWidth, inlineMin);
-            updatePreferredWidth(maxLogicalWidth, inlineMax);
-            inlineMin = inlineMax = 0;
-            stripFrontSpaces = true;
-            trailingSpaceChild = 0;
-            addedTextIndent = true;
-        }
-
-        if (!child->isText() && child->isRenderInline())
-            isPrevChildInlineFlow = true;
-        else
-            isPrevChildInlineFlow = false;
-
-        oldAutoWrap = autoWrap;
-    }
-
-    if (styleToUse->collapseWhiteSpace())
-        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
-
-    updatePreferredWidth(minLogicalWidth, inlineMin);
-    updatePreferredWidth(maxLogicalWidth, inlineMax);
-}
-
 void RenderBlock::computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const
 {
     RenderStyle* styleToUse = style();
@@ -4282,7 +3814,7 @@
     if (node()->isRootEditableElement())
         return true;
 
-    if (node()->isShadowRoot() && toShadowRoot(node())->host()->hasTagName(inputTag))
+    if (node()->isShadowRoot() && isHTMLInputElement(*toShadowRoot(node())->host()))
         return true;
 
     return false;
@@ -4543,7 +4075,7 @@
         newFirstLetter->setStyle(pseudoStyle);
 
         // Move the first letter into the new renderer.
-        LayoutStateDisabler layoutStateDisabler(view());
+        LayoutStateDisabler layoutStateDisabler(*this);
         while (RenderObject* child = firstLetter->firstChild()) {
             if (child->isText())
                 toRenderText(child)->removeAndDestroyTextBoxes();
@@ -4600,6 +4132,7 @@
             length = scanLength + 1;
     }
 
+    // FIXME: If text.length() is 0, length may still be 1!
     return length;
 }
 
@@ -4700,12 +4233,14 @@
         return;
     }
 
-    if (!currChild->isText() || currChild->isBR())
+    // FIXME: This black-list of disallowed RenderText subclasses is fragile.
+    // Should counter be on this list? What about RenderTextFragment?
+    if (!currChild->isText() || currChild->isBR() || toRenderText(currChild)->isWordBreak())
         return;
 
     // Our layout state is not valid for the repaints we are going to trigger by
     // adding and removing children of firstLetterContainer.
-    LayoutStateDisabler layoutStateDisabler(view());
+    LayoutStateDisabler layoutStateDisabler(*this);
 
     createFirstLetterRenderer(firstLetterBlock, currChild, length);
 }
@@ -4956,12 +4491,13 @@
     if (isAnonymousBlockContinuation()) {
         // FIXME: This is wrong for block-flows that are horizontal.
         // https://bugs.webkit.org/show_bug.cgi?id=46781
-        FloatRect localRect(0, -collapsedMarginBefore(),
-                            width(), height() + collapsedMarginBefore() + collapsedMarginAfter());
+        FloatRect localRect(0, -collapsedMarginBefore().toFloat(),
+            width().toFloat(), (height() + collapsedMarginBefore() + collapsedMarginAfter()).toFloat());
         quads.append(localToAbsoluteQuad(localRect, 0 /* mode */, wasFixed));
         continuation()->absoluteQuads(quads, wasFixed);
-    } else
-        quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed));
+    } else {
+        quads.append(RenderBox::localToAbsoluteQuad(FloatRect(0, 0, width().toFloat(), height().toFloat()), 0 /* mode */, wasFixed));
+    }
 }
 
 LayoutRect RenderBlock::rectWithOutlineForRepaint(const RenderLayerModelObject* repaintContainer, LayoutUnit outlineWidth) const
@@ -5028,10 +4564,10 @@
 
             LayoutUnit myRight = caretRect.maxX();
             // FIXME: why call localToAbsoluteForContent() twice here, too?
-            FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight, 0));
+            FloatPoint absRightPoint = localToAbsolute(FloatPoint(myRight.toFloat(), 0));
 
             LayoutUnit containerRight = containingBlock()->x() + containingBlockLogicalWidthForContent();
-            FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight, 0));
+            FloatPoint absContainerPoint = localToAbsolute(FloatPoint(containerRight.toFloat(), 0));
 
             *extraWidthToEndOfLine = absContainerPoint.x() - absRightPoint.x();
         }
@@ -5052,8 +4588,8 @@
         // FIXME: This is wrong for block-flows that are horizontal.
         // https://bugs.webkit.org/show_bug.cgi?id=46781
         bool prevInlineHasLineBox = toRenderInline(inlineElementContinuation()->node()->renderer())->firstLineBox();
-        float topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
-        float bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
+        LayoutUnit topMargin = prevInlineHasLineBox ? collapsedMarginBefore() : LayoutUnit();
+        LayoutUnit bottomMargin = nextInlineHasLineBox ? collapsedMarginAfter() : LayoutUnit();
         LayoutRect rect(additionalOffset.x(), additionalOffset.y() - topMargin, width(), height() + topMargin + bottomMargin);
         if (!rect.isEmpty())
             rects.append(pixelSnappedIntRect(rect));
@@ -5077,7 +4613,7 @@
                 if (box->layer())
                     pos = curr->localToContainerPoint(FloatPoint(), paintContainer);
                 else
-                    pos = FloatPoint(additionalOffset.x() + box->x(), additionalOffset.y() + box->y());
+                    pos = FloatPoint((additionalOffset.x() + box->x()).toFloat(), (additionalOffset.y() + box->y()).toFloat()); // FIXME: Snap offsets? crbug.com/350474
                 box->addFocusRingRects(rects, flooredLayoutPoint(pos), paintContainer);
             }
         }
@@ -5173,7 +4709,7 @@
 
 LayoutUnit RenderBlock::adjustForUnsplittableChild(RenderBox* child, LayoutUnit logicalOffset, bool includeMargins)
 {
-    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns();
+    bool checkColumnBreaks = view()->layoutState()->isPaginatingColumns() || flowThreadContainingBlock();
     bool checkPageBreaks = !checkColumnBreaks && view()->layoutState()->m_pageLogicalHeight;
     bool isUnsplittable = child->isUnsplittableForPagination() || (checkColumnBreaks && child->style()->columnBreakInside() == PBAVOID)
         || (checkPageBreaks && child->style()->pageBreakInside() == PBAVOID);
diff --git a/Source/core/rendering/RenderBlock.h b/Source/core/rendering/RenderBlock.h
index 16e2057..b11db74 100644
--- a/Source/core/rendering/RenderBlock.h
+++ b/Source/core/rendering/RenderBlock.h
@@ -116,6 +116,8 @@
         return objects && !objects->isEmpty();
     }
 
+    virtual bool visibleForTouchAction() const OVERRIDE FINAL { return true; }
+
     void addPercentHeightDescendant(RenderBox*);
     static void removePercentHeightDescendant(RenderBox*);
     TrackedRendererListHashSet* percentHeightDescendants() const;
@@ -225,12 +227,10 @@
     void setPageLogicalOffset(LayoutUnit);
 
     // Accessors for logical width/height and margins in the containing block's block-flow direction.
-    enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
     LayoutUnit logicalWidthForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->width() : child->height(); }
     LayoutUnit logicalHeightForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->height() : child->width(); }
+    LayoutSize logicalSizeForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->size() : child->size().transposedSize(); }
     LayoutUnit logicalTopForChild(const RenderBox* child) const { return isHorizontalWritingMode() ? child->y() : child->x(); }
-    void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
-    void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
     LayoutUnit marginBeforeForChild(const RenderBoxModelObject* child) const { return child->marginBefore(style()); }
     LayoutUnit marginAfterForChild(const RenderBoxModelObject* child) const { return child->marginAfter(style()); }
     LayoutUnit marginStartForChild(const RenderBoxModelObject* child) const { return child->marginStart(style()); }
@@ -257,15 +257,15 @@
     void showLineTreeAndMark(const InlineBox* = 0, const char* = 0, const InlineBox* = 0, const char* = 0, const RenderObject* = 0) const;
 #endif
 
-    ShapeInsideInfo* ensureShapeInsideInfo()
+    ShapeInsideInfo& ensureShapeInsideInfo()
     {
         if (!m_rareData || !m_rareData->m_shapeInsideInfo)
-            setShapeInsideInfo(ShapeInsideInfo::createInfo(this));
-        return m_rareData->m_shapeInsideInfo.get();
+            setShapeInsideInfo(ShapeInsideInfo::createInfo(*this));
+        return *m_rareData->m_shapeInsideInfo;
     }
     ShapeInsideInfo* shapeInsideInfo() const
     {
-        return m_rareData && m_rareData->m_shapeInsideInfo && ShapeInsideInfo::isEnabledFor(this) ? m_rareData->m_shapeInsideInfo.get() : 0;
+        return m_rareData && m_rareData->m_shapeInsideInfo && ShapeInsideInfo::isEnabledFor(*this) ? m_rareData->m_shapeInsideInfo.get() : 0;
     }
     void setShapeInsideInfo(PassOwnPtr<ShapeInsideInfo> value)
     {
@@ -290,15 +290,19 @@
     virtual void layout() OVERRIDE;
     virtual bool updateImageLoadingPriorities() OVERRIDE FINAL;
 
-    void layoutPositionedObjects(bool relayoutChildren, bool fixedPositionObjectsOnly = false);
+    enum PositionedLayoutBehavior {
+        DefaultLayout,
+        LayoutOnlyFixedPositionedObjects,
+        ForcedLayoutAfterContainingBlockMoved
+    };
+
+    void layoutPositionedObjects(bool relayoutChildren, PositionedLayoutBehavior = DefaultLayout);
     void markFixedPositionObjectForLayoutIfNeeded(RenderObject* child, SubtreeLayoutScope&);
 
     LayoutUnit marginIntrinsicLogicalWidthForChild(RenderBox* child) const;
 
     int beforeMarginInLineDirection(LineDirectionMode) const;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return true; };
-
     virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
     virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
     virtual void paintChildren(PaintInfo&, const LayoutPoint&);
@@ -389,9 +393,6 @@
     void insertIntoTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
     static void removeFromTrackedRendererMaps(RenderBox* descendant, TrackedDescendantsMap*&, TrackedContainerMap*&);
 
-    // Called to lay out the legend for a fieldset or the ruby text of a ruby run.
-    virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/, SubtreeLayoutScope&) { return 0; }
-
     void createFirstLetterRenderer(RenderObject* firstLetterBlock, RenderObject* currentChild, unsigned length);
     void updateFirstLetterStyle(RenderObject* firstLetterBlock, RenderObject* firstLetterContainer);
 
@@ -417,8 +418,6 @@
 
     virtual bool isPointInOverflowControl(HitTestResult&, const LayoutPoint& locationInContainer, const LayoutPoint& accumulatedOffset);
 
-    // FIXME: Make this method const so we can remove the const_cast in computeIntrinsicLogicalWidths.
-    void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
     void computeBlockPreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const;
 
     // Obtains the nearest enclosing block (including this block) that contributes a first-line style to our inline
@@ -484,8 +483,6 @@
     // End helper functions and structs used by layoutBlockChildren.
 
 protected:
-    void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
-
     // Returns the logicalOffset at the top of the next page. If the offset passed in is already at the top of the current page,
     // then nextPageLogicalTop with ExcludePageBoundary will still move to the top of the next page. nextPageLogicalTop with
     // IncludePageBoundary set will not.
diff --git a/Source/core/rendering/RenderBlockFlow.cpp b/Source/core/rendering/RenderBlockFlow.cpp
index a7ff4f4..2ae2cbd 100644
--- a/Source/core/rendering/RenderBlockFlow.cpp
+++ b/Source/core/rendering/RenderBlockFlow.cpp
@@ -39,7 +39,7 @@
 #include "core/rendering/LayoutRepainter.h"
 #include "core/rendering/RenderFlowThread.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
+#include "core/rendering/RenderMultiColumnFlowThread.h"
 #include "core/rendering/RenderText.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/line/LineWidth.h"
@@ -176,10 +176,37 @@
     return toRenderBlockFlow(createAnonymousWithParentRendererAndDisplay(this, BLOCK));
 }
 
+RenderObject* RenderBlockFlow::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
+{
+    RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread();
+    if (!flowThread)
+        return 0;
+    setLogicalTopForChild(flowThread, borderBefore() + paddingBefore());
+    flowThread->layoutColumns(relayoutChildren, layoutScope);
+    determineLogicalLeftPositionForChild(flowThread);
+    return flowThread;
+}
+
+bool RenderBlockFlow::updateLogicalWidthAndColumnWidth()
+{
+    bool relayoutChildren = RenderBlock::updateLogicalWidthAndColumnWidth();
+    if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
+        if (flowThread->computeColumnCountAndWidth())
+            return true;
+    }
+    return relayoutChildren;
+}
+
 void RenderBlockFlow::checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight)
 {
-    ColumnInfo* colInfo = columnInfo();
-    if (hasColumns()) {
+    if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
+        // We don't actually update any of the variables. We just subclassed to adjust our column height.
+        updateLogicalHeight();
+        flowThread->setColumnHeightAvailable(std::max<LayoutUnit>(contentLogicalHeight(), 0));
+        setLogicalHeight(0);
+    } else if (hasColumns()) {
+        ColumnInfo* colInfo = columnInfo();
+
         if (!pageLogicalHeight) {
             LayoutUnit oldLogicalHeight = logicalHeight();
             setLogicalHeight(0);
@@ -219,7 +246,7 @@
         // maximum page break distance.
         if (!pageLogicalHeight) {
             LayoutUnit distanceBetweenBreaks = max<LayoutUnit>(colInfo->maximumDistanceBetweenForcedBreaks(),
-                view()->layoutState()->pageLogicalOffset(this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
+                view()->layoutState()->pageLogicalOffset(*this, borderBefore() + paddingBefore() + layoutOverflowLogicalBottom) - colInfo->forcedBreakOffset());
             columnHeight = max(colInfo->minimumColumnHeight(), distanceBetweenBreaks);
         }
     } else if (layoutOverflowLogicalBottom > boundedMultiply(pageLogicalHeight, desiredColumnCount)) {
@@ -282,6 +309,7 @@
 {
     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
 
+    LayoutUnit oldLeft = logicalLeft();
     if (updateLogicalWidthAndColumnWidth())
         relayoutChildren = true;
 
@@ -291,8 +319,7 @@
     bool hasSpecifiedPageLogicalHeight = false;
     checkForPaginationLogicalHeightChange(pageLogicalHeight, pageLogicalHeightChanged, hasSpecifiedPageLogicalHeight);
 
-    RenderView* renderView = view();
-    LayoutStateMaintainer statePusher(renderView, this, locationOffset(), hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo());
+    LayoutStateMaintainer statePusher(*this, locationOffset(), pageLogicalHeight, pageLogicalHeightChanged, columnInfo());
 
     // Regions changing widths can force us to relayout our children.
     RenderFlowThread* flowThread = flowThreadContainingBlock();
@@ -327,24 +354,19 @@
     if (!firstChild() && !isAnonymousBlock())
         setChildrenInline(true);
 
-    FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(document(), this);
+    FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
 
     if (childrenInline())
         layoutInlineChildren(relayoutChildren, m_repaintLogicalTop, m_repaintLogicalBottom, afterEdge);
     else
         layoutBlockChildren(relayoutChildren, maxFloatLogicalBottom, layoutScope, beforeEdge, afterEdge);
 
-    if (frameView()->partialLayout().isStopping()) {
-        statePusher.pop();
-        return true;
-    }
-
     // Expand our intrinsic height to encompass floats.
     if (lowestFloatLogicalBottom() > (logicalHeight() - afterEdge) && createsBlockFormattingContext())
         setLogicalHeight(lowestFloatLogicalBottom() + afterEdge);
 
-    if (isRenderMultiColumnBlock()) {
-        if (toRenderMultiColumnBlock(this)->shouldRelayoutMultiColumnBlock()) {
+    if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread()) {
+        if (flowThread->recalculateColumnHeights()) {
             setChildNeedsLayout(MarkOnlyThis);
             statePusher.pop();
             return false;
@@ -399,7 +421,7 @@
     if (heightChanged)
         relayoutChildren = true;
 
-    layoutPositionedObjects(relayoutChildren || isRoot());
+    layoutPositionedObjects(relayoutChildren || isRoot(), oldLeft != logicalLeft() ? ForcedLayoutAfterContainingBlockMoved : DefaultLayout);
 
     updateRegionsAndShapesAfterChildLayout(flowThread, heightChanged);
 
@@ -410,11 +432,9 @@
 
     fitBorderToLinesIfNeeded();
 
-    if (frameView()->partialLayout().isStopping())
-        return true;
-
+    RenderView* renderView = view();
     if (renderView->layoutState()->m_pageLogicalHeight)
-        setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(this, logicalTop()));
+        setPageLogicalOffset(renderView->layoutState()->pageLogicalOffset(*this, logicalTop()));
 
     updateLayerTransform();
 
@@ -426,7 +446,7 @@
     bool didFullRepaint = repainter.repaintAfterLayout();
     if (!didFullRepaint && m_repaintLogicalTop != m_repaintLogicalBottom && (style()->visibility() == VISIBLE || enclosingLayer()->hasVisibleContent())) {
         if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
-            setShouldRepaintOverflowIfNeeded(true);
+            setShouldRepaintOverflow(true);
         else
             repaintOverflow();
     }
@@ -435,6 +455,51 @@
     return true;
 }
 
+void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode applyDelta)
+{
+    LayoutUnit startPosition = borderStart() + paddingStart();
+    if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+        startPosition -= verticalScrollbarWidth();
+    LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
+
+    // Add in our start margin.
+    LayoutUnit childMarginStart = marginStartForChild(child);
+    LayoutUnit newPosition = startPosition + childMarginStart;
+
+    // Some objects (e.g., tables, horizontal rules, overflow:auto blocks) avoid floats. They need
+    // to shift over as necessary to dodge any floats that might get in the way.
+    if (child->avoidsFloats() && containsFloats() && !flowThreadContainingBlock())
+        newPosition += computeStartPositionDeltaForChildAvoidingFloats(child, marginStartForChild(child));
+
+    setLogicalLeftForChild(child, style()->isLeftToRightDirection() ? newPosition : totalAvailableLogicalWidth - newPosition - logicalWidthForChild(child), applyDelta);
+}
+
+void RenderBlockFlow::setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode applyDelta)
+{
+    if (isHorizontalWritingMode()) {
+        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+            view()->addLayoutDelta(LayoutSize(child->x() - logicalLeft, 0));
+        child->setX(logicalLeft);
+    } else {
+        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+            view()->addLayoutDelta(LayoutSize(0, child->y() - logicalLeft));
+        child->setY(logicalLeft);
+    }
+}
+
+void RenderBlockFlow::setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode applyDelta)
+{
+    if (isHorizontalWritingMode()) {
+        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+            view()->addLayoutDelta(LayoutSize(0, child->y() - logicalTop));
+        child->setY(logicalTop);
+    } else {
+        if (applyDelta == ApplyLayoutDelta && !RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
+            view()->addLayoutDelta(LayoutSize(child->x() - logicalTop, 0));
+        child->setX(logicalTop);
+    }
+}
+
 void RenderBlockFlow::layoutBlockChild(RenderBox* child, MarginInfo& marginInfo, LayoutUnit& previousFloatLogicalBottom, LayoutUnit& maxFloatLogicalBottom)
 {
     LayoutUnit oldPosMarginBefore = maxPositiveMarginBefore();
@@ -494,9 +559,6 @@
     if (childNeededLayout)
         child->layout();
 
-    if (frameView()->partialLayout().isStopping())
-        return;
-
     // Cache if we are at the top of the block right now.
     bool atBeforeSideOfBlock = marginInfo.atBeforeSideOfBlock();
     bool childIsSelfCollapsing = child->isSelfCollapsingBlock();
@@ -867,11 +929,6 @@
         // Lay out the child.
         layoutBlockChild(child, marginInfo, previousFloatLogicalBottom, maxFloatLogicalBottom);
         lastNormalFlowChild = child;
-
-        // If doing a partial layout and the child was the target renderer, early exit here.
-        if (frameView()->partialLayout().checkPartialLayoutComplete(child))
-            return;
-
     }
 
     // Now do the handling of the bottom of the block, adding in our bottom border/padding and
@@ -1269,7 +1326,7 @@
     // Give up if in quirks mode and we're a body/table cell and the top margin of the child box is quirky.
     // Give up if the child specified -webkit-margin-collapse: separate that prevents collapsing.
     // FIXME: Use writing mode independent accessor for marginBeforeCollapse.
-    if ((document().inQuirksMode() && hasMarginAfterQuirk(child) && (isTableCell() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE)
+    if ((document().inQuirksMode() && hasMarginBeforeQuirk(child) && (isTableCell() || isBody())) || child->style()->marginBeforeCollapse() == MSEPARATE)
         return;
 
     // The margins are discarded by a child that specified -webkit-margin-collapse: discard.
@@ -1560,7 +1617,7 @@
                 if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset, child, true, &offsetBreakAdjustment))
                     return logicalOffset + offsetBreakAdjustment;
             } else {
-                view()->layoutState()->addForcedColumnBreak(child, logicalOffset);
+                view()->layoutState()->addForcedColumnBreak(*child, logicalOffset);
             }
         }
         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
@@ -1589,7 +1646,7 @@
                 if (flowThread->addForcedRegionBreak(offsetFromLogicalTopOfFirstPage() + logicalOffset + marginOffset, child, false, &offsetBreakAdjustment))
                     return logicalOffset + marginOffset + offsetBreakAdjustment;
             } else {
-                view()->layoutState()->addForcedColumnBreak(child, logicalOffset);
+                view()->layoutState()->addForcedColumnBreak(*child, logicalOffset);
             }
         }
         return nextPageLogicalTop(logicalOffset, IncludePageBoundary);
@@ -1809,6 +1866,8 @@
         parentBlockFlow->markAllDescendantsWithFloatsForLayout();
         parentBlockFlow->markSiblingsWithFloatsForLayout();
     }
+
+    createMultiColumnFlowThreadIfNeeded();
 }
 
 void RenderBlockFlow::updateStaticInlinePositionForChild(RenderBox* child, LayoutUnit logicalTop)
@@ -1824,6 +1883,13 @@
     child->layer()->setStaticInlinePosition(inlinePosition);
 }
 
+void RenderBlockFlow::addChild(RenderObject* newChild, RenderObject* beforeChild)
+{
+    if (RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread())
+        return flowThread->addChild(newChild, beforeChild);
+    RenderBlock::addChild(newChild, beforeChild);
+}
+
 void RenderBlockFlow::moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert)
 {
     RenderBlockFlow* toBlockFlow = toRenderBlockFlow(toBlock);
@@ -1875,7 +1941,7 @@
 
     // FIXME: Avoid disabling LayoutState. At the very least, don't disable it for floats originating
     // in this block. Better yet would be to push extra state for the containers of other floats.
-    LayoutStateDisabler layoutStateDisabler(view());
+    LayoutStateDisabler layoutStateDisabler(*this);
     const FloatingObjectSet& floatingObjectSet = m_floatingObjects->set();
     FloatingObjectSetIterator end = floatingObjectSet.end();
     for (FloatingObjectSetIterator it = floatingObjectSet.begin(); it != end; ++it) {
@@ -1934,6 +2000,9 @@
 
     // Make sure the rect is still non-empty after intersecting for overflow above
     if (!repaintRect.isEmpty()) {
+        // Hits in media/event-attributes.html
+        DisableCompositingQueryAsserts disabler;
+
         repaintRectangle(repaintRect); // We need to do a partial repaint of our content.
         if (hasReflection())
             repaintRectangle(reflectedRect(repaintRect));
@@ -2093,7 +2162,7 @@
 
         SegmentList segments = shapeInsideInfo->computeSegmentsForLine(logicalTopOffset, floatLogicalSize.height());
         // FIXME: Add support for shapes with multiple segments.
-        if (segments.size() == 1) {
+        if (segments.size() >= 1) {
             // The segment offsets are relative to the content box.
             logicalRightOffset = logicalLeftOffset + segments[0].logicalRight;
             logicalLeftOffset += segments[0].logicalLeft;
@@ -2341,7 +2410,7 @@
         m_floatingObjects->addPlacedObject(floatingObject);
 
         if (ShapeOutsideInfo* shapeOutside = childBox->shapeOutsideInfo())
-            shapeOutside->setShapeSize(logicalWidthForChild(childBox), logicalHeightForChild(childBox));
+            shapeOutside->setReferenceBoxLogicalSize(logicalSizeForChild(childBox));
 
         // If the child moved, we have to repaint it.
         if (!RuntimeEnabledFeatures::repaintAfterLayoutEnabled()
@@ -2724,9 +2793,36 @@
         expansion, flags);
 }
 
+TextRun RenderBlockFlow::constructTextRun(RenderObject* context, const Font& font, const RenderText* text, unsigned offset, unsigned length, RenderStyle* style, TextRun::ExpansionBehavior expansion)
+{
+    ASSERT(offset + length <= text->textLength());
+    TextRun run = text->is8Bit()
+        ? constructTextRunInternal(context, font, text->characters8() + offset, length, style, LTR, expansion)
+        : constructTextRunInternal(context, font, text->characters16() + offset, length, style, LTR, expansion);
+    bool hasStrongDirectionality;
+    run.setDirection(directionForRun(run, hasStrongDirectionality));
+    return run;
+}
+
 RootInlineBox* RenderBlockFlow::createRootInlineBox()
 {
-    return new RootInlineBox(this);
+    return new RootInlineBox(*this);
+}
+
+void RenderBlockFlow::createMultiColumnFlowThreadIfNeeded()
+{
+    if ((style()->hasAutoColumnCount() && style()->hasAutoColumnWidth()) || !document().regionBasedColumnsEnabled())
+        return;
+
+    if (multiColumnFlowThread())
+        return;
+
+    setChildrenInline(false);
+    RenderMultiColumnFlowThread* flowThread = RenderMultiColumnFlowThread::createAnonymous(document(), style());
+    RenderBlock::addChild(flowThread);
+    RenderBlockFlowRareData& rareData = ensureRareData();
+    ASSERT(!rareData.m_multiColumnFlowThread);
+    rareData.m_multiColumnFlowThread = flowThread;
 }
 
 RenderBlockFlow::RenderBlockFlowRareData& RenderBlockFlow::ensureRareData()
diff --git a/Source/core/rendering/RenderBlockFlow.h b/Source/core/rendering/RenderBlockFlow.h
index d769175..84f9136 100644
--- a/Source/core/rendering/RenderBlockFlow.h
+++ b/Source/core/rendering/RenderBlockFlow.h
@@ -46,6 +46,7 @@
 class MarginInfo;
 class LineBreaker;
 class LineWidth;
+class RenderMultiColumnFlowThread;
 
 class RenderBlockFlow : public RenderBlock {
 public:
@@ -112,6 +113,8 @@
 
     void removeFloatingObjects();
 
+    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
+
     void moveAllChildrenIncludingFloatsTo(RenderBlock* toBlock, bool fullRemoveInsert);
 
     bool generatesLineBoxesForInlineChild(RenderObject*);
@@ -171,6 +174,8 @@
     // Direction resolved from string value.
     static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*,
         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, TextRunFlags = DefaultTextRunFlags);
+    static TextRun constructTextRun(RenderObject* context, const Font&, const RenderText*, unsigned offset, unsigned length, RenderStyle*,
+        TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
 
     // Explicit direction.
     static TextRun constructTextRun(RenderObject* context, const Font&, const String&, RenderStyle*, TextDirection,
@@ -191,8 +196,13 @@
     static TextRun constructTextRun(RenderObject* context, const Font&, const UChar* characters, int length, RenderStyle*, TextDirection,
         TextRun::ExpansionBehavior = TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion);
 
+    RenderMultiColumnFlowThread* multiColumnFlowThread() const { return m_rareData ? m_rareData->m_multiColumnFlowThread : 0; }
+
     void addOverflowFromInlineChildren();
 
+    // FIXME: This should be const to avoid a const_cast, but can modify child dirty bits and RenderCombineText
+    void computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth);
+
     GapRects inlineSelectionGaps(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock,
         LayoutUnit& lastLogicalTop, LayoutUnit& lastLogicalLeft, LayoutUnit& lastLogicalRight, const PaintInfo*);
 protected:
@@ -215,6 +225,15 @@
         return adjustLogicalLeftOffsetForLine(logicalLeftFloatOffsetForLine(logicalTop, fixedOffset, logicalHeight), applyTextIndent);
     }
 
+    virtual RenderObject* layoutSpecialExcludedChild(bool /*relayoutChildren*/, SubtreeLayoutScope&);
+    virtual bool updateLogicalWidthAndColumnWidth() OVERRIDE;
+
+    // These functions optionally update LayoutState's layoutDelta, which is used to ensure they're repainted correctly when moved
+    enum ApplyLayoutDeltaMode { ApplyLayoutDelta, DoNotApplyLayoutDelta };
+    void setLogicalLeftForChild(RenderBox* child, LayoutUnit logicalLeft, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
+    void setLogicalTopForChild(RenderBox* child, LayoutUnit logicalTop, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
+    void determineLogicalLeftPositionForChild(RenderBox* child, ApplyLayoutDeltaMode = DoNotApplyLayoutDelta);
+
 private:
     bool layoutBlockFlow(bool relayoutChildren, LayoutUnit& pageLogicalHeight, SubtreeLayoutScope&);
     void layoutBlockChildren(bool relayoutChildren, LayoutUnit& maxFloatLogicalBottom, SubtreeLayoutScope&, LayoutUnit beforeEdge, LayoutUnit afterEdge);
@@ -282,8 +301,10 @@
 
     virtual RootInlineBox* createRootInlineBox(); // Subclassed by SVG
 
+    void createMultiColumnFlowThreadIfNeeded();
+
     void updateLogicalWidthForAlignment(const ETextAlign&, const RootInlineBox*, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount);
-    virtual void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
+    void checkForPaginationLogicalHeightChange(LayoutUnit& pageLogicalHeight, bool& pageLogicalHeightChanged, bool& hasSpecifiedPageLogicalHeight);
     bool shouldRelayoutForPagination(LayoutUnit& pageLogicalHeight, LayoutUnit layoutOverflowLogicalBottom) const;
     void setColumnCountAndHeight(unsigned count, LayoutUnit pageLogicalHeight);
 
@@ -334,6 +355,7 @@
     public:
         RenderBlockFlowRareData(const RenderBlockFlow* block)
             : m_margins(positiveMarginBeforeDefault(block), negativeMarginBeforeDefault(block), positiveMarginAfterDefault(block), negativeMarginAfterDefault(block))
+            , m_multiColumnFlowThread(0)
             , m_discardMarginBefore(false)
             , m_discardMarginAfter(false)
         {
@@ -358,6 +380,8 @@
 
         MarginValues m_margins;
 
+        RenderMultiColumnFlowThread* m_multiColumnFlowThread;
+
         bool m_discardMarginBefore : 1;
         bool m_discardMarginAfter : 1;
     };
diff --git a/Source/core/rendering/RenderBlockLineLayout.cpp b/Source/core/rendering/RenderBlockLineLayout.cpp
index 89f3a70..5666a46 100644
--- a/Source/core/rendering/RenderBlockLineLayout.cpp
+++ b/Source/core/rendering/RenderBlockLineLayout.cpp
@@ -256,7 +256,7 @@
         if (!box)
             continue;
 
-        if (!rootHasSelectedChildren && box->renderer()->selectionState() != RenderObject::SelectionNone)
+        if (!rootHasSelectedChildren && box->renderer().selectionState() != RenderObject::SelectionNone)
             rootHasSelectedChildren = true;
 
         // If we have no parent box yet, or if the run is not simply a sibling,
@@ -293,7 +293,7 @@
     // Set the m_selectedChildren flag on the root inline box if one of the leaf inline box
     // from the bidi runs walk above has a selection state.
     if (rootHasSelectedChildren)
-        lastLineBox()->root()->setHasSelectedChildren(true);
+        lastLineBox()->root().setHasSelectedChildren(true);
 
     // Set bits on our inline flow boxes that indicate which sides should
     // paint borders/margins/padding.  This knowledge will ultimately be used when
@@ -536,7 +536,7 @@
 void RenderBlockFlow::updateLogicalWidthForAlignment(const ETextAlign& textAlign, const RootInlineBox* rootInlineBox, BidiRun* trailingSpaceRun, float& logicalLeft, float& totalLogicalWidth, float& availableLogicalWidth, int expansionOpportunityCount)
 {
     TextDirection direction;
-    if (rootInlineBox && rootInlineBox->renderer()->style()->unicodeBidi() == Plaintext)
+    if (rootInlineBox && rootInlineBox->renderer().style()->unicodeBidi() == Plaintext)
         direction = rootInlineBox->direction();
     else
         direction = style()->direction();
@@ -586,10 +586,10 @@
 static void updateLogicalInlinePositions(RenderBlockFlow* block, float& lineLogicalLeft, float& lineLogicalRight, float& availableLogicalWidth, bool firstLine, IndentTextOrNot shouldIndentText, LayoutUnit boxLogicalHeight)
 {
     LayoutUnit lineLogicalHeight = block->minLineHeightForReplacedRenderer(firstLine, boxLogicalHeight);
-    lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
+    lineLogicalLeft = block->logicalLeftOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
     // FIXME: This shouldn't be pixel snapped once multicolumn layout has been updated to correctly carry over subpixel values.
     // https://bugs.webkit.org/show_bug.cgi?id=105461
-    lineLogicalRight = block->pixelSnappedLogicalRightOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight);
+    lineLogicalRight = block->pixelSnappedLogicalRightOffsetForLine(block->logicalHeight(), shouldIndentText == IndentText, lineLogicalHeight).toFloat();
     availableLogicalWidth = lineLogicalRight - lineLogicalLeft;
 }
 
@@ -657,7 +657,7 @@
     WordMeasurements& wordMeasurements)
 {
     bool needsWordSpacing = false;
-    float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth();
+    float totalLogicalWidth = lineBox->getFlowSpacingLogicalWidth().toFloat();
     unsigned expansionOpportunityCount = 0;
     bool isAfterExpansion = true;
     Vector<unsigned, 16> expansionOpportunities;
@@ -701,7 +701,7 @@
                 RenderBox* renderBox = toRenderBox(r->m_object);
                 if (renderBox->isRubyRun())
                     setMarginsForRubyRun(r, toRenderRubyRun(renderBox), previousObject, lineInfo);
-                r->m_box->setLogicalWidth(logicalWidthForChild(renderBox));
+                r->m_box->setLogicalWidth(logicalWidthForChild(renderBox).toFloat());
                 totalLogicalWidth += marginStartForChild(renderBox) + marginEndForChild(renderBox);
             }
         }
@@ -736,7 +736,7 @@
         // Align positioned boxes with the top of the line box.  This is
         // a reasonable approximation of an appropriate y position.
         if (r->m_object->isOutOfFlowPositioned())
-            r->m_box->setLogicalTop(logicalHeight());
+            r->m_box->setLogicalTop(logicalHeight().toFloat());
 
         // Position is used to properly position both replaced elements and
         // to update the static normal flow x/y of positioned elements.
@@ -845,7 +845,7 @@
         // If we encountered any nested isolate runs, just move them
         // to the top resolver's list for later processing.
         if (!isolatedResolver.isolatedRuns().isEmpty()) {
-            topResolver.isolatedRuns().append(isolatedResolver.isolatedRuns());
+            topResolver.isolatedRuns().appendVector(isolatedResolver.isolatedRuns());
             currentRoot = isolatedInline;
             restoreIsolatedMidpointStates(topResolver, isolatedResolver);
         }
@@ -977,9 +977,9 @@
         // adjust the height accordingly.
         // A line break can be either the first or the last object on a line, depending on its direction.
         if (InlineBox* lastLeafChild = lastRootBox()->lastLeafChild()) {
-            RenderObject* lastObject = lastLeafChild->renderer();
+            RenderObject* lastObject = &lastLeafChild->renderer();
             if (!lastObject->isBR())
-                lastObject = lastRootBox()->firstLeafChild()->renderer();
+                lastObject = &lastRootBox()->firstLeafChild()->renderer();
             if (lastObject->isBR()) {
                 EClear clear = lastObject->style()->clear();
                 if (clear != CNONE)
@@ -1033,7 +1033,7 @@
     LayoutUnit shapeLogicalBottom = shapeInsideInfo->shapeLogicalBottom();
     LayoutUnit shapeContainingBlockHeight = shapeInsideInfo->shapeContainingBlockHeight();
 
-    bool isOverflowPositionedAlready = (shapeContainingBlockHeight - shapeInsideInfo->owner()->borderAndPaddingAfter() + lineHeight) <= lineTop;
+    bool isOverflowPositionedAlready = (shapeContainingBlockHeight - shapeInsideInfo->owner().borderAndPaddingAfter() + lineHeight) <= lineTop;
 
     // If the last line overlaps with the shape, we don't need the segments anymore
     if (lineTop < shapeLogicalBottom && shapeLogicalBottom < logicalLineBottom)
@@ -1041,7 +1041,7 @@
     if (logicalLineBottom <= shapeLogicalBottom || !shapeContainingBlockHeight || isOverflowPositionedAlready)
         return;
 
-    LayoutUnit newLogicalHeight = block->logicalHeight() + (shapeContainingBlockHeight - (lineTop + shapeInsideInfo->owner()->borderAndPaddingAfter()));
+    LayoutUnit newLogicalHeight = block->logicalHeight() + (shapeContainingBlockHeight - (lineTop + shapeInsideInfo->owner().borderAndPaddingAfter()));
     block->setLogicalHeight(newLogicalHeight);
 }
 
@@ -1186,17 +1186,17 @@
     LayoutSize logicalOffsetFromShapeContainer;
     ShapeInsideInfo* shapeInsideInfo = layoutShapeInsideInfo();
     if (shapeInsideInfo) {
-        ASSERT(shapeInsideInfo->owner() == this || allowsShapeInsideInfoSharing(shapeInsideInfo->owner()));
+        ASSERT(&shapeInsideInfo->owner() == this || allowsShapeInsideInfoSharing(&shapeInsideInfo->owner()));
         if (shapeInsideInfo != this->shapeInsideInfo()) {
             // FIXME Bug 100284: If subsequent LayoutStates are pushed, we will have to add
             // their offsets from the original shape-inside container.
-            logicalOffsetFromShapeContainer = logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner());
+            logicalOffsetFromShapeContainer = logicalOffsetFromShapeAncestorContainer(&shapeInsideInfo->owner());
         }
         // Begin layout at the logical top of our shape inside.
         if (logicalHeight() + logicalOffsetFromShapeContainer.height() < shapeInsideInfo->shapeLogicalTop()) {
             LayoutUnit logicalHeight = shapeInsideInfo->shapeLogicalTop() - logicalOffsetFromShapeContainer.height();
             if (layoutState.flowThread())
-                logicalHeight -= shapeInsideInfo->owner()->borderAndPaddingBefore();
+                logicalHeight -= shapeInsideInfo->owner().borderAndPaddingBefore();
             setLogicalHeight(logicalHeight);
         }
     }
@@ -1283,7 +1283,7 @@
                     adjustLinePositionForPagination(lineBox, adjustment, layoutState.flowThread());
                     if (adjustment) {
                         LayoutUnit oldLineWidth = availableLogicalWidthForLine(oldLogicalHeight, layoutState.lineInfo().isFirstLine());
-                        lineBox->adjustBlockDirectionPosition(adjustment);
+                        lineBox->adjustBlockDirectionPosition(adjustment.toFloat());
                         if (layoutState.usesRepaintBounds())
                             layoutState.updateRepaintRangeFromBox(lineBox);
 
@@ -1412,7 +1412,7 @@
                 }
                 if (delta) {
                     layoutState.updateRepaintRangeFromBox(line, delta);
-                    line->adjustBlockDirectionPosition(delta);
+                    line->adjustBlockDirectionPosition(delta.toFloat());
                 }
                 if (Vector<RenderBox*>* cleanLineFloats = line->floatsPtr()) {
                     Vector<RenderBox*>::iterator end = cleanLineFloats->end();
@@ -1439,7 +1439,7 @@
         if (layoutState.checkForFloatsFromLastLine()) {
             LayoutUnit bottomVisualOverflow = lastRootBox()->logicalBottomVisualOverflow();
             LayoutUnit bottomLayoutOverflow = lastRootBox()->logicalBottomLayoutOverflow();
-            TrailingFloatsRootInlineBox* trailingFloatsLineBox = new TrailingFloatsRootInlineBox(this);
+            TrailingFloatsRootInlineBox* trailingFloatsLineBox = new TrailingFloatsRootInlineBox(*this);
             m_lineBoxes.appendLineBox(trailingFloatsLineBox);
             trailingFloatsLineBox->setConstructed();
             GlyphOverflowAndFallbackFontsMap textBoxDataMap;
@@ -1487,6 +1487,434 @@
     }
 }
 
+struct InlineMinMaxIterator {
+/* InlineMinMaxIterator is a class that will iterate over all render objects that contribute to
+   inline min/max width calculations.  Note the following about the way it walks:
+   (1) Positioned content is skipped (since it does not contribute to min/max width of a block)
+   (2) We do not drill into the children of floats or replaced elements, since you can't break
+       in the middle of such an element.
+   (3) Inline flows (e.g., <a>, <span>, <i>) are walked twice, since each side can have
+       distinct borders/margin/padding that contribute to the min/max width.
+*/
+    RenderObject* parent;
+    RenderObject* current;
+    bool endOfInline;
+
+    InlineMinMaxIterator(RenderObject* p, bool end = false)
+        : parent(p), current(p), endOfInline(end)
+    {
+
+    }
+
+    RenderObject* next();
+};
+
+RenderObject* InlineMinMaxIterator::next()
+{
+    RenderObject* result = 0;
+    bool oldEndOfInline = endOfInline;
+    endOfInline = false;
+    while (current || current == parent) {
+        if (!oldEndOfInline && (current == parent || (!current->isFloating() && !current->isReplaced() && !current->isOutOfFlowPositioned())))
+            result = current->firstChild();
+
+        if (!result) {
+            // We hit the end of our inline. (It was empty, e.g., <span></span>.)
+            if (!oldEndOfInline && current->isRenderInline()) {
+                result = current;
+                endOfInline = true;
+                break;
+            }
+
+            while (current && current != parent) {
+                result = current->nextSibling();
+                if (result)
+                    break;
+                current = current->parent();
+                if (current && current != parent && current->isRenderInline()) {
+                    result = current;
+                    endOfInline = true;
+                    break;
+                }
+            }
+        }
+
+        if (!result)
+            break;
+
+        if (!result->isOutOfFlowPositioned() && (result->isText() || result->isFloating() || result->isReplaced() || result->isRenderInline()))
+            break;
+
+        current = result;
+        result = 0;
+    }
+
+    // Update our position.
+    current = result;
+    return current;
+}
+
+static LayoutUnit getBPMWidth(LayoutUnit childValue, Length cssUnit)
+{
+    if (cssUnit.type() != Auto)
+        return (cssUnit.isFixed() ? static_cast<LayoutUnit>(cssUnit.value()) : childValue);
+    return 0;
+}
+
+static LayoutUnit getBorderPaddingMargin(RenderBoxModelObject* child, bool endOfInline)
+{
+    RenderStyle* childStyle = child->style();
+    if (endOfInline) {
+        return getBPMWidth(child->marginEnd(), childStyle->marginEnd()) +
+            getBPMWidth(child->paddingEnd(), childStyle->paddingEnd()) +
+            child->borderEnd();
+    }
+    return getBPMWidth(child->marginStart(), childStyle->marginStart()) +
+        getBPMWidth(child->paddingStart(), childStyle->paddingStart()) +
+        child->borderStart();
+}
+
+static inline void stripTrailingSpace(float& inlineMax, float& inlineMin, RenderObject* trailingSpaceChild)
+{
+    if (trailingSpaceChild && trailingSpaceChild->isText()) {
+        // Collapse away the trailing space at the end of a block.
+        RenderText* t = toRenderText(trailingSpaceChild);
+        const UChar space = ' ';
+        const Font& font = t->style()->font(); // FIXME: This ignores first-line.
+        float spaceWidth = font.width(RenderBlockFlow::constructTextRun(t, font, &space, 1, t->style(), LTR));
+        inlineMax -= spaceWidth + font.fontDescription().wordSpacing();
+        if (inlineMin > inlineMax)
+            inlineMin = inlineMax;
+    }
+}
+
+static inline void updatePreferredWidth(LayoutUnit& preferredWidth, float& result)
+{
+    LayoutUnit snappedResult = LayoutUnit::fromFloatCeil(result);
+    preferredWidth = max(snappedResult, preferredWidth);
+}
+
+// When converting between floating point and LayoutUnits we risk losing precision
+// with each conversion. When this occurs while accumulating our preferred widths,
+// we can wind up with a line width that's larger than our maxPreferredWidth due to
+// pure float accumulation.
+static inline LayoutUnit adjustFloatForSubPixelLayout(float value)
+{
+    return LayoutUnit::fromFloatCeil(value);
+}
+
+// FIXME: This function should be broken into something less monolithic.
+// FIXME: The main loop here is very similar to LineBreaker::nextSegmentBreak. They can probably reuse code.
+void RenderBlockFlow::computeInlinePreferredLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth)
+{
+    float inlineMax = 0;
+    float inlineMin = 0;
+
+    RenderStyle* styleToUse = style();
+    RenderBlock* containingBlock = this->containingBlock();
+    LayoutUnit cw = containingBlock ? containingBlock->contentLogicalWidth() : LayoutUnit();
+
+    // If we are at the start of a line, we want to ignore all white-space.
+    // Also strip spaces if we previously had text that ended in a trailing space.
+    bool stripFrontSpaces = true;
+    RenderObject* trailingSpaceChild = 0;
+
+    // Firefox and Opera will allow a table cell to grow to fit an image inside it under
+    // very specific cirucumstances (in order to match common WinIE renderings).
+    // Not supporting the quirk has caused us to mis-render some real sites. (See Bugzilla 10517.)
+    bool allowImagesToBreak = !document().inQuirksMode() || !isTableCell() || !styleToUse->logicalWidth().isIntrinsicOrAuto();
+
+    bool autoWrap, oldAutoWrap;
+    autoWrap = oldAutoWrap = styleToUse->autoWrap();
+
+    InlineMinMaxIterator childIterator(this);
+
+    // Only gets added to the max preffered width once.
+    bool addedTextIndent = false;
+    // Signals the text indent was more negative than the min preferred width
+    bool hasRemainingNegativeTextIndent = false;
+
+    LayoutUnit textIndent = minimumValueForLength(styleToUse->textIndent(), cw);
+    RenderObject* prevFloat = 0;
+    bool isPrevChildInlineFlow = false;
+    bool shouldBreakLineAfterText = false;
+    while (RenderObject* child = childIterator.next()) {
+        autoWrap = child->isReplaced() ? child->parent()->style()->autoWrap() :
+            child->style()->autoWrap();
+
+        if (!child->isBR()) {
+            // Step One: determine whether or not we need to go ahead and
+            // terminate our current line. Each discrete chunk can become
+            // the new min-width, if it is the widest chunk seen so far, and
+            // it can also become the max-width.
+
+            // Children fall into three categories:
+            // (1) An inline flow object. These objects always have a min/max of 0,
+            // and are included in the iteration solely so that their margins can
+            // be added in.
+            //
+            // (2) An inline non-text non-flow object, e.g., an inline replaced element.
+            // These objects can always be on a line by themselves, so in this situation
+            // we need to go ahead and break the current line, and then add in our own
+            // margins and min/max width on its own line, and then terminate the line.
+            //
+            // (3) A text object. Text runs can have breakable characters at the start,
+            // the middle or the end. They may also lose whitespace off the front if
+            // we're already ignoring whitespace. In order to compute accurate min-width
+            // information, we need three pieces of information.
+            // (a) the min-width of the first non-breakable run. Should be 0 if the text string
+            // starts with whitespace.
+            // (b) the min-width of the last non-breakable run. Should be 0 if the text string
+            // ends with whitespace.
+            // (c) the min/max width of the string (trimmed for whitespace).
+            //
+            // If the text string starts with whitespace, then we need to go ahead and
+            // terminate our current line (unless we're already in a whitespace stripping
+            // mode.
+            //
+            // If the text string has a breakable character in the middle, but didn't start
+            // with whitespace, then we add the width of the first non-breakable run and
+            // then end the current line. We then need to use the intermediate min/max width
+            // values (if any of them are larger than our current min/max). We then look at
+            // the width of the last non-breakable run and use that to start a new line
+            // (unless we end in whitespace).
+            RenderStyle* childStyle = child->style();
+            float childMin = 0;
+            float childMax = 0;
+
+            if (!child->isText()) {
+                // Case (1) and (2). Inline replaced and inline flow elements.
+                if (child->isRenderInline()) {
+                    // Add in padding/border/margin from the appropriate side of
+                    // the element.
+                    float bpm = getBorderPaddingMargin(toRenderInline(child), childIterator.endOfInline).toFloat();
+                    childMin += bpm;
+                    childMax += bpm;
+
+                    inlineMin += childMin;
+                    inlineMax += childMax;
+
+                    child->clearPreferredLogicalWidthsDirty();
+                } else {
+                    // Inline replaced elts add in their margins to their min/max values.
+                    LayoutUnit margins = 0;
+                    Length startMargin = childStyle->marginStart();
+                    Length endMargin = childStyle->marginEnd();
+                    if (startMargin.isFixed())
+                        margins += adjustFloatForSubPixelLayout(startMargin.value());
+                    if (endMargin.isFixed())
+                        margins += adjustFloatForSubPixelLayout(endMargin.value());
+                    childMin += margins.ceilToFloat();
+                    childMax += margins.ceilToFloat();
+                }
+            }
+
+            if (!child->isRenderInline() && !child->isText()) {
+                // Case (2). Inline replaced elements and floats.
+                // Go ahead and terminate the current line as far as
+                // minwidth is concerned.
+                LayoutUnit childMinPreferredLogicalWidth, childMaxPreferredLogicalWidth;
+                if (child->isBox() && child->isHorizontalWritingMode() != isHorizontalWritingMode()) {
+                    RenderBox* childBox = toRenderBox(child);
+                    LogicalExtentComputedValues computedValues;
+                    childBox->computeLogicalHeight(childBox->borderAndPaddingLogicalHeight(), 0, computedValues);
+                    childMinPreferredLogicalWidth = childMaxPreferredLogicalWidth = computedValues.m_extent;
+                } else {
+                    childMinPreferredLogicalWidth = child->minPreferredLogicalWidth();
+                    childMaxPreferredLogicalWidth = child->maxPreferredLogicalWidth();
+                }
+                childMin += childMinPreferredLogicalWidth.ceilToFloat();
+                childMax += childMaxPreferredLogicalWidth.ceilToFloat();
+
+                bool clearPreviousFloat;
+                if (child->isFloating()) {
+                    clearPreviousFloat = (prevFloat
+                        && ((prevFloat->style()->floating() == LeftFloat && (childStyle->clear() & CLEFT))
+                            || (prevFloat->style()->floating() == RightFloat && (childStyle->clear() & CRIGHT))));
+                    prevFloat = child;
+                } else {
+                    clearPreviousFloat = false;
+                }
+
+                bool canBreakReplacedElement = !child->isImage() || allowImagesToBreak;
+                if ((canBreakReplacedElement && (autoWrap || oldAutoWrap) && (!isPrevChildInlineFlow || shouldBreakLineAfterText)) || clearPreviousFloat) {
+                    updatePreferredWidth(minLogicalWidth, inlineMin);
+                    inlineMin = 0;
+                }
+
+                // If we're supposed to clear the previous float, then terminate maxwidth as well.
+                if (clearPreviousFloat) {
+                    updatePreferredWidth(maxLogicalWidth, inlineMax);
+                    inlineMax = 0;
+                }
+
+                // Add in text-indent. This is added in only once.
+                if (!addedTextIndent && !child->isFloating()) {
+                    float ceiledTextIndent = textIndent.ceilToFloat();
+                    childMin += ceiledTextIndent;
+                    childMax += ceiledTextIndent;
+
+                    if (childMin < 0)
+                        textIndent = adjustFloatForSubPixelLayout(childMin);
+                    else
+                        addedTextIndent = true;
+                }
+
+                // Add our width to the max.
+                inlineMax += max<float>(0, childMax);
+
+                if (!autoWrap || !canBreakReplacedElement || (isPrevChildInlineFlow && !shouldBreakLineAfterText)) {
+                    if (child->isFloating())
+                        updatePreferredWidth(minLogicalWidth, childMin);
+                    else
+                        inlineMin += childMin;
+                } else {
+                    // Now check our line.
+                    updatePreferredWidth(minLogicalWidth, childMin);
+
+                    // Now start a new line.
+                    inlineMin = 0;
+                }
+
+                if (autoWrap && canBreakReplacedElement && isPrevChildInlineFlow) {
+                    updatePreferredWidth(minLogicalWidth, inlineMin);
+                    inlineMin = 0;
+                }
+
+                // We are no longer stripping whitespace at the start of
+                // a line.
+                if (!child->isFloating()) {
+                    stripFrontSpaces = false;
+                    trailingSpaceChild = 0;
+                }
+            } else if (child->isText()) {
+                // Case (3). Text.
+                RenderText* t = toRenderText(child);
+
+                if (t->isWordBreak()) {
+                    updatePreferredWidth(minLogicalWidth, inlineMin);
+                    inlineMin = 0;
+                    continue;
+                }
+
+                if (t->style()->hasTextCombine() && t->isCombineText())
+                    toRenderCombineText(t)->combineText();
+
+                // Determine if we have a breakable character. Pass in
+                // whether or not we should ignore any spaces at the front
+                // of the string. If those are going to be stripped out,
+                // then they shouldn't be considered in the breakable char
+                // check.
+                bool hasBreakableChar, hasBreak;
+                float firstLineMinWidth, lastLineMinWidth;
+                bool hasBreakableStart, hasBreakableEnd;
+                float firstLineMaxWidth, lastLineMaxWidth;
+                t->trimmedPrefWidths(inlineMax,
+                    firstLineMinWidth, hasBreakableStart, lastLineMinWidth, hasBreakableEnd,
+                    hasBreakableChar, hasBreak, firstLineMaxWidth, lastLineMaxWidth,
+                    childMin, childMax, stripFrontSpaces, styleToUse->direction());
+
+                // This text object will not be rendered, but it may still provide a breaking opportunity.
+                if (!hasBreak && !childMax) {
+                    if (autoWrap && (hasBreakableStart || hasBreakableEnd)) {
+                        updatePreferredWidth(minLogicalWidth, inlineMin);
+                        inlineMin = 0;
+                    }
+                    continue;
+                }
+
+                if (stripFrontSpaces)
+                    trailingSpaceChild = child;
+                else
+                    trailingSpaceChild = 0;
+
+                // Add in text-indent. This is added in only once.
+                float ti = 0;
+                if (!addedTextIndent || hasRemainingNegativeTextIndent) {
+                    ti = textIndent.ceilToFloat();
+                    childMin += ti;
+                    firstLineMinWidth += ti;
+
+                    // It the text indent negative and larger than the child minimum, we re-use the remainder
+                    // in future minimum calculations, but using the negative value again on the maximum
+                    // will lead to under-counting the max pref width.
+                    if (!addedTextIndent) {
+                        childMax += ti;
+                        firstLineMaxWidth += ti;
+                        addedTextIndent = true;
+                    }
+
+                    if (childMin < 0) {
+                        textIndent = childMin;
+                        hasRemainingNegativeTextIndent = true;
+                    }
+                }
+
+                // If we have no breakable characters at all,
+                // then this is the easy case. We add ourselves to the current
+                // min and max and continue.
+                if (!hasBreakableChar) {
+                    inlineMin += childMin;
+                } else {
+                    if (hasBreakableStart) {
+                        updatePreferredWidth(minLogicalWidth, inlineMin);
+                    } else {
+                        inlineMin += firstLineMinWidth;
+                        updatePreferredWidth(minLogicalWidth, inlineMin);
+                        childMin -= ti;
+                    }
+
+                    inlineMin = childMin;
+
+                    if (hasBreakableEnd) {
+                        updatePreferredWidth(minLogicalWidth, inlineMin);
+                        inlineMin = 0;
+                        shouldBreakLineAfterText = false;
+                    } else {
+                        updatePreferredWidth(minLogicalWidth, inlineMin);
+                        inlineMin = lastLineMinWidth;
+                        shouldBreakLineAfterText = true;
+                    }
+                }
+
+                if (hasBreak) {
+                    inlineMax += firstLineMaxWidth;
+                    updatePreferredWidth(maxLogicalWidth, inlineMax);
+                    updatePreferredWidth(maxLogicalWidth, childMax);
+                    inlineMax = lastLineMaxWidth;
+                    addedTextIndent = true;
+                } else {
+                    inlineMax += max<float>(0, childMax);
+                }
+            }
+
+            // Ignore spaces after a list marker.
+            if (child->isListMarker())
+                stripFrontSpaces = true;
+        } else {
+            updatePreferredWidth(minLogicalWidth, inlineMin);
+            updatePreferredWidth(maxLogicalWidth, inlineMax);
+            inlineMin = inlineMax = 0;
+            stripFrontSpaces = true;
+            trailingSpaceChild = 0;
+            addedTextIndent = true;
+        }
+
+        if (!child->isText() && child->isRenderInline())
+            isPrevChildInlineFlow = true;
+        else
+            isPrevChildInlineFlow = false;
+
+        oldAutoWrap = autoWrap;
+    }
+
+    if (styleToUse->collapseWhiteSpace())
+        stripTrailingSpace(inlineMax, inlineMin, trailingSpaceChild);
+
+    updatePreferredWidth(minLogicalWidth, inlineMin);
+    updatePreferredWidth(maxLogicalWidth, inlineMax);
+}
+
 void RenderBlockFlow::layoutInlineChildren(bool relayoutChildren, LayoutUnit& repaintLogicalTop, LayoutUnit& repaintLogicalBottom, LayoutUnit afterEdge)
 {
     RenderFlowThread* flowThread = flowThreadContainingBlock();
@@ -1639,7 +2067,7 @@
                     }
 
                     layoutState.updateRepaintRangeFromBox(curr, paginationDelta);
-                    curr->adjustBlockDirectionPosition(paginationDelta);
+                    curr->adjustBlockDirectionPosition(paginationDelta.toFloat());
                 }
             }
 
@@ -1892,7 +2320,7 @@
             curr->clearTruncation();
 
             // Shift the line back where it belongs if we cannot accomodate an ellipsis.
-            float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine);
+            float logicalLeft = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine).toFloat();
             float availableLogicalWidth = logicalRightOffsetForLine(curr->lineTop(), false) - logicalLeft;
             float totalLogicalWidth = curr->logicalWidth();
             updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
@@ -1941,10 +2369,10 @@
             LayoutUnit width = firstLine ? firstLineEllipsisWidth : ellipsisWidth;
             LayoutUnit blockEdge = ltr ? blockRightEdge : blockLeftEdge;
             if (curr->lineCanAccommodateEllipsis(ltr, blockEdge, lineBoxEdge, width)) {
-                float totalLogicalWidth = curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge, blockRightEdge, width);
+                float totalLogicalWidth = curr->placeEllipsis(ellipsisStr, ltr, blockLeftEdge, blockRightEdge, width.toFloat());
 
                 float logicalLeft = 0; // We are only intersted in the delta from the base position.
-                float snappedLogicalLeft = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine);
+                float snappedLogicalLeft = pixelSnappedLogicalLeftOffsetForLine(curr->lineTop(), firstLine).toFloat();
                 float availableLogicalWidth = pixelSnappedLogicalRightOffsetForLine(curr->lineTop(), firstLine) - snappedLogicalLeft;
                 updateLogicalWidthForAlignment(textAlign, curr, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
                 if (ltr)
@@ -2019,7 +2447,7 @@
 
     // updateLogicalWidthForAlignment() handles the direction of the block so no need to consider it here
     float totalLogicalWidth = 0;
-    float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false);
+    float logicalLeft = logicalLeftOffsetForLine(logicalHeight(), false).toFloat();
     float availableLogicalWidth = logicalRightOffsetForLine(logicalHeight(), false) - logicalLeft;
     updateLogicalWidthForAlignment(textAlign, 0, 0, logicalLeft, totalLogicalWidth, availableLogicalWidth, 0);
 
diff --git a/Source/core/rendering/RenderBox.cpp b/Source/core/rendering/RenderBox.cpp
index aee4dcc..4b2f02d 100644
--- a/Source/core/rendering/RenderBox.cpp
+++ b/Source/core/rendering/RenderBox.cpp
@@ -31,11 +31,11 @@
 #include "HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/editing/htmlediting.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLFrameOwnerElement.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/AutoscrollController.h"
 #include "core/page/EventHandler.h"
 #include "core/page/Page.h"
@@ -48,11 +48,11 @@
 #include "core/rendering/RenderGrid.h"
 #include "core/rendering/RenderInline.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderListMarker.h"
 #include "core/rendering/RenderTableCell.h"
 #include "core/rendering/RenderTheme.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "platform/LengthFunctions.h"
 #include "platform/geometry/FloatQuad.h"
 #include "platform/geometry/TransformState.h"
@@ -105,7 +105,7 @@
 
     RenderBlock::removePercentHeightDescendantIfNeeded(this);
 
-    ShapeOutsideInfo::removeInfo(this);
+    ShapeOutsideInfo::removeInfo(*this);
 
     RenderBoxModelObject::willBeDestroyed();
 }
@@ -144,7 +144,7 @@
         // The background of the root element or the body element could propagate up to
         // the canvas.  Just dirty the entire canvas when our style changes substantially.
         if (diff >= StyleDifferenceRepaint && node() &&
-            (node()->hasTagName(htmlTag) || node()->hasTagName(bodyTag))) {
+            (isHTMLHtmlElement(*node()) || isHTMLBodyElement(*node()))) {
             view()->repaint();
 
             if (oldStyle->hasEntirelyFixedBackground() != newStyle->hasEntirelyFixedBackground())
@@ -238,9 +238,9 @@
         return;
 
     if (!shapeOutside)
-        ShapeOutsideInfo::removeInfo(this);
+        ShapeOutsideInfo::removeInfo(*this);
     else
-        ShapeOutsideInfo::ensureInfo(this)->dirtyShapeSize();
+        ShapeOutsideInfo::ensureInfo(*this).markShapeAsDirty();
 
     if (shapeOutside || shapeOutside != oldShapeOutside)
         markShapeOutsideDependentsForLayout();
@@ -308,7 +308,7 @@
         return;
     }
 
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
     while (child) {
         child->layoutIfNeeded();
         ASSERT(!child->needsLayout());
@@ -427,12 +427,19 @@
 
 void RenderBox::setScrollLeft(int newLeft)
 {
+    // This doesn't hit in any tests, but since the equivalent code in setScrollTop
+    // does, presumably this code does as well.
+    DisableCompositingQueryAsserts disabler;
+
     if (hasOverflowClip())
         layer()->scrollableArea()->scrollToXOffset(newLeft, ScrollOffsetClamped);
 }
 
 void RenderBox::setScrollTop(int newTop)
 {
+    // Hits in compositing/overflow/do-not-assert-on-invisible-composited-layers.html
+    DisableCompositingQueryAsserts disabler;
+
     if (hasOverflowClip())
         layer()->scrollableArea()->scrollToYOffset(newTop, ScrollOffsetClamped);
 }
@@ -440,6 +447,10 @@
 void RenderBox::scrollToOffset(const IntSize& offset)
 {
     ASSERT(hasOverflowClip());
+
+    // This doesn't hit in any tests, but since the equivalent code in setScrollTop
+    // does, presumably this code does as well.
+    DisableCompositingQueryAsserts disabler;
     layer()->scrollableArea()->scrollToOffset(offset, ScrollOffsetClamped);
 }
 
@@ -463,6 +474,9 @@
 
 void RenderBox::scrollRectToVisible(const LayoutRect& rect, const ScrollAlignment& alignX, const ScrollAlignment& alignY)
 {
+    // Presumably the same issue as in setScrollTop. See crbug.com/343132.
+    DisableCompositingQueryAsserts disabler;
+
     RenderBox* parentBox = 0;
     LayoutRect newRect = rect;
 
@@ -483,7 +497,7 @@
             if (ownerElement && ownerElement->renderer()) {
                 HTMLFrameElementBase* frameElementBase = 0;
 
-                if (ownerElement->hasTagName(frameTag) || ownerElement->hasTagName(iframeTag))
+                if (isHTMLFrameElement(*ownerElement) || isHTMLIFrameElement(*ownerElement))
                     frameElementBase = toHTMLFrameElementBase(ownerElement);
 
                 if (frameElementAndViewPermitScroll(frameElementBase, frameView)) {
@@ -529,7 +543,7 @@
 
 void RenderBox::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
 {
-    quads.append(localToAbsoluteQuad(FloatRect(0, 0, width(), height()), 0 /* mode */, wasFixed));
+    quads.append(localToAbsoluteQuad(FloatRect(0, 0, width().toFloat(), height().toFloat()), 0 /* mode */, wasFixed));
 }
 
 void RenderBox::updateLayerTransform()
@@ -587,7 +601,7 @@
 LayoutRect RenderBox::outlineBoundsForRepaint(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap* geometryMap) const
 {
     LayoutRect box = borderBoundingBox();
-    adjustRectForOutlineAndShadow(box);
+    adjustRectForOutline(box);
 
     if (repaintContainer != this) {
         FloatQuad containerRelativeQuad;
@@ -727,6 +741,9 @@
 
 bool RenderBox::scroll(ScrollDirection direction, ScrollGranularity granularity, float delta)
 {
+    // Presumably the same issue as in setScrollTop. See crbug.com/343132.
+    DisableCompositingQueryAsserts disabler;
+
     // Logical scroll is a higher level concept, all directions by here must be physical
     ASSERT(!isLogical(direction));
 
@@ -764,7 +781,7 @@
 
 void RenderBox::autoscroll(const IntPoint& position)
 {
-    Frame* frame = this->frame();
+    LocalFrame* frame = this->frame();
     if (!frame)
         return;
 
@@ -855,7 +872,7 @@
 
 void RenderBox::panScroll(const IntPoint& sourcePoint)
 {
-    Frame* frame = this->frame();
+    LocalFrame* frame = this->frame();
     if (!frame)
         return;
 
@@ -897,7 +914,7 @@
             if (RenderBox* scrollableBox = enclosingScrollableBox())
                 scrollableBox->scrollByRecursively(remainingScrollOffset, clamp);
 
-            Frame* frame = this->frame();
+            LocalFrame* frame = this->frame();
             if (frame && frame->page())
                 frame->page()->autoscrollController().updateAutoscrollRenderer();
         }
@@ -1193,7 +1210,7 @@
     if (!style->hasAppearance() && borderObscuresBackground() && backgroundHasOpaqueTopLayer())
         return BackgroundBleedBackgroundOverBorder;
 
-    return BackgroundBleedUseTransparencyLayer;
+    return BackgroundBleedClipBackground;
 }
 
 void RenderBox::paintBoxDecorations(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -1216,20 +1233,13 @@
         paintBoxShadow(paintInfo, paintRect, style(), Normal);
 
     GraphicsContextStateSaver stateSaver(*paintInfo.context, false);
-    if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
-        // To avoid the background color bleeding out behind the border, we'll render background and border
-        // into a transparency layer, and then clip that in one go (which requires setting up the clip before
-        // beginning the layer).
-        RoundedRect border = style()->getRoundedBorderFor(paintRect);
+    if (bleedAvoidance == BackgroundBleedClipBackground) {
         stateSaver.save();
+        RoundedRect border = style()->getRoundedBorderFor(paintRect);
         paintInfo.context->clipRoundedRect(border);
-        paintInfo.context->beginTransparencyLayer(1);
     }
 
     paintBackgroundWithBorderAndBoxShadow(paintInfo, paintRect, bleedAvoidance);
-
-    if (bleedAvoidance == BackgroundBleedUseTransparencyLayer)
-        paintInfo.context->endLayer();
 }
 
 void RenderBox::paintBackgroundWithBorderAndBoxShadow(PaintInfo& paintInfo, const LayoutRect& paintRect, BackgroundBleedAvoidance bleedAvoidance)
@@ -1568,7 +1578,7 @@
 
     ShapeValue* shapeOutsideValue = style()->shapeOutside();
     if (!frameView()->isInPerformLayout() && isFloating() && shapeOutsideValue && shapeOutsideValue->image() && shapeOutsideValue->image()->data() == image) {
-        ShapeOutsideInfo::ensureInfo(this)->dirtyShapeSize();
+        ShapeOutsideInfo::ensureInfo(*this).markShapeAsDirty();
         markShapeOutsideDependentsForLayout();
     }
 
@@ -1917,7 +1927,7 @@
         offset -= toRenderBox(o)->scrolledContentOffset();
 
     if (style()->position() == AbsolutePosition && o->isInFlowPositioned() && o->isRenderInline())
-        offset += toRenderInline(o)->offsetForInFlowPositionedInline(this);
+        offset += toRenderInline(o)->offsetForInFlowPositionedInline(*this);
 
     if (offsetDependsOnPoint)
         *offsetDependsOnPoint |= o->isRenderFlowThread();
@@ -1927,7 +1937,7 @@
 
 InlineBox* RenderBox::createInlineBox()
 {
-    return new InlineBox(this);
+    return new InlineBox(*this);
 }
 
 void RenderBox::dirtyLineBoxes(bool fullLayout)
@@ -1952,8 +1962,8 @@
             // The value is cached in the xPos of the box.  We only need this value if
             // our object was inline originally, since otherwise it would have ended up underneath
             // the inlines.
-            RootInlineBox* root = box->root();
-            root->block()->setStaticInlinePositionForChild(this, root->lineTopWithLeading(), LayoutUnit::fromFloatRound(box->logicalLeft()));
+            RootInlineBox& root = box->root();
+            root.block().setStaticInlinePositionForChild(this, root.lineTopWithLeading(), LayoutUnit::fromFloatRound(box->logicalLeft()));
             if (style()->hasStaticInlinePosition(box->isHorizontal()))
                 setChildNeedsLayout(MarkOnlyThis); // Just go ahead and mark the positioned object as needing layout, so it will update its position properly.
         } else {
@@ -2077,7 +2087,7 @@
         fixed = true;
 
     if (position == AbsolutePosition && o->isInFlowPositioned() && o->isRenderInline()) {
-        topLeft += toRenderInline(o)->offsetForInFlowPositionedInline(this);
+        topLeft += toRenderInline(o)->offsetForInFlowPositionedInline(*this);
     } else if (styleToUse->hasInFlowPosition() && layer()) {
         // Apply the relative position offset when invalidating a rectangle.  The layer
         // is translated, but the render box isn't, so we need to do this to get the
@@ -2149,7 +2159,7 @@
     ASSERT(renderer);
     Node* parentNode = renderer->generatingNode();
     ASSERT(parentNode);
-    ASSERT(parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag));
+    ASSERT(isHTMLOListElement(parentNode) || isHTMLUListElement(parentNode));
     ASSERT(renderer->style()->textAutosizingMultiplier() != 1);
 #endif
     float maxWidth = 0;
@@ -2240,11 +2250,8 @@
         computedValues.m_margins.m_start = minimumValueForLength(styleToUse->marginStart(), containerLogicalWidth);
         computedValues.m_margins.m_end = minimumValueForLength(styleToUse->marginEnd(), containerLogicalWidth);
     } else {
-        LayoutUnit containerLogicalWidthForAutoMargins = containerLogicalWidth;
-        if (avoidsFloats() && cb->containsFloats())
-            containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidth();
         bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
-        computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, computedValues.m_extent,
+        computeInlineDirectionMargins(cb, containerLogicalWidth, computedValues.m_extent,
             hasInvertedDirection ? computedValues.m_margins.m_end : computedValues.m_margins.m_start,
             hasInvertedDirection ? computedValues.m_margins.m_start : computedValues.m_margins.m_end);
     }
@@ -2261,7 +2268,7 @@
 
     if (styleToUse->textAutosizingMultiplier() != 1 && styleToUse->marginStart().type() == Fixed) {
         Node* parentNode = generatingNode();
-        if (parentNode && (parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag))) {
+        if (parentNode && (isHTMLOListElement(*parentNode) || isHTMLUListElement(*parentNode))) {
             // Make sure the markers in a list are properly positioned (i.e. not chopped off) when autosized.
             const float adjustedMargin = (1 - 1.0 / styleToUse->textAutosizingMultiplier()) * getMaxWidthListMarker(this);
             bool hasInvertedDirection = cb->style()->isLeftToRightDirection() != style()->isLeftToRightDirection();
@@ -2414,8 +2421,8 @@
 
 bool RenderBox::autoWidthShouldFitContent() const
 {
-    return node() && (node()->hasTagName(inputTag) || node()->hasTagName(selectTag) || node()->hasTagName(buttonTag)
-        || node()->hasTagName(textareaTag) || (node()->hasTagName(legendTag) && !style()->hasOutOfFlowPosition()));
+    return node() && (isHTMLInputElement(*node()) || isHTMLSelectElement(*node()) || isHTMLButtonElement(*node())
+        || isHTMLTextAreaElement(*node()) || (isHTMLLegendElement(*node()) && !style()->hasOutOfFlowPosition()));
 }
 
 void RenderBox::computeInlineDirectionMargins(RenderBlock* containingBlock, LayoutUnit containerWidth, LayoutUnit childWidth, LayoutUnit& marginStart, LayoutUnit& marginEnd) const
@@ -2441,31 +2448,35 @@
             marginEndLength.setValue(0);
     }
 
+    LayoutUnit availableWidth = containerWidth;
+    if (avoidsFloats() && containingBlock->containsFloats())
+        availableWidth = containingBlockAvailableLineWidth();
+
     // Case One: The object is being centered in the containing block's available logical width.
-    if ((marginStartLength.isAuto() && marginEndLength.isAuto() && childWidth < containerWidth)
+    if ((marginStartLength.isAuto() && marginEndLength.isAuto() && childWidth < availableWidth)
         || (!marginStartLength.isAuto() && !marginEndLength.isAuto() && containingBlock->style()->textAlign() == WEBKIT_CENTER)) {
         // Other browsers center the margin box for align=center elements so we match them here.
         LayoutUnit marginStartWidth = minimumValueForLength(marginStartLength, containerWidth);
         LayoutUnit marginEndWidth = minimumValueForLength(marginEndLength, containerWidth);
-        LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (containerWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
+        LayoutUnit centeredMarginBoxStart = max<LayoutUnit>(0, (availableWidth - childWidth - marginStartWidth - marginEndWidth) / 2);
         marginStart = centeredMarginBoxStart + marginStartWidth;
-        marginEnd = containerWidth - childWidth - marginStart + marginEndWidth;
+        marginEnd = availableWidth - childWidth - marginStart + marginEndWidth;
         return;
     }
 
     // Case Two: The object is being pushed to the start of the containing block's available logical width.
-    if (marginEndLength.isAuto() && childWidth < containerWidth) {
+    if (marginEndLength.isAuto() && childWidth < availableWidth) {
         marginStart = valueForLength(marginStartLength, containerWidth);
-        marginEnd = containerWidth - childWidth - marginStart;
+        marginEnd = availableWidth - childWidth - marginStart;
         return;
     }
 
     // Case Three: The object is being pushed to the end of the containing block's available logical width.
     bool pushToEndFromTextAlign = !marginEndLength.isAuto() && ((!containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_LEFT)
         || (containingBlockStyle->isLeftToRightDirection() && containingBlockStyle->textAlign() == WEBKIT_RIGHT));
-    if ((marginStartLength.isAuto() && childWidth < containerWidth) || pushToEndFromTextAlign) {
+    if ((marginStartLength.isAuto() && childWidth < availableWidth) || pushToEndFromTextAlign) {
         marginEnd = valueForLength(marginEndLength, containerWidth);
-        marginStart = containerWidth - childWidth - marginEnd;
+        marginStart = availableWidth - childWidth - marginEnd;
         return;
     }
 
@@ -2677,6 +2688,11 @@
 
 bool RenderBox::skipContainingBlockForPercentHeightCalculation(const RenderBox* containingBlock) const
 {
+    // Flow threads for multicol or paged overflow should be skipped. They are invisible to the DOM,
+    // and percent heights of children should be resolved against the multicol or paged container.
+    if (containingBlock->isRenderFlowThread())
+        return true;
+
     // For quirks mode and anonymous blocks, we skip auto-height containingBlocks when computing percentages.
     // For standards mode, we treat the percentage as auto if it has an auto-height containing block.
     if (!document().inQuirksMode() && !containingBlock->isAnonymousBlock())
@@ -3229,8 +3245,9 @@
     if (containerBlock->isHorizontalWritingMode() != child->isHorizontalWritingMode() && containerBlock->style()->isFlippedBlocksWritingMode()) {
         logicalLeftPos = containerLogicalWidth - logicalWidthValue - logicalLeftPos;
         logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->borderRight() : containerBlock->borderBottom());
-    } else
+    } else {
         logicalLeftPos += (child->isHorizontalWritingMode() ? containerBlock->borderLeft() : containerBlock->borderTop());
+    }
 }
 
 void RenderBox::shrinkToFitWidth(const LayoutUnit availableSpace, const LayoutUnit logicalLeftValue, const LayoutUnit bordersPlusPadding, LogicalExtentComputedValues& computedValues) const
@@ -3996,10 +4013,10 @@
         rect.move(LayoutSize(width() - caretWidth, 0));
 
     if (box) {
-        RootInlineBox* rootBox = box->root();
-        LayoutUnit top = rootBox->lineTop();
+        RootInlineBox& rootBox = box->root();
+        LayoutUnit top = rootBox.lineTop();
         rect.setY(top);
-        rect.setHeight(rootBox->lineBottom() - top);
+        rect.setHeight(rootBox.lineBottom() - top);
     }
 
     // If height of box is smaller than font height, use the latter one,
@@ -4132,6 +4149,15 @@
     return isReplaced() || hasOverflowClip() || isHR() || isLegend() || isWritingModeRoot() || isFlexItemIncludingDeprecated();
 }
 
+void RenderBox::markForPaginationRelayoutIfNeeded(SubtreeLayoutScope& layoutScope)
+{
+    ASSERT(!needsLayout());
+    // If fragmentation height has changed, we need to lay out. No need to enter the renderer if it
+    // is childless, though.
+    if (view()->layoutState()->pageLogicalHeightChanged() && firstChild())
+        layoutScope.setChildNeedsLayout(this);
+}
+
 void RenderBox::addVisualEffectOverflow()
 {
     if (!style()->boxShadow() && !style()->hasBorderImageOutsets())
@@ -4270,8 +4296,12 @@
         return;
     }
 
-    if (!m_overflow)
-        m_overflow = adoptPtr(new RenderOverflow(clientBoxRect(), borderBoxRect()));
+    if (!m_overflow) {
+        LayoutRect clientBox = clientBoxRect();
+        if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
+            clientBox.move(-verticalScrollbarWidth(), 0);
+        m_overflow = adoptPtr(new RenderOverflow(clientBox, borderBoxRect()));
+    }
     m_overflow->addContentsVisualOverflow(rect);
 }
 
@@ -4471,14 +4501,16 @@
 
 LayoutRect RenderBox::noOverflowRect() const
 {
-    // Because of the special coodinate system used for overflow rectangles and many other
+    // Because of the special coordinate system used for overflow rectangles and many other
     // rectangles (not quite logical, not quite physical), we need to flip the block progression
     // coordinate in vertical-rl and horizontal-bt writing modes. In other words, the rectangle
     // returned is physical, except for the block direction progression coordinate (y in horizontal
     // writing modes, x in vertical writing modes), which is always "logical top". Apart from the
     // flipping, this method does the same as clientBoxRect().
 
-    LayoutUnit left = borderLeft() + (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? verticalScrollbarWidth() : 0);
+    const int scrollBarWidth = verticalScrollbarWidth();
+    const int scrollBarHeight = horizontalScrollbarHeight();
+    LayoutUnit left = borderLeft() + (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? scrollBarWidth : 0);
     LayoutUnit top = borderTop();
     LayoutUnit right = borderRight();
     LayoutUnit bottom = borderBottom();
@@ -4494,9 +4526,9 @@
     // clientBoxRect() or paddingBoxRect() in this method, rather than fiddling with the edges on
     // our own.
     if (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
-        rect.contract(0, horizontalScrollbarHeight());
+        rect.contract(0, scrollBarHeight);
     else
-        rect.contract(verticalScrollbarWidth(), horizontalScrollbarHeight());
+        rect.contract(scrollBarWidth, scrollBarHeight);
     return rect;
 }
 
diff --git a/Source/core/rendering/RenderBox.h b/Source/core/rendering/RenderBox.h
index 0ec1ff8..39c943a 100644
--- a/Source/core/rendering/RenderBox.h
+++ b/Source/core/rendering/RenderBox.h
@@ -71,7 +71,7 @@
     // position:static elements that are not flex-items get their z-index coerced to auto.
     virtual LayerType layerTypeRequired() const OVERRIDE
     {
-        if (isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns() || !style()->hasAutoZIndex())
+        if (isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns() || !style()->hasAutoZIndex() || style()->hasWillChangeCompositingHint() || style()->hasWillChangeGpuRasterizationHint())
             return NormalLayer;
         if (hasOverflowClip())
             return OverflowClipLayer;
@@ -251,7 +251,7 @@
 
     // More IE extensions.  clientWidth and clientHeight represent the interior of an object
     // excluding border and scrollbar.  clientLeft/Top are just the borderLeftWidth and borderTopWidth.
-    LayoutUnit clientLeft() const { return borderLeft(); }
+    LayoutUnit clientLeft() const { return borderLeft() + (style()->shouldPlaceBlockDirectionScrollbarOnLogicalLeft() ? verticalScrollbarWidth() : 0); }
     LayoutUnit clientTop() const { return borderTop(); }
     LayoutUnit clientWidth() const;
     LayoutUnit clientHeight() const;
@@ -540,7 +540,7 @@
     bool shrinkToAvoidFloats() const;
     virtual bool avoidsFloats() const;
 
-    virtual void markForPaginationRelayoutIfNeeded(SubtreeLayoutScope&) { }
+    virtual void markForPaginationRelayoutIfNeeded(SubtreeLayoutScope&);
 
     bool isWritingModeRoot() const { return !parent() || parent()->style()->writingMode() != style()->writingMode(); }
 
@@ -613,7 +613,7 @@
 
     ShapeOutsideInfo* shapeOutsideInfo() const
     {
-        return ShapeOutsideInfo::isEnabledFor(this) ? ShapeOutsideInfo::info(this) : 0;
+        return ShapeOutsideInfo::isEnabledFor(*this) ? ShapeOutsideInfo::info(*this) : 0;
     }
 
     void markShapeOutsideDependentsForLayout()
diff --git a/Source/core/rendering/RenderBoxModelObject.cpp b/Source/core/rendering/RenderBoxModelObject.cpp
index b48e46f..dfa132b 100644
--- a/Source/core/rendering/RenderBoxModelObject.cpp
+++ b/Source/core/rendering/RenderBoxModelObject.cpp
@@ -30,19 +30,19 @@
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/page/scrolling/ScrollingConstraints.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/ImageQualityController.h"
 #include "core/rendering/RenderBlock.h"
 #include "core/rendering/RenderFlowThread.h"
 #include "core/rendering/RenderGeometryMap.h"
 #include "core/rendering/RenderInline.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderRegion.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/rendering/style/ShadowList.h"
 #include "platform/geometry/TransformState.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
 #include "platform/graphics/Path.h"
 #include "wtf/CurrentTime.h"
@@ -308,22 +308,22 @@
     constraints.setAbsoluteStickyBoxRect(absoluteStickyBoxRect);
 
     if (!style()->left().isAuto()) {
-        constraints.setLeftOffset(valueForLength(style()->left(), constrainingRect.width()));
+        constraints.setLeftOffset(floatValueForLength(style()->left(), constrainingRect.width()));
         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeLeft);
     }
 
     if (!style()->right().isAuto()) {
-        constraints.setRightOffset(valueForLength(style()->right(), constrainingRect.width()));
+        constraints.setRightOffset(floatValueForLength(style()->right(), constrainingRect.width()));
         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeRight);
     }
 
     if (!style()->top().isAuto()) {
-        constraints.setTopOffset(valueForLength(style()->top(), constrainingRect.height()));
+        constraints.setTopOffset(floatValueForLength(style()->top(), constrainingRect.height()));
         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeTop);
     }
 
     if (!style()->bottom().isAuto()) {
-        constraints.setBottomOffset(valueForLength(style()->bottom(), constrainingRect.height() ));
+        constraints.setBottomOffset(floatValueForLength(style()->bottom(), constrainingRect.height() ));
         constraints.addAnchorEdge(ViewportConstraints::AnchorEdgeBottom);
     }
 }
@@ -337,6 +337,9 @@
     if (enclosingClippingLayer) {
         RenderBox* enclosingClippingBox = toRenderBox(enclosingClippingLayer->renderer());
         LayoutRect clipRect = enclosingClippingBox->overflowClipRect(LayoutPoint());
+        clipRect.move(enclosingClippingBox->paddingLeft(), enclosingClippingBox->paddingTop());
+        clipRect.contract(LayoutSize(enclosingClippingBox->paddingLeft() + enclosingClippingBox->paddingRight(),
+            enclosingClippingBox->paddingTop() + enclosingClippingBox->paddingBottom()));
         constrainingRect = enclosingClippingBox->localToContainerQuad(FloatRect(clipRect), view()).boundingBox();
     } else {
         LayoutRect viewportRect = view()->frameView()->viewportConstrainedVisibleContentRect();
@@ -474,7 +477,7 @@
             continue;
         FloatSize shadowOffset(boxShadow.x(), boxShadow.y());
         context->setShadow(shadowOffset, boxShadow.blur(), boxShadow.color(),
-            DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
+            DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
         return;
     }
 }
@@ -534,7 +537,7 @@
         if (boxShadowShouldBeAppliedToBackground)
             applyBoxShadowForBackground(context, this);
 
-        if (hasRoundedBorder && bleedAvoidance != BackgroundBleedUseTransparencyLayer) {
+        if (hasRoundedBorder && bleedAvoidance != BackgroundBleedClipBackground) {
             RoundedRect border = backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge);
             if (border.isRenderable())
                 context->fillRoundedRect(border, bgColor);
@@ -551,8 +554,8 @@
         return;
     }
 
-    // BorderFillBox radius clipping is taken care of by BackgroundBleedUseTransparencyLayer
-    bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidance == BackgroundBleedUseTransparencyLayer);
+    // BorderFillBox radius clipping is taken care of by BackgroundBleedClipBackground
+    bool clipToBorderRadius = hasRoundedBorder && !(isBorderFill && bleedAvoidance == BackgroundBleedClipBackground);
     GraphicsContextStateSaver clipToBorderStateSaver(*context, clipToBorderRadius);
     if (clipToBorderRadius) {
         RoundedRect border = isBorderFill ? backgroundRoundedRectAdjustedForBleedAvoidance(context, rect, bleedAvoidance, box, boxSize, includeLeftEdge, includeRightEdge) : getBackgroundRoundedRect(rect, box, boxSize.width(), boxSize.height(), includeLeftEdge, includeRightEdge);
@@ -635,7 +638,7 @@
         if (!bgLayer->next() && bgColor.hasAlpha() && view()->frameView()) {
             Element* ownerElement = document().ownerElement();
             if (ownerElement) {
-                if (!ownerElement->hasTagName(frameTag)) {
+                if (!isHTMLFrameElement(*ownerElement)) {
                     // Locate the <body> element using the DOM.  This is easier than trying
                     // to crawl around a render tree with potential :before/:after content and
                     // anonymous blocks created by inline <body> tags etc.  We can locate the <body>
@@ -720,8 +723,8 @@
         PaintInfo info(context, maskRect, PaintPhaseTextClip, PaintBehaviorForceBlackText, 0);
         context->setCompositeOperation(CompositeSourceOver);
         if (box) {
-            RootInlineBox* root = box->root();
-            box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), root->lineTop(), root->lineBottom());
+            RootInlineBox& root = box->root();
+            box->paint(info, LayoutPoint(scrolledPaintRect.x() - box->x(), scrolledPaintRect.y() - box->y()), root.lineTop(), root.lineBottom());
         } else {
             LayoutSize localOffset = isBox() ? toRenderBox(this)->locationOffset() : LayoutSize();
             paint(info, scrolledPaintRect.location() - localOffset);
@@ -971,7 +974,7 @@
     bool fixedAttachment = fillLayer->attachment() == FixedBackgroundAttachment;
 
 #if ENABLE(FAST_MOBILE_SCROLLING)
-    if (view()->frameView() && view()->frameView()->canBlitOnScroll()) {
+    if (view()->frameView() && view()->frameView()->shouldAttemptToScrollUsingFastPath()) {
         // As a side effect of an optimization to blit on scroll, we do not honor the CSS
         // property "background-attachment: fixed" because it may result in rendering
         // artifacts. Note, these artifacts only appear if we are blitting on scroll of
@@ -1712,6 +1715,7 @@
     bool haveAllDoubleEdges = true;
     int numEdgesVisible = 4;
     bool allEdgesShareColor = true;
+    bool allEdgesShareWidth = true;
     int firstVisibleEdge = -1;
     BorderEdgeFlags edgesToDraw = 0;
 
@@ -1724,18 +1728,23 @@
         if (currEdge.presentButInvisible()) {
             --numEdgesVisible;
             allEdgesShareColor = false;
+            allEdgesShareWidth = false;
             continue;
         }
 
-        if (!currEdge.width) {
+        if (!currEdge.shouldRender()) {
             --numEdgesVisible;
             continue;
         }
 
-        if (firstVisibleEdge == -1)
+        if (firstVisibleEdge == -1) {
             firstVisibleEdge = i;
-        else if (currEdge.color != edges[firstVisibleEdge].color)
-            allEdgesShareColor = false;
+        } else {
+            if (currEdge.color != edges[firstVisibleEdge].color)
+                allEdgesShareColor = false;
+            if (currEdge.width != edges[firstVisibleEdge].width)
+                allEdgesShareWidth = false;
+        }
 
         if (currEdge.color.hasAlpha())
             haveAlphaColor = true;
@@ -1755,11 +1764,19 @@
     // isRenderable() check avoids issue described in https://bugs.webkit.org/show_bug.cgi?id=38787
     if ((haveAllSolidEdges || haveAllDoubleEdges) && allEdgesShareColor && innerBorder.isRenderable()) {
         // Fast path for drawing all solid edges and all unrounded double edges
+
         if (numEdgesVisible == 4 && (outerBorder.isRounded() || haveAlphaColor)
             && (haveAllSolidEdges || (!outerBorder.isRounded() && !innerBorder.isRounded()))) {
             Path path;
 
-            if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+            if (outerBorder.isRounded() && allEdgesShareWidth) {
+
+                // Very fast path for single stroked round rect with circular corners
+
+                graphicsContext->fillBetweenRoundedRects(outerBorder, innerBorder, edges[firstVisibleEdge].color);
+                return;
+            }
+            if (outerBorder.isRounded() && bleedAvoidance != BackgroundBleedClipBackground)
                 path.addRoundedRect(outerBorder);
             else
                 path.addRect(outerBorder.rect());
@@ -1792,12 +1809,12 @@
                 innerThird.setRect(innerThirdRect);
                 outerThird.setRect(outerThirdRect);
 
-                if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+                if (outerThird.isRounded() && bleedAvoidance != BackgroundBleedClipBackground)
                     path.addRoundedRect(outerThird);
                 else
                     path.addRect(outerThird.rect());
 
-                if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+                if (innerThird.isRounded() && bleedAvoidance != BackgroundBleedClipBackground)
                     path.addRoundedRect(innerThird);
                 else
                     path.addRect(innerThird.rect());
@@ -1836,7 +1853,7 @@
     GraphicsContextStateSaver stateSaver(*graphicsContext, clipToOuterBorder);
     if (clipToOuterBorder) {
         // Clip to the inner and outer radii rects.
-        if (bleedAvoidance != BackgroundBleedUseTransparencyLayer)
+        if (bleedAvoidance != BackgroundBleedClipBackground)
             graphicsContext->clipRoundedRect(outerBorder);
         // isRenderable() check avoids issue described in https://bugs.webkit.org/show_bug.cgi?id=38787
         // The inside will be clipped out later (in clipBorderSideForComplexInnerPath)
@@ -1942,7 +1959,7 @@
         {
             GraphicsContextStateSaver stateSaver(*graphicsContext);
             LayoutRect outerRect = borderRect;
-            if (bleedAvoidance == BackgroundBleedUseTransparencyLayer) {
+            if (bleedAvoidance == BackgroundBleedClipBackground) {
                 outerRect.inflate(1);
                 ++outerBorderTopWidth;
                 ++outerBorderBottomWidth;
@@ -2509,10 +2526,10 @@
             }
 
             // Draw only the shadow.
-            DrawLooper drawLooper;
-            drawLooper.addShadow(shadowOffset, shadowBlur, shadowColor,
-                DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowIgnoresAlpha);
-            context->setDrawLooper(drawLooper);
+            OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
+            drawLooperBuilder->addShadow(shadowOffset, shadowBlur, shadowColor,
+                DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha);
+            context->setDrawLooper(drawLooperBuilder.release());
 
             if (hasBorderRadius) {
                 RoundedRect influenceRect(pixelSnappedIntRect(LayoutRect(shadowRect)), border.radii());
@@ -2748,7 +2765,7 @@
     if (shouldUseTransformFromContainer(container)) {
         TransformationMatrix t;
         getTransformFromContainer(container, containerOffset, t);
-        t.translateRight(adjustmentForSkippedAncestor.width(), adjustmentForSkippedAncestor.height());
+        t.translateRight(adjustmentForSkippedAncestor.width().toFloat(), adjustmentForSkippedAncestor.height().toFloat());
         geometryMap.push(this, t, preserve3D, offsetDependsOnPoint, isFixedPos, hasTransform);
     } else {
         containerOffset += adjustmentForSkippedAncestor;
diff --git a/Source/core/rendering/RenderBoxModelObject.h b/Source/core/rendering/RenderBoxModelObject.h
index 52e8fb0..9eb4384 100644
--- a/Source/core/rendering/RenderBoxModelObject.h
+++ b/Source/core/rendering/RenderBoxModelObject.h
@@ -38,7 +38,7 @@
 enum BackgroundBleedAvoidance {
     BackgroundBleedNone,
     BackgroundBleedShrinkBackground,
-    BackgroundBleedUseTransparencyLayer,
+    BackgroundBleedClipBackground,
     BackgroundBleedBackgroundOverBorder
 };
 
@@ -48,7 +48,8 @@
     CanvasChanged,
     CanvasPixelsChanged,
     VideoChanged,
-    FullScreenChanged
+    FullScreenChanged,
+    CanvasContextChanged
 };
 
 class KeyframeList;
@@ -88,7 +89,7 @@
 
     virtual LayerType layerTypeRequired() const OVERRIDE
     {
-        if (isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns())
+        if (isRoot() || isPositioned() || createsGroup() || hasClipPath() || hasTransform() || hasHiddenBackface() || hasReflection() || style()->specifiesColumns() || style()->hasWillChangeCompositingHint() || style()->hasWillChangeGpuRasterizationHint())
             return NormalLayer;
 
         return NoLayer;
@@ -127,6 +128,9 @@
     virtual int borderStart() const { return style()->borderStartWidth(); }
     virtual int borderEnd() const { return style()->borderEndWidth(); }
 
+    int borderWidth() const { return borderLeft() + borderRight(); }
+    int borderHeight() const { return borderTop() + borderBottom(); }
+
     LayoutUnit borderAndPaddingStart() const { return borderStart() + paddingStart(); }
     LayoutUnit borderAndPaddingBefore() const { return borderBefore() + paddingBefore(); }
     LayoutUnit borderAndPaddingAfter() const { return borderAfter() + paddingAfter(); }
@@ -182,8 +186,6 @@
     virtual void mapAbsoluteToLocalPoint(MapCoordinatesFlags, TransformState&) const OVERRIDE;
     virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
 
-    void highQualityRepaintTimerFired(Timer<RenderBoxModelObject>*);
-
     virtual void setSelectionState(SelectionState) OVERRIDE;
 
     void contentChanged(ContentChangeType);
@@ -264,13 +266,13 @@
 
     LayoutRect localCaretRectForEmptyElement(LayoutUnit width, LayoutUnit textIndentOffset);
 
-    static bool shouldAntialiasLines(GraphicsContext*);
-
     static void clipRoundedInnerRect(GraphicsContext*, const LayoutRect&, const RoundedRect& clipRect);
 
     bool hasAutoHeightOrContainingBlockWithAutoHeight() const;
 
 public:
+    static bool shouldAntialiasLines(GraphicsContext*);
+
     // For RenderBlocks and RenderInlines with m_style->styleType() == FIRST_LETTER, this tracks their remaining text fragments
     RenderTextFragment* firstLetterRemainingText() const;
     void setFirstLetterRemainingText(RenderTextFragment*);
@@ -299,6 +301,9 @@
     }
     void moveChildrenTo(RenderBoxModelObject* toBoxModelObject, RenderObject* startChild, RenderObject* endChild, RenderObject* beforeChild, bool fullRemoveInsert = false);
 
+    enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom };
+    IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const;
+
 private:
     LayoutUnit computedCSSPadding(Length) const;
     virtual bool isBoxModelObject() const OVERRIDE FINAL { return true; }
@@ -307,9 +312,6 @@
 
     IntSize calculateFillTileSize(const FillLayer*, const IntSize& scaledPositioningAreaSize) const;
 
-    enum ScaleByEffectiveZoomOrNot { ScaleByEffectiveZoom, DoNotScaleByEffectiveZoom };
-    IntSize calculateImageIntrinsicDimensions(StyleImage*, const IntSize& scaledPositioningAreaSize, ScaleByEffectiveZoomOrNot) const;
-
     RoundedRect getBackgroundRoundedRect(const LayoutRect&, InlineFlowBox*, LayoutUnit inlineBoxWidth, LayoutUnit inlineBoxHeight,
         bool includeLogicalLeftEdge, bool includeLogicalRightEdge) const;
 
diff --git a/Source/core/rendering/RenderButton.cpp b/Source/core/rendering/RenderButton.cpp
index ce1bec4..76accbf 100644
--- a/Source/core/rendering/RenderButton.cpp
+++ b/Source/core/rendering/RenderButton.cpp
@@ -104,7 +104,7 @@
     // Input elements can't have generated children, but button elements can. We'll
     // write the code assuming any other button types that might emerge in the future
     // can also have children.
-    return !node()->hasTagName(inputTag);
+    return !isHTMLInputElement(*node());
 }
 
 LayoutRect RenderButton::controlClipRect(const LayoutPoint& additionalOffset) const
diff --git a/Source/core/rendering/RenderButton.h b/Source/core/rendering/RenderButton.h
index 246bab6..c90dd59 100644
--- a/Source/core/rendering/RenderButton.h
+++ b/Source/core/rendering/RenderButton.h
@@ -21,7 +21,7 @@
 #ifndef RenderButton_h
 #define RenderButton_h
 
-#include "HTMLNames.h"
+#include "core/html/HTMLInputElement.h"
 #include "core/rendering/RenderFlexibleBox.h"
 
 namespace WebCore {
@@ -62,7 +62,7 @@
     virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle) OVERRIDE;
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
 
-    virtual bool hasLineIfEmpty() const OVERRIDE { return node() && node()->hasTagName(HTMLNames::inputTag); }
+    virtual bool hasLineIfEmpty() const OVERRIDE { return isHTMLInputElement(node()); }
 
     RenderBlock* m_inner;
 };
diff --git a/Source/core/rendering/RenderCombineText.cpp b/Source/core/rendering/RenderCombineText.cpp
index da7ef5b..7e6e44c 100644
--- a/Source/core/rendering/RenderCombineText.cpp
+++ b/Source/core/rendering/RenderCombineText.cpp
@@ -76,7 +76,7 @@
 {
     ASSERT(start >= 0);
     if (m_isCombined) {
-        string = StringView(originalText());
+        string = StringView(m_renderingText.impl());
         length = string.length();
         return;
     }
@@ -136,6 +136,7 @@
 
     if (m_isCombined) {
         DEFINE_STATIC_LOCAL(String, objectReplacementCharacterString, (&objectReplacementCharacter, 1));
+        m_renderingText = text();
         RenderText::setTextInternal(objectReplacementCharacterString.impl());
     }
 }
diff --git a/Source/core/rendering/RenderCombineText.h b/Source/core/rendering/RenderCombineText.h
index 8e521f2..d15bdd7 100644
--- a/Source/core/rendering/RenderCombineText.h
+++ b/Source/core/rendering/RenderCombineText.h
@@ -45,6 +45,7 @@
     virtual void setTextInternal(PassRefPtr<StringImpl>) OVERRIDE;
 
     float m_combinedTextWidth;
+    String m_renderingText;
     bool m_isCombined : 1;
     bool m_needsFontUpdate : 1;
 };
diff --git a/Source/core/rendering/RenderCounter.cpp b/Source/core/rendering/RenderCounter.cpp
index 5aac629..3f16dff 100644
--- a/Source/core/rendering/RenderCounter.cpp
+++ b/Source/core/rendering/RenderCounter.cpp
@@ -148,12 +148,12 @@
             return true;
         }
         if (Node* e = object.node()) {
-            if (e->hasTagName(olTag)) {
+            if (isHTMLOListElement(*e)) {
                 value = toHTMLOListElement(e)->start();
                 isReset = true;
                 return true;
             }
-            if (e->hasTagName(ulTag) || e->hasTagName(menuTag) || e->hasTagName(dirTag)) {
+            if (isHTMLUListElement(*e) || isHTMLMenuElement(*e) || isHTMLDirectoryElement(*e)) {
                 value = 0;
                 isReset = true;
                 return true;
@@ -189,8 +189,8 @@
     // towards the begining of the document for counters with the same identifier as the one
     // we are trying to find a place for. This is the next renderer to be checked.
     RenderObject* currentRenderer = previousInPreOrder(counterOwner);
-    previousSibling = 0;
-    RefPtr<CounterNode> previousSiblingProtector = 0;
+    previousSibling = nullptr;
+    RefPtr<CounterNode> previousSiblingProtector = nullptr;
 
     while (currentRenderer) {
         CounterNode* currentCounter = makeCounterNode(*currentRenderer, identifier, false);
@@ -216,7 +216,7 @@
                         // In these cases the identified previousSibling will be invalid as its parent is different from
                         // our identified parent.
                         if (previousSiblingProtector->parent() != currentCounter)
-                            previousSiblingProtector = 0;
+                            previousSiblingProtector = nullptr;
 
                         previousSibling = previousSiblingProtector.get();
                         return true;
@@ -307,8 +307,8 @@
     if (!planCounter(object, identifier, isReset, value) && !alwaysCreateCounter)
         return 0;
 
-    RefPtr<CounterNode> newParent = 0;
-    RefPtr<CounterNode> newPreviousSibling = 0;
+    RefPtr<CounterNode> newParent = nullptr;
+    RefPtr<CounterNode> newPreviousSibling = nullptr;
     RefPtr<CounterNode> newNode = CounterNode::create(object, isReset, value);
     if (findPlaceForCounter(object, identifier, isReset, newParent, newPreviousSibling))
         newParent->insertAfter(newNode.get(), newPreviousSibling.get(), identifier);
@@ -385,9 +385,9 @@
         RenderObject* beforeAfterContainer = parent();
         while (true) {
             if (!beforeAfterContainer)
-                return 0;
+                return nullptr;
             if (!beforeAfterContainer->isAnonymous() && !beforeAfterContainer->isPseudoElement())
-                return 0; // RenderCounters are restricted to before and after pseudo elements
+                return nullptr; // RenderCounters are restricted to before and after pseudo elements
             PseudoId containerStyle = beforeAfterContainer->style()->styleType();
             if ((containerStyle == BEFORE) || (containerStyle == AFTER))
                 break;
@@ -515,8 +515,8 @@
             makeCounterNode(renderer, it->key, false);
             continue;
         }
-        RefPtr<CounterNode> newParent = 0;
-        RefPtr<CounterNode> newPreviousSibling = 0;
+        RefPtr<CounterNode> newParent = nullptr;
+        RefPtr<CounterNode> newPreviousSibling = nullptr;
 
         findPlaceForCounter(renderer, it->key, node->hasResetType(), newParent, newPreviousSibling);
         if (node != counterMap->get(it->key))
diff --git a/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp b/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
index 676a735..0405fda 100644
--- a/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
+++ b/Source/core/rendering/RenderDeprecatedFlexibleBox.cpp
@@ -258,7 +258,7 @@
         return;
 
     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     RenderFlowThread* flowThread = flowThreadContainingBlock();
     if (updateRegionsAndShapesLogicalSize(flowThread))
@@ -300,7 +300,7 @@
     updateLayerTransform();
 
     if (view()->layoutState()->pageLogicalHeight())
-        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logicalTop()));
+        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(*this, logicalTop()));
 
     // Update our scrollbars if we're overflow:auto/scroll/hidden now that we know if
     // we overflow or not.
@@ -942,9 +942,9 @@
         const Font& font = style(numVisibleLines == 1)->font();
 
         // Get ellipsis width, and if the last child is an anchor, it will go after the ellipsis, so add in a space and the anchor width too
-        LayoutUnit totalWidth;
+        float totalWidth;
         InlineBox* anchorBox = lastLine->lastChild();
-        if (anchorBox && anchorBox->renderer()->style()->isLink())
+        if (anchorBox && anchorBox->renderer().style()->isLink())
             totalWidth = anchorBox->logicalWidth() + font.width(RenderBlockFlow::constructTextRun(this, font, ellipsisAndSpace, 2, style(), style()->direction()));
         else {
             anchorBox = 0;
@@ -952,26 +952,26 @@
         }
 
         // See if this width can be accommodated on the last visible line
-        RenderBlockFlow* destBlock = lastVisibleLine->block();
-        RenderBlockFlow* srcBlock = lastLine->block();
+        RenderBlockFlow& destBlock = lastVisibleLine->block();
+        RenderBlockFlow& srcBlock = lastLine->block();
 
         // FIXME: Directions of src/destBlock could be different from our direction and from one another.
-        if (!srcBlock->style()->isLeftToRightDirection())
+        if (!srcBlock.style()->isLeftToRightDirection())
             continue;
 
-        bool leftToRight = destBlock->style()->isLeftToRightDirection();
+        bool leftToRight = destBlock.style()->isLeftToRightDirection();
         if (!leftToRight)
             continue;
 
-        LayoutUnit blockRightEdge = destBlock->logicalRightOffsetForLine(lastVisibleLine->y(), false);
+        LayoutUnit blockRightEdge = destBlock.logicalRightOffsetForLine(lastVisibleLine->y(), false);
         if (!lastVisibleLine->lineCanAccommodateEllipsis(leftToRight, blockRightEdge, lastVisibleLine->x() + lastVisibleLine->logicalWidth(), totalWidth))
             continue;
 
         // Let the truncation code kick in.
         // FIXME: the text alignment should be recomputed after the width changes due to truncation.
-        LayoutUnit blockLeftEdge = destBlock->logicalLeftOffsetForLine(lastVisibleLine->y(), false);
-        lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, leftToRight, blockLeftEdge, blockRightEdge, totalWidth, anchorBox);
-        destBlock->setHasMarkupTruncation(true);
+        LayoutUnit blockLeftEdge = destBlock.logicalLeftOffsetForLine(lastVisibleLine->y(), false);
+        lastVisibleLine->placeEllipsis(anchorBox ? ellipsisAndSpaceStr : ellipsisStr, leftToRight, blockLeftEdge.toFloat(), blockRightEdge.toFloat(), totalWidth, anchorBox);
+        destBlock.setHasMarkupTruncation(true);
     }
 }
 
diff --git a/Source/core/rendering/RenderDeprecatedFlexibleBox.h b/Source/core/rendering/RenderDeprecatedFlexibleBox.h
index 91ba298..3c8d456 100644
--- a/Source/core/rendering/RenderDeprecatedFlexibleBox.h
+++ b/Source/core/rendering/RenderDeprecatedFlexibleBox.h
@@ -64,8 +64,6 @@
     bool m_stretchingChildren;
 
 private:
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     void applyLineClamp(FlexBoxIterator&, bool relayoutChildren);
     void clearLineClamp();
 };
diff --git a/Source/core/rendering/RenderDetailsMarker.cpp b/Source/core/rendering/RenderDetailsMarker.cpp
index 68e6083..d6717f3 100644
--- a/Source/core/rendering/RenderDetailsMarker.cpp
+++ b/Source/core/rendering/RenderDetailsMarker.cpp
@@ -23,6 +23,7 @@
 
 #include "HTMLNames.h"
 #include "core/dom/Element.h"
+#include "core/html/HTMLElement.h"
 #include "core/rendering/PaintInfo.h"
 #include "platform/graphics/GraphicsContext.h"
 
@@ -106,8 +107,8 @@
 Path RenderDetailsMarker::getPath(const LayoutPoint& origin) const
 {
     Path result = getCanonicalPath();
-    result.transform(AffineTransform().scale(contentWidth(), contentHeight()));
-    result.translate(FloatSize(origin.x(), origin.y()));
+    result.transform(AffineTransform().scale(contentWidth().toFloat(), contentHeight().toFloat()));
+    result.translate(FloatSize(origin.x().toFloat(), origin.y().toFloat()));
     return result;
 }
 
@@ -141,9 +142,9 @@
     for (RenderObject* renderer = parent(); renderer; renderer = renderer->parent()) {
         if (!renderer->node())
             continue;
-        if (renderer->node()->hasTagName(detailsTag))
+        if (isHTMLDetailsElement(*renderer->node()))
             return !toElement(renderer->node())->getAttribute(openAttr).isNull();
-        if (renderer->node()->hasTagName(inputTag))
+        if (isHTMLInputElement(*renderer->node()))
             return true;
     }
 
diff --git a/Source/core/rendering/RenderDetailsMarker.h b/Source/core/rendering/RenderDetailsMarker.h
index 6876cda..5b20924 100644
--- a/Source/core/rendering/RenderDetailsMarker.h
+++ b/Source/core/rendering/RenderDetailsMarker.h
@@ -35,7 +35,6 @@
 
 private:
     virtual const char* renderName() const OVERRIDE { return "RenderDetailsMarker"; }
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
     virtual bool isDetailsMarker() const OVERRIDE { return true; }
     virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
 
diff --git a/Source/core/rendering/RenderEmbeddedObject.cpp b/Source/core/rendering/RenderEmbeddedObject.cpp
index 9dac195..ff57118 100644
--- a/Source/core/rendering/RenderEmbeddedObject.cpp
+++ b/Source/core/rendering/RenderEmbeddedObject.cpp
@@ -26,8 +26,8 @@
 
 #include "CSSValueKeywords.h"
 #include "HTMLNames.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "core/plugins/PluginView.h"
@@ -148,7 +148,7 @@
 
     GraphicsContextStateSaver stateSaver(*context);
     context->clip(contentRect);
-    context->setAlpha(replacementTextRoundedRectOpacity);
+    context->setAlphaAsFloat(replacementTextRoundedRectOpacity);
     context->setFillColor(Color::white);
     context->fillPath(path);
 
@@ -157,7 +157,7 @@
     float labelY = roundf(replacementTextRect.location().y() + (replacementTextRect.size().height() - fontMetrics.height()) / 2 + fontMetrics.ascent());
     TextRunPaintInfo runInfo(run);
     runInfo.bounds = replacementTextRect;
-    context->setAlpha(replacementTextTextOpacity);
+    context->setAlphaAsFloat(replacementTextTextOpacity);
     context->setFillColor(Color::black);
     context->drawBidiText(font, runInfo, FloatPoint(labelX, labelY));
 }
@@ -176,7 +176,7 @@
         return false;
     fontDescription.setComputedSize(fontDescription.specifiedSize());
     font = Font(fontDescription);
-    font.update(0);
+    font.update(nullptr);
 
     run = TextRun(m_unavailablePluginReplacementText);
     textWidth = font.width(run);
@@ -231,10 +231,7 @@
     if (newSize == oldSize && !childBox->needsLayout())
         return;
 
-    // When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or
-    // instantiate LayoutStateDisabler. Since using a LayoutStateMaintainer is slightly more efficient,
-    // and this method will be called many times per second during playback, use a LayoutStateMaintainer:
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     childBox->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
     childBox->style()->setHeight(Length(newSize.height(), Fixed));
diff --git a/Source/core/rendering/RenderFieldset.cpp b/Source/core/rendering/RenderFieldset.cpp
index 2537a9d..b83c824 100644
--- a/Source/core/rendering/RenderFieldset.cpp
+++ b/Source/core/rendering/RenderFieldset.cpp
@@ -26,6 +26,7 @@
 
 #include "CSSPropertyNames.h"
 #include "HTMLNames.h"
+#include "core/html/HTMLLegendElement.h"
 #include "core/rendering/PaintInfo.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
 
@@ -129,7 +130,7 @@
         if (option == IgnoreFloatingOrOutOfFlow && legend->isFloatingOrOutOfFlowPositioned())
             continue;
 
-        if (legend->node() && (legend->node()->hasTagName(legendTag)))
+        if (isHTMLLegendElement(legend->node()))
             return toRenderBox(legend);
     }
     return 0;
diff --git a/Source/core/rendering/RenderFieldset.h b/Source/core/rendering/RenderFieldset.h
index 545f10c..0ebc486 100644
--- a/Source/core/rendering/RenderFieldset.h
+++ b/Source/core/rendering/RenderFieldset.h
@@ -44,8 +44,6 @@
     virtual void computePreferredLogicalWidths() OVERRIDE;
     virtual bool avoidsFloats() const OVERRIDE { return true; }
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
     virtual void paintMask(PaintInfo&, const LayoutPoint&) OVERRIDE;
 };
diff --git a/Source/core/rendering/RenderFileUploadControl.cpp b/Source/core/rendering/RenderFileUploadControl.cpp
index 5829bec..de9bfba 100644
--- a/Source/core/rendering/RenderFileUploadControl.cpp
+++ b/Source/core/rendering/RenderFileUploadControl.cpp
@@ -131,10 +131,9 @@
         else
             textY = baselinePosition(AlphabeticBaseline, true, HorizontalLine, PositionOnContainingLine);
         TextRunPaintInfo textRunPaintInfo(textRun);
-        textRunPaintInfo.bounds = FloatRect(textX,
-                                            textY - style()->fontMetrics().ascent(),
-                                            textWidth,
-                                            style()->fontMetrics().height());
+        // FIXME: Shouldn't these offsets be rounded? crbug.com/350474
+        textRunPaintInfo.bounds = FloatRect(textX.toFloat(), textY.toFloat() - style()->fontMetrics().ascent(),
+            textWidth, style()->fontMetrics().height());
 
         paintInfo.context->setFillColor(resolveColor(CSSPropertyColor));
 
@@ -207,7 +206,7 @@
     // FIXME: This should be on HTMLInputElement as an API like innerButtonElement().
     HTMLInputElement* input = toHTMLInputElement(node());
     Node* buttonNode = input->userAgentShadowRoot()->firstChild();
-    return buttonNode && buttonNode->isHTMLElement() && buttonNode->hasTagName(inputTag) ? toHTMLInputElement(buttonNode) : 0;
+    return isHTMLInputElement(buttonNode) ? toHTMLInputElement(buttonNode) : 0;
 }
 
 String RenderFileUploadControl::buttonValue()
diff --git a/Source/core/rendering/RenderFileUploadControl.h b/Source/core/rendering/RenderFileUploadControl.h
index 85c4126..5e2f704 100644
--- a/Source/core/rendering/RenderFileUploadControl.h
+++ b/Source/core/rendering/RenderFileUploadControl.h
@@ -49,8 +49,6 @@
     virtual void computePreferredLogicalWidths() OVERRIDE;
     virtual void paintObject(PaintInfo&, const LayoutPoint&) OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     int maxFilenameWidth() const;
 
     virtual PositionWithAffinity positionForPoint(const LayoutPoint&) OVERRIDE;
diff --git a/Source/core/rendering/RenderFlexibleBox.cpp b/Source/core/rendering/RenderFlexibleBox.cpp
index 52772a5..696ff78 100644
--- a/Source/core/rendering/RenderFlexibleBox.cpp
+++ b/Source/core/rendering/RenderFlexibleBox.cpp
@@ -241,7 +241,7 @@
     LayoutUnit previousHeight = logicalHeight();
     setLogicalHeight(borderAndPaddingLogicalHeight() + scrollbarLogicalHeight());
 
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     RenderFlowThread* flowThread = flowThreadContainingBlock();
     if (updateRegionsAndShapesLogicalSize(flowThread))
diff --git a/Source/core/rendering/RenderFlexibleBox.h b/Source/core/rendering/RenderFlexibleBox.h
index 0801168..4309c27 100644
--- a/Source/core/rendering/RenderFlexibleBox.h
+++ b/Source/core/rendering/RenderFlexibleBox.h
@@ -61,8 +61,6 @@
 protected:
     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
     virtual void removeChild(RenderObject*) OVERRIDE;
 
diff --git a/Source/core/rendering/RenderFlowThread.cpp b/Source/core/rendering/RenderFlowThread.cpp
index a42e8b6..e72ec8a 100644
--- a/Source/core/rendering/RenderFlowThread.cpp
+++ b/Source/core/rendering/RenderFlowThread.cpp
@@ -67,7 +67,7 @@
     newStyle->setTop(Length(0, Fixed));
     newStyle->setWidth(Length(100, Percent));
     newStyle->setHeight(Length(100, Percent));
-    newStyle->font().update(0);
+    newStyle->font().update(nullptr);
 
     return newStyle.release();
 }
@@ -211,7 +211,7 @@
     if (!shouldRepaint(repaintRect) || !hasValidRegionInfo())
         return;
 
-    LayoutStateDisabler layoutStateDisabler(view()); // We can't use layout state to repaint, since the regions are somewhere else.
+    LayoutStateDisabler layoutStateDisabler(*this); // We can't use layout state to repaint, since the regions are somewhere else.
 
     // We can't use currentFlowThread as it is possible to have interleaved flow threads and the wrong one could be used.
     // Let each region figure out the proper enclosing flow thread.
@@ -566,7 +566,7 @@
     return 0;
 }
 
-void RenderFlowThread::pushFlowThreadLayoutState(const RenderObject* object)
+void RenderFlowThread::pushFlowThreadLayoutState(const RenderObject& object)
 {
     if (const RenderBox* currentBoxDescendant = currentStatePusherRenderBox()) {
         LayoutState* layoutState = currentBoxDescendant->view()->layoutState();
@@ -577,7 +577,7 @@
         }
     }
 
-    m_statePusherObjectsStack.add(object);
+    m_statePusherObjectsStack.add(&object);
 }
 
 void RenderFlowThread::popFlowThreadLayoutState()
diff --git a/Source/core/rendering/RenderFlowThread.h b/Source/core/rendering/RenderFlowThread.h
index 96010d9..385520a 100644
--- a/Source/core/rendering/RenderFlowThread.h
+++ b/Source/core/rendering/RenderFlowThread.h
@@ -123,7 +123,7 @@
     void collectLayerFragments(LayerFragments&, const LayoutRect& layerBoundingBox, const LayoutRect& dirtyRect);
     LayoutRect fragmentsBoundingBox(const LayoutRect& layerBoundingBox);
 
-    void pushFlowThreadLayoutState(const RenderObject*);
+    void pushFlowThreadLayoutState(const RenderObject&);
     void popFlowThreadLayoutState();
     LayoutUnit offsetFromLogicalTopOfFirstRegion(const RenderBlock*) const;
 
@@ -220,10 +220,6 @@
     bool m_regionsInvalidated : 1;
     bool m_regionsHaveUniformLogicalHeight : 1;
     bool m_pageLogicalSizeChanged : 1;
-
-private:
-    virtual bool supportsPartialLayout() const OVERRIDE FINAL { return false; }
-
 };
 
 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderFlowThread, isRenderFlowThread());
diff --git a/Source/core/rendering/RenderFrameSet.cpp b/Source/core/rendering/RenderFrameSet.cpp
index 40cdbd0..c2bee49 100644
--- a/Source/core/rendering/RenderFrameSet.cpp
+++ b/Source/core/rendering/RenderFrameSet.cpp
@@ -27,10 +27,10 @@
 #include "core/dom/Document.h"
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLDimension.h"
 #include "core/html/HTMLFrameSetElement.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/GraphicsContextAnnotator.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/PaintInfo.h"
@@ -596,7 +596,7 @@
         if (ancestor->isFrameSet())
             toRenderFrameSet(ancestor)->m_isChildResizing = isResizing;
     }
-    if (Frame* frame = this->frame())
+    if (LocalFrame* frame = this->frame())
         frame->eventHandler().setResizingFrameSet(isResizing ? frameSet() : 0);
 }
 
diff --git a/Source/core/rendering/RenderFullScreen.cpp b/Source/core/rendering/RenderFullScreen.cpp
index 664bc02..bca1d5b 100644
--- a/Source/core/rendering/RenderFullScreen.cpp
+++ b/Source/core/rendering/RenderFullScreen.cpp
@@ -40,7 +40,6 @@
     }
 private:
     virtual bool isRenderFullScreenPlaceholder() const OVERRIDE { return true; }
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
     virtual void willBeDestroyed() OVERRIDE;
     RenderFullScreen* m_owner;
 };
@@ -76,9 +75,9 @@
 
     // RenderObjects are unretained, so notify the document (which holds a pointer to a RenderFullScreen)
     // if it's RenderFullScreen is destroyed.
-    FullscreenElementStack* controller = FullscreenElementStack::from(&document());
-    if (controller->fullScreenRenderer() == this)
-        controller->fullScreenRendererDestroyed();
+    FullscreenElementStack& controller = FullscreenElementStack::from(document());
+    if (controller.fullScreenRenderer() == this)
+        controller.fullScreenRendererDestroyed();
 
     RenderFlexibleBox::willBeDestroyed();
 }
@@ -91,7 +90,7 @@
     fullscreenStyle->setZIndex(INT_MAX);
 
     fullscreenStyle->setFontDescription(FontDescription());
-    fullscreenStyle->font().update(0);
+    fullscreenStyle->font().update(nullptr);
 
     fullscreenStyle->setDisplay(FLEX);
     fullscreenStyle->setJustifyContent(JustifyCenter);
@@ -140,7 +139,8 @@
         fullscreenRenderer->setNeedsLayoutAndPrefWidthsRecalc();
     }
 
-    FullscreenElementStack::from(document)->setFullScreenRenderer(fullscreenRenderer);
+    ASSERT(document);
+    FullscreenElementStack::from(*document).setFullScreenRenderer(fullscreenRenderer);
     return fullscreenRenderer;
 }
 
@@ -162,7 +162,7 @@
     if (placeholder())
         placeholder()->remove();
     remove();
-    FullscreenElementStack::from(&document())->setFullScreenRenderer(0);
+    FullscreenElementStack::from(document()).setFullScreenRenderer(0);
 }
 
 void RenderFullScreen::setPlaceholder(RenderBlock* placeholder)
diff --git a/Source/core/rendering/RenderGeometryMap.cpp b/Source/core/rendering/RenderGeometryMap.cpp
index 07ab16f..038fe90 100644
--- a/Source/core/rendering/RenderGeometryMap.cpp
+++ b/Source/core/rendering/RenderGeometryMap.cpp
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "core/rendering/RenderGeometryMap.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderView.h"
 #include "platform/geometry/TransformState.h"
diff --git a/Source/core/rendering/RenderGrid.cpp b/Source/core/rendering/RenderGrid.cpp
index 2485447..3518810 100644
--- a/Source/core/rendering/RenderGrid.cpp
+++ b/Source/core/rendering/RenderGrid.cpp
@@ -258,7 +258,7 @@
     // FIXME: Much of this method is boiler plate that matches RenderBox::layoutBlock and Render*FlexibleBox::layoutBlock.
     // It would be nice to refactor some of the duplicate code.
     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     RenderFlowThread* flowThread = flowThreadContainingBlock();
     if (updateRegionsAndShapesLogicalSize(flowThread))
@@ -341,9 +341,9 @@
     computeUsedBreadthOfGridTracks(direction, sizingData, availableLogicalSpace);
 }
 
-static bool gridElementIsShrinkToFit(const RenderStyle& style)
+bool RenderGrid::gridElementIsShrinkToFit()
 {
-    return style.isFloating() || style.position() == AbsolutePosition;
+    return isFloatingOrOutOfFlowPositioned();
 }
 
 void RenderGrid::computeUsedBreadthOfGridTracks(GridTrackSizingDirection direction, GridSizingData& sizingData, LayoutUnit& availableLogicalSpace)
@@ -379,7 +379,7 @@
         availableLogicalSpace -= tracks[i].m_usedBreadth;
     }
 
-    const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->logicalHeight().isAuto() : gridElementIsShrinkToFit(*style());
+    const bool hasUndefinedRemainingSpace = (direction == ForRows) ? style()->logicalHeight().isAuto() : gridElementIsShrinkToFit();
 
     if (!hasUndefinedRemainingSpace && availableLogicalSpace <= 0)
         return;
@@ -970,13 +970,21 @@
 
 PassOwnPtr<GridSpan> RenderGrid::resolveGridPositionsFromStyle(const RenderBox* gridItem, GridTrackSizingDirection direction) const
 {
-    const GridPosition& initialPosition = (direction == ForColumns) ? gridItem->style()->gridColumnStart() : gridItem->style()->gridRowStart();
+    GridPosition initialPosition = (direction == ForColumns) ? gridItem->style()->gridColumnStart() : gridItem->style()->gridRowStart();
     const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide;
-    const GridPosition& finalPosition = (direction == ForColumns) ? gridItem->style()->gridColumnEnd() : gridItem->style()->gridRowEnd();
+    GridPosition finalPosition = (direction == ForColumns) ? gridItem->style()->gridColumnEnd() : gridItem->style()->gridRowEnd();
     const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide;
 
-    // We should NEVER see both spans as they should have been handled during style resolve.
-    ASSERT(!initialPosition.isSpan() || !finalPosition.isSpan());
+    // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to
+    // overwrite the specified values.
+    if (initialPosition.isSpan() && finalPosition.isSpan())
+        finalPosition.setAutoPosition();
+
+    if (initialPosition.isNamedGridArea() && !style()->namedGridArea().contains(initialPosition.namedGridLine()))
+        initialPosition.setAutoPosition();
+
+    if (finalPosition.isNamedGridArea() && !style()->namedGridArea().contains(finalPosition.namedGridLine()))
+        finalPosition.setAutoPosition();
 
     if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) {
         if (style()->gridAutoFlow() == AutoFlowNone)
diff --git a/Source/core/rendering/RenderGrid.h b/Source/core/rendering/RenderGrid.h
index 7e7cf0a..b893585 100644
--- a/Source/core/rendering/RenderGrid.h
+++ b/Source/core/rendering/RenderGrid.h
@@ -72,6 +72,7 @@
 
     class GridIterator;
     struct GridSizingData;
+    bool gridElementIsShrinkToFit();
     void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&);
     void computeUsedBreadthOfGridTracks(GridTrackSizingDirection, GridSizingData&, LayoutUnit& availableLogicalSpace);
     LayoutUnit computeUsedBreadthOfMinLength(GridTrackSizingDirection, const GridLength&) const;
@@ -93,8 +94,6 @@
     void layoutGridItems();
     void populateGridPositions(const GridSizingData&);
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     typedef LayoutUnit (RenderGrid::* SizingFunction)(RenderBox*, GridTrackSizingDirection, Vector<GridTrack>&);
     typedef LayoutUnit (GridTrack::* AccumulatorGetter)() const;
     typedef void (GridTrack::* AccumulatorGrowFunction)(LayoutUnit);
diff --git a/Source/core/rendering/RenderHTMLCanvas.cpp b/Source/core/rendering/RenderHTMLCanvas.cpp
index 1b83517..f2b67c7 100644
--- a/Source/core/rendering/RenderHTMLCanvas.cpp
+++ b/Source/core/rendering/RenderHTMLCanvas.cpp
@@ -28,8 +28,8 @@
 
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/canvas/CanvasRenderingContext.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/Page.h"
 #include "core/rendering/PaintInfo.h"
 #include "core/rendering/RenderView.h"
diff --git a/Source/core/rendering/RenderIFrame.cpp b/Source/core/rendering/RenderIFrame.cpp
index 986240a..4afa113 100644
--- a/Source/core/rendering/RenderIFrame.cpp
+++ b/Source/core/rendering/RenderIFrame.cpp
@@ -27,9 +27,9 @@
 #include "core/rendering/RenderIFrame.h"
 
 #include "HTMLNames.h"
-#include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLIFrameElement.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/RenderView.h"
 
@@ -58,7 +58,10 @@
     if (type != NoLayer)
         return type;
 
-    return NormalLayer;
+    if (style()->resize() != RESIZE_NONE)
+        return NormalLayer;
+
+    return ForcedLayer;
 }
 
 RenderView* RenderIFrame::contentRootRenderer() const
diff --git a/Source/core/rendering/RenderImage.cpp b/Source/core/rendering/RenderImage.cpp
index 7e7e5ea..0730452 100644
--- a/Source/core/rendering/RenderImage.cpp
+++ b/Source/core/rendering/RenderImage.cpp
@@ -33,12 +33,12 @@
 #include "core/fetch/ImageResource.h"
 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
 #include "core/fetch/ResourceLoader.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAreaElement.h"
 #include "core/html/HTMLImageElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLMapElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/PaintInfo.h"
@@ -351,7 +351,7 @@
                 // Only draw the alt text if it'll fit within the content box,
                 // and only if it fits above the error image.
                 TextRun textRun = RenderBlockFlow::constructTextRun(this, font, m_altText, style(), TextRun::AllowTrailingExpansion | TextRun::ForbidLeadingExpansion, DefaultTextRunFlags | RespectDirection);
-                LayoutUnit textWidth = font.width(textRun);
+                float textWidth = font.width(textRun);
                 TextRunPaintInfo textRunPaintInfo(textRun);
                 textRunPaintInfo.bounds = FloatRect(textRectOrigin, FloatSize(textWidth, fontMetrics.height()));
                 context->setFillColor(resolveColor(CSSPropertyColor));
@@ -408,21 +408,21 @@
         return;
 
     Element* focusedElement = document.focusedElement();
-    if (!focusedElement || !focusedElement->hasTagName(areaTag))
+    if (!isHTMLAreaElement(focusedElement))
         return;
 
-    HTMLAreaElement* areaElement = toHTMLAreaElement(focusedElement);
-    if (areaElement->imageElement() != node())
+    HTMLAreaElement& areaElement = toHTMLAreaElement(*focusedElement);
+    if (areaElement.imageElement() != node())
         return;
 
     // Even if the theme handles focus ring drawing for entire elements, it won't do it for
     // an area within an image, so we don't call RenderTheme::supportsFocusRing here.
 
-    Path path = areaElement->computePath(this);
+    Path path = areaElement.computePath(this);
     if (path.isEmpty())
         return;
 
-    RenderStyle* areaElementStyle = areaElement->computedStyle();
+    RenderStyle* areaElementStyle = areaElement.computedStyle();
     unsigned short outlineWidth = areaElementStyle->outlineWidth();
     if (!outlineWidth)
         return;
@@ -464,7 +464,7 @@
     if (!img || img->isNull())
         return;
 
-    HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? toHTMLImageElement(node()) : 0;
+    HTMLImageElement* imageElt = isHTMLImageElement(node()) ? toHTMLImageElement(node()) : 0;
     CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver;
     Image* image = m_imageResource->image().get();
     bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, alignedRect.size());
@@ -522,7 +522,7 @@
 
 HTMLMapElement* RenderImage::imageMap() const
 {
-    HTMLImageElement* i = node() && node()->hasTagName(imgTag) ? toHTMLImageElement(node()) : 0;
+    HTMLImageElement* i = isHTMLImageElement(node()) ? toHTMLImageElement(node()) : 0;
     return i ? i->treeScope().getImageMap(i->fastGetAttribute(usemapAttr)) : 0;
 }
 
@@ -555,9 +555,9 @@
     if (!node())
         return;
 
-    if (node()->hasTagName(inputTag))
+    if (isHTMLInputElement(*node()))
         m_altText = toHTMLInputElement(node())->altText();
-    else if (node()->hasTagName(imgTag))
+    else if (isHTMLImageElement(*node()))
         m_altText = toHTMLImageElement(node())->altText();
 }
 
@@ -601,8 +601,8 @@
         RenderObject* containingBlock = isOutOfFlowPositioned() ? container() : this->containingBlock();
         if (containingBlock->isBox()) {
             RenderBox* box = toRenderBox(containingBlock);
-            intrinsicSize.setWidth(box->availableLogicalWidth());
-            intrinsicSize.setHeight(box->availableLogicalHeight(IncludeMarginBorderPadding));
+            intrinsicSize.setWidth(box->availableLogicalWidth().toFloat());
+            intrinsicSize.setHeight(box->availableLogicalHeight(IncludeMarginBorderPadding).toFloat());
         }
     }
     // Don't compute an intrinsic ratio to preserve historical WebKit behavior if we're painting alt text and/or a broken image.
diff --git a/Source/core/rendering/RenderImageResourceStyleImage.cpp b/Source/core/rendering/RenderImageResourceStyleImage.cpp
index 5e0fff7..eded16a 100644
--- a/Source/core/rendering/RenderImageResourceStyleImage.cpp
+++ b/Source/core/rendering/RenderImageResourceStyleImage.cpp
@@ -65,7 +65,7 @@
 {
     // Generated content may trigger calls to image() while we're still pending, don't assert but gracefully exit.
     if (m_styleImage->isPendingImage())
-        return 0;
+        return nullptr;
     return m_styleImage->image(m_renderer, IntSize(width, height));
 }
 
diff --git a/Source/core/rendering/RenderInline.cpp b/Source/core/rendering/RenderInline.cpp
index 90a4c32..40cd807 100644
--- a/Source/core/rendering/RenderInline.cpp
+++ b/Source/core/rendering/RenderInline.cpp
@@ -349,7 +349,7 @@
     // that renderer is wrapped in a RenderFullScreen, so |this| is not its
     // parent. Since the splitting logic expects |this| to be the parent, set
     // |beforeChild| to be the RenderFullScreen.
-    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(&document())) {
+    if (FullscreenElementStack* fullscreen = FullscreenElementStack::fromIfExists(document())) {
         const Element* fullScreenElement = fullscreen->webkitCurrentFullScreenElement();
         if (fullScreenElement && beforeChild && beforeChild->node() == fullScreenElement)
             beforeChild = fullscreen->fullScreenRenderer();
@@ -558,13 +558,13 @@
         if (curr->isBox()) {
             RenderBox* currBox = toRenderBox(curr);
             if (currBox->inlineBoxWrapper()) {
-                RootInlineBox* rootBox = currBox->inlineBoxWrapper()->root();
-                int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
-                int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
+                RootInlineBox& rootBox = currBox->inlineBoxWrapper()->root();
+                int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
+                int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
                 if (isHorizontal)
-                    yield(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, currBox->width() + currBox->marginWidth(), logicalHeight));
+                    yield(FloatRect(currBox->inlineBoxWrapper()->x() - currBox->marginLeft(), logicalTop, (currBox->width() + currBox->marginWidth()).toFloat(), logicalHeight));
                 else
-                    yield(FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, currBox->height() + currBox->marginHeight()));
+                    yield(FloatRect(logicalTop, currBox->inlineBoxWrapper()->y() - currBox->marginTop(), logicalHeight, (currBox->height() + currBox->marginHeight()).toFloat()));
             }
         } else if (curr->isRenderInline()) {
             // If the child doesn't need line boxes either, then we can recur.
@@ -573,9 +573,9 @@
                 currInline->generateCulledLineBoxRects(yield, container);
             else {
                 for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox()) {
-                    RootInlineBox* rootBox = childLine->root();
-                    int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
-                    int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
+                    RootInlineBox& rootBox = childLine->root();
+                    int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
+                    int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
                     if (isHorizontal)
                         yield(FloatRect(childLine->x() - childLine->marginLogicalLeft(),
                             logicalTop,
@@ -591,9 +591,9 @@
         } else if (curr->isText()) {
             RenderText* currText = toRenderText(curr);
             for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox()) {
-                RootInlineBox* rootBox = childText->root();
-                int logicalTop = rootBox->logicalTop() + (rootBox->renderer()->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox->isFirstLineStyle())->font().fontMetrics().ascent());
-                int logicalHeight = container->style(rootBox->isFirstLineStyle())->font().fontMetrics().height();
+                RootInlineBox& rootBox = childText->root();
+                int logicalTop = rootBox.logicalTop() + (rootBox.renderer().style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent() - container->style(rootBox.isFirstLineStyle())->font().fontMetrics().ascent());
+                int logicalHeight = container->style(rootBox.isFirstLineStyle())->font().fontMetrics().height();
                 if (isHorizontal)
                     yield(FloatRect(childText->x(), logicalTop, childText->logicalWidth(), logicalHeight));
                 else
@@ -980,12 +980,12 @@
         logicalRightSide = max(logicalRightSide, curr->logicalRightVisualOverflow());
     }
 
-    RootInlineBox* firstRootBox = firstLineBox()->root();
-    RootInlineBox* lastRootBox = lastLineBox()->root();
+    RootInlineBox& firstRootBox = firstLineBox()->root();
+    RootInlineBox& lastRootBox = lastLineBox()->root();
 
-    LayoutUnit logicalTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox->lineTop());
+    LayoutUnit logicalTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox.lineTop());
     LayoutUnit logicalWidth = logicalRightSide - logicalLeftSide;
-    LayoutUnit logicalHeight = lastLineBox()->logicalBottomVisualOverflow(lastRootBox->lineBottom()) - logicalTop;
+    LayoutUnit logicalHeight = lastLineBox()->logicalBottomVisualOverflow(lastRootBox.lineBottom()) - logicalTop;
 
     LayoutRect rect(logicalLeftSide, logicalTop, logicalWidth, logicalHeight);
     if (!style()->isHorizontalWritingMode())
@@ -1246,16 +1246,16 @@
             if (curr->isBox() && !curr->needsLayout()) {
                 RenderBox* currBox = toRenderBox(curr);
                 if (currBox->inlineBoxWrapper())
-                    currBox->inlineBoxWrapper()->root()->markDirty();
+                    currBox->inlineBoxWrapper()->root().markDirty();
             } else if (!curr->selfNeedsLayout()) {
                 if (curr->isRenderInline()) {
                     RenderInline* currInline = toRenderInline(curr);
                     for (InlineFlowBox* childLine = currInline->firstLineBox(); childLine; childLine = childLine->nextLineBox())
-                        childLine->root()->markDirty();
+                        childLine->root().markDirty();
                 } else if (curr->isText()) {
                     RenderText* currText = toRenderText(curr);
                     for (InlineTextBox* childText = currText->firstTextBox(); childText; childText = childText->nextTextBox())
-                        childText->root()->markDirty();
+                        childText->root().markDirty();
                 }
             }
         }
@@ -1270,7 +1270,7 @@
 
 InlineFlowBox* RenderInline::createInlineFlowBox()
 {
-    return new InlineFlowBox(this);
+    return new InlineFlowBox(*this);
 }
 
 InlineFlowBox* RenderInline::createAndAppendInlineFlowBox()
@@ -1299,7 +1299,7 @@
     return fontMetrics.ascent(baselineType) + (lineHeight(firstLine, direction, linePositionMode) - fontMetrics.height()) / 2;
 }
 
-LayoutSize RenderInline::offsetForInFlowPositionedInline(const RenderBox* child) const
+LayoutSize RenderInline::offsetForInFlowPositionedInline(const RenderBox& child) const
 {
     // FIXME: This function isn't right with mixed writing modes.
 
@@ -1322,18 +1322,18 @@
         blockPosition = layer()->staticBlockPosition();
     }
 
-    if (!child->style()->hasStaticInlinePosition(style()->isHorizontalWritingMode()))
+    if (!child.style()->hasStaticInlinePosition(style()->isHorizontalWritingMode()))
         logicalOffset.setWidth(inlinePosition);
 
     // This is not terribly intuitive, but we have to match other browsers.  Despite being a block display type inside
     // an inline, we still keep our x locked to the left of the relative positioned inline.  Arguably the correct
     // behavior would be to go flush left to the block that contains the inline, but that isn't what other browsers
     // do.
-    else if (!child->style()->isOriginalDisplayInlineType())
+    else if (!child.style()->isOriginalDisplayInlineType())
         // Avoid adding in the left border/padding of the containing block twice.  Subtract it out.
-        logicalOffset.setWidth(inlinePosition - child->containingBlock()->borderAndPaddingLogicalLeft());
+        logicalOffset.setWidth(inlinePosition - child.containingBlock()->borderAndPaddingLogicalLeft());
 
-    if (!child->style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
+    if (!child.style()->hasStaticBlockPosition(style()->isHorizontalWritingMode()))
         logicalOffset.setHeight(blockPosition);
 
     return style()->isHorizontalWritingMode() ? logicalOffset : logicalOffset.transposedSize();
@@ -1424,9 +1424,9 @@
 
     rects.append(LayoutRect());
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
-        RootInlineBox* root = curr->root();
-        LayoutUnit top = max<LayoutUnit>(root->lineTop(), curr->logicalTop());
-        LayoutUnit bottom = min<LayoutUnit>(root->lineBottom(), curr->logicalBottom());
+        RootInlineBox& root = curr->root();
+        LayoutUnit top = max<LayoutUnit>(root.lineTop(), curr->logicalTop());
+        LayoutUnit bottom = min<LayoutUnit>(root.lineBottom(), curr->logicalBottom());
         rects.append(LayoutRect(curr->x(), top, curr->logicalWidth(), bottom - top));
     }
     rects.append(LayoutRect());
diff --git a/Source/core/rendering/RenderInline.h b/Source/core/rendering/RenderInline.h
index e3a9f0c..947492e 100644
--- a/Source/core/rendering/RenderInline.h
+++ b/Source/core/rendering/RenderInline.h
@@ -79,7 +79,7 @@
 
     virtual void updateDragState(bool dragOn) OVERRIDE FINAL;
 
-    LayoutSize offsetForInFlowPositionedInline(const RenderBox* child) const;
+    LayoutSize offsetForInFlowPositionedInline(const RenderBox& child) const;
 
     virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE FINAL;
     void paintOutline(PaintInfo&, const LayoutPoint&);
diff --git a/Source/core/rendering/RenderLayer.cpp b/Source/core/rendering/RenderLayer.cpp
index 26a550c..ebda58d 100644
--- a/Source/core/rendering/RenderLayer.cpp
+++ b/Source/core/rendering/RenderLayer.cpp
@@ -53,14 +53,13 @@
 #include "core/dom/Document.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/frame/DeprecatedScheduleStyleRecalcDuringLayout.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLFrameElement.h"
 #include "core/page/Page.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
 #include "core/rendering/ColumnInfo.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/FilterEffectRenderer.h"
 #include "core/rendering/HitTestRequest.h"
 #include "core/rendering/HitTestResult.h"
@@ -68,12 +67,13 @@
 #include "core/rendering/RenderFlowThread.h"
 #include "core/rendering/RenderGeometryMap.h"
 #include "core/rendering/RenderInline.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderReplica.h"
 #include "core/rendering/RenderScrollbar.h"
 #include "core/rendering/RenderScrollbarPart.h"
 #include "core/rendering/RenderTreeAsText.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/rendering/svg/ReferenceFilterBuilder.h"
 #include "core/rendering/svg/RenderSVGResourceClipper.h"
 #include "platform/LengthFunctions.h"
@@ -105,7 +105,7 @@
 using namespace HTMLNames;
 
 RenderLayer::RenderLayer(RenderLayerModelObject* renderer, LayerType type)
-    : m_isOverflowOnlyLayer(type == OverflowClipLayer)
+    : m_layerType(type)
     , m_hasSelfPaintingLayerDescendant(false)
     , m_hasSelfPaintingLayerDescendantDirty(false)
     , m_hasOutOfFlowPositionedDescendant(false)
@@ -193,12 +193,13 @@
 
 void RenderLayer::contentChanged(ContentChangeType changeType)
 {
-    DisableCompositingQueryAsserts disabler;
-
     // This can get called when video becomes accelerated, so the layers may change.
     if (changeType == CanvasChanged || changeType == VideoChanged || changeType == FullScreenChanged)
         compositor()->updateLayerCompositingState(this);
 
+    if (changeType == CanvasContextChanged)
+        compositor()->setNeedsCompositingUpdate(CompositingUpdateAfterCanvasContextChange);
+
     if (m_compositedLayerMapping)
         m_compositedLayerMapping->contentChanged(changeType);
 }
@@ -215,10 +216,9 @@
 
     // https://code.google.com/p/chromium/issues/detail?id=343759
     DisableCompositingQueryAsserts disabler;
-    if (compositingState() != PaintsIntoOwnBacking)
-        return true;
-
-    if (!m_compositedLayerMapping || !m_compositedLayerMapping->canCompositeFilters())
+    if (!m_compositedLayerMapping
+        || compositingState() != PaintsIntoOwnBacking
+        || !m_compositedLayerMapping->canCompositeFilters())
         return true;
 
     return false;
@@ -712,8 +712,17 @@
         return;
     }
 
-    m_visibleContentStatusDirty = false;
     m_hasVisibleContent = true;
+    m_visibleContentStatusDirty = false;
+
+    {
+        // FIXME: We can remove this code once we remove the recursive tree
+        // walk inside updateGraphicsLayerGeometry.
+        DisableCompositingQueryAsserts disabler;
+        if (RenderLayer* compositingLayer = enclosingCompositingLayer())
+            compositingLayer->compositedLayerMapping()->setNeedsGeometryUpdate();
+    }
+
     repainter().computeRepaintRects(renderer()->containerForRepaint());
     if (!m_stackingNode->isNormalFlowOnly()) {
         // We don't collect invisible layers in z-order lists if we are not in compositing mode.
@@ -850,6 +859,7 @@
     }
 
     if (m_visibleContentStatusDirty) {
+        bool previouslyHasVisibleCOntent = m_hasVisibleContent;
         if (renderer()->style()->visibility() == VISIBLE)
             m_hasVisibleContent = true;
         else {
@@ -877,6 +887,14 @@
             }
         }
         m_visibleContentStatusDirty = false;
+
+        // FIXME: We can remove this code once we remove the recursive tree
+        // walk inside updateGraphicsLayerGeometry.
+        if (hasVisibleContent() != previouslyHasVisibleCOntent) {
+            DisableCompositingQueryAsserts disabler;
+            if (RenderLayer* compositingLayer = enclosingCompositingLayer())
+                compositingLayer->compositedLayerMapping()->setNeedsGeometryUpdate();
+        }
     }
 }
 
@@ -966,7 +984,7 @@
         }
 
         if (renderer()->isOutOfFlowPositioned() && positionedParent->renderer()->isInFlowPositioned() && positionedParent->renderer()->isRenderInline()) {
-            LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(toRenderBox(renderer()));
+            LayoutSize offset = toRenderInline(positionedParent->renderer())->offsetForInFlowPositionedInline(*toRenderBox(renderer()));
             localPoint += offset;
         }
     } else if (parent()) {
@@ -1073,7 +1091,11 @@
 
 const RenderLayer* RenderLayer::compositingContainer() const
 {
-    return stackingNode()->isNormalFlowOnly() ? parent() : (stackingNode()->ancestorStackingContainerNode() ? stackingNode()->ancestorStackingContainerNode()->layer() : 0);
+    if (stackingNode()->isNormalFlowOnly())
+        return parent();
+    if (RenderLayerStackingNode* ancestorStackingNode = stackingNode()->ancestorStackingContainerNode())
+        return ancestorStackingNode->layer();
+    return 0;
 }
 
 // FIXME: having two different functions named enclosingCompositingLayer and enclosingCompositingLayerForRepaint
@@ -1155,6 +1177,14 @@
     return 0;
 }
 
+void RenderLayer::setCompositingReasons(CompositingReasons reasons)
+{
+    if (m_compositingProperties.compositingReasons == reasons)
+        return;
+    m_compositingProperties.compositingReasons = reasons;
+    m_clipper.setCompositingClipRectsDirty();
+}
+
 bool RenderLayer::hasAncestorWithFilterOutsets() const
 {
     for (const RenderLayer* curr = this; curr; curr = curr->parent()) {
@@ -1206,10 +1236,10 @@
     RootOfTransparencyClipBox
 };
 
-static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, PaintBehavior = 0);
+static LayoutRect transparencyClipBox(const RenderLayer*, const RenderLayer* rootLayer, TransparencyClipBoxBehavior, TransparencyClipBoxMode, const LayoutSize& subPixelAccumulation, PaintBehavior = 0);
 
 static void expandClipRectForDescendantsAndReflection(LayoutRect& clipRect, const RenderLayer* layer, const RenderLayer* rootLayer,
-    TransparencyClipBoxBehavior transparencyBehavior, PaintBehavior paintBehavior)
+    TransparencyClipBoxBehavior transparencyBehavior, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
     // If we have a mask, then the clip is limited to the border box area (and there is
     // no need to examine child layers).
@@ -1218,7 +1248,7 @@
         // a stacking container. This means we can just walk the layer tree directly.
         for (RenderLayer* curr = layer->firstChild(); curr; curr = curr->nextSibling()) {
             if (!layer->reflectionInfo() || layer->reflectionInfo()->reflectionLayer() != curr)
-                clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, paintBehavior));
+                clipRect.unite(transparencyClipBox(curr, rootLayer, transparencyBehavior, DescendantsOfTransparencyClipBox, subPixelAccumulation, paintBehavior));
         }
     }
 
@@ -1236,7 +1266,7 @@
 }
 
 static LayoutRect transparencyClipBox(const RenderLayer* layer, const RenderLayer* rootLayer, TransparencyClipBoxBehavior transparencyBehavior,
-    TransparencyClipBoxMode transparencyMode, PaintBehavior paintBehavior)
+    TransparencyClipBoxMode transparencyMode, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
     // FIXME: Although this function completely ignores CSS-imposed clipping, we did already intersect with the
     // paintDirtyRect, and that should cut down on the amount we have to paint.  Still it
@@ -1251,14 +1281,16 @@
         LayoutPoint delta;
         layer->convertToLayerCoords(rootLayerForTransform, delta);
 
+        delta.move(subPixelAccumulation);
+        IntPoint pixelSnappedDelta = roundedIntPoint(delta);
         TransformationMatrix transform;
-        transform.translate(delta.x(), delta.y());
+        transform.translate(pixelSnappedDelta.x(), pixelSnappedDelta.y());
         transform = transform * *layer->transform();
 
         // We don't use fragment boxes when collecting a transformed layer's bounding box, since it always
         // paints unfragmented.
         LayoutRect clipRect = layer->boundingBox(layer);
-        expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, paintBehavior);
+        expandClipRectForDescendantsAndReflection(clipRect, layer, layer, transparencyBehavior, subPixelAccumulation, paintBehavior);
         layer->renderer()->style()->filterOutsets().expandRect(clipRect);
         LayoutRect result = transform.mapRect(clipRect);
         if (!paginationLayer)
@@ -1277,17 +1309,18 @@
     }
 
     LayoutRect clipRect = layer->boundingBox(rootLayer, RenderLayer::UseFragmentBoxes);
-    expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, paintBehavior);
+    expandClipRectForDescendantsAndReflection(clipRect, layer, rootLayer, transparencyBehavior, subPixelAccumulation, paintBehavior);
     layer->renderer()->style()->filterOutsets().expandRect(clipRect);
+    clipRect.move(subPixelAccumulation);
     return clipRect;
 }
 
-LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
+LayoutRect RenderLayer::paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
-    return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintBehavior), paintDirtyRect);
+    return intersection(transparencyClipBox(this, rootLayer, PaintingTransparencyClipBox, RootOfTransparencyClipBox, subPixelAccumulation, paintBehavior), paintDirtyRect);
 }
 
-void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior paintBehavior)
+void RenderLayer::beginTransparencyLayers(GraphicsContext* context, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior paintBehavior)
 {
     bool createTransparencyLayerForBlendMode = m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode();
     if (context->paintingDisabled() || ((paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) && m_usedTransparency))
@@ -1295,12 +1328,12 @@
 
     RenderLayer* ancestor = transparentPaintingAncestor();
     if (ancestor)
-        ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, paintBehavior);
+        ancestor->beginTransparencyLayers(context, rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
 
     if (paintsWithTransparency(paintBehavior) || paintsWithBlendMode() || createTransparencyLayerForBlendMode) {
         m_usedTransparency = true;
         context->save();
-        LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, paintBehavior);
+        LayoutRect clipRect = paintingExtent(rootLayer, paintDirtyRect, subPixelAccumulation, paintBehavior);
         context->clip(clipRect);
 
         if (paintsWithBlendMode())
@@ -1408,6 +1441,9 @@
         oldChild->stackingNode()->dirtyStackingContainerZOrderLists();
     }
 
+    if (renderer()->style()->visibility() != VISIBLE)
+        dirtyVisibleContentStatus();
+
     oldChild->setPreviousSibling(0);
     oldChild->setNextSibling(0);
     oldChild->setParent(0);
@@ -1457,6 +1493,10 @@
         removeChild(current);
         m_parent->addChild(current, nextSib);
         current->repainter().setRepaintStatus(NeedsFullRepaint);
+
+        // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-part-1.html
+        DisableCompositingQueryAsserts disabler;
+
         current->updateLayerPositions(0); // FIXME: use geometry map.
         current = next;
     }
@@ -1666,15 +1706,11 @@
 
 RenderLayer* RenderLayer::clipParent() const
 {
-    const bool needsAncestorClip = compositor()->clippedByAncestor(this);
-
-    RenderLayer* clipParent = 0;
-    if ((compositingReasons() & CompositingReasonOutOfFlowClipping) && !needsAncestorClip) {
+    if (compositingReasons() & CompositingReasonOutOfFlowClipping && !compositor()->clippedByAncestor(this)) {
         if (RenderObject* containingBlock = renderer()->containingBlock())
-            clipParent = containingBlock->enclosingLayer()->enclosingCompositingLayer();
+            return containingBlock->enclosingLayer()->enclosingCompositingLayer();
     }
-
-    return clipParent;
+    return 0;
 }
 
 void RenderLayer::didUpdateNeedsCompositedScrolling()
@@ -1770,10 +1806,10 @@
     return false;
 }
 
-void RenderLayer::clipToRect(RenderLayer* rootLayer, GraphicsContext* context, const LayoutRect& paintDirtyRect, const ClipRect& clipRect,
+void RenderLayer::clipToRect(const LayerPaintingInfo& localPaintingInfo, GraphicsContext* context, const ClipRect& clipRect,
                              BorderRadiusClippingRule rule)
 {
-    if (clipRect.rect() == paintDirtyRect && !clipRect.hasRadius())
+    if (clipRect.rect() == localPaintingInfo.paintDirtyRect && !clipRect.hasRadius())
         return;
     context->save();
     context->clip(pixelSnappedIntRect(clipRect.rect()));
@@ -1787,11 +1823,11 @@
     for (RenderLayer* layer = rule == IncludeSelfForBorderRadius ? this : parent(); layer; layer = layer->parent()) {
         if (layer->renderer()->hasOverflowClip() && layer->renderer()->style()->hasBorderRadius() && inContainingBlockChain(this, layer)) {
                 LayoutPoint delta;
-                layer->convertToLayerCoords(rootLayer, delta);
+                layer->convertToLayerCoords(localPaintingInfo.rootLayer, delta);
                 context->clipRoundedRect(layer->renderer()->style()->getRoundedInnerBorderFor(LayoutRect(delta, layer->size())));
         }
 
-        if (layer == rootLayer)
+        if (layer == localPaintingInfo.rootLayer)
             break;
     }
 }
@@ -1887,9 +1923,9 @@
         // layer from the parent now, assuming there is a parent
         if (paintFlags & PaintLayerHaveTransparency) {
             if (parent())
-                parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+                parent()->beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
             else
-                beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+                beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
         }
 
         if (enclosingPaginationLayer()) {
@@ -1906,7 +1942,7 @@
             clipRect.intersect(paintingInfo.paintDirtyRect);
 
             // Push the parent coordinate space's clip.
-            parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
+            parent()->clipToRect(paintingInfo, context, clipRect);
         }
 
         paintLayerByApplyingTransform(context, paintingInfo, paintFlags);
@@ -2001,7 +2037,7 @@
             Document& document = renderer()->document();
             // FIXME: It doesn't work with forward or external SVG references (https://bugs.webkit.org/show_bug.cgi?id=90405)
             Element* element = document.getElementById(referenceClipPathOperation->fragment());
-            if (element && element->hasTagName(SVGNames::clipPathTag) && element->renderer()) {
+            if (isSVGClipPathElement(element) && element->renderer()) {
                 if (!rootRelativeBoundsComputed) {
                     rootRelativeBounds = calculateLayerBounds(paintingInfo.rootLayer, &offsetFromRoot, 0);
                     rootRelativeBoundsComputed = true;
@@ -2022,7 +2058,7 @@
     bool createTransparencyLayerForBlendMode = !renderer()->isRoot() && m_stackingNode->isStackingContext() && m_blendInfo.childLayerHasBlendMode();
 
     if (createTransparencyLayerForBlendMode)
-        beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.paintBehavior);
+        beginTransparencyLayers(context, paintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
 
     LayerPaintingInfo localPaintingInfo(paintingInfo);
     FilterEffectRendererHelper filterPainter(filterRenderer() && paintsWithFilters());
@@ -2058,7 +2094,7 @@
 
     if (filterPainter.hasStartedFilterEffect() && haveTransparency) {
         // If we have a filter and transparency, we have to eagerly start a transparency layer here, rather than risk a child layer lazily starts one with the wrong context.
-        beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, localPaintingInfo.paintBehavior);
+        beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, paintingInfo.paintDirtyRect, paintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
     }
 
     // If this layer's renderer is a child of the paintingRoot, we render unconditionally, which
@@ -2123,7 +2159,7 @@
         // Apply the correct clipping (ie. overflow: hidden).
         // FIXME: It is incorrect to just clip to the damageRect here once multiple fragments are involved.
         ClipRect backgroundRect = layerFragments.isEmpty() ? ClipRect() : layerFragments[0].backgroundRect;
-        clipToRect(localPaintingInfo.rootLayer, transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
+        clipToRect(localPaintingInfo, transparencyLayerContext, backgroundRect);
         context = filterPainter.applyFilterEffect();
         restoreClip(transparencyLayerContext, localPaintingInfo.paintDirtyRect, backgroundRect);
     }
@@ -2292,7 +2328,7 @@
 {
     LayerFragments enclosingPaginationFragments;
     LayoutPoint offsetOfPaginationLayerFromRoot;
-    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.paintBehavior);
+    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), PaintingTransparencyClipBox, RootOfTransparencyClipBox, paintingInfo.subPixelAccumulation, paintingInfo.paintBehavior);
     enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, paintingInfo.rootLayer, paintingInfo.paintDirtyRect,
         (paintFlags & PaintLayerTemporaryClipRects) ? TemporaryClipRects : PaintingClipRects, IgnoreOverlayScrollbarSize,
         (paintFlags & PaintLayerPaintingOverflowContents) ? IgnoreOverflowClip : RespectOverflowClip, &offsetOfPaginationLayerFromRoot, paintingInfo.subPixelAccumulation, &transformedExtent);
@@ -2315,7 +2351,7 @@
             clipRect.intersect(parentClipRect);
         }
 
-        parent()->clipToRect(paintingInfo.rootLayer, context, paintingInfo.paintDirtyRect, clipRect);
+        parent()->clipToRect(paintingInfo, context, clipRect);
         paintLayerByApplyingTransform(context, paintingInfo, paintFlags, fragment.paginationOffset);
         parent()->restoreClip(context, paintingInfo.paintDirtyRect, clipRect);
     }
@@ -2341,12 +2377,12 @@
 
         // Begin transparency layers lazily now that we know we have to paint something.
         if (haveTransparency || paintsWithBlendMode())
-            beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
+            beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
 
         if (localPaintingInfo.clipToDirtyRect) {
             // Paint our background first, before painting any child layers.
             // Establish the clip used to paint our background.
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
+            clipToRect(localPaintingInfo, context, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Background painting will handle clipping to self.
         }
 
         // Paint the background.
@@ -2368,7 +2404,7 @@
         for (size_t i = 0; i < layerFragments.size(); ++i) {
             const LayerFragment& fragment = layerFragments.at(i);
             if (fragment.shouldPaintContent && !fragment.foregroundRect.isEmpty()) {
-                beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.paintBehavior);
+                beginTransparencyLayers(transparencyLayerContext, localPaintingInfo.rootLayer, transparencyPaintDirtyRect, localPaintingInfo.subPixelAccumulation, localPaintingInfo.paintBehavior);
                 break;
             }
         }
@@ -2379,7 +2415,7 @@
     // Optimize clipping for the single fragment case.
     bool shouldClip = localPaintingInfo.clipToDirtyRect && layerFragments.size() == 1 && layerFragments[0].shouldPaintContent && !layerFragments[0].foregroundRect.isEmpty();
     if (shouldClip)
-        clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, layerFragments[0].foregroundRect);
+        clipToRect(localPaintingInfo, context, layerFragments[0].foregroundRect);
 
     // We have to loop through every fragment multiple times, since we have to repaint in each specific phase in order for
     // interleaving of the fragments to work properly.
@@ -2407,7 +2443,7 @@
             continue;
 
         if (shouldClip)
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect);
+            clipToRect(localPaintingInfo, context, fragment.foregroundRect);
 
         PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.foregroundRect.rect()), phase, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
         if (phase == PaintPhaseForeground)
@@ -2429,7 +2465,7 @@
 
         // Paint our own outline
         PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.outlineRect.rect()), PaintPhaseSelfOutline, paintBehavior, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
-        clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.outlineRect, DoNotIncludeSelfForBorderRadius);
+        clipToRect(localPaintingInfo, context, fragment.outlineRect, DoNotIncludeSelfForBorderRadius);
         renderer()->paint(paintInfo, toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState())));
         restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.outlineRect);
     }
@@ -2444,7 +2480,7 @@
             continue;
 
         if (localPaintingInfo.clipToDirtyRect)
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
+            clipToRect(localPaintingInfo, context, fragment.backgroundRect, DoNotIncludeSelfForBorderRadius); // Mask painting will handle clipping to self.
 
         // Paint the mask.
         // FIXME: Eventually we will collect the region from the fragment itself instead of just from the paint info.
@@ -2465,7 +2501,7 @@
             continue;
 
         if (localPaintingInfo.clipToDirtyRect)
-            clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.foregroundRect, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
+            clipToRect(localPaintingInfo, context, fragment.foregroundRect, IncludeSelfForBorderRadius); // Child clipping mask painting will handle clipping to self.
 
         // Paint the the clipped mask.
         PaintInfo paintInfo(context, pixelSnappedIntRect(fragment.backgroundRect.rect()), PaintPhaseClippingMask, PaintBehaviorNormal, paintingRootForRenderer, 0, 0, localPaintingInfo.rootLayer->renderer());
@@ -2480,7 +2516,7 @@
 {
     for (size_t i = 0; i < layerFragments.size(); ++i) {
         const LayerFragment& fragment = layerFragments.at(i);
-        clipToRect(localPaintingInfo.rootLayer, context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
+        clipToRect(localPaintingInfo, context, fragment.backgroundRect);
         if (RenderLayerScrollableArea* scrollableArea = this->scrollableArea())
             scrollableArea->paintOverflowControls(context, roundedIntPoint(toPoint(fragment.layerBounds.location() - renderBoxLocation() + subPixelAccumulationIfNeeded(localPaintingInfo.subPixelAccumulation, compositingState()))), pixelSnappedIntRect(fragment.backgroundRect.rect()), true);
         restoreClip(context, localPaintingInfo.paintDirtyRect, fragment.backgroundRect);
@@ -2941,7 +2977,8 @@
 {
     LayerFragments enclosingPaginationFragments;
     LayoutPoint offsetOfPaginationLayerFromRoot;
-    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox);
+    // FIXME: We're missing a sub-pixel offset here crbug.com/348728
+    LayoutRect transformedExtent = transparencyClipBox(this, enclosingPaginationLayer(), HitTestingTransparencyClipBox, RootOfTransparencyClipBox, LayoutSize());
     enclosingPaginationLayer()->collectFragments(enclosingPaginationFragments, rootLayer, hitTestRect,
         RootRelativeClipRects, IncludeOverlayScrollbarSize, RespectOverflowClip, &offsetOfPaginationLayerFromRoot, LayoutSize(), &transformedExtent);
 
@@ -3470,10 +3507,9 @@
     if (!m_compositedLayerMapping)
         return NotComposited;
 
-    if (m_compositedLayerMapping && compositedLayerMapping()->paintsIntoCompositedAncestor())
+    if (compositedLayerMapping()->paintsIntoCompositedAncestor())
         return HasOwnBackingButPaintsIntoAncestor;
 
-    ASSERT(m_compositedLayerMapping);
     return PaintsIntoOwnBacking;
 }
 
@@ -3484,10 +3520,17 @@
     return renderer()->document().lifecycle().state() >= DocumentLifecycle::InCompositingUpdate;
 }
 
+CompositedLayerMappingPtr RenderLayer::compositedLayerMapping() const
+{
+    ASSERT(isAllowedToQueryCompositingState());
+    return m_compositedLayerMapping.get();
+}
+
 CompositedLayerMappingPtr RenderLayer::ensureCompositedLayerMapping()
 {
     if (!m_compositedLayerMapping) {
-        m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(this));
+        m_compositedLayerMapping = adoptPtr(new CompositedLayerMapping(*this));
+        m_compositedLayerMapping->setNeedsGeometryUpdate();
 
         updateOrRemoveFilterEffectRenderer();
 
@@ -3499,12 +3542,30 @@
 
 void RenderLayer::clearCompositedLayerMapping(bool layerBeingDestroyed)
 {
+    if (!layerBeingDestroyed) {
+        // We need to make sure our decendants get a geometry update. In principle,
+        // we could call setNeedsGeometryUpdate on our children, but that would
+        // require walking the z-order lists to find them. Instead, we over-invalidate
+        // by marking our parent as needing a geometry update.
+        if (RenderLayer* compositingParent = enclosingCompositingLayer(ExcludeSelf))
+            compositingParent->compositedLayerMapping()->setNeedsGeometryUpdate();
+    }
+
     m_compositedLayerMapping.clear();
 
     if (!layerBeingDestroyed)
         updateOrRemoveFilterEffectRenderer();
 }
 
+void RenderLayer::setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed)
+{
+    if (!layerBeingDestroyed && m_groupedMapping)
+        m_groupedMapping->setNeedsGeometryUpdate();
+    m_groupedMapping = groupedMapping;
+    if (!layerBeingDestroyed && m_groupedMapping)
+        m_groupedMapping->setNeedsGeometryUpdate();
+}
+
 bool RenderLayer::hasCompositedMask() const
 {
     return m_compositedLayerMapping && m_compositedLayerMapping->hasMaskLayer();
@@ -3613,7 +3674,7 @@
 
 bool RenderLayer::shouldBeSelfPaintingLayer() const
 {
-    return !m_isOverflowOnlyLayer
+    return m_layerType == NormalLayer
         || (m_scrollableArea && m_scrollableArea->hasOverlayScrollbars())
         || needsCompositedScrolling();
 }
@@ -3739,11 +3800,14 @@
 inline bool RenderLayer::needsCompositingLayersRebuiltForOverflow(const RenderStyle* oldStyle, const RenderStyle* newStyle) const
 {
     ASSERT(newStyle);
-    return !hasCompositedLayerMapping()
-        && oldStyle
-        && (oldStyle->overflowX() != newStyle->overflowX())
-        && m_stackingNode->ancestorStackingContainerNode()
-        && m_stackingNode->ancestorStackingContainerNode()->layer()->hasCompositingDescendant();
+    if (hasCompositedLayerMapping())
+        return false;
+    if (!oldStyle)
+        return false;
+    if (oldStyle->overflowX() == newStyle->overflowX())
+        return false;
+    RenderLayerStackingNode* stackingNode = m_stackingNode->ancestorStackingContainerNode();
+    return stackingNode && stackingNode->layer()->hasCompositingDescendant();
 }
 
 inline bool RenderLayer::needsCompositingLayersRebuiltForFilters(const RenderStyle* oldStyle, const RenderStyle* newStyle, bool didPaintWithFilters) const
@@ -3767,16 +3831,6 @@
         return true;
     }
 
-#if HAVE(COMPOSITOR_FILTER_OUTSETS)
-    if ((didPaintWithFilters != paintsWithFilters()) && !newOutsets.isZero()) {
-        // When the layer used to paint filters in software and now paints filters in the
-        // compositor, the compositing layer bounds need to change from including filter outsets to
-        // excluding filter outsets, on platforms whose compositors compute their own outsets.
-        // Similarly for the reverse change from compositor-painted to software-painted filters.
-        return true;
-    }
-#endif
-
     return false;
 }
 
@@ -3851,9 +3905,12 @@
     // https://code.google.com/p/chromium/issues/detail?id=343756
     DisableCompositingQueryAsserts disabler;
 
+    if (RenderLayer* compositingLayer = enclosingCompositingLayer())
+        compositingLayer->compositedLayerMapping()->setNeedsGeometryUpdate();
+
     const RenderStyle* newStyle = renderer()->style();
 
-    compositor()->updateLayerCompositingState(this);
+    compositor()->updateLayerCompositingState(this, RenderLayerCompositor::UseChickenEggHacks);
     // FIXME: this compositing logic should be pushed into the compositing code, not here.
     if (needsCompositingLayersRebuiltForClip(oldStyle, newStyle)
         || needsCompositingLayersRebuiltForOverflow(oldStyle, newStyle)
@@ -3882,7 +3939,11 @@
             ReferenceFilterOperation* referenceOperation = toReferenceFilterOperation(filterOperation);
             // FIXME: Cache the ReferenceFilter if it didn't change.
             RefPtr<ReferenceFilter> referenceFilter = ReferenceFilter::create();
+#ifdef BLINK_SCALE_FILTERS_AT_RECORD_TIME
             float zoom = style->effectiveZoom() * WebCore::deviceScaleFactor(renderer()->frame());
+#else
+            float zoom = style->effectiveZoom();
+#endif
             referenceFilter->setAbsoluteTransform(AffineTransform().scale(zoom, zoom));
             referenceFilter->setLastEffect(ReferenceFilterBuilder::build(referenceFilter.get(), renderer(), referenceFilter->sourceGraphic(),
                 referenceOperation));
@@ -3915,7 +3976,7 @@
         // Don't delete the whole filter info here, because we might use it
         // for loading CSS shader files.
         if (RenderLayerFilterInfo* filterInfo = this->filterInfo())
-            filterInfo->setRenderer(0);
+            filterInfo->setRenderer(nullptr);
 
         return;
     }
@@ -3933,7 +3994,7 @@
     // If the filter fails to build, remove it from the layer. It will still attempt to
     // go through regular processing (e.g. compositing), but never apply anything.
     if (!filterInfo->renderer()->build(renderer(), computeFilterOperations(renderer()->style())))
-        filterInfo->setRenderer(0);
+        filterInfo->setRenderer(nullptr);
 }
 
 void RenderLayer::filterNeedsRepaint()
@@ -3996,6 +4057,8 @@
 DisableCompositingQueryAsserts::DisableCompositingQueryAsserts()
     : m_disabler(gCompositingQueryMode, CompositingQueriesAreAllowed) { }
 
+COMPILE_ASSERT(1 << RenderLayer::ViewportConstrainedNotCompositedReasonBits >= RenderLayer::NumNotCompositedReasons, too_many_viewport_constrained_not_compositing_reasons);
+
 } // namespace WebCore
 
 #ifndef NDEBUG
@@ -4004,7 +4067,7 @@
     if (!layer)
         return;
 
-    if (WebCore::Frame* frame = layer->renderer()->frame()) {
+    if (WebCore::LocalFrame* frame = layer->renderer()->frame()) {
         WTF::String output = externalRepresentation(frame, WebCore::RenderAsTextShowAllLayers | WebCore::RenderAsTextShowLayerNesting | WebCore::RenderAsTextShowCompositedLayers | WebCore::RenderAsTextShowAddresses | WebCore::RenderAsTextShowIDAndClass | WebCore::RenderAsTextDontUpdateLayout | WebCore::RenderAsTextShowLayoutState);
         fprintf(stderr, "%s\n", output.utf8().data());
     }
diff --git a/Source/core/rendering/RenderLayer.h b/Source/core/rendering/RenderLayer.h
index 4d9d0ee..cf9654a 100644
--- a/Source/core/rendering/RenderLayer.h
+++ b/Source/core/rendering/RenderLayer.h
@@ -45,7 +45,7 @@
 #ifndef RenderLayer_h
 #define RenderLayer_h
 
-#include "core/rendering/CompositedLayerMappingPtr.h"
+#include "core/rendering/compositing/CompositedLayerMappingPtr.h"
 #include "core/rendering/LayerPaintingInfo.h"
 #include "core/rendering/RenderBox.h"
 #include "core/rendering/RenderLayerBlendInfo.h"
@@ -99,6 +99,7 @@
 };
 
 class RenderLayer {
+    WTF_MAKE_NONCOPYABLE(RenderLayer);
 public:
     friend class RenderReplica;
     // FIXME: Needed until we move all the necessary bits to the new class.
@@ -130,15 +131,16 @@
     void styleChanged(StyleDifference, const RenderStyle* oldStyle);
 
     bool isSelfPaintingLayer() const { return m_isSelfPaintingLayer; }
+    bool isOverflowOnlyLayer() const { return m_layerType == OverflowClipLayer; }
+    bool isForcedLayer() const { return m_layerType == ForcedLayer; }
 
-    bool isOverflowOnlyLayer() const { return m_isOverflowOnlyLayer; }
-    void setIsOverflowOnlyLayer(bool isOverflowOnlyLayer) { m_isOverflowOnlyLayer = isOverflowOnlyLayer; }
+    void setLayerType(LayerType layerType) { m_layerType = layerType; }
 
     bool cannotBlitToWindow() const;
 
     bool isTransparent() const;
     RenderLayer* transparentPaintingAncestor();
-    void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior);
+    void beginTransparencyLayers(GraphicsContext*, const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior);
 
     bool isReflection() const { return renderer()->isReplica(); }
     RenderLayerReflectionInfo* reflectionInfo() { return m_reflectionInfo.get(); }
@@ -356,7 +358,7 @@
     // compositing state may legally be read.
     bool isAllowedToQueryCompositingState() const;
 
-    CompositedLayerMappingPtr compositedLayerMapping() const { return m_compositedLayerMapping.get(); }
+    CompositedLayerMappingPtr compositedLayerMapping() const;
     CompositedLayerMappingPtr ensureCompositedLayerMapping();
 
     // NOTE: If you are using hasCompositedLayerMapping to determine the state of compositing for this layer,
@@ -366,7 +368,7 @@
     void clearCompositedLayerMapping(bool layerBeingDestroyed = false);
 
     CompositedLayerMapping* groupedMapping() const { return m_groupedMapping; }
-    void setGroupedMapping(CompositedLayerMapping* groupedMapping) { m_groupedMapping = groupedMapping; }
+    void setGroupedMapping(CompositedLayerMapping* groupedMapping, bool layerBeingDestroyed = false);
 
     bool hasCompositedMask() const;
     bool hasCompositedClippingMask() const;
@@ -424,11 +426,17 @@
     bool isInTopLayerSubtree() const;
 
     enum ViewportConstrainedNotCompositedReason {
-        NoNotCompositedReason,
+        NoNotCompositedReason = 0,
         NotCompositedForBoundsOutOfView,
         NotCompositedForNonViewContainer,
         NotCompositedForNoVisibleContent,
         NotCompositedForUnscrollableAncestors,
+        NumNotCompositedReasons,
+
+        // This is the number of bits used to store the viewport constrained not composited
+        // reasons. We define this constant since sizeof won't return the number of bits, and we
+        // shouldn't duplicate the constant.
+        ViewportConstrainedNotCompositedReasonBits = 3
     };
 
     void setViewportConstrainedNotCompositedReason(ViewportConstrainedNotCompositedReason reason) { m_compositingProperties.viewportConstrainedNotCompositedReason = reason; }
@@ -482,8 +490,7 @@
     void setAncestorChainHasOutOfFlowPositionedDescendant();
     void dirtyAncestorChainHasOutOfFlowPositionedDescendantStatus();
 
-    void clipToRect(RenderLayer* rootLayer, GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&,
-                    BorderRadiusClippingRule = IncludeSelfForBorderRadius);
+    void clipToRect(const LayerPaintingInfo&, GraphicsContext*, const ClipRect&, BorderRadiusClippingRule = IncludeSelfForBorderRadius);
     void restoreClip(GraphicsContext*, const LayoutRect& paintDirtyRect, const ClipRect&);
 
     void updateSelfPaintingLayer();
@@ -595,7 +602,7 @@
     void updateOrRemoveFilterClients();
     void updateOrRemoveFilterEffectRenderer();
 
-    LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, PaintBehavior);
+    LayoutRect paintingExtent(const RenderLayer* rootLayer, const LayoutRect& paintDirtyRect, const LayoutSize& subPixelAccumulation, PaintBehavior);
 
     RenderLayer* enclosingTransformedAncestor() const;
 
@@ -616,19 +623,20 @@
     bool lostGroupedMapping() const { return m_compositingProperties.lostGroupedMapping; }
     void setLostGroupedMapping(bool b) { m_compositingProperties.lostGroupedMapping = b; }
 
-    void setCompositingReasons(CompositingReasons reasons) { m_compositingProperties.compositingReasons = reasons; }
+    void setCompositingReasons(CompositingReasons);
     CompositingReasons compositingReasons() const { return m_compositingProperties.compositingReasons; }
 
     friend class CompositedLayerMapping;
     friend class RenderLayerCompositor;
     friend class RenderLayerModelObject;
 
-protected:
+private:
+    LayerType m_layerType;
+
     // Self-painting layer is an optimization where we avoid the heavy RenderLayer painting
     // machinery for a RenderLayer allocated only to handle the overflow clip case.
     // FIXME(crbug.com/332791): Self-painting layer should be merged into the overflow-only concept.
     unsigned m_isSelfPaintingLayer : 1;
-    unsigned m_isOverflowOnlyLayer : 1;
 
     // If have no self-painting descendants, we don't have to walk our children during painting. This can lead to
     // significant savings, especially if the tree has lots of non-self-painting layers grouped together (e.g. table cells).
@@ -732,7 +740,7 @@
         bool lostGroupedMapping : 1;
 
         // The reason, if any exists, that a fixed-position layer is chosen not to be composited.
-        unsigned viewportConstrainedNotCompositedReason : 2;
+        unsigned viewportConstrainedNotCompositedReason : ViewportConstrainedNotCompositedReasonBits;
 
         // Once computed, indicates all that a layer needs to become composited using the CompositingReasons enum bitfield.
         CompositingReasons compositingReasons;
@@ -743,7 +751,6 @@
 
     CompositingProperties m_compositingProperties;
 
-private:
     IntRect m_blockSelectionGapsBounds;
 
     OwnPtr<CompositedLayerMapping> m_compositedLayerMapping;
diff --git a/Source/core/rendering/RenderLayerBlendInfo.cpp b/Source/core/rendering/RenderLayerBlendInfo.cpp
index aeebc4e..55c463f 100644
--- a/Source/core/rendering/RenderLayerBlendInfo.cpp
+++ b/Source/core/rendering/RenderLayerBlendInfo.cpp
@@ -44,9 +44,9 @@
 #include "config.h"
 #include "core/rendering/RenderLayerBlendInfo.h"
 
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderLayerModelObject.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
 
 namespace WebCore {
 
diff --git a/Source/core/rendering/RenderLayerClipper.cpp b/Source/core/rendering/RenderLayerClipper.cpp
index c1284a9..cbfe17b 100644
--- a/Source/core/rendering/RenderLayerClipper.cpp
+++ b/Source/core/rendering/RenderLayerClipper.cpp
@@ -55,10 +55,8 @@
     ASSERT(clipRectsType < NumCachedClipRectsTypes);
     if (m_clipRectsCache && m_clipRectsCache->getClipRects(clipRectsType, clipRectsContext.respectOverflowClip)) {
         // FIXME: these asserts trigger for squashing. Need to update this code to support squashing as appropriate.
-        // These ASSERTs also are triggering ASSERTs on some ChromeOS tests:
-        // https://code.google.com/p/chromium/issues/detail?id=342478
-        // ASSERT(clipRectsContext.rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
-        // ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy);
+        ASSERT(clipRectsContext.rootLayer == m_clipRectsCache->m_clipRectsRoot[clipRectsType]);
+        ASSERT(m_clipRectsCache->m_scrollbarRelevancy[clipRectsType] == clipRectsContext.overlayScrollbarSizeRelevancy);
 
 #ifdef CHECK_CACHED_CLIP_RECTS
         // This code is useful to check cached clip rects, but is too expensive to leave enabled in debug builds by default.
@@ -110,7 +108,11 @@
 {
     if (typeToClear == AllClipRectTypes) {
         m_clipRectsCache = nullptr;
+        m_compositingClipRectsDirty = false;
     } else {
+        if (typeToClear == CompositingClipRects)
+            m_compositingClipRectsDirty = false;
+
         ASSERT(typeToClear < NumCachedClipRectsTypes);
         RefPtr<ClipRects> dummy;
         m_clipRectsCache->setClipRects(typeToClear, RespectOverflowClip, dummy);
@@ -169,6 +171,7 @@
 {
     if (clipRectsContext.rootLayer != m_renderer->layer() && m_renderer->layer()->parent()) {
         backgroundRect = backgroundClipRect(clipRectsContext);
+        backgroundRect.move(roundedIntSize(clipRectsContext.subPixelAccumulation));
         backgroundRect.intersect(paintDirtyRect);
     } else {
         backgroundRect = paintDirtyRect;
@@ -307,10 +310,18 @@
     return parentRects.overflowClipRect();
 }
 
+void RenderLayerClipper::setCompositingClipRectsDirty()
+{
+    m_compositingClipRectsDirty = true;
+}
+
 ClipRect RenderLayerClipper::backgroundClipRect(const ClipRectsContext& clipRectsContext) const
 {
     ASSERT(m_renderer->layer()->parent());
 
+    if (clipRectsContext.clipRectsType == CompositingClipRects)
+        const_cast<RenderLayerClipper*>(this)->clearClipRectsIncludingDescendants(CompositingClipRects);
+
     ClipRects parentRects;
 
     // If we cross into a different pagination context, then we can't rely on the cache.
diff --git a/Source/core/rendering/RenderLayerClipper.h b/Source/core/rendering/RenderLayerClipper.h
index 1d6551a..7ea1cd4 100644
--- a/Source/core/rendering/RenderLayerClipper.h
+++ b/Source/core/rendering/RenderLayerClipper.h
@@ -64,14 +64,15 @@
     ClipRectsType clipRectsType;
     OverlayScrollbarSizeRelevancy overlayScrollbarSizeRelevancy;
     ShouldRespectOverflowClip respectOverflowClip;
-    const LayoutSize& subPixelAccumulation;
+    LayoutSize subPixelAccumulation;
 };
 
-class RenderLayerClipper {
+class RenderLayerClipper FINAL {
     WTF_MAKE_NONCOPYABLE(RenderLayerClipper);
 public:
-    RenderLayerClipper(RenderLayerModelObject* renderer)
-    : m_renderer(renderer)
+    explicit RenderLayerClipper(RenderLayerModelObject* renderer)
+        : m_renderer(renderer)
+        , m_compositingClipRectsDirty(false)
     {
     }
 
@@ -87,6 +88,8 @@
     void clearClipRectsIncludingDescendants(ClipRectsType typeToClear = AllClipRectTypes);
     void clearClipRects(ClipRectsType typeToClear = AllClipRectTypes);
 
+    void setCompositingClipRectsDirty();
+
     LayoutRect childrenClipRect() const; // Returns the foreground clip rect of the layer in the document's coordinate space.
     LayoutRect selfClipRect() const; // Returns the background clip rect of the layer in the document's coordinate space.
     LayoutRect localClipRect() const; // Returns the background clip rect of the layer in the local coordinate space.
@@ -114,8 +117,8 @@
 
     // FIXME: Could this be a RenderBox?
     RenderLayerModelObject* m_renderer;
-
     OwnPtr<ClipRectsCache> m_clipRectsCache;
+    unsigned m_compositingClipRectsDirty : 1;
 };
 
 } // namespace WebCore
diff --git a/Source/core/rendering/RenderLayerFilterInfo.cpp b/Source/core/rendering/RenderLayerFilterInfo.cpp
index bfb25ee..473e9eb 100644
--- a/Source/core/rendering/RenderLayerFilterInfo.cpp
+++ b/Source/core/rendering/RenderLayerFilterInfo.cpp
@@ -127,7 +127,7 @@
             // Reference is internal; add layer as a client so we can trigger
             // filter repaint on SVG attribute change.
             Element* filter = m_layer->renderer()->node()->document().getElementById(referenceFilterOperation->fragment());
-            if (!filter || !filter->hasTagName(SVGNames::filterTag))
+            if (!isSVGFilterElement(filter))
                 continue;
             if (filter->renderer())
                 toRenderSVGResourceContainer(filter->renderer())->addClientRenderLayer(m_layer);
diff --git a/Source/core/rendering/RenderLayerModelObject.cpp b/Source/core/rendering/RenderLayerModelObject.cpp
index e0039fc..2799d99 100644
--- a/Source/core/rendering/RenderLayerModelObject.cpp
+++ b/Source/core/rendering/RenderLayerModelObject.cpp
@@ -25,7 +25,7 @@
 #include "config.h"
 #include "core/rendering/RenderLayerModelObject.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderView.h"
 
@@ -75,7 +75,7 @@
 {
     if (isPositioned()) {
         // Don't use this->view() because the document's renderView has been set to 0 during destruction.
-        if (Frame* frame = this->frame()) {
+        if (LocalFrame* frame = this->frame()) {
             if (FrameView* frameView = frame->view()) {
                 if (style()->hasViewportConstrainedPosition())
                     frameView->removeViewportConstrainedObject(this);
@@ -101,7 +101,7 @@
             // having an outline to not having an outline.
             if (diff == StyleDifferenceRepaintLayer) {
                 layer()->repainter().repaintIncludingDescendants();
-                if (!(oldStyle->clip() == newStyle->clip()))
+                if (oldStyle->clip() != newStyle->clip())
                     layer()->clipper().clearClipRectsIncludingDescendants();
             } else if (diff == StyleDifferenceRepaint || newStyle->outlineSize() < oldStyle->outlineSize())
                 repaint();
@@ -111,16 +111,19 @@
             // When a layout hint happens, we go ahead and do a repaint of the layer, since the layer could
             // end up being destroyed.
             if (hasLayer()) {
-                if (oldStyle->position() != newStyle->position()
-                    || oldStyle->zIndex() != newStyle->zIndex()
-                    || oldStyle->hasAutoZIndex() != newStyle->hasAutoZIndex()
-                    || !(oldStyle->clip() == newStyle->clip())
-                    || oldStyle->hasClip() != newStyle->hasClip()
-                    || oldStyle->opacity() != newStyle->opacity()
-                    || oldStyle->transform() != newStyle->transform()
-                    || oldStyle->filter() != newStyle->filter()
-                    )
-                layer()->repainter().repaintIncludingDescendants();
+                if (oldStyle->hasClip() != newStyle->hasClip()
+                    || oldStyle->clip() != newStyle->clip()) {
+                    // Composited layers don't need to be repainted when a parent's clip changes.
+                    layer()->repainter().repaintIncludingNonCompositingDescendants(containerForRepaint());
+                } else if (!layer()->hasCompositedLayerMapping()) {
+                    if (oldStyle->position() != newStyle->position()
+                        || oldStyle->zIndex() != newStyle->zIndex()
+                        || oldStyle->hasAutoZIndex() != newStyle->hasAutoZIndex()
+                        || oldStyle->opacity() != newStyle->opacity()
+                        || oldStyle->transform() != newStyle->transform()
+                        || oldStyle->filter() != newStyle->filter())
+                    layer()->repainter().repaintIncludingDescendants();
+                }
             } else if (newStyle->hasTransform() || newStyle->opacity() < 1 || newStyle->hasFilter()) {
                 // If we don't have a layer yet, but we are going to get one because of transform or opacity,
                 //  then we need to repaint the old position of the object.
@@ -167,7 +170,7 @@
     if (layer()) {
         // FIXME: Ideally we shouldn't need this setter but we can't easily infer an overflow-only layer
         // from the style.
-        layer()->setIsOverflowOnlyLayer(type == OverflowClipLayer);
+        layer()->setLayerType(type);
 
         layer()->styleChanged(diff, oldStyle);
         if (hadLayer && layer()->isSelfPaintingLayer() != layerWasSelfPainting)
diff --git a/Source/core/rendering/RenderLayerModelObject.h b/Source/core/rendering/RenderLayerModelObject.h
index e4d34f3..ed3a5a1 100644
--- a/Source/core/rendering/RenderLayerModelObject.h
+++ b/Source/core/rendering/RenderLayerModelObject.h
@@ -23,7 +23,7 @@
 #ifndef RenderLayerModelObject_h
 #define RenderLayerModelObject_h
 
-#include "core/rendering/CompositedLayerMappingPtr.h"
+#include "core/rendering/compositing/CompositedLayerMappingPtr.h"
 #include "core/rendering/RenderObject.h"
 
 namespace WebCore {
@@ -34,8 +34,11 @@
 
 enum LayerType {
     NoLayer,
+    NormalLayer,
+    // A forced or overflow clip layer is required for bookkeeping purposes,
+    // but does not force a layer to be self painting.
     OverflowClipLayer,
-    NormalLayer
+    ForcedLayer
 };
 
 class RenderLayerModelObject : public RenderObject {
diff --git a/Source/core/rendering/RenderLayerRepainter.cpp b/Source/core/rendering/RenderLayerRepainter.cpp
index a06d55f..7381c8e 100644
--- a/Source/core/rendering/RenderLayerRepainter.cpp
+++ b/Source/core/rendering/RenderLayerRepainter.cpp
@@ -44,10 +44,10 @@
 #include "config.h"
 #include "core/rendering/RenderLayerRepainter.h"
 
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/FilterEffectRenderer.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
 
 namespace WebCore {
 
diff --git a/Source/core/rendering/RenderLayerScrollableArea.cpp b/Source/core/rendering/RenderLayerScrollableArea.cpp
index 0cc87c2..73cdbd4 100644
--- a/Source/core/rendering/RenderLayerScrollableArea.cpp
+++ b/Source/core/rendering/RenderLayerScrollableArea.cpp
@@ -47,21 +47,21 @@
 #include "core/css/PseudoStyleRequest.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/editing/FrameSelection.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/page/EventHandler.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/RenderGeometryMap.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderScrollbar.h"
 #include "core/rendering/RenderScrollbarPart.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "platform/PlatformGestureEvent.h"
 #include "platform/PlatformMouseEvent.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
@@ -104,11 +104,11 @@
 RenderLayerScrollableArea::~RenderLayerScrollableArea()
 {
     if (inResizeMode() && !m_box->documentBeingDestroyed()) {
-        if (Frame* frame = m_box->frame())
+        if (LocalFrame* frame = m_box->frame())
             frame->eventHandler().resizeScrollableAreaDestroyed();
     }
 
-    if (Frame* frame = m_box->frame()) {
+    if (LocalFrame* frame = m_box->frame()) {
         if (FrameView* frameView = frame->view()) {
             frameView->removeScrollableArea(this);
         }
@@ -125,7 +125,7 @@
             toElement(node)->setSavedLayerScrollOffset(m_scrollOffset);
     }
 
-    if (Frame* frame = m_box->frame()) {
+    if (LocalFrame* frame = m_box->frame()) {
         if (FrameView* frameView = frame->view())
             frameView->removeResizerArea(m_box);
     }
@@ -139,16 +139,6 @@
         m_resizer->destroy();
 }
 
-ScrollableArea* RenderLayerScrollableArea::enclosingScrollableArea() const
-{
-    if (RenderBox* enclosingScrollableBox = m_box->enclosingScrollableBox())
-        return enclosingScrollableBox->layer()->scrollableArea();
-
-    // FIXME: We should return the frame view here (or possibly an ancestor frame view,
-    // if the frame view isn't scrollable.
-    return 0;
-}
-
 GraphicsLayer* RenderLayerScrollableArea::layerForScrolling() const
 {
     return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->scrollingContentsLayer() : 0;
@@ -156,21 +146,33 @@
 
 GraphicsLayer* RenderLayerScrollableArea::layerForHorizontalScrollbar() const
 {
+    // See crbug.com/343132.
+    DisableCompositingQueryAsserts disabler;
+
     return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForHorizontalScrollbar() : 0;
 }
 
 GraphicsLayer* RenderLayerScrollableArea::layerForVerticalScrollbar() const
 {
+    // See crbug.com/343132.
+    DisableCompositingQueryAsserts disabler;
+
     return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForVerticalScrollbar() : 0;
 }
 
 GraphicsLayer* RenderLayerScrollableArea::layerForScrollCorner() const
 {
+    // See crbug.com/343132.
+    DisableCompositingQueryAsserts disabler;
+
     return m_box->hasCompositedLayerMapping() ? m_box->compositedLayerMapping()->layerForScrollCorner() : 0;
 }
 
 void RenderLayerScrollableArea::invalidateScrollbarRect(Scrollbar* scrollbar, const IntRect& rect)
 {
+    // See crbug.com/343132.
+    DisableCompositingQueryAsserts disabler;
+
     if (scrollbar == m_vBar.get()) {
         if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
             layer->setNeedsDisplayInRect(rect);
@@ -350,7 +352,7 @@
 
     setScrollOffset(toIntSize(newScrollOffset));
 
-    Frame* frame = m_box->frame();
+    LocalFrame* frame = m_box->frame();
     ASSERT(frame);
 
     RefPtr<FrameView> frameView = m_box->frameView();
@@ -405,6 +407,9 @@
     if (m_box->node())
         m_box->node()->document().enqueueScrollEventForNode(m_box->node());
 
+    if (AXObjectCache* cache = m_box->document().existingAXObjectCache())
+        cache->handleScrollPositionChanged(m_box);
+
     InspectorInstrumentation::didScrollLayer(m_box);
 }
 
@@ -575,11 +580,16 @@
     bool hasHorizontalOverflow = this->hasHorizontalOverflow();
     bool hasVerticalOverflow = this->hasVerticalOverflow();
 
-    // overflow:scroll should just enable/disable.
-    if (m_box->style()->overflowX() == OSCROLL)
-        horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
-    if (m_box->style()->overflowY() == OSCROLL)
-        verticalScrollbar()->setEnabled(hasVerticalOverflow);
+    {
+        // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
+        DisableCompositingQueryAsserts disabler;
+
+        // overflow:scroll should just enable/disable.
+        if (m_box->style()->overflowX() == OSCROLL)
+            horizontalScrollbar()->setEnabled(hasHorizontalOverflow);
+        if (m_box->style()->overflowY() == OSCROLL)
+            verticalScrollbar()->setEnabled(hasVerticalOverflow);
+    }
 
     // overflow:auto may need to lay out again if scrollbars got added/removed.
     bool autoHorizontalScrollBarChanged = m_box->hasAutoHorizontalScrollbar() && (hasHorizontalScrollbar() != hasHorizontalOverflow);
@@ -591,6 +601,9 @@
         if (m_box->hasAutoVerticalScrollbar())
             setHasVerticalScrollbar(hasVerticalOverflow);
 
+        if (hasVerticalOverflow || hasHorizontalOverflow)
+            updateScrollCornerStyle();
+
         layer()->updateSelfPaintingLayer();
 
         // Force an update since we know the scrollbars have changed things.
@@ -618,14 +631,19 @@
         }
     }
 
-    // Set up the range (and page step/line step).
-    if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
-        int clientWidth = m_box->pixelSnappedClientWidth();
-        horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
-    }
-    if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
-        int clientHeight = m_box->pixelSnappedClientHeight();
-        verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+    {
+        // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html.
+        DisableCompositingQueryAsserts disabler;
+
+        // Set up the range (and page step/line step).
+        if (Scrollbar* horizontalScrollbar = this->horizontalScrollbar()) {
+            int clientWidth = m_box->pixelSnappedClientWidth();
+            horizontalScrollbar->setProportion(clientWidth, overflowRect().width());
+        }
+        if (Scrollbar* verticalScrollbar = this->verticalScrollbar()) {
+            int clientHeight = m_box->pixelSnappedClientHeight();
+            verticalScrollbar->setProportion(clientHeight, overflowRect().height());
+        }
     }
 
     updateScrollableAreaSet(hasScrollableHorizontalOverflow() || hasScrollableVerticalOverflow());
@@ -824,7 +842,7 @@
 
     scrollbar->removeFromParent();
     scrollbar->disconnectFromScrollableArea();
-    scrollbar = 0;
+    scrollbar = nullptr;
 }
 
 void RenderLayerScrollableArea::setHasHorizontalScrollbar(bool hasScrollbar)
@@ -832,10 +850,14 @@
     if (hasScrollbar == hasHorizontalScrollbar())
         return;
 
-    if (hasScrollbar)
+    if (hasScrollbar) {
+        // This doesn't hit in any tests, but since the equivalent code in setHasVerticalScrollbar
+        // does, presumably this code does as well.
+        DisableCompositingQueryAsserts disabler;
         m_hBar = createScrollbar(HorizontalScrollbar);
-    else
+    } else {
         destroyScrollbar(HorizontalScrollbar);
+    }
 
     // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
     if (m_hBar)
@@ -853,10 +875,13 @@
     if (hasScrollbar == hasVerticalScrollbar())
         return;
 
-    if (hasScrollbar)
+    if (hasScrollbar) {
+        // Hits in compositing/overflow/automatically-opt-into-composited-scrolling-after-style-change.html
+        DisableCompositingQueryAsserts disabler;
         m_vBar = createScrollbar(VerticalScrollbar);
-    else
+    } else {
         destroyScrollbar(VerticalScrollbar);
+    }
 
     // Destroying or creating one bar can cause our scrollbar corner to come and go. We need to update the opposite scrollbar's style.
     if (m_hBar)
@@ -936,8 +961,13 @@
 
 void RenderLayerScrollableArea::updateScrollCornerStyle()
 {
+    if (!m_scrollCorner && !hasScrollbar())
+        return;
+    if (!m_scrollCorner && hasOverlayScrollbars())
+        return;
+
     RenderObject* actualRenderer = rendererForScrollbar(m_box);
-    RefPtr<RenderStyle> corner = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
+    RefPtr<RenderStyle> corner = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(SCROLLBAR_CORNER), actualRenderer->style()) : PassRefPtr<RenderStyle>(nullptr);
     if (corner) {
         if (!m_scrollCorner) {
             m_scrollCorner = RenderScrollbarPart::createAnonymous(&m_box->document());
@@ -1187,7 +1217,7 @@
 
 void RenderLayerScrollableArea::updateResizerAreaSet()
 {
-    Frame* frame = m_box->frame();
+    LocalFrame* frame = m_box->frame();
     if (!frame)
         return;
     FrameView* frameView = frame->view();
@@ -1201,8 +1231,11 @@
 
 void RenderLayerScrollableArea::updateResizerStyle()
 {
+    if (!m_resizer && !m_box->canResize())
+        return;
+
     RenderObject* actualRenderer = rendererForScrollbar(m_box);
-    RefPtr<RenderStyle> resizer = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(RESIZER), actualRenderer->style()) : PassRefPtr<RenderStyle>(0);
+    RefPtr<RenderStyle> resizer = m_box->hasOverflowClip() ? actualRenderer->getUncachedPseudoStyle(PseudoStyleRequest(RESIZER), actualRenderer->style()) : PassRefPtr<RenderStyle>(nullptr);
     if (resizer) {
         if (!m_resizer) {
             m_resizer = RenderScrollbarPart::createAnonymous(&m_box->document());
@@ -1354,7 +1387,7 @@
 
 void RenderLayerScrollableArea::updateScrollableAreaSet(bool hasOverflow)
 {
-    Frame* frame = m_box->frame();
+    LocalFrame* frame = m_box->frame();
     if (!frame)
         return;
 
@@ -1474,6 +1507,7 @@
     if (m_box && (m_box->isIntristicallyScrollable(VerticalScrollbar) || m_box->isIntristicallyScrollable(HorizontalScrollbar)))
         return false;
 
+    DisableCompositingQueryAsserts disabler;
     return m_box->hasCompositedLayerMapping() && m_box->compositedLayerMapping()->scrollingLayer();
 }
 
diff --git a/Source/core/rendering/RenderLayerScrollableArea.h b/Source/core/rendering/RenderLayerScrollableArea.h
index 02ab6af..8df1400 100644
--- a/Source/core/rendering/RenderLayerScrollableArea.h
+++ b/Source/core/rendering/RenderLayerScrollableArea.h
@@ -76,7 +76,6 @@
 
     virtual Scrollbar* horizontalScrollbar() const OVERRIDE { return m_hBar.get(); }
     virtual Scrollbar* verticalScrollbar() const OVERRIDE { return m_vBar.get(); }
-    virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
 
     virtual GraphicsLayer* layerForScrolling() const OVERRIDE;
     virtual GraphicsLayer* layerForHorizontalScrollbar() const OVERRIDE;
diff --git a/Source/core/rendering/RenderLayerStackingNode.cpp b/Source/core/rendering/RenderLayerStackingNode.cpp
index 4d1b706..8a1bdda 100644
--- a/Source/core/rendering/RenderLayerStackingNode.cpp
+++ b/Source/core/rendering/RenderLayerStackingNode.cpp
@@ -45,8 +45,8 @@
 #include "core/rendering/RenderLayerStackingNode.h"
 
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "public/platform/Platform.h"
 
 namespace WebCore {
@@ -86,11 +86,6 @@
 #endif
 }
 
-bool RenderLayerStackingNode::isStackingContext(const RenderStyle* style) const
-{
-    return !style->hasAutoZIndex() || layer()->isRootLayer();
-}
-
 // Helper for the sorting of layers by z-index.
 static inline bool compareZIndex(RenderLayerStackingNode* first, RenderLayerStackingNode* second)
 {
@@ -386,7 +381,7 @@
 
 void RenderLayerStackingNode::updateStackingNodesAfterStyleChange(const RenderStyle* oldStyle)
 {
-    bool wasStackingContext = oldStyle ? isStackingContext(oldStyle) : false;
+    bool wasStackingContext = oldStyle ? !oldStyle->hasAutoZIndex() : false;
     EVisibility oldVisibility = oldStyle ? oldStyle->visibility() : VISIBLE;
     int oldZIndex = oldStyle ? oldStyle->zIndex() : 0;
 
diff --git a/Source/core/rendering/RenderLayerStackingNode.h b/Source/core/rendering/RenderLayerStackingNode.h
index 12d7490..0f42c75 100644
--- a/Source/core/rendering/RenderLayerStackingNode.h
+++ b/Source/core/rendering/RenderLayerStackingNode.h
@@ -65,7 +65,7 @@
     int zIndex() const { return renderer()->style()->zIndex(); }
 
     // A stacking context is a layer that has a non-auto z-index.
-    bool isStackingContext() const { return isStackingContext(renderer()->style()); }
+    bool isStackingContext() const { return !renderer()->style()->hasAutoZIndex(); }
 
     // A stacking container can have z-order lists. All stacking contexts are
     // stacking containers, but the converse is not true. Layers that use
@@ -147,8 +147,6 @@
         OnlyStackingContextsCanBeStackingContainers
     };
 
-    bool isStackingContext(const RenderStyle*) const;
-
     void rebuildZOrderLists();
 
     // layerToForceAsStackingContainer allows us to build pre-promotion and
diff --git a/Source/core/rendering/RenderLineBoxList.cpp b/Source/core/rendering/RenderLineBoxList.cpp
index 0852247..db990d8 100644
--- a/Source/core/rendering/RenderLineBoxList.cpp
+++ b/Source/core/rendering/RenderLineBoxList.cpp
@@ -176,10 +176,10 @@
     // intersect.  This is a quick short-circuit that we can take to avoid walking any lines.
     // FIXME: This check is flawed in the following extremely obscure way:
     // if some line in the middle has a huge overflow, it might actually extend below the last line.
-    RootInlineBox* firstRootBox = firstLineBox()->root();
-    RootInlineBox* lastRootBox = lastLineBox()->root();
-    LayoutUnit firstLineTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox->lineTop());
-    LayoutUnit lastLineBottom = lastLineBox()->logicalBottomVisualOverflow(lastRootBox->lineBottom());
+    RootInlineBox& firstRootBox = firstLineBox()->root();
+    RootInlineBox& lastRootBox = lastLineBox()->root();
+    LayoutUnit firstLineTop = firstLineBox()->logicalTopVisualOverflow(firstRootBox.lineTop());
+    LayoutUnit lastLineBottom = lastLineBox()->logicalBottomVisualOverflow(lastRootBox.lineBottom());
     LayoutUnit logicalTop = firstLineTop - outlineSize;
     LayoutUnit logicalBottom = outlineSize + lastLineBottom;
 
@@ -188,9 +188,9 @@
 
 bool RenderLineBoxList::lineIntersectsDirtyRect(RenderBoxModelObject* renderer, InlineFlowBox* box, const PaintInfo& paintInfo, const LayoutPoint& offset) const
 {
-    RootInlineBox* root = box->root();
-    LayoutUnit logicalTop = min<LayoutUnit>(box->logicalTopVisualOverflow(root->lineTop()), root->selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase);
-    LayoutUnit logicalBottom = box->logicalBottomVisualOverflow(root->lineBottom()) + renderer->maximalOutlineSize(paintInfo.phase);
+    RootInlineBox& root = box->root();
+    LayoutUnit logicalTop = min<LayoutUnit>(box->logicalTopVisualOverflow(root.lineTop()), root.selectionTop()) - renderer->maximalOutlineSize(paintInfo.phase);
+    LayoutUnit logicalBottom = box->logicalBottomVisualOverflow(root.lineBottom()) + renderer->maximalOutlineSize(paintInfo.phase);
 
     return rangeIntersectsRect(renderer, logicalTop, logicalBottom, paintInfo.rect, offset);
 }
@@ -222,8 +222,8 @@
     // based off positions of our first line box or our last line box.
     for (InlineFlowBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) {
         if (lineIntersectsDirtyRect(renderer, curr, info, paintOffset)) {
-            RootInlineBox* root = curr->root();
-            curr->paint(info, paintOffset, root->lineTop(), root->lineBottom());
+            RootInlineBox& root = curr->root();
+            curr->paint(info, paintOffset, root.lineTop(), root.lineBottom());
         }
     }
 
@@ -260,9 +260,9 @@
     // them further.  Note that boxes can easily overlap, so we can't make any assumptions
     // based off positions of our first line box or our last line box.
     for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
-        RootInlineBox* root = curr->root();
-        if (rangeIntersectsRect(renderer, curr->logicalTopVisualOverflow(root->lineTop()), curr->logicalBottomVisualOverflow(root->lineBottom()), rect, accumulatedOffset)) {
-            bool inside = curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, root->lineTop(), root->lineBottom());
+        RootInlineBox& root = curr->root();
+        if (rangeIntersectsRect(renderer, curr->logicalTopVisualOverflow(root.lineTop()), curr->logicalBottomVisualOverflow(root.lineBottom()), rect, accumulatedOffset)) {
+            bool inside = curr->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, root.lineTop(), root.lineBottom());
             if (inside) {
                 renderer->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
                 return true;
@@ -304,15 +304,15 @@
         if (curr->isReplaced()) {
             InlineBox* wrapper = toRenderBox(curr)->inlineBoxWrapper();
             if (wrapper)
-                box = wrapper->root();
+                box = &wrapper->root();
         } else if (curr->isText()) {
             InlineTextBox* textBox = toRenderText(curr)->lastTextBox();
             if (textBox)
-                box = textBox->root();
+                box = &textBox->root();
         } else if (curr->isRenderInline()) {
             InlineBox* lastSiblingBox = toRenderInline(curr)->lastLineBoxIncludingCulling();
             if (lastSiblingBox)
-                box = lastSiblingBox->root();
+                box = &lastSiblingBox->root();
         }
 
         if (box)
@@ -331,7 +331,7 @@
             }
             return;
         }
-        box = firstBox->root();
+        box = &firstBox->root();
     }
 
     // If we found a line box, then dirty it.
diff --git a/Source/core/rendering/RenderListBox.cpp b/Source/core/rendering/RenderListBox.cpp
index d529308..8918b0a 100644
--- a/Source/core/rendering/RenderListBox.cpp
+++ b/Source/core/rendering/RenderListBox.cpp
@@ -38,13 +38,13 @@
 #include "core/dom/Document.h"
 #include "core/dom/NodeRenderStyle.h"
 #include "core/editing/FrameSelection.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLOptGroupElement.h"
 #include "core/html/HTMLOptionElement.h"
 #include "core/html/HTMLSelectElement.h"
 #include "core/page/EventHandler.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/page/SpatialNavigation.h"
 #include "core/rendering/HitTestResult.h"
@@ -90,7 +90,7 @@
 {
     ASSERT(element);
     ASSERT(element->isHTMLElement());
-    ASSERT(element->hasTagName(HTMLNames::selectTag));
+    ASSERT(isHTMLSelectElement(element));
 
     if (FrameView* frameView = frame()->view())
         frameView->addScrollableArea(this);
@@ -129,10 +129,10 @@
             HTMLElement* element = listItems[i];
             String text;
             Font itemFont = style()->font();
-            if (element->hasTagName(optionTag)) {
-                text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
-            } else if (element->hasTagName(optgroupTag)) {
-                text = toHTMLOptGroupElement(element)->groupLabelText();
+            if (isHTMLOptionElement(*element)) {
+                text = toHTMLOptionElement(*element).textIndentedToRespectGroupLabel();
+            } else if (isHTMLOptGroupElement(*element)) {
+                text = toHTMLOptGroupElement(*element).groupLabelText();
                 FontDescription d = itemFont.fontDescription();
                 d.setWeight(d.bolderWeight());
                 itemFont = Font(d);
@@ -191,7 +191,7 @@
     }
 
     if (m_scrollToRevealSelectionAfterLayout) {
-        LayoutStateDisabler layoutStateDisabler(view());
+        LayoutStateDisabler layoutStateDisabler(*this);
         scrollToRevealSelection();
     }
 }
@@ -352,7 +352,7 @@
     const Vector<HTMLElement*>& listItems = select->listItems();
     for (int i = 0; i < size; ++i) {
         HTMLElement* element = listItems[i];
-        if (element->hasTagName(optionTag) && !element->isDisabledFormControl()) {
+        if (isHTMLOptionElement(*element) && !element->isDisabledFormControl()) {
             rects.append(pixelSnappedIntRect(itemBoundingBoxRect(additionalOffset, i)));
             return;
         }
@@ -418,15 +418,15 @@
         return;
 
     String itemText;
-    bool isOptionElement = element->hasTagName(optionTag);
+    bool isOptionElement = isHTMLOptionElement(*element);
     if (isOptionElement)
-        itemText = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
-    else if (element->hasTagName(optgroupTag))
-        itemText = toHTMLOptGroupElement(element)->groupLabelText();
+        itemText = toHTMLOptionElement(*element).textIndentedToRespectGroupLabel();
+    else if (isHTMLOptGroupElement(*element))
+        itemText = toHTMLOptGroupElement(*element).groupLabelText();
     applyTextTransform(style(), itemText, ' ');
 
     Color textColor = element->renderStyle() ? resolveColor(element->renderStyle(), CSSPropertyColor) : resolveColor(CSSPropertyColor);
-    if (isOptionElement && toHTMLOptionElement(element)->selected()) {
+    if (isOptionElement && toHTMLOptionElement(*element).selected()) {
         if (frame()->selection().isFocusedAndActive() && document().focusedElement() == node())
             textColor = RenderTheme::theme().activeListBoxSelectionForegroundColor();
         // Honor the foreground color for disabled items
@@ -441,7 +441,7 @@
     LayoutRect r = itemBoundingBoxRect(paintOffset, listIndex);
     r.move(itemOffsetForAlignment(textRun, itemStyle, itemFont, r));
 
-    if (element->hasTagName(optgroupTag)) {
+    if (isHTMLOptGroupElement(*element)) {
         FontDescription d = itemFont.fontDescription();
         d.setWeight(d.bolderWeight());
         itemFont = Font(d);
@@ -460,7 +460,7 @@
     HTMLElement* element = listItems[listIndex];
 
     Color backColor;
-    if (element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected()) {
+    if (isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selected()) {
         if (frame()->selection().isFocusedAndActive() && document().focusedElement() == node())
             backColor = RenderTheme::theme().activeListBoxSelectionBackgroundColor();
         else
@@ -539,8 +539,7 @@
         return;
 
     if (yDelta > 0)
-        //offsetY = view()->viewHeight();
-        absOffset.move(0, listHeight());
+        absOffset.move(0, listHeight().toFloat());
     else if (yDelta < 0)
         yDelta--;
 
@@ -908,12 +907,6 @@
     return 1.0f / itemHeight();
 }
 
-ScrollableArea* RenderListBox::enclosingScrollableArea() const
-{
-    // FIXME: Return a RenderLayer that's scrollable.
-    return 0;
-}
-
 IntRect RenderListBox::scrollableAreaBoundingBox() const
 {
     return absoluteBoundingBoxRect();
@@ -942,7 +935,7 @@
         ScrollableArea::willRemoveScrollbar(m_vBar.get(), VerticalScrollbar);
     m_vBar->removeFromParent();
     m_vBar->disconnectFromScrollableArea();
-    m_vBar = 0;
+    m_vBar = nullptr;
 }
 
 void RenderListBox::setHasVerticalScrollbar(bool hasScrollbar)
diff --git a/Source/core/rendering/RenderListBox.h b/Source/core/rendering/RenderListBox.h
index dfe947a..c824b7c 100644
--- a/Source/core/rendering/RenderListBox.h
+++ b/Source/core/rendering/RenderListBox.h
@@ -83,8 +83,6 @@
 
     virtual void layout() OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
 
     virtual bool canBeProgramaticallyScrolled() const OVERRIDE { return true; }
@@ -130,9 +128,6 @@
     virtual int lineStep(ScrollbarOrientation) const OVERRIDE;
     virtual int pageStep(ScrollbarOrientation) const OVERRIDE;
     virtual float pixelStep(ScrollbarOrientation) const OVERRIDE;
-
-
-    virtual ScrollableArea* enclosingScrollableArea() const OVERRIDE;
     virtual IntRect scrollableAreaBoundingBox() const OVERRIDE;
 
     // NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
diff --git a/Source/core/rendering/RenderListItem.cpp b/Source/core/rendering/RenderListItem.cpp
index 8fce613..8f14092 100644
--- a/Source/core/rendering/RenderListItem.cpp
+++ b/Source/core/rendering/RenderListItem.cpp
@@ -25,7 +25,7 @@
 #include "core/rendering/RenderListItem.h"
 
 #include "HTMLNames.h"
-#include "core/dom/ElementTraversal.h"
+#include "core/dom/NodeRenderingTraversal.h"
 #include "core/html/HTMLOListElement.h"
 #include "core/rendering/FastTextAutosizer.h"
 #include "core/rendering/LayoutRectRecorder.h"
@@ -57,10 +57,6 @@
     if (style()->listStyleType() != NoneListStyle
         || (style()->listStyleImage() && !style()->listStyleImage()->errorOccurred())) {
         RefPtr<RenderStyle> newStyle = RenderStyle::create();
-        // Markers update their own margin style. By copying the existing style we can
-        // avoid an unnecessary layout in setStyle below.
-        if (m_marker)
-            newStyle->copyNonInheritedFrom(m_marker->style());
         // The marker always inherits from the list item, regardless of where it might end
         // up (e.g., in some deeply nested line box). See CSS3 spec.
         newStyle->inheritFrom(style());
@@ -96,9 +92,9 @@
     updateListMarkerNumbers();
 }
 
-static bool isList(const Node* node)
+static bool isList(const Node& node)
 {
-    return (node->hasTagName(ulTag) || node->hasTagName(olTag));
+    return isHTMLUListElement(node) || isHTMLOListElement(node);
 }
 
 // Returns the enclosing list with respect to the DOM order.
@@ -107,8 +103,8 @@
     Node* listItemNode = listItem->node();
     Node* firstNode = 0;
     // We use parentNode because the enclosing list could be a ShadowRoot that's not Element.
-    for (Node* parent = listItemNode->parentNode(); parent; parent = parent->parentNode()) {
-        if (isList(parent))
+    for (Node* parent = NodeRenderingTraversal::parent(listItemNode); parent; parent = NodeRenderingTraversal::parent(parent)) {
+        if (isList(*parent))
             return parent;
         if (!firstNode)
             firstNode = parent;
@@ -128,12 +124,13 @@
 
     const Node* current = item ? item->node() : listNode;
     ASSERT(current);
-    current = ElementTraversal::nextIncludingPseudo(*current, listNode);
+    ASSERT(!current->document().childNeedsDistributionRecalc());
+    current = NodeRenderingTraversal::next(current, listNode);
 
     while (current) {
-        if (isList(current)) {
+        if (isList(*current)) {
             // We've found a nested, independent list: nothing to do here.
-            current = ElementTraversal::nextIncludingPseudoSkippingChildren(*current, listNode);
+            current = NodeRenderingTraversal::next(current, listNode);
             continue;
         }
 
@@ -142,7 +139,7 @@
             return toRenderListItem(renderer);
 
         // FIXME: Can this be optimized to skip the children of the elements without a renderer?
-        current = ElementTraversal::nextIncludingPseudo(*current, listNode);
+        current = NodeRenderingTraversal::next(current, listNode);
     }
 
     return 0;
@@ -153,7 +150,8 @@
 {
     Node* current = item->node();
     ASSERT(current);
-    for (current = ElementTraversal::previousIncludingPseudo(*current, listNode); current; current = ElementTraversal::previousIncludingPseudo(*current, listNode)) {
+    ASSERT(!current->document().childNeedsDistributionRecalc());
+    for (current = NodeRenderingTraversal::previous(current, listNode); current && current != listNode; current = NodeRenderingTraversal::previous(current, listNode)) {
         RenderObject* renderer = current->renderer();
         if (!renderer || (renderer && !renderer->isListItem()))
             continue;
@@ -166,7 +164,7 @@
         // be a list item itself. We need to examine it, so we do this to counteract
         // the previousIncludingPseudo() that will be done by the loop.
         if (otherList)
-            current = ElementTraversal::nextIncludingPseudo(*otherList);
+            current = NodeRenderingTraversal::next(otherList, listNode);
     }
     return 0;
 }
@@ -196,7 +194,7 @@
         return m_explicitValue;
 
     Node* list = enclosingList(this);
-    HTMLOListElement* oListElement = (list && list->hasTagName(olTag)) ? toHTMLOListElement(list) : 0;
+    HTMLOListElement* oListElement = isHTMLOListElement(list) ? toHTMLOListElement(list) : 0;
     int valueStep = 1;
     if (oListElement && oListElement->isReversed())
         valueStep = -1;
@@ -244,7 +242,7 @@
             break;
 
         if (curr->isListItem() && inQuirksMode && currChild->node() &&
-            (currChild->node()->hasTagName(ulTag)|| currChild->node()->hasTagName(olTag)))
+            (isHTMLUListElement(*currChild->node()) || isHTMLOListElement(*currChild->node())))
             break;
 
         RenderObject* lineBox = getParentOfFirstLineBox(toRenderBlockFlow(currChild), marker);
@@ -292,7 +290,7 @@
         if (markerParent != lineBoxParent || m_marker->preferredLogicalWidthsDirty()) {
             // Removing and adding the marker can trigger repainting in
             // containers other than ourselves, so we need to disable LayoutState.
-            LayoutStateDisabler layoutStateDisabler(view());
+            LayoutStateDisabler layoutStateDisabler(*this);
             updateFirstLetter();
             m_marker->remove();
             if (markerParent)
@@ -349,18 +347,17 @@
 
         bool adjustOverflow = false;
         LayoutUnit markerLogicalLeft;
-        RootInlineBox* root = m_marker->inlineBoxWrapper()->root();
+        RootInlineBox& root = m_marker->inlineBoxWrapper()->root();
         bool hitSelfPaintingLayer = false;
 
-        RootInlineBox* rootBox = m_marker->inlineBoxWrapper()->root();
-        LayoutUnit lineTop = rootBox->lineTop();
-        LayoutUnit lineBottom = rootBox->lineBottom();
+        LayoutUnit lineTop = root.lineTop();
+        LayoutUnit lineBottom = root.lineBottom();
 
         // FIXME: Need to account for relative positioning in the layout overflow.
         if (style()->isLeftToRightDirection()) {
             LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, logicalLeftOffsetForLine(blockOffset, false), false);
             markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - borderStart() + m_marker->marginStart();
-            m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft);
+            m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
             for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
                 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom);
                 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom);
@@ -383,7 +380,7 @@
         } else {
             LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false);
             markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd();
-            m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft);
+            m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat());
             for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) {
                 LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom);
                 LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom);
@@ -508,6 +505,11 @@
 
 void RenderListItem::updateListMarkerNumbers()
 {
+    // If distribution recalc is needed, updateListMarkerNumber will be re-invoked
+    // after distribution is calculated.
+    if (node()->document().childNeedsDistributionRecalc())
+        return;
+
     Node* listNode = enclosingList(this);
     // The list node can be the shadow root which has no renderer.
     ASSERT(listNode);
@@ -515,7 +517,7 @@
         return;
 
     bool isListReversed = false;
-    HTMLOListElement* oListElement = (listNode && listNode->hasTagName(olTag)) ? toHTMLOListElement(listNode) : 0;
+    HTMLOListElement* oListElement = isHTMLOListElement(listNode) ? toHTMLOListElement(listNode) : 0;
     if (oListElement) {
         oListElement->itemCountChanged();
         isListReversed = oListElement->isReversed();
diff --git a/Source/core/rendering/RenderListItem.h b/Source/core/rendering/RenderListItem.h
index f3b42fb..5c17a71 100644
--- a/Source/core/rendering/RenderListItem.h
+++ b/Source/core/rendering/RenderListItem.h
@@ -69,8 +69,6 @@
 
     virtual void layout() OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     void positionListMarker();
 
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
diff --git a/Source/core/rendering/RenderListMarker.cpp b/Source/core/rendering/RenderListMarker.cpp
index b66aab5..9ea89bd 100644
--- a/Source/core/rendering/RenderListMarker.cpp
+++ b/Source/core/rendering/RenderListMarker.cpp
@@ -1116,11 +1116,11 @@
     InlineBox* box = inlineBoxWrapper();
     if (!box)
         return LayoutRect(LayoutPoint(), size());
-    RootInlineBox* root = inlineBoxWrapper()->root();
-    LayoutUnit newLogicalTop = root->block()->style()->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root->selectionBottom() : root->selectionTop() - inlineBoxWrapper()->logicalTop();
-    if (root->block()->style()->isHorizontalWritingMode())
-        return LayoutRect(0, newLogicalTop, width(), root->selectionHeight());
-    return LayoutRect(newLogicalTop, 0, root->selectionHeight(), height());
+    RootInlineBox& root = inlineBoxWrapper()->root();
+    LayoutUnit newLogicalTop = root.block().style()->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectionTop() - inlineBoxWrapper()->logicalTop();
+    if (root.block().style()->isHorizontalWritingMode())
+        return LayoutRect(0, newLogicalTop, width(), root.selectionHeight());
+    return LayoutRect(newLogicalTop, 0, root.selectionHeight(), height());
 }
 
 void RenderListMarker::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
@@ -1377,7 +1377,9 @@
         // FIXME: This is a somewhat arbitrary width.  Generated images for markers really won't become particularly useful
         // until we support the CSS3 marker pseudoclass to allow control over the width and height of the marker box.
         int bulletWidth = style()->fontMetrics().ascent() / 2;
-        m_image->setContainerSizeForRenderer(this, IntSize(bulletWidth, bulletWidth), style()->effectiveZoom());
+        IntSize defaultBulletSize(bulletWidth, bulletWidth);
+        IntSize imageSize = calculateImageIntrinsicDimensions(m_image.get(), defaultBulletSize, DoNotScaleByEffectiveZoom);
+        m_image->setContainerSizeForRenderer(this, imageSize, style()->effectiveZoom());
         return;
     }
 
@@ -1825,8 +1827,7 @@
     RenderBox::setSelectionState(state);
 
     if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes())
-        if (RootInlineBox* root = inlineBoxWrapper()->root())
-            root->setHasSelectedChildren(state != SelectionNone);
+        inlineBoxWrapper()->root().setHasSelectedChildren(state != SelectionNone);
 }
 
 LayoutRect RenderListMarker::selectionRectForRepaint(const RenderLayerModelObject* repaintContainer, bool clipToVisibleContent)
@@ -1836,8 +1837,8 @@
     if (selectionState() == SelectionNone || !inlineBoxWrapper())
         return LayoutRect();
 
-    RootInlineBox* root = inlineBoxWrapper()->root();
-    LayoutRect rect(0, root->selectionTop() - y(), width(), root->selectionHeight());
+    RootInlineBox& root = inlineBoxWrapper()->root();
+    LayoutRect rect(0, root.selectionTop() - y(), width(), root.selectionHeight());
 
     if (clipToVisibleContent)
         computeRectForRepaint(repaintContainer, rect);
diff --git a/Source/core/rendering/RenderMarquee.cpp b/Source/core/rendering/RenderMarquee.cpp
index 9dce7e7..03ac5dc 100644
--- a/Source/core/rendering/RenderMarquee.cpp
+++ b/Source/core/rendering/RenderMarquee.cpp
@@ -173,7 +173,7 @@
         m_stopped = false;
     }
 
-    m_timer.startRepeating(speed() * 0.001);
+    m_timer.startRepeating(speed() * 0.001, FROM_HERE);
 }
 
 void RenderMarquee::suspend()
@@ -195,8 +195,11 @@
         EMarqueeBehavior behavior = style()->marqueeBehavior();
         m_start = computePosition(direction(), behavior == MALTERNATE);
         m_end = computePosition(reverseDirection(), behavior == MALTERNATE || behavior == MSLIDE);
-        if (!m_stopped)
+        if (!m_stopped) {
+            // Hits in compositing/overflow/do-not-repaint-if-scrolling-composited-layers.html during layout.
+            DisableCompositingQueryAsserts disabler;
             start();
+        }
     }
 }
 
@@ -249,7 +252,7 @@
     if (speed() != marqueeSpeed()) {
         m_speed = marqueeSpeed();
         if (m_timer.isActive())
-            m_timer.startRepeating(speed() * 0.001);
+            m_timer.startRepeating(speed() * 0.001, FROM_HERE);
     }
 
     // Check the loop count to see if we should now stop.
diff --git a/Source/core/rendering/RenderMarquee.h b/Source/core/rendering/RenderMarquee.h
index 458f7dd..71b61d7 100644
--- a/Source/core/rendering/RenderMarquee.h
+++ b/Source/core/rendering/RenderMarquee.h
@@ -91,8 +91,6 @@
 
     virtual void layoutBlock(bool relayoutChildren) OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     int m_currentLoop;
     int m_totalLoops;
     Timer<HTMLMarqueeElement> m_timer;
diff --git a/Source/core/rendering/RenderMedia.cpp b/Source/core/rendering/RenderMedia.cpp
index f00de2e..b7f5bc0 100644
--- a/Source/core/rendering/RenderMedia.cpp
+++ b/Source/core/rendering/RenderMedia.cpp
@@ -64,10 +64,7 @@
     if (newSize == oldSize && !controlsNeedLayout)
         return;
 
-    // When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or
-    // instantiate LayoutStateDisabler. Since using a LayoutStateMaintainer is slightly more efficient,
-    // and this method will be called many times per second during playback, use a LayoutStateMaintainer:
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     controlsRenderer->setLocation(LayoutPoint(borderLeft(), borderTop()) + LayoutSize(paddingLeft(), paddingTop()));
     controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed));
diff --git a/Source/core/rendering/RenderMediaControlElements.cpp b/Source/core/rendering/RenderMediaControlElements.cpp
index e332416..2ca723e 100644
--- a/Source/core/rendering/RenderMediaControlElements.cpp
+++ b/Source/core/rendering/RenderMediaControlElements.cpp
@@ -51,7 +51,7 @@
 
     DeprecatedScheduleStyleRecalcDuringLayout marker(node()->document().lifecycle());
 
-    LayoutStateDisabler layoutStateDisabler(view());
+    LayoutStateDisabler layoutStateDisabler(*this);
     static_cast<MediaControlTextTrackContainerElement*>(node())->updateSizes();
 }
 
diff --git a/Source/core/rendering/RenderMediaControlElements.h b/Source/core/rendering/RenderMediaControlElements.h
index 3282f34..b22aa73 100644
--- a/Source/core/rendering/RenderMediaControlElements.h
+++ b/Source/core/rendering/RenderMediaControlElements.h
@@ -40,7 +40,6 @@
 
 private:
     virtual void layout() OVERRIDE;
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
 };
 
 
diff --git a/Source/core/rendering/RenderMenuList.cpp b/Source/core/rendering/RenderMenuList.cpp
index 1ed8698..5b28b71 100644
--- a/Source/core/rendering/RenderMenuList.cpp
+++ b/Source/core/rendering/RenderMenuList.cpp
@@ -32,9 +32,9 @@
 #include "core/css/CSSFontSelector.h"
 #include "core/css/resolver/StyleResolver.h"
 #include "core/dom/NodeRenderStyle.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLOptGroupElement.h"
 #include "core/html/HTMLOptionElement.h"
 #include "core/html/HTMLSelectElement.h"
@@ -61,16 +61,14 @@
     , m_lastActiveIndex(-1)
     , m_popupIsVisible(false)
 {
-    ASSERT(element);
-    ASSERT(element->isHTMLElement());
-    ASSERT(element->hasTagName(HTMLNames::selectTag));
+    ASSERT(isHTMLSelectElement(element));
 }
 
 RenderMenuList::~RenderMenuList()
 {
     if (m_popup)
         m_popup->disconnectClient();
-    m_popup = 0;
+    m_popup = nullptr;
 }
 
 // FIXME: Instead of this hack we should add a ShadowRoot to <select> with no insertion point
@@ -100,9 +98,6 @@
     RenderStyle* innerStyle = m_innerBlock->style();
     innerStyle->setFlexGrow(1);
     innerStyle->setFlexShrink(1);
-    // min-width: 0; is needed for correct shrinking.
-    // FIXME: Remove this line when https://bugs.webkit.org/show_bug.cgi?id=111790 is fixed.
-    innerStyle->setMinWidth(Length(0, Fixed));
     // Use margin:auto instead of align-items:center to get safe centering, i.e.
     // when the content overflows, treat it the same as align-items: flex-start.
     // But we only do that for the cases where html.css would otherwise use center.
@@ -173,7 +168,7 @@
 
     for (int i = 0; i < size; ++i) {
         HTMLElement* element = listItems[i];
-        if (!element->hasTagName(optionTag))
+        if (!isHTMLOptionElement(*element))
             continue;
 
         String text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
@@ -222,7 +217,7 @@
     String text = emptyString();
     if (i >= 0 && i < size) {
         Element* element = listItems[i];
-        if (element->hasTagName(optionTag)) {
+        if (isHTMLOptionElement(*element)) {
             text = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
             m_optionStyle = element->renderStyle();
         }
@@ -398,10 +393,10 @@
 
     String itemString;
     Element* element = listItems[listIndex];
-    if (element->hasTagName(optgroupTag))
-        itemString = toHTMLOptGroupElement(element)->groupLabelText();
-    else if (element->hasTagName(optionTag))
-        itemString = toHTMLOptionElement(element)->textIndentedToRespectGroupLabel();
+    if (isHTMLOptGroupElement(*element))
+        itemString = toHTMLOptGroupElement(*element).groupLabelText();
+    else if (isHTMLOptionElement(*element))
+        itemString = toHTMLOptionElement(*element).textIndentedToRespectGroupLabel();
 
     applyTextTransform(style(), itemString, ' ');
     return itemString;
@@ -430,12 +425,12 @@
     if (listIndex >= listItems.size())
         return false;
     HTMLElement* element = listItems[listIndex];
-    if (!element->hasTagName(optionTag))
+    if (!isHTMLOptionElement(*element))
         return false;
 
     bool groupEnabled = true;
     if (Element* parentElement = element->parentElement()) {
-        if (parentElement->hasTagName(optgroupTag))
+        if (isHTMLOptGroupElement(*parentElement))
             groupEnabled = !parentElement->isDisabledFormControl();
     }
     if (!groupEnabled)
@@ -548,13 +543,13 @@
 bool RenderMenuList::itemIsSeparator(unsigned listIndex) const
 {
     const Vector<HTMLElement*>& listItems = selectElement()->listItems();
-    return listIndex < listItems.size() && listItems[listIndex]->hasTagName(hrTag);
+    return listIndex < listItems.size() && isHTMLHRElement(*listItems[listIndex]);
 }
 
 bool RenderMenuList::itemIsLabel(unsigned listIndex) const
 {
     const Vector<HTMLElement*>& listItems = selectElement()->listItems();
-    return listIndex < listItems.size() && listItems[listIndex]->hasTagName(optgroupTag);
+    return listIndex < listItems.size() && isHTMLOptGroupElement(*listItems[listIndex]);
 }
 
 bool RenderMenuList::itemIsSelected(unsigned listIndex) const
@@ -563,7 +558,7 @@
     if (listIndex >= listItems.size())
         return false;
     HTMLElement* element = listItems[listIndex];
-    return element->hasTagName(optionTag) && toHTMLOptionElement(element)->selected();
+    return isHTMLOptionElement(*element) && toHTMLOptionElement(*element).selected();
 }
 
 void RenderMenuList::setTextFromItem(unsigned listIndex)
diff --git a/Source/core/rendering/RenderMeter.cpp b/Source/core/rendering/RenderMeter.cpp
index d4765ab..fe95076 100644
--- a/Source/core/rendering/RenderMeter.cpp
+++ b/Source/core/rendering/RenderMeter.cpp
@@ -44,7 +44,7 @@
 {
     ASSERT(node());
 
-    if (node()->hasTagName(meterTag))
+    if (isHTMLMeterElement(*node()))
         return toHTMLMeterElement(node());
 
     ASSERT(node()->shadowHost());
diff --git a/Source/core/rendering/RenderMeter.h b/Source/core/rendering/RenderMeter.h
index a984799..51ced21 100644
--- a/Source/core/rendering/RenderMeter.h
+++ b/Source/core/rendering/RenderMeter.h
@@ -40,8 +40,6 @@
     virtual void updateLogicalWidth() OVERRIDE;
     virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     virtual const char* renderName() const OVERRIDE { return "RenderMeter"; }
     virtual bool isMeter() const OVERRIDE { return true; }
 
diff --git a/Source/core/rendering/RenderMultiColumnBlock.cpp b/Source/core/rendering/RenderMultiColumnBlock.cpp
deleted file mode 100644
index 75d291b..0000000
--- a/Source/core/rendering/RenderMultiColumnBlock.cpp
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
-
-#include "core/rendering/RenderMultiColumnFlowThread.h"
-#include "core/rendering/RenderMultiColumnSet.h"
-#include "core/rendering/RenderView.h"
-
-using namespace std;
-
-namespace WebCore {
-
-RenderMultiColumnBlock::RenderMultiColumnBlock(Element* element)
-    : RenderBlockFlow(element)
-    , m_flowThread(0)
-    , m_columnCount(1)
-    , m_columnWidth(0)
-    , m_columnHeightAvailable(0)
-    , m_inBalancingPass(false)
-    , m_needsRebalancing(false)
-{
-}
-
-void RenderMultiColumnBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
-{
-    RenderBlockFlow::styleDidChange(diff, oldStyle);
-    for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox())
-        child->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
-}
-
-void RenderMultiColumnBlock::computeColumnCountAndWidth()
-{
-    // Calculate our column width and column count.
-    // FIXME: Can overflow on fast/block/float/float-not-removed-from-next-sibling4.html, see https://bugs.webkit.org/show_bug.cgi?id=68744
-    m_columnCount = 1;
-    m_columnWidth = contentLogicalWidth();
-
-    ASSERT(!style()->hasAutoColumnCount() || !style()->hasAutoColumnWidth());
-
-    LayoutUnit availWidth = m_columnWidth;
-    LayoutUnit colGap = columnGap();
-    LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(style()->columnWidth()));
-    int colCount = max<int>(1, style()->columnCount());
-
-    if (style()->hasAutoColumnWidth() && !style()->hasAutoColumnCount()) {
-        m_columnCount = colCount;
-        m_columnWidth = max<LayoutUnit>(0, (availWidth - ((m_columnCount - 1) * colGap)) / m_columnCount);
-    } else if (!style()->hasAutoColumnWidth() && style()->hasAutoColumnCount()) {
-        m_columnCount = max<LayoutUnit>(1, (availWidth + colGap) / (colWidth + colGap));
-        m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
-    } else {
-        m_columnCount = max<LayoutUnit>(min<LayoutUnit>(colCount, (availWidth + colGap) / (colWidth + colGap)), 1);
-        m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
-    }
-}
-
-bool RenderMultiColumnBlock::updateLogicalWidthAndColumnWidth()
-{
-    bool relayoutChildren = RenderBlockFlow::updateLogicalWidthAndColumnWidth();
-    LayoutUnit oldColumnWidth = m_columnWidth;
-    computeColumnCountAndWidth();
-    if (m_columnWidth != oldColumnWidth)
-        relayoutChildren = true;
-    return relayoutChildren;
-}
-
-void RenderMultiColumnBlock::checkForPaginationLogicalHeightChange(LayoutUnit& /*pageLogicalHeight*/, bool& /*pageLogicalHeightChanged*/, bool& /*hasSpecifiedPageLogicalHeight*/)
-{
-    // We don't actually update any of the variables. We just subclassed to adjust our column height.
-    updateLogicalHeight();
-    m_columnHeightAvailable = max<LayoutUnit>(contentLogicalHeight(), 0);
-    setLogicalHeight(0);
-}
-
-bool RenderMultiColumnBlock::shouldRelayoutMultiColumnBlock()
-{
-    if (!m_needsRebalancing)
-        return false;
-
-    // Column heights may change here because of balancing. We may have to do multiple layout
-    // passes, depending on how the contents is fitted to the changed column heights. In most
-    // cases, laying out again twice or even just once will suffice. Sometimes we need more
-    // passes than that, though, but the number of retries should not exceed the number of
-    // columns, unless we have a bug.
-    bool needsRelayout = false;
-    for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
-        if (childBox != m_flowThread && childBox->isRenderMultiColumnSet()) {
-            RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
-            if (multicolSet->recalculateBalancedHeight(!m_inBalancingPass)) {
-                multicolSet->setChildNeedsLayout(MarkOnlyThis);
-                needsRelayout = true;
-            }
-        }
-    }
-
-    if (needsRelayout)
-        m_flowThread->setChildNeedsLayout(MarkOnlyThis);
-
-    m_inBalancingPass = needsRelayout;
-    return needsRelayout;
-}
-
-void RenderMultiColumnBlock::addChild(RenderObject* newChild, RenderObject* beforeChild)
-{
-    if (!m_flowThread) {
-        m_flowThread = RenderMultiColumnFlowThread::createAnonymous(&document());
-        m_flowThread->setStyle(RenderStyle::createAnonymousStyleWithDisplay(style(), BLOCK));
-        RenderBlockFlow::addChild(m_flowThread);
-    }
-    m_flowThread->addChild(newChild, beforeChild);
-}
-
-RenderObject* RenderMultiColumnBlock::layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
-{
-    if (!m_flowThread)
-        return 0;
-
-    // Update the dimensions of our regions before we lay out the flow thread.
-    // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
-    // instead of trying to keep them around.
-    bool shouldInvalidateRegions = false;
-    for (RenderBox* childBox = firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
-        if (childBox == m_flowThread)
-            continue;
-
-        if (relayoutChildren || childBox->needsLayout()) {
-            if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
-                toRenderMultiColumnSet(childBox)->prepareForLayout();
-            shouldInvalidateRegions = true;
-        }
-    }
-
-    if (shouldInvalidateRegions)
-        m_flowThread->invalidateRegions();
-
-    if (relayoutChildren)
-        layoutScope.setChildNeedsLayout(m_flowThread);
-
-    if (requiresBalancing()) {
-        // At the end of multicol layout, relayoutForPagination() is called unconditionally, but if
-        // no children are to be laid out (e.g. fixed width with layout already being up-to-date),
-        // we want to prevent it from doing any work, so that the column balancing machinery doesn't
-        // kick in and trigger additional unnecessary layout passes. Actually, it's not just a good
-        // idea in general to not waste time on balancing content that hasn't been re-laid out; we
-        // are actually required to guarantee this. The calculation of implicit breaks needs to be
-        // preceded by a proper layout pass, since it's layout that sets up content runs, and the
-        // runs get deleted right after every pass.
-        m_needsRebalancing = shouldInvalidateRegions || m_flowThread->needsLayout();
-    }
-
-    setLogicalTopForChild(m_flowThread, borderBefore() + paddingBefore());
-    m_flowThread->layoutIfNeeded();
-    determineLogicalLeftPositionForChild(m_flowThread);
-
-    return m_flowThread;
-}
-
-const char* RenderMultiColumnBlock::renderName() const
-{
-    if (isFloating())
-        return "RenderMultiColumnBlock (floating)";
-    if (isOutOfFlowPositioned())
-        return "RenderMultiColumnBlock (positioned)";
-    if (isAnonymousBlock())
-        return "RenderMultiColumnBlock (anonymous)";
-    // FIXME: Temporary hack while the new generated content system is being implemented.
-    if (isPseudoElement())
-        return "RenderMultiColumnBlock (generated)";
-    if (isAnonymous())
-        return "RenderMultiColumnBlock (generated)";
-    if (isRelPositioned())
-        return "RenderMultiColumnBlock (relative positioned)";
-    return "RenderMultiColumnBlock";
-}
-
-}
diff --git a/Source/core/rendering/RenderMultiColumnBlock.h b/Source/core/rendering/RenderMultiColumnBlock.h
deleted file mode 100644
index 8b6115e..0000000
--- a/Source/core/rendering/RenderMultiColumnBlock.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2012 Apple Inc.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-#ifndef RenderMultiColumnBlock_h
-#define RenderMultiColumnBlock_h
-
-#include "core/rendering/RenderBlockFlow.h"
-
-namespace WebCore {
-
-class RenderMultiColumnFlowThread;
-
-class RenderMultiColumnBlock FINAL : public RenderBlockFlow {
-public:
-    RenderMultiColumnBlock(Element*);
-
-    LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; }
-
-    LayoutUnit columnWidth() const { return m_columnWidth; }
-    unsigned columnCount() const { return m_columnCount; }
-
-    RenderMultiColumnFlowThread* flowThread() const { return m_flowThread; }
-
-    bool requiresBalancing() const { return !m_columnHeightAvailable || style()->columnFill() == ColumnFillBalance; }
-
-    bool shouldRelayoutMultiColumnBlock();
-
-private:
-    virtual bool isRenderMultiColumnBlock() const OVERRIDE { return true; }
-
-    virtual const char* renderName() const OVERRIDE;
-
-    virtual RenderObject* layoutSpecialExcludedChild(bool relayoutChildren, SubtreeLayoutScope&) OVERRIDE;
-
-    virtual void styleDidChange(StyleDifference, const RenderStyle*) OVERRIDE;
-
-    virtual bool updateLogicalWidthAndColumnWidth() OVERRIDE;
-    virtual void checkForPaginationLogicalHeightChange(LayoutUnit&, bool&, bool&) OVERRIDE;
-
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
-    virtual void addChild(RenderObject* newChild, RenderObject* beforeChild = 0) OVERRIDE;
-
-    void computeColumnCountAndWidth();
-
-    void ensureColumnSets();
-
-    RenderMultiColumnFlowThread* m_flowThread;
-    unsigned m_columnCount;   // The default column count/width that are based off our containing block width. These values represent only the default,
-    LayoutUnit m_columnWidth; // since a multi-column block that is split across variable width pages or regions will have different column counts and widths in each.
-                              // These values will be cached (eventually) for multi-column blocks.
-    LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto.
-    bool m_inBalancingPass; // Set when relayouting for column balancing.
-    bool m_needsRebalancing;
-};
-
-DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderMultiColumnBlock, isRenderMultiColumnBlock());
-
-} // namespace WebCore
-
-#endif // RenderMultiColumnBlock_h
-
diff --git a/Source/core/rendering/RenderMultiColumnFlowThread.cpp b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
index 86ee4ed..dc0e663 100644
--- a/Source/core/rendering/RenderMultiColumnFlowThread.cpp
+++ b/Source/core/rendering/RenderMultiColumnFlowThread.cpp
@@ -26,12 +26,16 @@
 #include "config.h"
 #include "core/rendering/RenderMultiColumnFlowThread.h"
 
-#include "core/rendering/RenderMultiColumnBlock.h"
 #include "core/rendering/RenderMultiColumnSet.h"
 
 namespace WebCore {
 
 RenderMultiColumnFlowThread::RenderMultiColumnFlowThread()
+    : m_columnCount(1)
+    , m_columnWidth(0)
+    , m_columnHeightAvailable(0)
+    , m_inBalancingPass(false)
+    , m_needsRebalancing(false)
 {
     setFlowThreadState(InsideInFlowThread);
 }
@@ -40,13 +44,112 @@
 {
 }
 
-RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Document* document)
+RenderMultiColumnFlowThread* RenderMultiColumnFlowThread::createAnonymous(Document& document, RenderStyle* parentStyle)
 {
     RenderMultiColumnFlowThread* renderer = new RenderMultiColumnFlowThread();
-    renderer->setDocumentForAnonymous(document);
+    renderer->setDocumentForAnonymous(&document);
+    renderer->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentStyle, BLOCK));
     return renderer;
 }
 
+void RenderMultiColumnFlowThread::layoutColumns(bool relayoutChildren, SubtreeLayoutScope& layoutScope)
+{
+    // Update the dimensions of our regions before we lay out the flow thread.
+    // FIXME: Eventually this is going to get way more complicated, and we will be destroying regions
+    // instead of trying to keep them around.
+    RenderBlockFlow* container = multiColumnBlockFlow();
+    bool shouldInvalidateRegions = false;
+    for (RenderBox* childBox = container->firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
+        if (childBox == this)
+            continue;
+
+        if (relayoutChildren || childBox->needsLayout()) {
+            if (!m_inBalancingPass && childBox->isRenderMultiColumnSet())
+                toRenderMultiColumnSet(childBox)->prepareForLayout();
+            shouldInvalidateRegions = true;
+        }
+    }
+
+    if (shouldInvalidateRegions)
+        invalidateRegions();
+
+    if (relayoutChildren)
+        layoutScope.setChildNeedsLayout(this);
+
+    if (requiresBalancing()) {
+        // At the end of multicol layout, relayoutForPagination() is called unconditionally, but if
+        // no children are to be laid out (e.g. fixed width with layout already being up-to-date),
+        // we want to prevent it from doing any work, so that the column balancing machinery doesn't
+        // kick in and trigger additional unnecessary layout passes. Actually, it's not just a good
+        // idea in general to not waste time on balancing content that hasn't been re-laid out; we
+        // are actually required to guarantee this. The calculation of implicit breaks needs to be
+        // preceded by a proper layout pass, since it's layout that sets up content runs, and the
+        // runs get deleted right after every pass.
+        m_needsRebalancing = shouldInvalidateRegions || needsLayout();
+    }
+
+    layoutIfNeeded();
+}
+
+bool RenderMultiColumnFlowThread::computeColumnCountAndWidth()
+{
+    RenderBlock* columnBlock = multiColumnBlockFlow();
+    LayoutUnit oldColumnWidth = m_columnWidth;
+
+    // Calculate our column width and column count.
+    m_columnCount = 1;
+    m_columnWidth = columnBlock->contentLogicalWidth();
+
+    const RenderStyle* columnStyle = columnBlock->style();
+    ASSERT(!columnStyle->hasAutoColumnCount() || !columnStyle->hasAutoColumnWidth());
+
+    LayoutUnit availWidth = m_columnWidth;
+    LayoutUnit colGap = columnBlock->columnGap();
+    LayoutUnit colWidth = max<LayoutUnit>(1, LayoutUnit(columnStyle->columnWidth()));
+    int colCount = max<int>(1, columnStyle->columnCount());
+
+    if (columnStyle->hasAutoColumnWidth() && !columnStyle->hasAutoColumnCount()) {
+        m_columnCount = colCount;
+        m_columnWidth = std::max<LayoutUnit>(0, (availWidth - ((m_columnCount - 1) * colGap)) / m_columnCount);
+    } else if (!columnStyle->hasAutoColumnWidth() && columnStyle->hasAutoColumnCount()) {
+        m_columnCount = std::max<LayoutUnit>(1, (availWidth + colGap) / (colWidth + colGap));
+        m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
+    } else {
+        m_columnCount = std::max<LayoutUnit>(std::min<LayoutUnit>(colCount, (availWidth + colGap) / (colWidth + colGap)), 1);
+        m_columnWidth = ((availWidth + colGap) / m_columnCount) - colGap;
+    }
+
+    return m_columnWidth != oldColumnWidth;
+}
+
+bool RenderMultiColumnFlowThread::recalculateColumnHeights()
+{
+    if (!m_needsRebalancing)
+        return false;
+
+    // Column heights may change here because of balancing. We may have to do multiple layout
+    // passes, depending on how the contents is fitted to the changed column heights. In most
+    // cases, laying out again twice or even just once will suffice. Sometimes we need more
+    // passes than that, though, but the number of retries should not exceed the number of
+    // columns, unless we have a bug.
+    bool needsRelayout = false;
+    for (RenderBox* childBox = multiColumnBlockFlow()->firstChildBox(); childBox; childBox = childBox->nextSiblingBox()) {
+        if (childBox != this && childBox->isRenderMultiColumnSet()) {
+            RenderMultiColumnSet* multicolSet = toRenderMultiColumnSet(childBox);
+            if (multicolSet->recalculateBalancedHeight(!m_inBalancingPass)) {
+                multicolSet->setChildNeedsLayout(MarkOnlyThis);
+                needsRelayout = true;
+            }
+        }
+    }
+
+    if (needsRelayout)
+        setChildNeedsLayout(MarkOnlyThis);
+
+    m_inBalancingPass = needsRelayout;
+    return needsRelayout;
+}
+
 const char* RenderMultiColumnFlowThread::renderName() const
 {
     return "RenderMultiColumnFlowThread";
@@ -61,8 +164,7 @@
 
 LayoutUnit RenderMultiColumnFlowThread::initialLogicalWidth() const
 {
-    RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
-    return parentBlock->columnWidth();
+    return columnWidth();
 }
 
 void RenderMultiColumnFlowThread::autoGenerateRegionsToBlockOffset(LayoutUnit /*offset*/)
@@ -91,7 +193,7 @@
 
     invalidateRegions();
 
-    RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
+    RenderBlockFlow* parentBlock = multiColumnBlockFlow();
     firstSet = RenderMultiColumnSet::createAnonymous(this);
     firstSet->setStyle(RenderStyle::createAnonymousStyleWithDisplay(parentBlock->style(), BLOCK));
     parentBlock->RenderBlock::addChild(firstSet);
diff --git a/Source/core/rendering/RenderMultiColumnFlowThread.h b/Source/core/rendering/RenderMultiColumnFlowThread.h
index 45b4d93..6687de7 100644
--- a/Source/core/rendering/RenderMultiColumnFlowThread.h
+++ b/Source/core/rendering/RenderMultiColumnFlowThread.h
@@ -35,7 +35,18 @@
 public:
     virtual ~RenderMultiColumnFlowThread();
 
-    static RenderMultiColumnFlowThread* createAnonymous(Document*);
+    static RenderMultiColumnFlowThread* createAnonymous(Document&, RenderStyle* parentStyle);
+
+    RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(parent()); }
+    unsigned columnCount() const { return m_columnCount; }
+    LayoutUnit columnWidth() const { return m_columnWidth; }
+    LayoutUnit columnHeightAvailable() const { return m_columnHeightAvailable; }
+    void setColumnHeightAvailable(LayoutUnit available) { m_columnHeightAvailable = available; }
+    bool requiresBalancing() const { return !columnHeightAvailable() || multiColumnBlockFlow()->style()->columnFill() == ColumnFillBalance; }
+
+    void layoutColumns(bool relayoutChildren, SubtreeLayoutScope&);
+    bool computeColumnCountAndWidth();
+    bool recalculateColumnHeights();
 
 private:
     RenderMultiColumnFlowThread();
@@ -47,6 +58,12 @@
     virtual void setPageBreak(LayoutUnit offset, LayoutUnit spaceShortage) OVERRIDE;
     virtual void updateMinimumPageHeight(LayoutUnit offset, LayoutUnit minHeight) OVERRIDE;
     virtual bool addForcedRegionBreak(LayoutUnit, RenderObject* breakChild, bool isBefore, LayoutUnit* offsetBreakAdjustment = 0) OVERRIDE;
+
+    unsigned m_columnCount; // The used value of column-count
+    LayoutUnit m_columnWidth; // The used value of column-width
+    LayoutUnit m_columnHeightAvailable; // Total height available to columns, or 0 if auto.
+    bool m_inBalancingPass; // Set when relayouting for column balancing.
+    bool m_needsRebalancing;
 };
 
 } // namespace WebCore
diff --git a/Source/core/rendering/RenderMultiColumnSet.cpp b/Source/core/rendering/RenderMultiColumnSet.cpp
index a38addb..9b1394b 100644
--- a/Source/core/rendering/RenderMultiColumnSet.cpp
+++ b/Source/core/rendering/RenderMultiColumnSet.cpp
@@ -28,7 +28,6 @@
 
 #include "core/rendering/PaintInfo.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
 #include "core/rendering/RenderMultiColumnFlowThread.h"
 
 using namespace std;
@@ -56,7 +55,7 @@
 
 LayoutUnit RenderMultiColumnSet::heightAdjustedForSetOffset(LayoutUnit height) const
 {
-    RenderMultiColumnBlock* multicolBlock = toRenderMultiColumnBlock(parent());
+    RenderBlockFlow* multicolBlock = multiColumnBlockFlow();
     LayoutUnit contentLogicalTop = logicalTop() - multicolBlock->borderBefore() - multicolBlock->paddingBefore();
 
     height -= contentLogicalTop;
@@ -162,7 +161,7 @@
 
 void RenderMultiColumnSet::addForcedBreak(LayoutUnit offsetFromFirstPage)
 {
-    if (!toRenderMultiColumnBlock(parent())->requiresBalancing())
+    if (!multiColumnFlowThread()->requiresBalancing())
         return;
     if (!m_contentRuns.isEmpty() && offsetFromFirstPage <= m_contentRuns.last().breakOffset())
         return;
@@ -174,7 +173,7 @@
 
 bool RenderMultiColumnSet::recalculateBalancedHeight(bool initial)
 {
-    ASSERT(toRenderMultiColumnBlock(parent())->requiresBalancing());
+    ASSERT(multiColumnFlowThread()->requiresBalancing());
 
     LayoutUnit oldColumnHeight = m_computedColumnHeight;
     if (initial)
@@ -210,8 +209,8 @@
 
 void RenderMultiColumnSet::updateLogicalWidth()
 {
-    RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
-    setComputedColumnWidthAndCount(parentBlock->columnWidth(), parentBlock->columnCount()); // FIXME: This will eventually vary if we are contained inside regions.
+    RenderMultiColumnFlowThread* flowThread = multiColumnFlowThread();
+    setComputedColumnWidthAndCount(flowThread->columnWidth(), flowThread->columnCount());
 
     // FIXME: When we add regions support, we'll start it off at the width of the multi-column
     // block in that particular region.
@@ -232,7 +231,7 @@
 
 void RenderMultiColumnSet::prepareForLayout()
 {
-    RenderMultiColumnBlock* multicolBlock = toRenderMultiColumnBlock(parent());
+    RenderBlockFlow* multicolBlock = multiColumnBlockFlow();
     RenderStyle* multicolStyle = multicolBlock->style();
 
     // Set box logical top.
@@ -242,7 +241,7 @@
     // Set box width.
     updateLogicalWidth();
 
-    if (multicolBlock->requiresBalancing()) {
+    if (multicolBlock->multiColumnFlowThread()->requiresBalancing()) {
         // Set maximum column height. We will not stretch beyond this.
         m_maxColumnHeight = RenderFlowThread::maxLogicalHeight();
         if (!multicolStyle->logicalHeight().isAuto()) {
@@ -258,7 +257,7 @@
         m_maxColumnHeight = heightAdjustedForSetOffset(m_maxColumnHeight);
         m_computedColumnHeight = 0; // Restart balancing.
     } else {
-        setAndConstrainColumnHeight(heightAdjustedForSetOffset(multicolBlock->columnHeightAvailable()));
+        setAndConstrainColumnHeight(heightAdjustedForSetOffset(multicolBlock->multiColumnFlowThread()->columnHeightAvailable()));
     }
 
     clearForcedBreaks();
@@ -275,9 +274,7 @@
 
 LayoutUnit RenderMultiColumnSet::columnGap() const
 {
-    // FIXME: Eventually we will cache the column gap when the widths of columns start varying, but for now we just
-    // go to the parent block to get the gap.
-    RenderMultiColumnBlock* parentBlock = toRenderMultiColumnBlock(parent());
+    RenderBlockFlow* parentBlock = multiColumnBlockFlow();
     if (parentBlock->style()->hasNormalColumnGap())
         return parentBlock->style()->fontDescription().computedPixelSize(); // "1em" is recommended as the normal gap setting. Matches <p> margins.
     return parentBlock->style()->columnGap();
@@ -292,6 +289,9 @@
 
     // Our portion rect determines our column count. We have as many columns as needed to fit all the content.
     LayoutUnit logicalHeightInColumns = flowThread()->isHorizontalWritingMode() ? flowThreadPortionRect().height() : flowThreadPortionRect().width();
+    if (!logicalHeightInColumns)
+        return 1;
+
     unsigned count = ceil(static_cast<float>(logicalHeightInColumns) / computedColumnHeight());
     ASSERT(count >= 1);
     return count;
@@ -404,7 +404,7 @@
     if (paintInfo.context->paintingDisabled())
         return;
 
-    RenderStyle* blockStyle = toRenderMultiColumnBlock(parent())->style();
+    RenderStyle* blockStyle = multiColumnBlockFlow()->style();
     const Color& ruleColor = resolveColor(blockStyle, CSSPropertyWebkitColumnRuleColor);
     bool ruleTransparent = blockStyle->columnRuleIsTransparent();
     EBorderStyle ruleStyle = blockStyle->columnRuleStyle();
diff --git a/Source/core/rendering/RenderMultiColumnSet.h b/Source/core/rendering/RenderMultiColumnSet.h
index 0e0152f..da7a783 100644
--- a/Source/core/rendering/RenderMultiColumnSet.h
+++ b/Source/core/rendering/RenderMultiColumnSet.h
@@ -48,6 +48,8 @@
 
     virtual bool isRenderMultiColumnSet() const OVERRIDE { return true; }
 
+    RenderBlockFlow* multiColumnBlockFlow() const { return toRenderBlockFlow(parent()); }
+    RenderMultiColumnFlowThread* multiColumnFlowThread() const { return multiColumnBlockFlow()->multiColumnFlowThread(); }
     unsigned computedColumnCount() const { return m_computedColumnCount; }
     LayoutUnit computedColumnWidth() const { return m_computedColumnWidth; }
     LayoutUnit computedColumnHeight() const { return m_computedColumnHeight; }
diff --git a/Source/core/rendering/RenderObject.cpp b/Source/core/rendering/RenderObject.cpp
index a778300..82c6a94 100644
--- a/Source/core/rendering/RenderObject.cpp
+++ b/Source/core/rendering/RenderObject.cpp
@@ -37,18 +37,18 @@
 #include "core/editing/htmlediting.h"
 #include "core/fetch/ResourceLoadPriorityOptimizer.h"
 #include "core/fetch/ResourceLoader.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLElement.h"
 #include "core/html/HTMLHtmlElement.h"
+#include "core/html/HTMLTableCellElement.h"
 #include "core/html/HTMLTableElement.h"
 #include "core/page/AutoscrollController.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "core/frame/UseCounter.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/FlowThreadController.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/LayoutRectRecorder.h"
@@ -62,10 +62,8 @@
 #include "core/rendering/RenderImageResourceStyleImage.h"
 #include "core/rendering/RenderInline.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderListItem.h"
 #include "core/rendering/RenderMarquee.h"
-#include "core/rendering/RenderMultiColumnBlock.h"
 #include "core/rendering/RenderScrollbarPart.h"
 #include "core/rendering/RenderTableCaption.h"
 #include "core/rendering/RenderTableCell.h"
@@ -73,6 +71,8 @@
 #include "core/rendering/RenderTableRow.h"
 #include "core/rendering/RenderTheme.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/rendering/style/ContentData.h"
 #include "core/rendering/style/CursorList.h"
 #include "core/rendering/style/ShadowList.h"
@@ -152,7 +152,7 @@
             image->setIsGeneratedContent();
         } else
             image->setImageResource(RenderImageResource::create());
-        image->setStyleInternal(0);
+        image->setStyleInternal(nullptr);
         return image;
     }
 
@@ -163,8 +163,6 @@
         return new RenderInline(element);
     case BLOCK:
     case INLINE_BLOCK:
-        if ((!style->hasAutoColumnCount() || !style->hasAutoColumnWidth()) && element->document().regionBasedColumnsEnabled())
-            return new RenderMultiColumnBlock(element);
         return new RenderBlockFlow(element);
     case LIST_ITEM:
         return new RenderListItem(element);
@@ -202,7 +200,7 @@
 
 RenderObject::RenderObject(Node* node)
     : ImageResourceClient()
-    , m_style(0)
+    , m_style(nullptr)
     , m_node(node)
     , m_parent(0)
     , m_previous(0)
@@ -251,17 +249,17 @@
 
 bool RenderObject::isBody() const
 {
-    return node() && node()->hasTagName(bodyTag);
+    return isHTMLBodyElement(node());
 }
 
 bool RenderObject::isHR() const
 {
-    return node() && node()->hasTagName(hrTag);
+    return isHTMLHRElement(node());
 }
 
 bool RenderObject::isLegend() const
 {
-    return node() && node()->hasTagName(legendTag);
+    return isHTMLLegendElement(node());
 }
 
 void RenderObject::setFlowThreadStateIncludingDescendants(FlowThreadState state)
@@ -704,12 +702,6 @@
     if (isRenderBlock())
         toRenderBlock(this)->checkPositionedObjectsNeedLayout();
 }
-
-void RenderObject::checkNotInPartialLayout()
-{
-    // During partial layout, setNeedsLayout(true or false) should not be called.
-    ASSERT(!frameView()->partialLayout().isStopping());
-}
 #endif
 
 void RenderObject::setPreferredLogicalWidthsDirty(MarkingBehavior markParents)
@@ -818,6 +810,29 @@
     return toRenderBlock(o);
 }
 
+RenderObject* RenderObject::clippingContainer() const
+{
+    RenderObject* container = const_cast<RenderObject*>(this);
+    while (container) {
+        if (container->style()->position() == FixedPosition) {
+            for (container = container->parent(); container && !container->canContainFixedPositionObjects(); container = container->parent()) {
+                // CSS clip applies to fixed position elements even for ancestors that are not what the
+                // fixed element is positioned with respect to.
+                if (container->hasClip())
+                    return container;
+            }
+        } else {
+            container = container->containingBlock();
+        }
+
+        if (!container)
+            return 0;
+        if (container->hasClipOrOverflowClip())
+            return container;
+    }
+    return 0;
+}
+
 static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* layer)
 {
     // Nobody will use multiple layers without wanting fancy positioning.
@@ -1494,10 +1509,17 @@
         // This ASSERT fails due to animations.  See https://bugs.webkit.org/show_bug.cgi?id=37048
         // ASSERT(!newOutlineBoxRectPtr || *newOutlineBoxRectPtr == outlineBoundsForRepaint(repaintContainer));
         newOutlineBox = newOutlineBoxRectPtr ? *newOutlineBoxRectPtr : outlineBoundsForRepaint(repaintContainer);
-        if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox)))
+
+        if ((hasOutline() && newOutlineBox.location() != oldOutlineBox.location())
+            || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || (hasOutline() && newOutlineBox != oldOutlineBox))))
             fullRepaint = true;
     }
 
+    // If there is no intersection between the old and the new bounds, invalidating
+    // the difference is more expensive than just doing a full repaint.
+    if (!fullRepaint && !newBounds.intersects(oldBounds))
+        fullRepaint = true;
+
     if (!repaintContainer)
         repaintContainer = v;
 
@@ -1592,6 +1614,12 @@
 {
 }
 
+void RenderObject::repaintOverflowIfNeeded()
+{
+    if (shouldRepaintOverflow())
+        repaintOverflow();
+}
+
 bool RenderObject::checkForRepaint() const
 {
     return !document().view()->needsFullRepaint() && !hasLayer() && everHadLayout();
@@ -2035,6 +2063,20 @@
                 view()->frameView()->addSlowRepaintObject();
         }
     }
+
+    // Elements with non-auto touch-action will send a SetTouchAction message
+    // on touchstart in EventHandler::handleTouchEvent, and so effectively have
+    // a touchstart handler that must be reported.
+    //
+    // Since a CSS property cannot be applied directly to a text node, a
+    // handler will have already been added for its parent so ignore it.
+    TouchAction oldTouchAction = m_style ? m_style->touchAction() : TouchActionAuto;
+    if (node() && !node()->isTextNode() && (oldTouchAction == TouchActionAuto) != (newStyle->touchAction() == TouchActionAuto)) {
+        if (newStyle->touchAction() != TouchActionAuto)
+            document().didAddTouchEventHandler(node());
+        else
+            document().didRemoveTouchEventHandler(node());
+    }
 }
 
 static bool areNonIdenticalCursorListsEqual(const RenderStyle* a, const RenderStyle* b)
@@ -2081,7 +2123,7 @@
     // updated by subclasses before we know if we have to repaint (in setStyle()).
 
     if (oldStyle && !areCursorsEqual(oldStyle, style())) {
-        if (Frame* frame = this->frame())
+        if (LocalFrame* frame = this->frame())
             frame->eventHandler().scheduleCursorUpdate();
     }
 }
@@ -2247,7 +2289,7 @@
 void RenderObject::getTransformFromContainer(const RenderObject* containerObject, const LayoutSize& offsetInContainer, TransformationMatrix& transform) const
 {
     transform.makeIdentity();
-    transform.translate(offsetInContainer.width(), offsetInContainer.height());
+    transform.translate(offsetInContainer.width().toFloat(), offsetInContainer.height().toFloat());
     RenderLayer* layer;
     if (hasLayer() && (layer = toRenderLayerModelObject(this)->layer()) && layer->transform())
         transform.multiply(layer->currentTransform());
@@ -2433,7 +2475,7 @@
 RenderObject* RenderObject::rendererForRootBackground()
 {
     ASSERT(isRoot());
-    if (!hasBackground() && node() && node()->hasTagName(htmlTag)) {
+    if (!hasBackground() && isHTMLHtmlElement(node())) {
         // Locate the <body> element using the DOM. This is easier than trying
         // to crawl around a render tree with potential :before/:after content and
         // anonymous blocks created by inline <body> tags etc. We can locate the <body>
@@ -2452,7 +2494,7 @@
     // Respect the image's orientation if it's being used as a full-page image or it's
     // an <img> and the setting to respect it everywhere is set.
     return document().isImageDocument()
-        || (document().settings() && document().settings()->shouldRespectImageOrientation() && node() && node()->hasTagName(HTMLNames::imgTag)) ? RespectImageOrientation : DoNotRespectImageOrientation;
+        || (document().settings() && document().settings()->shouldRespectImageOrientation() && isHTMLImageElement(node())) ? RespectImageOrientation : DoNotRespectImageOrientation;
 }
 
 bool RenderObject::hasOutlineAnnotation() const
@@ -2538,7 +2580,7 @@
         children->destroyLeftoverChildren();
 
     // If this renderer is being autoscrolled, stop the autoscrolling.
-    if (Frame* frame = this->frame()) {
+    if (LocalFrame* frame = this->frame()) {
         if (frame->page())
             frame->page()->autoscrollController().stopAutoscrollIfNeeded(this);
     }
@@ -2563,6 +2605,13 @@
     if (hasCounterNodeMap())
         RenderCounter::destroyCounterNodes(*this);
 
+    // Remove the handler if node had touch-action set. Don't call when
+    // document is being destroyed as all handlers will have been cleared
+    // previously. Handlers are not added for text nodes so don't try removing
+    // for one too. Need to check if m_style is null in cases of partial construction.
+    if (!documentBeingDestroyed() && node() && !node()->isTextNode() && m_style && m_style->touchAction() != TouchActionAuto)
+        document().didRemoveTouchEventHandler(node());
+
     setAncestorLineBoxDirty(false);
 
     clearLayoutRootIfNeeded();
@@ -2745,11 +2794,10 @@
 // overflow scroll is ready (crbug.com/254111).
 bool RenderObject::compositorDrivenAcceleratedScrollingEnabled() const
 {
-    if (!acceleratedCompositingForOverflowScrollEnabled())
-        return false;
-
     const Settings* settings = document().settings();
-    return settings && settings->compositorDrivenAcceleratedScrollingEnabled();
+    if (!settings)
+        return false;
+    return settings->acceleratedCompositingForOverflowScrollEnabled() && settings->compositorDrivenAcceleratedScrollingEnabled();
 }
 
 bool RenderObject::hitTest(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestFilter hitTestFilter)
@@ -2861,13 +2909,13 @@
             return rendererForFirstLineStyle->getUncachedPseudoStyle(PseudoStyleRequest(FIRST_LINE_INHERITED), parentStyle, style);
         }
     }
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<RenderStyle> RenderObject::uncachedFirstLineStyle(RenderStyle* style) const
 {
     if (!document().styleEngine()->usesFirstLineRules())
-        return 0;
+        return nullptr;
 
     ASSERT(!isText());
 
@@ -2902,7 +2950,7 @@
 PassRefPtr<RenderStyle> RenderObject::getUncachedPseudoStyle(const PseudoStyleRequest& pseudoStyleRequest, RenderStyle* parentStyle, RenderStyle* ownStyle) const
 {
     if (pseudoStyleRequest.pseudoId < FIRST_INTERNAL_PSEUDOID && !ownStyle && !style()->hasPseudoStyle(pseudoStyleRequest.pseudoId))
-        return 0;
+        return nullptr;
 
     if (!parentStyle) {
         ASSERT(!ownStyle);
@@ -2914,7 +2962,7 @@
     while (n && !n->isElementNode())
         n = n->parentNode();
     if (!n)
-        return 0;
+        return nullptr;
     Element* element = toElement(n);
 
     if (pseudoStyleRequest.pseudoId == FIRST_LINE_INHERITED) {
@@ -2948,31 +2996,35 @@
     return object->resolveColor(style, CSSPropertyWebkitTextFillColor);
 }
 
-void RenderObject::getTextDecorationColors(unsigned decorations, Color& underline, Color& overline,
-                                           Color& linethrough, bool quirksMode, bool firstlineStyle)
+void RenderObject::getTextDecorations(unsigned decorations, AppliedTextDecoration& underline, AppliedTextDecoration& overline, AppliedTextDecoration& linethrough, bool quirksMode, bool firstlineStyle)
 {
     RenderObject* curr = this;
     RenderStyle* styleToUse = 0;
     unsigned currDecs = TextDecorationNone;
     Color resultColor;
+    TextDecorationStyle resultStyle;
     do {
         styleToUse = curr->style(firstlineStyle);
         currDecs = styleToUse->textDecoration();
         currDecs &= decorations;
         resultColor = decorationColor(this, styleToUse);
+        resultStyle = styleToUse->textDecorationStyle();
         // Parameter 'decorations' is cast as an int to enable the bitwise operations below.
         if (currDecs) {
             if (currDecs & TextDecorationUnderline) {
                 decorations &= ~TextDecorationUnderline;
-                underline = resultColor;
+                underline.color = resultColor;
+                underline.style = resultStyle;
             }
             if (currDecs & TextDecorationOverline) {
                 decorations &= ~TextDecorationOverline;
-                overline = resultColor;
+                overline.color = resultColor;
+                overline.style = resultStyle;
             }
             if (currDecs & TextDecorationLineThrough) {
                 decorations &= ~TextDecorationLineThrough;
-                linethrough = resultColor;
+                linethrough.color = resultColor;
+                linethrough.style = resultStyle;
             }
         }
         if (curr->isRubyText())
@@ -2980,18 +3032,24 @@
         curr = curr->parent();
         if (curr && curr->isAnonymousBlock() && toRenderBlock(curr)->continuation())
             curr = toRenderBlock(curr)->continuation();
-    } while (curr && decorations && (!quirksMode || !curr->node() || (!curr->node()->hasTagName(aTag) && !curr->node()->hasTagName(fontTag))));
+    } while (curr && decorations && (!quirksMode || !curr->node() || (!isHTMLAnchorElement(*curr->node()) && !isHTMLFontElement(*curr->node()))));
 
     // If we bailed out, use the element we bailed out at (typically a <font> or <a> element).
     if (decorations && curr) {
         styleToUse = curr->style(firstlineStyle);
         resultColor = decorationColor(this, styleToUse);
-        if (decorations & TextDecorationUnderline)
-            underline = resultColor;
-        if (decorations & TextDecorationOverline)
-            overline = resultColor;
-        if (decorations & TextDecorationLineThrough)
-            linethrough = resultColor;
+        if (decorations & TextDecorationUnderline) {
+            underline.color = resultColor;
+            underline.style = resultStyle;
+        }
+        if (decorations & TextDecorationOverline) {
+            overline.color = resultColor;
+            overline.style = resultStyle;
+        }
+        if (decorations & TextDecorationLineThrough) {
+            linethrough.color = resultColor;
+            linethrough.style = resultStyle;
+        }
     }
 }
 
@@ -3005,7 +3063,7 @@
         return;
 
     RenderBox* box = toRenderBox(this);
-    FloatRect localBounds(FloatPoint(), FloatSize(box->width(), box->height()));
+    FloatRect localBounds(FloatPoint(), FloatSize(box->width().toFloat(), box->height().toFloat()));
     FloatRect absBounds = localToAbsoluteQuad(localBounds).boundingBox();
 
     AnnotatedRegionValue region;
@@ -3056,7 +3114,7 @@
 int RenderObject::caretMaxOffset() const
 {
     if (isReplaced())
-        return node() ? max(1U, node()->childNodeCount()) : 1;
+        return node() ? max(1U, node()->countChildren()) : 1;
     if (isHR())
         return 1;
     return 0;
@@ -3077,15 +3135,9 @@
     return current + 1;
 }
 
-void RenderObject::adjustRectForOutlineAndShadow(LayoutRect& rect) const
+void RenderObject::adjustRectForOutline(LayoutRect& rect) const
 {
-    int outlineSize = outlineStyleForRepaint()->outlineSize();
-    if (const ShadowList* boxShadow = style()->boxShadow()) {
-        boxShadow->adjustRectForShadow(rect, outlineSize);
-        return;
-    }
-
-    rect.inflate(outlineSize);
+    rect.inflate(outlineStyleForRepaint()->outlineSize());
 }
 
 bool RenderObject::isInert() const
@@ -3126,10 +3178,10 @@
         if (ancestor->isPositioned())
             break;
 
-        if (node->hasTagName(bodyTag))
+        if (isHTMLBodyElement(*node))
             break;
 
-        if (!isPositioned() && (node->hasTagName(tableTag) || node->hasTagName(tdTag) || node->hasTagName(thTag)))
+        if (!isPositioned() && (isHTMLTableElement(*node) || isHTMLTableCellElement(*node)))
             break;
 
         // Webkit specific extension where offsetParent stops at zoom level changes.
diff --git a/Source/core/rendering/RenderObject.h b/Source/core/rendering/RenderObject.h
index 7fd2dfe..579d006 100644
--- a/Source/core/rendering/RenderObject.h
+++ b/Source/core/rendering/RenderObject.h
@@ -30,7 +30,7 @@
 #include "core/dom/Position.h"
 #include "core/dom/StyleEngine.h"
 #include "core/fetch/ImageResourceClient.h"
-#include "core/rendering/CompositingState.h"
+#include "core/rendering/compositing/CompositingState.h"
 #include "core/rendering/PaintPhase.h"
 #include "core/rendering/RenderObjectChildList.h"
 #include "core/rendering/ScrollAlignment.h"
@@ -136,6 +136,7 @@
     friend class RenderLayerReflectionInfo; // For setParent
     friend class RenderLayerScrollableArea; // For setParent.
     friend class RenderObjectChildList;
+    WTF_MAKE_NONCOPYABLE(RenderObject);
 public:
     // Anonymous objects should pass the document as their node, and they will then automatically be
     // marked as anonymous in the constructor.
@@ -373,7 +374,6 @@
     bool isInFlowRenderFlowThread() const { return isRenderFlowThread() && !isOutOfFlowPositioned(); }
     bool isOutOfFlowRenderFlowThread() const { return isRenderFlowThread() && isOutOfFlowPositioned(); }
 
-    virtual bool isRenderMultiColumnBlock() const { return false; }
     virtual bool isRenderMultiColumnSet() const { return false; }
 
     virtual bool isRenderScrollbarPart() const { return false; }
@@ -594,7 +594,7 @@
     Node* generatingNode() const { return isPseudoElement() ? node()->parentOrShadowHostNode() : node(); }
 
     Document& document() const { return m_node->document(); }
-    Frame* frame() const { return document().frame(); }
+    LocalFrame* frame() const { return document().frame(); }
 
     bool hasOutlineAnnotation() const;
     bool hasOutline() const { return style()->hasOutline() || hasOutlineAnnotation(); }
@@ -668,9 +668,6 @@
     void forceLayout();
     void forceChildLayout();
 
-    // True if we can abort layout, leaving a partially laid out tree.
-    virtual bool supportsPartialLayout() const { return false; }
-
     // used for element state updates that cannot be fixed with a
     // repaint and do not need a relayout
     virtual void updateFromElement() { }
@@ -706,6 +703,7 @@
 
     // returns the containing block level element for this element.
     RenderBlock* containingBlock() const;
+    RenderObject* clippingContainer() const;
 
     bool canContainFixedPositionObjects() const
     {
@@ -782,7 +780,13 @@
 
     virtual CursorDirective getCursor(const LayoutPoint&, Cursor&) const;
 
-    void getTextDecorationColors(unsigned decorations, Color& underline, Color& overline, Color& linethrough, bool quirksMode = false, bool firstlineStyle = false);
+    struct AppliedTextDecoration {
+        Color color;
+        TextDecorationStyle style;
+        AppliedTextDecoration() : color(Color::transparent), style(TextDecorationStyleSolid) { }
+    };
+
+    void getTextDecorations(unsigned decorations, AppliedTextDecoration& underline, AppliedTextDecoration& overline, AppliedTextDecoration& linethrough, bool quirksMode = false, bool firstlineStyle = false);
 
     // Return the RenderLayerModelObject in the container chain which is responsible for painting this object, or 0
     // if painting is root-relative. This is the container that should be passed to the 'forRepaint'
@@ -804,6 +808,7 @@
         const LayoutRect& oldBounds, const LayoutRect& oldOutlineBox, const LayoutRect* newBoundsPtr = 0, const LayoutRect* newOutlineBoxPtr = 0);
 
     virtual void repaintOverflow();
+    void repaintOverflowIfNeeded();
 
     bool checkForRepaint() const;
     bool checkForRepaintDuringLayout() const;
@@ -922,7 +927,14 @@
     void remove() { if (parent()) parent()->removeChild(this); }
 
     bool isInert() const;
-    bool visibleToHitTestRequest(const HitTestRequest& request) const { return style()->visibility() == VISIBLE && (request.ignorePointerEventsNone() || style()->pointerEvents() != PE_NONE) && !isInert(); }
+    virtual bool visibleForTouchAction() const { return false; }
+    bool visibleToHitTestRequest(const HitTestRequest& request) const
+    {
+        if (request.touchAction() && !visibleForTouchAction())
+            return false;
+        return style()->visibility() == VISIBLE && (request.ignorePointerEventsNone() || style()->pointerEvents() != PE_NONE) && !isInert();
+    }
+
     bool visibleToHitTesting() const { return style()->visibility() == VISIBLE && style()->pointerEvents() != PE_NONE && !isInert(); }
 
     // Map points and quads through elements, potentially via 3d transforms. You should never need to call these directly; use
@@ -964,7 +976,7 @@
 
     bool shouldDoFullRepaintAfterLayout() const { return m_bitfields.shouldDoFullRepaintAfterLayout(); }
     void setShouldDoFullRepaintAfterLayout(bool b) { m_bitfields.setShouldDoFullRepaintAfterLayout(b); }
-    bool shouldRepaintOverflowIfNeeded() const { return m_bitfields.shouldRepaintOverflowIfNeeded(); }
+    bool shouldRepaintOverflow() const { return m_bitfields.shouldRepaintOverflow(); }
 
     void clearRepaintRects()
     {
@@ -972,7 +984,7 @@
         setOldRepaintRect(LayoutRect());
 
         setShouldDoFullRepaintAfterLayout(false);
-        setShouldRepaintOverflowIfNeeded(false);
+        setShouldRepaintOverflow(false);
         setLayoutDidGetCalled(false);
     }
 
@@ -981,6 +993,8 @@
     bool layoutDidGetCalled() { return m_bitfields.layoutDidGetCalled(); }
     void setLayoutDidGetCalled(bool b) { m_bitfields.setLayoutDidGetCalled(b); }
 
+    bool shouldDisableLayoutState() const { return hasColumns() || hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode(); }
+
 protected:
     inline bool layerCreationAllowedForSubtree() const;
 
@@ -1007,7 +1021,7 @@
 
     virtual LayoutRect viewRect() const;
 
-    void adjustRectForOutlineAndShadow(LayoutRect&) const;
+    void adjustRectForOutline(LayoutRect&) const;
 
     void clearLayoutRootIfNeeded() const;
     virtual void willBeDestroyed();
@@ -1051,7 +1065,6 @@
 
 #ifndef NDEBUG
     void checkBlockPositionedObjectsNeedLayout();
-    void checkNotInPartialLayout();
 #endif
 
     RefPtr<RenderStyle> m_style;
@@ -1090,7 +1103,7 @@
             // Holding the layout bits until after repaint would remove the need
             // for this flag.
             , m_shouldDoFullRepaintAfterLayout(false)
-            , m_shouldRepaintOverflowIfNeeded(false)
+            , m_shouldRepaintOverflow(false)
             , m_needsPositionedMovementLayout(false)
             , m_normalChildNeedsLayout(false)
             , m_posChildNeedsLayout(false)
@@ -1125,7 +1138,7 @@
         // 32 bits have been used in the first word, and 3 in the second.
         ADD_BOOLEAN_BITFIELD(selfNeedsLayout, SelfNeedsLayout);
         ADD_BOOLEAN_BITFIELD(shouldDoFullRepaintAfterLayout, ShouldDoFullRepaintAfterLayout);
-        ADD_BOOLEAN_BITFIELD(shouldRepaintOverflowIfNeeded, ShouldRepaintOverflowIfNeeded);
+        ADD_BOOLEAN_BITFIELD(shouldRepaintOverflow, ShouldRepaintOverflow);
         ADD_BOOLEAN_BITFIELD(needsPositionedMovementLayout, NeedsPositionedMovementLayout);
         ADD_BOOLEAN_BITFIELD(normalChildNeedsLayout, NormalChildNeedsLayout);
         ADD_BOOLEAN_BITFIELD(posChildNeedsLayout, PosChildNeedsLayout);
@@ -1199,7 +1212,7 @@
     void setNeedsSimplifiedNormalFlowLayout(bool b) { m_bitfields.setNeedsSimplifiedNormalFlowLayout(b); }
     void setIsDragging(bool b) { m_bitfields.setIsDragging(b); }
     void setEverHadLayout(bool b) { m_bitfields.setEverHadLayout(b); }
-    void setShouldRepaintOverflowIfNeeded(bool b) { m_bitfields.setShouldRepaintOverflowIfNeeded(b); }
+    void setShouldRepaintOverflow(bool b) { m_bitfields.setShouldRepaintOverflow(b); }
 
 private:
     // Store state between styleWillChange and styleDidChange
@@ -1209,6 +1222,14 @@
     LayoutRect m_newRepaintRect;
 };
 
+// Allow equality comparisons of RenderObject's by reference or pointer, interchangeably.
+inline bool operator==(const RenderObject& a, const RenderObject& b) { return &a == &b; }
+inline bool operator==(const RenderObject& a, const RenderObject* b) { return &a == b; }
+inline bool operator==(const RenderObject* a, const RenderObject& b) { return a == &b; }
+inline bool operator!=(const RenderObject& a, const RenderObject& b) { return !(a == b); }
+inline bool operator!=(const RenderObject& a, const RenderObject* b) { return !(a == b); }
+inline bool operator!=(const RenderObject* a, const RenderObject& b) { return !(a == b); }
+
 inline bool RenderObject::documentBeingDestroyed() const
 {
     return !document().renderer();
@@ -1241,9 +1262,6 @@
 
 inline void RenderObject::setNeedsLayout(MarkingBehavior markParents, SubtreeLayoutScope* layouter)
 {
-#ifndef NDEBUG
-    checkNotInPartialLayout();
-#endif
     ASSERT(!isSetNeedsLayoutForbidden());
     bool alreadyNeededLayout = m_bitfields.selfNeedsLayout();
     setSelfNeedsLayout(true);
@@ -1257,9 +1275,6 @@
 
 inline void RenderObject::clearNeedsLayout()
 {
-#ifndef NDEBUG
-    checkNotInPartialLayout();
-#endif
     setSelfNeedsLayout(false);
     setEverHadLayout(true);
     setPosChildNeedsLayout(false);
diff --git a/Source/core/rendering/RenderOverflow.h b/Source/core/rendering/RenderOverflow.h
index 2a965c7..2860b7c 100644
--- a/Source/core/rendering/RenderOverflow.h
+++ b/Source/core/rendering/RenderOverflow.h
@@ -50,16 +50,6 @@
     const LayoutRect visualOverflowRect() const { return m_visualOverflow; }
     LayoutRect contentsVisualOverflowRect() const { return m_contentsVisualOverflow; }
 
-    void setMinYLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setY(overflow); }
-    void setMaxYLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setHeight(overflow - m_layoutOverflow.y()); }
-    void setMinXLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setX(overflow); }
-    void setMaxXLayoutOverflow(LayoutUnit overflow) { m_layoutOverflow.setWidth(overflow - m_layoutOverflow.x()); }
-
-    void setMinYVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setY(overflow); }
-    void setMaxYVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setHeight(overflow - m_layoutOverflow.y()); }
-    void setMinXVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setX(overflow); }
-    void setMaxXVisualOverflow(LayoutUnit overflow) { m_visualOverflow.setWidth(overflow - m_layoutOverflow.x()); }
-
     void move(LayoutUnit dx, LayoutUnit dy);
 
     void addLayoutOverflow(const LayoutRect&);
diff --git a/Source/core/rendering/RenderPart.cpp b/Source/core/rendering/RenderPart.cpp
index 689219e..c535ae4 100644
--- a/Source/core/rendering/RenderPart.cpp
+++ b/Source/core/rendering/RenderPart.cpp
@@ -25,8 +25,8 @@
 #include "config.h"
 #include "core/rendering/RenderPart.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/plugins/PluginView.h"
 #include "core/rendering/HitTestResult.h"
diff --git a/Source/core/rendering/RenderProgress.cpp b/Source/core/rendering/RenderProgress.cpp
index c44ce5c..00bcb33 100644
--- a/Source/core/rendering/RenderProgress.cpp
+++ b/Source/core/rendering/RenderProgress.cpp
@@ -73,7 +73,7 @@
 {
     repaint();
     if (!m_animationTimer.isActive() && m_animating)
-        m_animationTimer.startOneShot(m_animationRepeatInterval);
+        m_animationTimer.startOneShot(m_animationRepeatInterval, FROM_HERE);
 }
 
 void RenderProgress::updateAnimationState()
@@ -88,7 +88,7 @@
     m_animating = animating;
     if (m_animating) {
         m_animationStartTime = currentTime();
-        m_animationTimer.startOneShot(m_animationRepeatInterval);
+        m_animationTimer.startOneShot(m_animationRepeatInterval, FROM_HERE);
     } else
         m_animationTimer.stop();
 }
@@ -98,7 +98,7 @@
     if (!node())
         return 0;
 
-    if (node()->hasTagName(HTMLNames::progressTag))
+    if (isHTMLProgressElement(*node()))
         return toHTMLProgressElement(node());
 
     ASSERT(node()->shadowHost());
diff --git a/Source/core/rendering/RenderProgress.h b/Source/core/rendering/RenderProgress.h
index c1014d2..18d5c5d 100644
--- a/Source/core/rendering/RenderProgress.h
+++ b/Source/core/rendering/RenderProgress.h
@@ -44,7 +44,6 @@
 private:
     virtual const char* renderName() const OVERRIDE { return "RenderProgress"; }
     virtual bool isProgress() const OVERRIDE { return true; }
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
 
     void animationTimerFired(Timer<RenderProgress>*);
     void updateAnimationState();
diff --git a/Source/core/rendering/RenderRegion.h b/Source/core/rendering/RenderRegion.h
index b57d159..66f3985 100644
--- a/Source/core/rendering/RenderRegion.h
+++ b/Source/core/rendering/RenderRegion.h
@@ -106,7 +106,6 @@
     virtual void willBeRemovedFromTree() OVERRIDE FINAL;
 
     virtual void layoutBlock(bool relayoutChildren) OVERRIDE FINAL;
-    virtual bool supportsPartialLayout() const OVERRIDE FINAL { return false; }
 
 protected:
     RenderFlowThread* m_flowThread;
diff --git a/Source/core/rendering/RenderReplaced.cpp b/Source/core/rendering/RenderReplaced.cpp
index ead5b9c..23a62f5 100644
--- a/Source/core/rendering/RenderReplaced.cpp
+++ b/Source/core/rendering/RenderReplaced.cpp
@@ -198,8 +198,8 @@
     LayoutUnit top = adjustedPaintOffset.y() + visualOverflowRect().y();
     LayoutUnit bottom = adjustedPaintOffset.y() + visualOverflowRect().maxY();
     if (isSelected() && inlineBoxWrapper()) {
-        LayoutUnit selTop = paintOffset.y() + inlineBoxWrapper()->root()->selectionTop();
-        LayoutUnit selBottom = paintOffset.y() + selTop + inlineBoxWrapper()->root()->selectionHeight();
+        LayoutUnit selTop = paintOffset.y() + inlineBoxWrapper()->root().selectionTop();
+        LayoutUnit selBottom = paintOffset.y() + selTop + inlineBoxWrapper()->root().selectionHeight();
         top = min(selTop, top);
         bottom = max(selBottom, bottom);
     }
@@ -225,7 +225,9 @@
         return 0;
 
     for (; !containingBlock->isRenderView() && !containingBlock->isBody(); containingBlock = containingBlock->containingBlock()) {
-        if (containingBlock->style()->logicalWidth().isSpecified())
+        if (containingBlock->style()->logicalWidth().isSpecified()
+            && containingBlock->style()->logicalMinWidth().isSpecified()
+            && (containingBlock->style()->logicalMaxWidth().isSpecified() || containingBlock->style()->logicalMaxWidth().isUndefined()))
             return containingBlock;
     }
 
@@ -371,7 +373,7 @@
     // If there's an embeddedContentBox() of a remote, referenced document available, this code-path should never be used.
     ASSERT(!embeddedContentBox());
     isPercentageIntrinsicSize = false;
-    intrinsicSize = FloatSize(intrinsicLogicalWidth(), intrinsicLogicalHeight());
+    intrinsicSize = FloatSize(intrinsicLogicalWidth().toFloat(), intrinsicLogicalHeight().toFloat());
 
     // Figure out if we need to compute an intrinsic ratio.
     if (intrinsicSize.isEmpty() || !rendererHasAspectRatio(this))
@@ -418,10 +420,19 @@
                 // The aforementioned 'constraint equation' used for block-level, non-replaced elements in normal flow:
                 // 'margin-left' + 'border-left-width' + 'padding-left' + 'width' + 'padding-right' + 'border-right-width' + 'margin-right' = width of containing block
                 LayoutUnit logicalWidth;
-                if (RenderBlock* blockWithWidth = firstContainingBlockWithLogicalWidth(this))
+                // FIXME: This walking up the containgBlock chain to find the first one with a specified width is bonkers.
+                // If nothing else, it requires making sure that computeReplacedLogicalWidthRespectingMinMaxWidth cannot
+                // depend on the width of the replaced element or we infinite loop. Right now we do that in
+                // firstContainingBlockWithLogicalWidth by checking that width/min-width/max-width are all specified.
+                //
+                // Firefox 27 seems to only do this if the <svg> has a viewbox.
+                if (RenderBlock* blockWithWidth = firstContainingBlockWithLogicalWidth(this)) {
                     logicalWidth = blockWithWidth->computeReplacedLogicalWidthRespectingMinMaxWidth(blockWithWidth->computeReplacedLogicalWidthUsing(blockWithWidth->style()->logicalWidth()), shouldComputePreferred);
-                else
+                } else {
+                    // FIXME: If shouldComputePreferred == ComputePreferred, then we're reading this during preferred width
+                    // computation, at which point this is reading stale data from a previous layout.
                     logicalWidth = containingBlock()->availableLogicalWidth();
+                }
 
                 // This solves above equation for 'width' (== logicalWidth).
                 LayoutUnit marginStart = minimumValueForLength(style()->marginStart(), logicalWidth);
@@ -523,7 +534,7 @@
 {
     // FIXME: This code is buggy if the replaced element is relative positioned.
     InlineBox* box = inlineBoxWrapper();
-    RootInlineBox* rootBox = box ? box->root() : 0;
+    RootInlineBox* rootBox = box ? &box->root() : 0;
 
     LayoutUnit top = rootBox ? rootBox->selectionTop() : logicalTop();
     LayoutUnit bottom = rootBox ? rootBox->selectionBottom() : logicalBottom();
@@ -571,11 +582,11 @@
         // We're a block-level replaced element.  Just return our own dimensions.
         return LayoutRect(LayoutPoint(), size());
 
-    RootInlineBox* root = inlineBoxWrapper()->root();
-    LayoutUnit newLogicalTop = root->block()->style()->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root->selectionBottom() : root->selectionTop() - inlineBoxWrapper()->logicalTop();
-    if (root->block()->style()->isHorizontalWritingMode())
-        return LayoutRect(0, newLogicalTop, width(), root->selectionHeight());
-    return LayoutRect(newLogicalTop, 0, root->selectionHeight(), height());
+    RootInlineBox& root = inlineBoxWrapper()->root();
+    LayoutUnit newLogicalTop = root.block().style()->isFlippedBlocksWritingMode() ? inlineBoxWrapper()->logicalBottom() - root.selectionBottom() : root.selectionTop() - inlineBoxWrapper()->logicalTop();
+    if (root.block().style()->isHorizontalWritingMode())
+        return LayoutRect(0, newLogicalTop, width(), root.selectionHeight());
+    return LayoutRect(newLogicalTop, 0, root.selectionHeight(), height());
 }
 
 void RenderReplaced::setSelectionState(SelectionState state)
@@ -584,8 +595,7 @@
     RenderBox::setSelectionState(state);
 
     if (inlineBoxWrapper() && canUpdateSelectionOnRootLineBoxes())
-        if (RootInlineBox* root = inlineBoxWrapper()->root())
-            root->setHasSelectedChildren(isSelected());
+        inlineBoxWrapper()->root().setHasSelectedChildren(isSelected());
 }
 
 bool RenderReplaced::isSelected() const
@@ -601,7 +611,7 @@
     if (s == SelectionStart)
         return selectionStart == 0;
 
-    int end = node()->hasChildNodes() ? node()->childNodeCount() : 1;
+    int end = node()->hasChildren() ? node()->countChildren() : 1;
     if (s == SelectionEnd)
         return selectionEnd == end;
     if (s == SelectionBoth)
diff --git a/Source/core/rendering/RenderRuby.h b/Source/core/rendering/RenderRuby.h
index afa0d55..cd0a7fc 100644
--- a/Source/core/rendering/RenderRuby.h
+++ b/Source/core/rendering/RenderRuby.h
@@ -83,7 +83,6 @@
 private:
     virtual bool isRuby() const OVERRIDE { return true; }
     virtual const char* renderName() const OVERRIDE { return "RenderRuby (block)"; }
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
     virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
     virtual void removeLeftoverAnonymousBlock(RenderBlock*) OVERRIDE { ASSERT_NOT_REACHED(); }
 };
diff --git a/Source/core/rendering/RenderRubyBase.h b/Source/core/rendering/RenderRubyBase.h
index 800515d..5831f2c 100644
--- a/Source/core/rendering/RenderRubyBase.h
+++ b/Source/core/rendering/RenderRubyBase.h
@@ -55,8 +55,6 @@
     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const OVERRIDE;
     virtual void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     void moveChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
     void moveInlineChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
     void moveBlockChildren(RenderRubyBase* toBase, RenderObject* beforeChild = 0);
diff --git a/Source/core/rendering/RenderRubyRun.h b/Source/core/rendering/RenderRubyRun.h
index 65b1243..682ab94 100644
--- a/Source/core/rendering/RenderRubyRun.h
+++ b/Source/core/rendering/RenderRubyRun.h
@@ -74,7 +74,6 @@
 
     virtual bool isRubyRun() const OVERRIDE { return true; }
     virtual const char* renderName() const OVERRIDE { return "RenderRubyRun (anonymous)"; }
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
     virtual bool createsAnonymousWrapper() const OVERRIDE { return true; }
     virtual void removeLeftoverAnonymousBlock(RenderBlock*) OVERRIDE { }
 };
diff --git a/Source/core/rendering/RenderRubyText.h b/Source/core/rendering/RenderRubyText.h
index 0f35383..432f0ab 100644
--- a/Source/core/rendering/RenderRubyText.h
+++ b/Source/core/rendering/RenderRubyText.h
@@ -49,8 +49,6 @@
 private:
     virtual bool avoidsFloats() const OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     virtual ETextAlign textAlignmentForLine(bool endsWithSoftBreak) const OVERRIDE;
     virtual void adjustInlineDirectionLineBounds(int expansionOpportunityCount, float& logicalLeft, float& logicalWidth) const OVERRIDE;
 };
diff --git a/Source/core/rendering/RenderScrollbar.cpp b/Source/core/rendering/RenderScrollbar.cpp
index f2f7a89..ef442a9 100644
--- a/Source/core/rendering/RenderScrollbar.cpp
+++ b/Source/core/rendering/RenderScrollbar.cpp
@@ -27,20 +27,20 @@
 #include "core/rendering/RenderScrollbar.h"
 
 #include "core/css/PseudoStyleRequest.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderPart.h"
 #include "core/rendering/RenderScrollbarPart.h"
 #include "core/rendering/RenderScrollbarTheme.h"
 
 namespace WebCore {
 
-PassRefPtr<Scrollbar> RenderScrollbar::createCustomScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, Frame* owningFrame)
+PassRefPtr<Scrollbar> RenderScrollbar::createCustomScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, LocalFrame* owningFrame)
 {
     return adoptRef(new RenderScrollbar(scrollableArea, orientation, ownerNode, owningFrame));
 }
 
-RenderScrollbar::RenderScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, Frame* owningFrame)
+RenderScrollbar::RenderScrollbar(ScrollableArea* scrollableArea, ScrollbarOrientation orientation, Node* ownerNode, LocalFrame* owningFrame)
     : Scrollbar(scrollableArea, orientation, RegularScrollbar, RenderScrollbarTheme::renderScrollbarTheme())
     , m_owner(ownerNode)
     , m_owningFrame(owningFrame)
@@ -148,7 +148,7 @@
 PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId)
 {
     if (!owningRenderer())
-        return 0;
+        return nullptr;
 
     RefPtr<RenderStyle> result = owningRenderer()->getUncachedPseudoStyle(PseudoStyleRequest(pseudoId, this, partType), owningRenderer()->style());
     // Scrollbars for root frames should always have background color
@@ -223,7 +223,7 @@
     if (partType == NoPart)
         return;
 
-    RefPtr<RenderStyle> partStyle = !destroy ? getScrollbarPseudoStyle(partType,  pseudoForScrollbarPart(partType)) : PassRefPtr<RenderStyle>(0);
+    RefPtr<RenderStyle> partStyle = !destroy ? getScrollbarPseudoStyle(partType,  pseudoForScrollbarPart(partType)) : PassRefPtr<RenderStyle>(nullptr);
 
     bool needRenderer = !destroy && partStyle && partStyle->display() != NONE && partStyle->visibility() == VISIBLE;
 
diff --git a/Source/core/rendering/RenderScrollbar.h b/Source/core/rendering/RenderScrollbar.h
index d9a9718..c4b81fc 100644
--- a/Source/core/rendering/RenderScrollbar.h
+++ b/Source/core/rendering/RenderScrollbar.h
@@ -32,7 +32,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class Node;
 class RenderBox;
 class RenderScrollbarPart;
@@ -40,11 +40,11 @@
 
 class RenderScrollbar FINAL : public Scrollbar {
 protected:
-    RenderScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, Frame*);
+    RenderScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, LocalFrame*);
 
 public:
     friend class Scrollbar;
-    static PassRefPtr<Scrollbar> createCustomScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, Frame* owningFrame = 0);
+    static PassRefPtr<Scrollbar> createCustomScrollbar(ScrollableArea*, ScrollbarOrientation, Node*, LocalFrame* owningFrame = 0);
     virtual ~RenderScrollbar();
 
     RenderBox* owningRenderer() const;
@@ -83,7 +83,7 @@
     // FrameView which this Node pointer can in no way keep alive. See webkit bug 80610.
     RefPtr<Node> m_owner;
 
-    Frame* m_owningFrame;
+    LocalFrame* m_owningFrame;
     HashMap<unsigned, RenderScrollbarPart*> m_parts;
 };
 
diff --git a/Source/core/rendering/RenderScrollbarPart.h b/Source/core/rendering/RenderScrollbarPart.h
index fa6695a..9aee927 100644
--- a/Source/core/rendering/RenderScrollbarPart.h
+++ b/Source/core/rendering/RenderScrollbarPart.h
@@ -66,7 +66,18 @@
 
     virtual void computePreferredLogicalWidths() OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
+    // Have all padding getters return 0. The important point here is to avoid resolving percents
+    // against the containing block, since scroll bar corners don't always have one (so it would
+    // crash). Scroll bar corners are not actually laid out, and they don't have child content, so
+    // what we return here doesn't really matter.
+    virtual LayoutUnit paddingTop() const OVERRIDE { return LayoutUnit(); }
+    virtual LayoutUnit paddingBottom() const OVERRIDE { return LayoutUnit(); }
+    virtual LayoutUnit paddingLeft() const OVERRIDE { return LayoutUnit(); }
+    virtual LayoutUnit paddingRight() const OVERRIDE { return LayoutUnit(); }
+    virtual LayoutUnit paddingBefore() const OVERRIDE { return LayoutUnit(); }
+    virtual LayoutUnit paddingAfter() const OVERRIDE { return LayoutUnit(); }
+    virtual LayoutUnit paddingStart() const OVERRIDE { return LayoutUnit(); }
+    virtual LayoutUnit paddingEnd() const OVERRIDE { return LayoutUnit(); }
 
     void layoutHorizontalPart();
     void layoutVerticalPart();
diff --git a/Source/core/rendering/RenderScrollbarTheme.h b/Source/core/rendering/RenderScrollbarTheme.h
index 8340ca5..571185b 100644
--- a/Source/core/rendering/RenderScrollbarTheme.h
+++ b/Source/core/rendering/RenderScrollbarTheme.h
@@ -41,11 +41,10 @@
 
     virtual ScrollbarButtonsPlacement buttonsPlacement() const OVERRIDE { return ScrollbarTheme::theme()->buttonsPlacement(); }
 
-    virtual bool supportsControlTints() const OVERRIDE { return true; }
-
     virtual void paintScrollCorner(GraphicsContext*, const IntRect& cornerRect) OVERRIDE;
 
     virtual bool shouldCenterOnThumb(ScrollbarThemeClient* scrollbar, const PlatformMouseEvent& event) OVERRIDE { return ScrollbarTheme::theme()->shouldCenterOnThumb(scrollbar, event); }
+    virtual bool shouldSnapBackToDragOrigin(ScrollbarThemeClient* scrollbar, const PlatformMouseEvent& event) OVERRIDE { return ScrollbarTheme::theme()->shouldSnapBackToDragOrigin(scrollbar, event); }
 
     virtual double initialAutoscrollTimerDelay() OVERRIDE { return ScrollbarTheme::theme()->initialAutoscrollTimerDelay(); }
     virtual double autoscrollTimerDelay() OVERRIDE { return ScrollbarTheme::theme()->autoscrollTimerDelay(); }
diff --git a/Source/core/rendering/RenderTable.cpp b/Source/core/rendering/RenderTable.cpp
index 80fe1d6..25476f5 100644
--- a/Source/core/rendering/RenderTable.cpp
+++ b/Source/core/rendering/RenderTable.cpp
@@ -29,7 +29,9 @@
 #include "HTMLNames.h"
 #include "core/dom/Document.h"
 #include "core/frame/FrameView.h"
+#include "core/html/HTMLTableElement.h"
 #include "core/rendering/AutoTableLayout.h"
+#include "core/rendering/FastTextAutosizer.h"
 #include "core/rendering/FixedTableLayout.h"
 #include "core/rendering/GraphicsContextAnnotator.h"
 #include "core/rendering/HitTestResult.h"
@@ -304,12 +306,9 @@
     setMarginStart(0);
     setMarginEnd(0);
     if (!hasPerpendicularContainingBlock) {
-        LayoutUnit containerLogicalWidthForAutoMargins = availableLogicalWidth;
-        if (avoidsFloats() && cb->containsFloats())
-            containerLogicalWidthForAutoMargins = containingBlockAvailableLineWidth();
         ComputedMarginValues marginValues;
         bool hasInvertedDirection =  cb->style()->isLeftToRightDirection() == style()->isLeftToRightDirection();
-        computeInlineDirectionMargins(cb, containerLogicalWidthForAutoMargins, logicalWidth(),
+        computeInlineDirectionMargins(cb, availableLogicalWidth, logicalWidth(),
             hasInvertedDirection ? marginValues.m_start : marginValues.m_end,
             hasInvertedDirection ? marginValues.m_end : marginValues.m_start);
         setMarginStart(marginValues.m_start);
@@ -334,7 +333,7 @@
 
     // HTML tables' width styles already include borders and paddings, but CSS tables' width styles do not.
     LayoutUnit borders = 0;
-    bool isCSSTable = !node() || !node()->hasTagName(tableTag);
+    bool isCSSTable = !isHTMLTableElement(node());
     if (isCSSTable && styleLogicalWidth.isSpecified() && styleLogicalWidth.isPositive() && style()->boxSizing() == CONTENT_BOX)
         borders = borderStart() + borderEnd() + (collapseBorders() ? LayoutUnit() : paddingStart() + paddingEnd());
 
@@ -351,7 +350,7 @@
         // HTML tables size as though CSS height includes border/padding, CSS tables do not.
         LayoutUnit borders = LayoutUnit();
         // FIXME: We cannot apply box-sizing: content-box on <table> which other browsers allow.
-        if ((node() && node()->hasTagName(tableTag)) || style()->boxSizing() == BORDER_BOX) {
+        if (isHTMLTableElement(node()) || style()->boxSizing() == BORDER_BOX) {
             borders = borderAndPadding;
         }
         computedLogicalHeight = styleLogicalHeight.value() - borders;
@@ -413,6 +412,9 @@
 
 void RenderTable::layout()
 {
+    // Note: RenderTable is handled differently than other RenderBlocks and the LayoutScope
+    //       must be created before the table begins laying out.
+    FastTextAutosizer::LayoutScope fastTextAutosizerLayoutScope(this);
     ASSERT(needsLayout());
 
     LayoutRectRecorder recorder(*this);
@@ -426,7 +428,7 @@
     recalcBordersInRowDirection();
 
     LayoutRepainter repainter(*this, checkForRepaintDuringLayout());
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     setLogicalHeight(0);
 
@@ -454,6 +456,8 @@
     bool collapsing = collapseBorders();
 
     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
+        if (!child->needsLayout() && child->isBox())
+            toRenderBox(child)->markForPaginationRelayoutIfNeeded(layouter);
         if (child->isTableSection()) {
             RenderTableSection* section = toRenderTableSection(child);
             if (m_columnLogicalWidthChanged)
@@ -572,7 +576,7 @@
     statePusher.pop();
 
     if (view()->layoutState()->pageLogicalHeight())
-        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(this, logicalTop()));
+        setPageLogicalOffset(view()->layoutState()->pageLogicalOffset(*this, logicalTop()));
 
     bool didFullRepaint = repainter.repaintAfterLayout();
     // Repaint with our new bounds if they are different from our old bounds.
diff --git a/Source/core/rendering/RenderTable.h b/Source/core/rendering/RenderTable.h
index 9c460df..536c00f 100644
--- a/Source/core/rendering/RenderTable.h
+++ b/Source/core/rendering/RenderTable.h
@@ -284,7 +284,6 @@
     virtual void paintBoxDecorations(PaintInfo&, const LayoutPoint&) OVERRIDE;
     virtual void paintMask(PaintInfo&, const LayoutPoint&) OVERRIDE;
     virtual void layout() OVERRIDE;
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minWidth, LayoutUnit& maxWidth) const OVERRIDE;
     virtual void computePreferredLogicalWidths() OVERRIDE;
     virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
diff --git a/Source/core/rendering/RenderTableCaption.h b/Source/core/rendering/RenderTableCaption.h
index 35755a9..d24acf8 100644
--- a/Source/core/rendering/RenderTableCaption.h
+++ b/Source/core/rendering/RenderTableCaption.h
@@ -35,8 +35,6 @@
 private:
     virtual bool isTableCaption() const OVERRIDE { return true; }
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     virtual void insertedIntoTree() OVERRIDE;
     virtual void willBeRemovedFromTree() OVERRIDE;
 
diff --git a/Source/core/rendering/RenderTableCell.cpp b/Source/core/rendering/RenderTableCell.cpp
index e33032a..b465f0e 100644
--- a/Source/core/rendering/RenderTableCell.cpp
+++ b/Source/core/rendering/RenderTableCell.cpp
@@ -75,16 +75,16 @@
 unsigned RenderTableCell::parseColSpanFromDOM() const
 {
     ASSERT(node());
-    if (node()->hasTagName(tdTag) || node()->hasTagName(thTag))
-        return min<unsigned>(toHTMLTableCellElement(node())->colSpan(), maxColumnIndex);
+    if (isHTMLTableCellElement(*node()))
+        return min<unsigned>(toHTMLTableCellElement(*node()).colSpan(), maxColumnIndex);
     return 1;
 }
 
 unsigned RenderTableCell::parseRowSpanFromDOM() const
 {
     ASSERT(node());
-    if (node()->hasTagName(tdTag) || node()->hasTagName(thTag))
-        return min<unsigned>(toHTMLTableCellElement(node())->rowSpan(), maxRowIndex);
+    if (isHTMLTableCellElement(*node()))
+        return min<unsigned>(toHTMLTableCellElement(*node()).rowSpan(), maxRowIndex);
     return 1;
 }
 
@@ -99,7 +99,7 @@
 void RenderTableCell::colSpanOrRowSpanChanged()
 {
     ASSERT(node());
-    ASSERT(node()->hasTagName(tdTag) || node()->hasTagName(thTag));
+    ASSERT(isHTMLTableCellElement(*node()));
 
     updateColAndRowSpanFlags();
 
diff --git a/Source/core/rendering/RenderTableCell.h b/Source/core/rendering/RenderTableCell.h
index 212cc05..c7067a4 100644
--- a/Source/core/rendering/RenderTableCell.h
+++ b/Source/core/rendering/RenderTableCell.h
@@ -123,8 +123,6 @@
 
     virtual void layout() OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
-
     virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
 
     void paintCollapsedBorders(PaintInfo&, const LayoutPoint&);
diff --git a/Source/core/rendering/RenderTableCol.cpp b/Source/core/rendering/RenderTableCol.cpp
index 26c5935..60d548e 100644
--- a/Source/core/rendering/RenderTableCol.cpp
+++ b/Source/core/rendering/RenderTableCol.cpp
@@ -60,9 +60,9 @@
 {
     unsigned oldSpan = m_span;
     Node* n = node();
-    if (n && (n->hasTagName(colTag) || n->hasTagName(colgroupTag))) {
-        HTMLTableColElement* tc = toHTMLTableColElement(n);
-        m_span = tc->span();
+    if (n && isHTMLTableColElement(*n)) {
+        HTMLTableColElement& tc = toHTMLTableColElement(*n);
+        m_span = tc.span();
     } else
         m_span = !(style() && style()->display() == TABLE_COLUMN_GROUP);
     if (m_span != oldSpan && style() && parent())
diff --git a/Source/core/rendering/RenderTableRow.cpp b/Source/core/rendering/RenderTableRow.cpp
index 02cc260..df4d58a 100644
--- a/Source/core/rendering/RenderTableRow.cpp
+++ b/Source/core/rendering/RenderTableRow.cpp
@@ -163,18 +163,15 @@
     LayoutRectRecorder recorder(*this);
 
     // Table rows do not add translation.
-    LayoutStateMaintainer statePusher(view(), this, LayoutSize(), style()->isFlippedBlocksWritingMode());
-
-    bool paginated = view()->layoutState()->isPaginated();
+    LayoutStateMaintainer statePusher(*this, LayoutSize());
 
     for (RenderObject* child = firstChild(); child; child = child->nextSibling()) {
         if (child->isTableCell()) {
             SubtreeLayoutScope layouter(child);
             RenderTableCell* cell = toRenderTableCell(child);
-            if (!cell->needsLayout() && paginated && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell, cell->logicalTop()) != cell->pageLogicalOffset())
-                layouter.setChildNeedsLayout(cell);
-
-            if (child->needsLayout()) {
+            if (!cell->needsLayout())
+                cell->markForPaginationRelayoutIfNeeded(layouter);
+            if (cell->needsLayout()) {
                 cell->computeAndSetBlockDirectionMargins(table());
                 cell->layout();
             }
diff --git a/Source/core/rendering/RenderTableRow.h b/Source/core/rendering/RenderTableRow.h
index 28be9df..126502a 100644
--- a/Source/core/rendering/RenderTableRow.h
+++ b/Source/core/rendering/RenderTableRow.h
@@ -105,7 +105,7 @@
 
     virtual LayerType layerTypeRequired() const OVERRIDE
     {
-        if (hasTransform() || hasHiddenBackface() || hasClipPath() || createsGroup() || isStickyPositioned())
+        if (hasTransform() || hasHiddenBackface() || hasClipPath() || createsGroup() || isStickyPositioned() || style()->hasWillChangeCompositingHint() || style()->hasWillChangeGpuRasterizationHint())
             return NormalLayer;
 
         if (hasOverflowClip())
diff --git a/Source/core/rendering/RenderTableSection.cpp b/Source/core/rendering/RenderTableSection.cpp
index c88b490..259b387 100644
--- a/Source/core/rendering/RenderTableSection.cpp
+++ b/Source/core/rendering/RenderTableSection.cpp
@@ -289,7 +289,7 @@
 
         spanningRowsHeight.rowHeight[row] = m_rowPos[actualRow + 1] - m_rowPos[actualRow] - borderSpacingForRow(actualRow);
         if (!spanningRowsHeight.rowHeight[row])
-            spanningRowsHeight.rowWithOnlySpanningCells |= rowHasOnlySpanningCells(actualRow);
+            spanningRowsHeight.isAnyRowWithOnlySpanningCells |= rowHasOnlySpanningCells(actualRow);
 
         spanningRowsHeight.totalRowsHeight += spanningRowsHeight.rowHeight[row];
         spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing -= borderSpacingForRow(actualRow);
@@ -542,14 +542,31 @@
 
         populateSpanningRowsHeightFromCell(cell, spanningRowsHeight);
 
-        if (spanningRowsHeight.rowWithOnlySpanningCells)
+        // Here we are handling only row(s) who have only rowspanning cells and do not have any empty cell.
+        if (spanningRowsHeight.isAnyRowWithOnlySpanningCells)
             updateRowsHeightHavingOnlySpanningCells(cell, spanningRowsHeight);
 
-        if (!spanningRowsHeight.totalRowsHeight || spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanningRowsHeight.totalRowsHeight) {
+        // This code handle row(s) that have rowspanning cell(s) and at least one empty cell.
+        // Such rows are not handled below and end up having a height of 0. That would mean
+        // content overlapping if one of their cells has any content. To avoid the problem, we
+        // add all the remaining spanning cells' height to the last spanned row.
+        // This means that we could grow a row past its 'height' or break percentage spreading
+        // however this is better than overlapping content.
+        // FIXME: Is there a better algorithm?
+        if (!spanningRowsHeight.totalRowsHeight) {
+            if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing)
+                m_rowPos[spanningCellEndIndex] += spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing + borderSpacingForRow(spanningCellEndIndex - 1);
+
+            extraHeightToPropagate = m_rowPos[spanningCellEndIndex] - originalBeforePosition;
+            continue;
+        }
+
+        if (spanningRowsHeight.spanningCellHeightIgnoringBorderSpacing <= spanningRowsHeight.totalRowsHeight) {
             extraHeightToPropagate = m_rowPos[rowIndex + rowSpan] - originalBeforePosition;
             continue;
         }
 
+        // Below we are handling only row(s) who have at least one visible cell without rowspan value.
         int totalPercent = 0;
         int totalAutoRowsHeight = 0;
         int totalRemainingRowsHeight = spanningRowsHeight.totalRowsHeight;
@@ -619,7 +636,7 @@
 
     RenderTableCell* cell;
 
-    LayoutStateMaintainer statePusher(view());
+    LayoutStateMaintainer statePusher(*this);
 
     m_rowPos.resize(m_grid.size() + 1);
 
@@ -675,7 +692,7 @@
                     if (!statePusher.didPush()) {
                         // Technically, we should also push state for the row, but since
                         // rows don't push a coordinate transform, that's not necessary.
-                        statePusher.push(this, locationOffset());
+                        statePusher.push(*this, locationOffset());
                     }
                     cell->clearIntrinsicPadding();
                     cell->clearOverrideSize();
@@ -716,7 +733,7 @@
     // can be called in a loop (e.g during parsing). Doing it now ensures we have a stable-enough structure.
     m_grid.shrinkToFit();
 
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     const Vector<int>& columnPos = table()->columnPositions();
 
@@ -745,8 +762,11 @@
             cell->setCellLogicalWidth(tableLayoutLogicalWidth, layouter);
         }
 
-        if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer)
+        if (RenderTableRow* rowRenderer = m_grid[r].rowRenderer) {
+            if (!rowRenderer->needsLayout())
+                rowRenderer->markForPaginationRelayoutIfNeeded(layouter);
             rowRenderer->layoutIfNeeded();
+        }
     }
 
     statePusher.pop();
@@ -871,7 +891,7 @@
     int vspacing = table()->vBorderSpacing();
     unsigned nEffCols = table()->numEffCols();
 
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     for (unsigned r = 0; r < totalRows; r++) {
         // Set the row's x/y position and width/height.
@@ -956,8 +976,8 @@
 
             setLogicalPositionForCell(cell, c);
 
-            if (!cell->needsLayout() && view()->layoutState()->pageLogicalHeight() && view()->layoutState()->pageLogicalOffset(cell, cell->logicalTop()) != cell->pageLogicalOffset())
-                layouter.setChildNeedsLayout(cell);
+            if (!cell->needsLayout())
+                cell->markForPaginationRelayoutIfNeeded(layouter);
 
             cell->layoutIfNeeded();
 
@@ -1183,7 +1203,7 @@
 {
     ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
 
-    ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());
+    ASSERT(!needsLayout());
     // avoid crashing on bugs that cause us to paint with dirty layout
     if (needsLayout())
         return;
@@ -1582,7 +1602,7 @@
         Row& r = m_grid[row].row;
         r.insert(pos + 1, CellStruct());
         if (r[pos].hasCells()) {
-            r[pos + 1].cells.append(r[pos].cells);
+            r[pos + 1].cells.appendVector(r[pos].cells);
             RenderTableCell* cell = r[pos].primaryCell();
             ASSERT(cell);
             ASSERT(cell->colSpan() >= (r[pos].inColSpan ? 1u : 0));
diff --git a/Source/core/rendering/RenderTableSection.h b/Source/core/rendering/RenderTableSection.h
index 37f49e2..f8d476f 100644
--- a/Source/core/rendering/RenderTableSection.h
+++ b/Source/core/rendering/RenderTableSection.h
@@ -129,14 +129,14 @@
         SpanningRowsHeight()
             : totalRowsHeight(0)
             , spanningCellHeightIgnoringBorderSpacing(0)
-            , rowWithOnlySpanningCells(false)
+            , isAnyRowWithOnlySpanningCells(false)
         {
         }
 
         Vector<int> rowHeight;
         int totalRowsHeight;
         int spanningCellHeightIgnoringBorderSpacing;
-        bool rowWithOnlySpanningCells;
+        bool isAnyRowWithOnlySpanningCells;
     };
 
     const BorderValue& borderAdjoiningTableStart() const
diff --git a/Source/core/rendering/RenderText.cpp b/Source/core/rendering/RenderText.cpp
index 88ac68e..8d6c379 100644
--- a/Source/core/rendering/RenderText.cpp
+++ b/Source/core/rendering/RenderText.cpp
@@ -79,7 +79,7 @@
     {
         m_lastTypedCharacterOffset = lastTypedCharacterOffset;
         if (Settings* settings = m_renderText->document().settings())
-            startOneShot(settings->passwordEchoDurationInSeconds());
+            startOneShot(settings->passwordEchoDurationInSeconds(), FROM_HERE);
     }
     void invalidate() { m_lastTypedCharacterOffset = -1; }
     unsigned lastTypedCharacterOffset() { return m_lastTypedCharacterOffset; }
@@ -213,7 +213,7 @@
     if (!documentBeingDestroyed()) {
         if (firstTextBox()) {
             if (isBR()) {
-                RootInlineBox* next = firstTextBox()->root()->nextRootBox();
+                RootInlineBox* next = firstTextBox()->root().nextRootBox();
                 if (next)
                     next->markDirty();
             }
@@ -365,11 +365,11 @@
             if (useSelectionHeight) {
                 LayoutRect selectionRect = box->localSelectionRect(start, end);
                 if (box->isHorizontal()) {
-                    r.setHeight(selectionRect.height());
-                    r.setY(selectionRect.y());
+                    r.setHeight(selectionRect.height().toFloat());
+                    r.setY(selectionRect.y().toFloat());
                 } else {
-                    r.setWidth(selectionRect.width());
-                    r.setX(selectionRect.x());
+                    r.setWidth(selectionRect.width().toFloat());
+                    r.setX(selectionRect.x().toFloat());
                 }
             }
             rects.append(localToAbsoluteQuad(r, 0, wasFixed).enclosingBoundingBox());
@@ -392,7 +392,7 @@
         return IntRect();
 
     IntRect rect;
-    if (EllipsisBox* ellipsis = box->root()->ellipsisBox()) {
+    if (EllipsisBox* ellipsis = box->root().ellipsisBox()) {
         int ellipsisStartPosition = max<int>(startPos - box->start(), 0);
         int ellipsisEndPosition = min<int>(endPos - box->start(), box->len());
 
@@ -448,11 +448,11 @@
             if (useSelectionHeight) {
                 LayoutRect selectionRect = box->localSelectionRect(start, end);
                 if (box->isHorizontal()) {
-                    r.setHeight(selectionRect.height());
-                    r.setY(selectionRect.y());
+                    r.setHeight(selectionRect.height().toFloat());
+                    r.setY(selectionRect.y().toFloat());
                 } else {
-                    r.setWidth(selectionRect.width());
-                    r.setX(selectionRect.x());
+                    r.setWidth(selectionRect.width().toFloat());
+                    r.setX(selectionRect.x().toFloat());
                 }
             }
             quads.append(localToAbsoluteQuad(r, 0, wasFixed));
@@ -536,14 +536,13 @@
         affinity = offset > box->caretMinOffset() ? VP_UPSTREAM_IF_POSSIBLE : DOWNSTREAM;
         break;
     }
-    int textStartOffset = box->renderer()->isText() ? toRenderText(box->renderer())->textStartOffset() : 0;
-    return box->renderer()->createPositionWithAffinity(offset + textStartOffset, affinity);
+    int textStartOffset = box->renderer().isText() ? toRenderText(box->renderer()).textStartOffset() : 0;
+    return box->renderer().createPositionWithAffinity(offset + textStartOffset, affinity);
 }
 
 static PositionWithAffinity createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(const InlineTextBox* box, int offset, ShouldAffinityBeDownstream shouldAffinityBeDownstream)
 {
     ASSERT(box);
-    ASSERT(box->renderer());
     ASSERT(offset >= 0);
 
     if (offset && static_cast<unsigned>(offset) < box->len())
@@ -555,7 +554,7 @@
 
         const InlineBox* prevBox = box->prevLeafChildIgnoringLineBreak();
         if ((prevBox && prevBox->bidiLevel() == box->bidiLevel())
-            || box->renderer()->containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA
+            || box->renderer().containingBlock()->style()->direction() == box->direction()) // FIXME: left on 12CBA
             return createPositionWithAffinityForBox(box, box->caretLeftmostOffset(), shouldAffinityBeDownstream);
 
         if (prevBox && prevBox->bidiLevel() > box->bidiLevel()) {
@@ -585,7 +584,7 @@
 
     const InlineBox* nextBox = box->nextLeafChildIgnoringLineBreak();
     if ((nextBox && nextBox->bidiLevel() == box->bidiLevel())
-        || box->renderer()->containingBlock()->style()->direction() == box->direction())
+        || box->renderer().containingBlock()->style()->direction() == box->direction())
         return createPositionWithAffinityForBox(box, box->caretRightmostOffset(), shouldAffinityBeDownstream);
 
     // offset is on the right edge
@@ -628,17 +627,17 @@
         if (box->isLineBreak() && !box->prevLeafChild() && box->nextLeafChild() && !box->nextLeafChild()->isLineBreak())
             box = box->nextTextBox();
 
-        RootInlineBox* rootBox = box->root();
-        LayoutUnit top = min(rootBox->selectionTop(), rootBox->lineTop());
+        RootInlineBox& rootBox = box->root();
+        LayoutUnit top = min(rootBox.selectionTop(), rootBox.lineTop());
         if (pointBlockDirection > top || (!blocksAreFlipped && pointBlockDirection == top)) {
-            LayoutUnit bottom = rootBox->selectionBottom();
-            if (rootBox->nextRootBox())
-                bottom = min(bottom, rootBox->nextRootBox()->lineTop());
+            LayoutUnit bottom = rootBox.selectionBottom();
+            if (rootBox.nextRootBox())
+                bottom = min(bottom, rootBox.nextRootBox()->lineTop());
 
             if (pointBlockDirection < bottom || (blocksAreFlipped && pointBlockDirection == bottom)) {
                 ShouldAffinityBeDownstream shouldAffinityBeDownstream;
                 if (lineDirectionPointFitsInBox(pointLineDirection, box, shouldAffinityBeDownstream))
-                    return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection), shouldAffinityBeDownstream);
+                    return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(box, box->offsetForPosition(pointLineDirection.toFloat()), shouldAffinityBeDownstream);
             }
         }
         lastBox = box;
@@ -647,7 +646,7 @@
     if (lastBox) {
         ShouldAffinityBeDownstream shouldAffinityBeDownstream;
         lineDirectionPointFitsInBox(pointLineDirection, lastBox, shouldAffinityBeDownstream);
-        return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection) + lastBox->start(), shouldAffinityBeDownstream);
+        return createPositionWithAffinityForBoxAfterAdjustingOffsetForBiDi(lastBox, lastBox->offsetForPosition(pointLineDirection.toFloat()) + lastBox->start(), shouldAffinityBeDownstream);
     }
     return createPositionWithAffinity(0, DOWNSTREAM);
 }
@@ -663,8 +662,8 @@
 
     InlineTextBox* box = toInlineTextBox(inlineBox);
 
-    int height = box->root()->selectionHeight();
-    int top = box->root()->selectionTop();
+    int height = box->root().selectionHeight();
+    int top = box->root().selectionTop();
 
     // Go ahead and round left to snap it to the nearest pixel.
     float left = box->positionForOffset(caretOffset);
@@ -676,13 +675,13 @@
 
     left = roundf(left);
 
-    float rootLeft = box->root()->logicalLeft();
-    float rootRight = box->root()->logicalRight();
+    float rootLeft = box->root().logicalLeft();
+    float rootRight = box->root().logicalRight();
 
     // FIXME: should we use the width of the root inline box or the
     // width of the containing block for this?
     if (extraWidthToEndOfLine)
-        *extraWidthToEndOfLine = (box->root()->logicalWidth() + rootLeft) - (left + 1);
+        *extraWidthToEndOfLine = (box->root().logicalWidth() + rootLeft) - (left + 1);
 
     RenderBlock* cb = containingBlock();
     RenderStyle* cbStyle = cb->style();
@@ -690,7 +689,7 @@
     float leftEdge;
     float rightEdge;
     leftEdge = min<float>(0, rootLeft);
-    rightEdge = max<float>(cb->logicalWidth(), rootRight);
+    rightEdge = max<float>(cb->logicalWidth().toFloat(), rootRight);
 
     bool rightAligned = false;
     switch (cbStyle->textAlign()) {
@@ -731,7 +730,7 @@
             return combineText->combinedTextWidth(f);
     }
 
-    if (f.isFixedPitch() && !f.fontDescription().smallCaps() && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) {
+    if (f.isFixedPitch() && !f.fontDescription().variant() && m_isAllASCII && (!glyphOverflow || !glyphOverflow->computeBounds)) {
         float monospaceCharacterWidth = f.spaceWidth();
         float w = 0;
         bool isSpace;
@@ -929,10 +928,7 @@
     bool firstLine = true;
     int nextBreakable = -1;
     int lastWordBoundary = 0;
-
-    // Non-zero only when kerning is enabled, in which case we measure words with their trailing
-    // space, then subtract its width.
-    float wordTrailingSpaceWidth = f.fontDescription().typesettingFeatures() & Kerning ? f.width(RenderBlockFlow::constructTextRun(this, f, &space, 1, styleToUse, LTR)) + wordSpacing : 0;
+    float cachedWordTrailingSpaceWidth[2] = { 0, 0 }; // LTR, RTL
 
     // If automatic hyphenation is allowed, we keep track of the width of the widest word (or word
     // fragment) encountered so far, and only try hyphenating words that are wider.
@@ -943,7 +939,9 @@
 
     TextRun textRun(text());
     BidiResolver<TextRunIterator, BidiCharacterRun> bidiResolver;
-    bidiResolver.setStatus(BidiStatus(textRun.direction(), textRun.directionalOverride()));
+    BidiStatus status(LTR, false);
+    status.last = status.lastStrong = WTF::Unicode::OtherNeutral;
+    bidiResolver.setStatus(status);
     bidiResolver.setPositionIgnoringNestedIsolates(TextRunIterator(&textRun, 0));
     bool hardLineBreak = false;
     bool reorderRuns = false;
@@ -954,11 +952,14 @@
     for (int i = 0; i < len; i++) {
         UChar c = uncheckedCharacterAt(i);
 
-        while (i > run->stop())
+        // Treat adjacent runs with the same resolved directionality
+        // (TextDirection as opposed to WTF::Unicode::Direction) as belonging
+        // to the same run to avoid breaking unnecessarily.
+        while (i > run->stop() || (run->next() && run->next()->direction() == run->direction()))
             run = run->next();
 
         ASSERT(run);
-        ASSERT(i >= run->start() && i <= run->stop());
+        ASSERT(i <= run->stop());
         TextDirection textDirection = run->direction();
 
         bool previousCharacterIsSpace = isSpace;
@@ -1027,6 +1028,17 @@
         int wordLen = j - i;
         if (wordLen) {
             bool isSpace = (j < len) && c == ' ';
+
+            // Non-zero only when kerning is enabled, in which case we measure words with their trailing
+            // space, then subtract its width.
+            float wordTrailingSpaceWidth = 0;
+            if (isSpace && (f.fontDescription().typesettingFeatures() & Kerning)) {
+                ASSERT(textDirection >=0 && textDirection <= 1);
+                if (!cachedWordTrailingSpaceWidth[textDirection])
+                    cachedWordTrailingSpaceWidth[textDirection] = f.width(RenderBlockFlow::constructTextRun(this, f, &space, 1, styleToUse, textDirection)) + wordSpacing;
+                wordTrailingSpaceWidth = cachedWordTrailingSpaceWidth[textDirection];
+            }
+
             float w;
             if (wordTrailingSpaceWidth && isSpace)
                 w = widthFromCache(f, i, wordLen + 1, leadWidth + currMaxWidth, textDirection, &fallbackFonts, &glyphOverflow) - wordTrailingSpaceWidth;
@@ -1195,16 +1207,12 @@
 
             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
                 if (box->isSelected(startPos, endPos)) {
-                    RootInlineBox* root = box->root();
-                    if (root)
-                        root->setHasSelectedChildren(true);
+                    box->root().setHasSelectedChildren(true);
                 }
             }
         } else {
             for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
-                RootInlineBox* root = box->root();
-                if (root)
-                    root->setHasSelectedChildren(state == SelectionInside);
+                box->root().setHasSelectedChildren(state == SelectionInside);
             }
         }
     }
@@ -1240,7 +1248,7 @@
         // Text run is entirely after the affected range.
         if (curr->start() > end) {
             curr->offsetRun(delta);
-            RootInlineBox* root = curr->root();
+            RootInlineBox* root = &curr->root();
             if (!firstRootBox) {
                 firstRootBox = root;
                 // The affected area was in between two runs. Go ahead and mark the root box of
@@ -1274,7 +1282,7 @@
             firstRootBox = prev;
     } else if (lastTextBox()) {
         ASSERT(!lastRootBox);
-        firstRootBox = lastTextBox()->root();
+        firstRootBox = &lastTextBox()->root();
         firstRootBox->markDirty();
         dirtiedLines = true;
     }
@@ -1432,7 +1440,7 @@
 
 InlineTextBox* RenderText::createTextBox()
 {
-    return new InlineTextBox(this);
+    return new InlineTextBox(*this);
 }
 
 InlineTextBox* RenderText::createInlineTextBox()
@@ -1500,8 +1508,9 @@
                         m_knownToHaveNoOverflowAndNoFallbackFonts = true;
                 }
                 w = m_maxWidth;
-            } else
+            } else {
                 w = maxLogicalWidth();
+            }
         } else {
             w = widthFromCache(f, from, len, xPos, textDirection, fallbackFonts, glyphOverflow);
         }
diff --git a/Source/core/rendering/RenderTextControl.h b/Source/core/rendering/RenderTextControl.h
index db23e59..0da5793 100644
--- a/Source/core/rendering/RenderTextControl.h
+++ b/Source/core/rendering/RenderTextControl.h
@@ -71,7 +71,6 @@
 private:
     virtual const char* renderName() const OVERRIDE { return "RenderTextControl"; }
     virtual bool isTextControl() const OVERRIDE FINAL { return true; }
-    virtual bool supportsPartialLayout() const OVERRIDE FINAL { return false; }
     virtual void computeIntrinsicLogicalWidths(LayoutUnit& minLogicalWidth, LayoutUnit& maxLogicalWidth) const OVERRIDE FINAL;
     virtual void computePreferredLogicalWidths() OVERRIDE FINAL;
     virtual void removeLeftoverAnonymousBlock(RenderBlock*) OVERRIDE FINAL { }
diff --git a/Source/core/rendering/RenderTextControlSingleLine.cpp b/Source/core/rendering/RenderTextControlSingleLine.cpp
index 4a0c073..2745ff1 100644
--- a/Source/core/rendering/RenderTextControlSingleLine.cpp
+++ b/Source/core/rendering/RenderTextControlSingleLine.cpp
@@ -27,8 +27,8 @@
 #include "CSSValueKeywords.h"
 #include "core/dom/shadow/ShadowRoot.h"
 #include "core/editing/FrameSelection.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/shadow/ShadowElementNames.h"
-#include "core/frame/Frame.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/RenderLayer.h"
@@ -47,7 +47,6 @@
     , m_shouldDrawCapsLockIndicator(false)
     , m_desiredInnerTextLogicalHeight(-1)
 {
-    ASSERT(element->hasTagName(inputTag));
 }
 
 RenderTextControlSingleLine::~RenderTextControlSingleLine()
@@ -271,7 +270,7 @@
     // 4) The caps lock is on
     bool shouldDrawCapsLockIndicator = false;
 
-    if (Frame* frame = document().frame())
+    if (LocalFrame* frame = document().frame())
         shouldDrawCapsLockIndicator = inputElement()->isPasswordField() && frame->selection().isFocusedAndActive() && document().focusedElement() == node() && PlatformKeyboardEvent::currentCapsLockState();
 
     if (shouldDrawCapsLockIndicator != m_shouldDrawCapsLockIndicator) {
diff --git a/Source/core/rendering/RenderTextFragment.cpp b/Source/core/rendering/RenderTextFragment.cpp
index 759eb9d..91d9546 100644
--- a/Source/core/rendering/RenderTextFragment.cpp
+++ b/Source/core/rendering/RenderTextFragment.cpp
@@ -30,7 +30,7 @@
 namespace WebCore {
 
 RenderTextFragment::RenderTextFragment(Node* node, StringImpl* str, int startOffset, int length)
-    : RenderText(node, str ? str->substring(startOffset, length) : PassRefPtr<StringImpl>(0))
+    : RenderText(node, str ? str->substring(startOffset, length) : PassRefPtr<StringImpl>(nullptr))
     , m_start(startOffset)
     , m_end(length)
     , m_firstLetter(0)
@@ -64,7 +64,7 @@
     Node* e = node();
     RefPtr<StringImpl> result = ((e && e->isTextNode()) ? toText(e)->dataImpl() : contentString());
     if (!result)
-        return 0;
+        return nullptr;
     return result->substring(start(), end());
 }
 
diff --git a/Source/core/rendering/RenderTheme.cpp b/Source/core/rendering/RenderTheme.cpp
index 329aa85..972bcf6 100644
--- a/Source/core/rendering/RenderTheme.cpp
+++ b/Source/core/rendering/RenderTheme.cpp
@@ -30,8 +30,10 @@
 #include "core/dom/shadow/ElementShadow.h"
 #include "core/editing/FrameSelection.h"
 #include "core/fileapi/FileList.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLCollection.h"
 #include "core/html/HTMLDataListElement.h"
+#include "core/html/HTMLFormControlElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLMeterElement.h"
 #include "core/html/HTMLOptionElement.h"
@@ -41,7 +43,6 @@
 #include "core/html/shadow/SpinButtonElement.h"
 #include "core/html/shadow/TextControlInnerElements.h"
 #include "core/page/FocusController.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/PaintInfo.h"
@@ -188,7 +189,7 @@
 
             // Now update our font.
             if (style->setFontDescription(controlFont))
-                style->font().update(0);
+                style->font().update(nullptr);
         }
     }
     default:
@@ -441,13 +442,6 @@
 String RenderTheme::extraDefaultStyleSheet()
 {
     StringBuilder runtimeCSS;
-
-    runtimeCSS.appendLiteral("datalist {display: none ;}");
-
-    runtimeCSS.appendLiteral("input[type=\"color\"][list] { -webkit-appearance: menulist; width: 88px; height: 23px;}");
-    runtimeCSS.appendLiteral("input[type=\"color\"][list]::-webkit-color-swatch-wrapper { padding-left: 8px; padding-right: 24px;}");
-    runtimeCSS.appendLiteral("input[type=\"color\"][list]::-webkit-color-swatch { border-color: #000000;}");
-
     if (RuntimeEnabledFeatures::dialogElementEnabled()) {
         runtimeCSS.appendLiteral("dialog:not([open]) { display: none; }");
         runtimeCSS.appendLiteral("dialog { position: absolute; left: 0; right: 0; width: -webkit-fit-content; height: -webkit-fit-content; margin: auto; border: solid; padding: 1em; background: white; color: black;}");
@@ -717,14 +711,14 @@
 
 bool RenderTheme::isChecked(const RenderObject* o) const
 {
-    if (!o->node() || !o->node()->hasTagName(inputTag))
+    if (!isHTMLInputElement(o->node()))
         return false;
     return toHTMLInputElement(o->node())->shouldAppearChecked();
 }
 
 bool RenderTheme::isIndeterminate(const RenderObject* o) const
 {
-    if (!o->node() || !o->node()->hasTagName(inputTag))
+    if (!isHTMLInputElement(o->node()))
         return false;
     return toHTMLInputElement(o->node())->shouldAppearIndeterminate();
 }
@@ -745,7 +739,7 @@
 
     node = node->focusDelegate();
     Document& document = node->document();
-    Frame* frame = document.frame();
+    LocalFrame* frame = document.frame();
     return node == document.focusedElement() && node->shouldHaveFocusAppearance() && frame && frame->selection().isFocusedAndActive();
 }
 
@@ -769,9 +763,10 @@
 bool RenderTheme::isReadOnlyControl(const RenderObject* o) const
 {
     Node* node = o->node();
-    if (!node || !node->isElementNode())
+    if (!node || !node->isElementNode() || !toElement(node)->isFormControlElement())
         return false;
-    return toElement(node)->matchesReadOnlyPseudoClass();
+    HTMLFormControlElement* element = toHTMLFormControlElement(node);
+    return element->isReadOnly();
 }
 
 bool RenderTheme::isHovered(const RenderObject* o) const
@@ -869,7 +864,7 @@
 void RenderTheme::paintSliderTicks(RenderObject* o, const PaintInfo& paintInfo, const IntRect& rect)
 {
     Node* node = o->node();
-    if (!node || !node->hasTagName(inputTag))
+    if (!isHTMLInputElement(node))
         return;
 
     HTMLInputElement* input = toHTMLInputElement(node);
@@ -928,9 +923,9 @@
     GraphicsContextStateSaver stateSaver(*paintInfo.context);
     paintInfo.context->setFillColor(o->resolveColor(CSSPropertyColor));
     for (unsigned i = 0; Element* element = options->item(i); i++) {
-        ASSERT(element->hasTagName(optionTag));
-        HTMLOptionElement* optionElement = toHTMLOptionElement(element);
-        String value = optionElement->value();
+        ASSERT(isHTMLOptionElement(*element));
+        HTMLOptionElement& optionElement = toHTMLOptionElement(*element);
+        String value = optionElement.value();
         if (!input->isValidValue(value))
             continue;
         double parsedValue = parseToDoubleForNumberType(input->sanitizeValue(value));
@@ -1123,20 +1118,6 @@
     return false;
 }
 
-bool RenderTheme::supportsDataListUI(const AtomicString& type) const
-{
-    return type == InputTypeNames::text || type == InputTypeNames::search || type == InputTypeNames::url
-        || type == InputTypeNames::tel || type == InputTypeNames::email || type == InputTypeNames::number
-        || type == InputTypeNames::color
-        || type == InputTypeNames::date
-        || type == InputTypeNames::datetime
-        || type == InputTypeNames::datetime_local
-        || type == InputTypeNames::month
-        || type == InputTypeNames::week
-        || type == InputTypeNames::time
-        || type == InputTypeNames::range;
-}
-
 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
 bool RenderTheme::supportsCalendarPicker(const AtomicString& type) const
 {
diff --git a/Source/core/rendering/RenderTheme.h b/Source/core/rendering/RenderTheme.h
index 12f765a..8ecd331 100644
--- a/Source/core/rendering/RenderTheme.h
+++ b/Source/core/rendering/RenderTheme.h
@@ -115,9 +115,6 @@
     // A method asking if the theme's controls actually care about redrawing when hovered.
     virtual bool supportsHover(const RenderStyle*) const { return false; }
 
-    // A method asking if the platform is able to show datalist suggestions for a given input type.
-    virtual bool supportsDataListUI(const AtomicString&) const;
-
 #if ENABLE(INPUT_MULTIPLE_FIELDS_UI)
     // A method asking if the platform is able to show a calendar picker for a given input type.
     virtual bool supportsCalendarPicker(const AtomicString&) const;
diff --git a/Source/core/rendering/RenderThemeChromiumDefault.cpp b/Source/core/rendering/RenderThemeChromiumDefault.cpp
index c1a04da..a93d07c 100644
--- a/Source/core/rendering/RenderThemeChromiumDefault.cpp
+++ b/Source/core/rendering/RenderThemeChromiumDefault.cpp
@@ -220,11 +220,6 @@
         RenderThemeChromiumSkia::adjustSliderThumbSize(style, element);
 }
 
-bool RenderThemeChromiumDefault::supportsControlTints() const
-{
-    return true;
-}
-
 void RenderThemeChromiumDefault::setCaretBlinkInterval(double interval)
 {
     m_caretBlinkInterval = interval;
diff --git a/Source/core/rendering/RenderThemeChromiumDefault.h b/Source/core/rendering/RenderThemeChromiumDefault.h
index 6a08626..e695468 100644
--- a/Source/core/rendering/RenderThemeChromiumDefault.h
+++ b/Source/core/rendering/RenderThemeChromiumDefault.h
@@ -93,9 +93,6 @@
     virtual bool shouldUseFallbackTheme(RenderStyle*) const OVERRIDE;
 
 private:
-    // A general method asking if any control tinting is supported at all.
-    virtual bool supportsControlTints() const OVERRIDE;
-
     static double m_caretBlinkInterval;
 
     static unsigned m_activeSelectionBackgroundColor;
diff --git a/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp b/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp
index 3d1d026..b26db49 100644
--- a/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp
+++ b/Source/core/rendering/RenderThemeChromiumFontProviderLinux.cpp
@@ -65,7 +65,7 @@
     fontDescription.setIsAbsoluteSize(true);
     fontDescription.setGenericFamily(FontDescription::NoFamily);
     fontDescription.setWeight(FontWeightNormal);
-    fontDescription.setItalic(false);
+    fontDescription.setStyle(false);
 }
 
 } // namespace WebCore
diff --git a/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp b/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp
index 18305cc..a2da016 100644
--- a/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp
+++ b/Source/core/rendering/RenderThemeChromiumFontProviderWin.cpp
@@ -175,7 +175,7 @@
         cachedDesc->setGenericFamily(FontDescription::NoFamily);
         cachedDesc->setSpecifiedSize(fontSize);
         cachedDesc->setWeight(FontWeightNormal);
-        cachedDesc->setItalic(false);
+        cachedDesc->setStyle(false);
     }
     fontDescription = *cachedDesc;
 }
diff --git a/Source/core/rendering/RenderThemeChromiumMac.h b/Source/core/rendering/RenderThemeChromiumMac.h
index 4742574..a90c0a1 100644
--- a/Source/core/rendering/RenderThemeChromiumMac.h
+++ b/Source/core/rendering/RenderThemeChromiumMac.h
@@ -150,7 +150,6 @@
     const IntSize* popupButtonSizes() const;
     const int* popupButtonMargins() const;
     const int* popupButtonPadding(NSControlSize) const;
-    void paintMenuListButtonGradients(RenderObject*, const PaintInfo&, const IntRect&);
     const IntSize* menuListSizes() const;
 
     const IntSize* searchFieldSizes() const;
diff --git a/Source/core/rendering/RenderThemeChromiumMac.mm b/Source/core/rendering/RenderThemeChromiumMac.mm
index dfdd539..4f41185 100644
--- a/Source/core/rendering/RenderThemeChromiumMac.mm
+++ b/Source/core/rendering/RenderThemeChromiumMac.mm
@@ -311,7 +311,7 @@
         cachedDesc->firstFamily().setFamily([font webCoreFamilyName]);
         cachedDesc->setSpecifiedSize([font pointSize]);
         cachedDesc->setWeight(toFontWeight([fontManager weightOfFont:font]));
-        cachedDesc->setItalic([fontManager traitsOfFont:font] & NSItalicFontMask);
+        cachedDesc->setStyle([fontManager traitsOfFont:font] & NSItalicFontMask);
     }
     fontDescription = *cachedDesc;
 }
@@ -740,7 +740,7 @@
     style->setLineHeight(RenderStyle::initialLineHeight());
 
     if (style->setFontDescription(fontDescription))
-        style->font().update(0);
+        style->font().update(nullptr);
 }
 
 NSControlSize RenderThemeChromiumMac::controlSizeForSystemFont(RenderStyle* style) const
@@ -1122,112 +1122,12 @@
 const int styledPopupPaddingTop = 1;
 const int styledPopupPaddingBottom = 2;
 
-static void TopGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
-    static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.4f };
-    static float light[4] = { 1.0f, 1.0f, 1.0f, 0.15f };
-    float a = inData[0];
-    int i = 0;
-    for (i = 0; i < 4; i++)
-        outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-static void BottomGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
-    static float dark[4] = { 1.0f, 1.0f, 1.0f, 0.0f };
-    static float light[4] = { 1.0f, 1.0f, 1.0f, 0.3f };
-    float a = inData[0];
-    int i = 0;
-    for (i = 0; i < 4; i++)
-        outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-static void MainGradientInterpolate(void*, const CGFloat* inData, CGFloat* outData)
-{
-    static float dark[4] = { 0.0f, 0.0f, 0.0f, 0.15f };
-    static float light[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
-    float a = inData[0];
-    int i = 0;
-    for (i = 0; i < 4; i++)
-        outData[i] = (1.0f - a) * dark[i] + a * light[i];
-}
-
-void RenderThemeChromiumMac::paintMenuListButtonGradients(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
-{
-    if (r.isEmpty())
-        return;
-
-    ContextContainer cgContextContainer(paintInfo.context);
-    CGContextRef context = cgContextContainer.context();
-
-    GraphicsContextStateSaver stateSaver(*paintInfo.context);
-
-    RoundedRect border = o->style()->getRoundedBorderFor(r);
-    int radius = border.radii().topLeft().width();
-
-    CGColorSpaceRef cspace = deviceRGBColorSpaceRef();
-
-    FloatRect topGradient(r.x(), r.y(), r.width(), r.height() / 2.0f);
-    struct CGFunctionCallbacks topCallbacks = { 0, TopGradientInterpolate, NULL };
-    RetainPtr<CGFunctionRef> topFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &topCallbacks));
-    RetainPtr<CGShadingRef> topShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(topGradient.x(), topGradient.y()), CGPointMake(topGradient.x(), topGradient.maxY()), topFunction.get(), false, false));
-
-    FloatRect bottomGradient(r.x() + radius, r.y() + r.height() / 2.0f, r.width() - 2.0f * radius, r.height() / 2.0f);
-    struct CGFunctionCallbacks bottomCallbacks = { 0, BottomGradientInterpolate, NULL };
-    RetainPtr<CGFunctionRef> bottomFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &bottomCallbacks));
-    RetainPtr<CGShadingRef> bottomShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(bottomGradient.x(),  bottomGradient.y()), CGPointMake(bottomGradient.x(), bottomGradient.maxY()), bottomFunction.get(), false, false));
-
-    struct CGFunctionCallbacks mainCallbacks = { 0, MainGradientInterpolate, NULL };
-    RetainPtr<CGFunctionRef> mainFunction(AdoptCF, CGFunctionCreate(NULL, 1, NULL, 4, NULL, &mainCallbacks));
-    RetainPtr<CGShadingRef> mainShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(),  r.y()), CGPointMake(r.x(), r.maxY()), mainFunction.get(), false, false));
-
-    RetainPtr<CGShadingRef> leftShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.x(),  r.y()), CGPointMake(r.x() + radius, r.y()), mainFunction.get(), false, false));
-
-    RetainPtr<CGShadingRef> rightShading(AdoptCF, CGShadingCreateAxial(cspace, CGPointMake(r.maxX(),  r.y()), CGPointMake(r.maxX() - radius, r.y()), mainFunction.get(), false, false));
-
-    {
-        GraphicsContextStateSaver stateSaver(*paintInfo.context);
-        CGContextClipToRect(context, r);
-        paintInfo.context->clipRoundedRect(border);
-        context = cgContextContainer.context();
-        CGContextDrawShading(context, mainShading.get());
-    }
-
-    {
-        GraphicsContextStateSaver stateSaver(*paintInfo.context);
-        CGContextClipToRect(context, topGradient);
-        paintInfo.context->clipRoundedRect(RoundedRect(enclosingIntRect(topGradient), border.radii().topLeft(), border.radii().topRight(), IntSize(), IntSize()));
-        context = cgContextContainer.context();
-        CGContextDrawShading(context, topShading.get());
-    }
-
-    if (!bottomGradient.isEmpty()) {
-        GraphicsContextStateSaver stateSaver(*paintInfo.context);
-        CGContextClipToRect(context, bottomGradient);
-        paintInfo.context->clipRoundedRect(RoundedRect(enclosingIntRect(bottomGradient), IntSize(), IntSize(), border.radii().bottomLeft(), border.radii().bottomRight()));
-        context = cgContextContainer.context();
-        CGContextDrawShading(context, bottomShading.get());
-    }
-
-    {
-        GraphicsContextStateSaver stateSaver(*paintInfo.context);
-        CGContextClipToRect(context, r);
-        paintInfo.context->clipRoundedRect(border);
-        context = cgContextContainer.context();
-        CGContextDrawShading(context, leftShading.get());
-        CGContextDrawShading(context, rightShading.get());
-    }
-}
-
 bool RenderThemeChromiumMac::paintMenuListButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 {
     IntRect bounds = IntRect(r.x() + o->style()->borderLeftWidth(),
                              r.y() + o->style()->borderTopWidth(),
                              r.width() - o->style()->borderLeftWidth() - o->style()->borderRightWidth(),
                              r.height() - o->style()->borderTopWidth() - o->style()->borderBottomWidth());
-    // Draw the gradients to give the styled popup menu a button appearance
-    paintMenuListButtonGradients(o, paintInfo, bounds);
-
     // Since we actually know the size of the control here, we restrict the font scale to make sure the arrows will fit vertically in the bounds
     float fontScale = min(o->style()->fontSize() / baseFontSize, bounds.height() / (baseArrowHeight * 2 + baseSpaceBetweenArrows));
     float centerY = bounds.y() + bounds.height() / 2.0f;
@@ -1259,24 +1159,6 @@
 
     // Draw the bottom arrow
     paintInfo.context->drawConvexPolygon(3, arrow2, true);
-
-    Color leftSeparatorColor(0, 0, 0, 40);
-    Color rightSeparatorColor(255, 255, 255, 40);
-
-    // FIXME: Should the separator thickness and space be scaled up by fontScale?
-    int separatorSpace = 2; // Deliberately ignores zoom since it looks nicer if it stays thin.
-    int leftEdgeOfSeparator = static_cast<int>(leftEdge - arrowPaddingLeft * o->style()->effectiveZoom()); // FIXME: Round?
-
-    // Draw the separator to the left of the arrows
-    paintInfo.context->setStrokeThickness(1.0f); // Deliberately ignores zoom since it looks nicer if it stays thin.
-    paintInfo.context->setStrokeStyle(SolidStroke);
-    paintInfo.context->setStrokeColor(leftSeparatorColor);
-    paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator, bounds.y()),
-                                IntPoint(leftEdgeOfSeparator, bounds.maxY()));
-
-    paintInfo.context->setStrokeColor(rightSeparatorColor);
-    paintInfo.context->drawLine(IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.y()),
-                                IntPoint(leftEdgeOfSeparator + separatorSpace, bounds.maxY()));
     return false;
 }
 
@@ -1663,6 +1545,8 @@
 
 bool RenderThemeChromiumMac::paintSearchFieldCancelButton(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 {
+    if (!o->node())
+        return false;
     Element* input = o->node()->shadowHost();
     if (!input)
         input = toElement(o->node());
@@ -1761,6 +1645,8 @@
 
 bool RenderThemeChromiumMac::paintSearchFieldResultsDecoration(RenderObject* o, const PaintInfo& paintInfo, const IntRect& r)
 {
+    if (!o->node())
+        return false;
     Node* input = o->node()->shadowHost();
     if (!input)
         input = o->node();
@@ -1966,7 +1852,8 @@
 String RenderThemeChromiumMac::extraDefaultStyleSheet()
 {
     return RenderTheme::extraDefaultStyleSheet() +
-           String(themeChromiumUserAgentStyleSheet, sizeof(themeChromiumUserAgentStyleSheet));
+           String(themeChromiumUserAgentStyleSheet, sizeof(themeChromiumUserAgentStyleSheet)) +
+           String(themeMacUserAgentStyleSheet, sizeof(themeMacUserAgentStyleSheet));
 }
 
 bool RenderThemeChromiumMac::paintMediaVolumeSliderContainer(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect)
diff --git a/Source/core/rendering/RenderThemeChromiumSkia.cpp b/Source/core/rendering/RenderThemeChromiumSkia.cpp
index 26396e8..b08f121 100644
--- a/Source/core/rendering/RenderThemeChromiumSkia.cpp
+++ b/Source/core/rendering/RenderThemeChromiumSkia.cpp
@@ -222,6 +222,8 @@
 bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* cancelButtonObject, const PaintInfo& paintInfo, const IntRect& r)
 {
     // Get the renderer of <input> element.
+    if (!cancelButtonObject->node())
+        return false;
     Node* input = cancelButtonObject->node()->shadowHost();
     RenderObject* baseRenderer = input ? input->renderer() : cancelButtonObject;
     if (!baseRenderer->isBox())
@@ -265,6 +267,8 @@
 bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* magnifierObject, const PaintInfo& paintInfo, const IntRect& r)
 {
     // Get the renderer of <input> element.
+    if (!magnifierObject->node())
+        return false;
     Node* input = magnifierObject->node()->shadowHost();
     RenderObject* baseRenderer = input ? input->renderer() : magnifierObject;
     if (!baseRenderer->isBox())
diff --git a/Source/core/rendering/RenderTreeAsText.cpp b/Source/core/rendering/RenderTreeAsText.cpp
index 6a639ed..f0dad98 100644
--- a/Source/core/rendering/RenderTreeAsText.cpp
+++ b/Source/core/rendering/RenderTreeAsText.cpp
@@ -30,11 +30,10 @@
 #include "core/css/StylePropertySet.h"
 #include "core/dom/Document.h"
 #include "core/editing/FrameSelection.h"
-#include "core/html/HTMLElement.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLElement.h"
 #include "core/page/PrintContext.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/FlowThreadController.h"
 #include "core/rendering/InlineTextBox.h"
 #include "core/rendering/RenderBR.h"
@@ -49,6 +48,7 @@
 #include "core/rendering/RenderTableCell.h"
 #include "core/rendering/RenderView.h"
 #include "core/rendering/RenderWidget.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
 #include "core/rendering/svg/RenderSVGContainer.h"
 #include "core/rendering/svg/RenderSVGGradientStop.h"
 #include "core/rendering/svg/RenderSVGImage.h"
@@ -114,17 +114,17 @@
 
 static bool isEmptyOrUnstyledAppleStyleSpan(const Node* node)
 {
-    if (!node || !node->isHTMLElement() || !node->hasTagName(spanTag))
+    if (!isHTMLSpanElement(node))
         return false;
 
-    const HTMLElement* elem = toHTMLElement(node);
-    if (elem->getAttribute(classAttr) != "Apple-style-span")
+    const HTMLElement& elem = toHTMLElement(*node);
+    if (elem.getAttribute(classAttr) != "Apple-style-span")
         return false;
 
-    if (!node->hasChildNodes())
+    if (!elem.hasChildren())
         return true;
 
-    const StylePropertySet* inlineStyleDecl = elem->inlineStyle();
+    const StylePropertySet* inlineStyleDecl = elem.inlineStyle();
     return (!inlineStyleDecl || inlineStyleDecl->isEmpty());
 }
 
@@ -671,7 +671,7 @@
         return;
 
     Document* doc = toDocument(n);
-    Frame* frame = doc->frame();
+    LocalFrame* frame = doc->frame();
     if (!frame)
         return;
 
@@ -698,7 +698,7 @@
     return ts.release();
 }
 
-String externalRepresentation(Frame* frame, RenderAsTextBehavior behavior)
+String externalRepresentation(LocalFrame* frame, RenderAsTextBehavior behavior)
 {
     if (!(behavior & RenderAsTextDontUpdateLayout))
         frame->document()->updateLayout();
@@ -709,7 +709,7 @@
 
     PrintContext printContext(frame);
     if (behavior & RenderAsTextPrintingMode)
-        printContext.begin(toRenderBox(renderer)->width());
+        printContext.begin(toRenderBox(renderer)->width().toFloat());
 
     return externalRepresentation(toRenderBox(renderer), behavior);
 }
diff --git a/Source/core/rendering/RenderTreeAsText.h b/Source/core/rendering/RenderTreeAsText.h
index 63c900c..aa66a86 100644
--- a/Source/core/rendering/RenderTreeAsText.h
+++ b/Source/core/rendering/RenderTreeAsText.h
@@ -32,7 +32,7 @@
 namespace WebCore {
 
 class Element;
-class Frame;
+class LocalFrame;
 class LayoutRect;
 class RenderLayer;
 class RenderObject;
@@ -52,7 +52,7 @@
 typedef unsigned RenderAsTextBehavior;
 
 // You don't need pageWidthInPixels if you don't specify RenderAsTextInPrintingMode.
-String externalRepresentation(Frame*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
+String externalRepresentation(LocalFrame*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
 String externalRepresentation(Element*, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
 void write(TextStream&, const RenderObject&, int indent = 0, RenderAsTextBehavior = RenderAsTextBehaviorNormal);
 
diff --git a/Source/core/rendering/RenderVTTCue.cpp b/Source/core/rendering/RenderVTTCue.cpp
index 4507321..7f1160a 100644
--- a/Source/core/rendering/RenderVTTCue.cpp
+++ b/Source/core/rendering/RenderVTTCue.cpp
@@ -50,7 +50,7 @@
     if (!m_cue->regionId().isEmpty())
         return;
 
-    LayoutStateMaintainer statePusher(view(), this, locationOffset(), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode());
+    LayoutStateMaintainer statePusher(*this, locationOffset());
 
     if (m_cue->snapToLines())
         repositionCueSnapToLinesSet();
@@ -127,7 +127,8 @@
 
     // 9. Default: Remember the position of all the boxes in boxes as their
     // default position.
-    m_fallbackPosition = FloatPoint(x(), y());
+    // FIXME: Why the direct conversion between float and LayoutUnit? crbug.com/350474
+    m_fallbackPosition = FloatPoint(location());
 
     // 10. Let switched be false.
     switched = false;
diff --git a/Source/core/rendering/RenderVTTCue.h b/Source/core/rendering/RenderVTTCue.h
index d357b24..953ff82 100644
--- a/Source/core/rendering/RenderVTTCue.h
+++ b/Source/core/rendering/RenderVTTCue.h
@@ -41,7 +41,6 @@
 
 private:
     virtual void layout() OVERRIDE;
-    virtual bool supportsPartialLayout() const OVERRIDE { return false; }
 
     bool isOutside() const;
     bool isOverlapping() const;
diff --git a/Source/core/rendering/RenderVideo.cpp b/Source/core/rendering/RenderVideo.cpp
index 5737494..1f9d928 100644
--- a/Source/core/rendering/RenderVideo.cpp
+++ b/Source/core/rendering/RenderVideo.cpp
@@ -29,9 +29,9 @@
 
 #include "HTMLNames.h"
 #include "core/dom/Document.h"
-#include "core/html/HTMLVideoElement.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/html/HTMLVideoElement.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/PaintInfo.h"
 #include "core/rendering/RenderFullScreen.h"
diff --git a/Source/core/rendering/RenderView.cpp b/Source/core/rendering/RenderView.cpp
index c101b70..ec0f512 100644
--- a/Source/core/rendering/RenderView.cpp
+++ b/Source/core/rendering/RenderView.cpp
@@ -24,13 +24,12 @@
 #include "RuntimeEnabledFeatures.h"
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLDialogElement.h"
 #include "core/html/HTMLFrameOwnerElement.h"
 #include "core/html/HTMLIFrameElement.h"
-#include "core/frame/Frame.h"
 #include "core/page/Page.h"
 #include "core/rendering/ColumnInfo.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/FlowThreadController.h"
 #include "core/rendering/GraphicsContextAnnotator.h"
 #include "core/rendering/HitTestResult.h"
@@ -38,8 +37,9 @@
 #include "core/rendering/RenderFlowThread.h"
 #include "core/rendering/RenderGeometryMap.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderSelectionInfo.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/svg/SVGDocumentExtensions.h"
 #include "platform/geometry/FloatQuad.h"
 #include "platform/geometry/TransformState.h"
@@ -141,7 +141,7 @@
     }
     FrameView* frameView = document().view();
     int scrollTop = frameView->scrollOffset().height();
-    int visibleHeight = frameView->visibleContentRect(ScrollableArea::IncludeScrollbars).height();
+    int visibleHeight = frameView->visibleContentRect(IncludeScrollbars).height();
     LayoutUnit top = scrollTop;
     if (box->height() < visibleHeight)
         top += (visibleHeight - box->height()) / 2;
@@ -157,7 +157,7 @@
     TrackedRendererListHashSet::iterator end = positionedDescendants->end();
     for (TrackedRendererListHashSet::iterator it = positionedDescendants->begin(); it != end; ++it) {
         RenderBox* box = *it;
-        if (box->node() && box->node()->hasTagName(HTMLNames::dialogTag))
+        if (isHTMLDialogElement(box->node()))
             positionDialog(box);
     }
 }
@@ -172,9 +172,6 @@
     if (RuntimeEnabledFeatures::dialogElementEnabled())
         positionDialogs();
 
-    if (m_frameView->partialLayout().isStopping())
-        return;
-
 #ifndef NDEBUG
     checkLayoutState(state);
 #endif
@@ -193,7 +190,6 @@
 
 void RenderView::initializeLayoutState(LayoutState& state)
 {
-    // FIXME: May be better to push a clip and avoid issuing offscreen repaints.
     state.m_clipped = false;
     state.m_pageLogicalHeight = m_pageLogicalHeight;
     state.m_pageLogicalHeightChanged = m_pageLogicalHeightChanged;
@@ -226,7 +222,7 @@
         }
 
         if (document().svgExtensions())
-            document().accessSVGExtensions()->invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope);
+            document().accessSVGExtensions().invalidateSVGRootsWithRelativeLengthDescendents(&layoutScope);
     }
 
     ASSERT(!m_layoutState);
@@ -241,11 +237,6 @@
 
     layoutContent(state);
 
-    if (m_frameView->partialLayout().isStopping()) {
-        m_layoutState = 0;
-        return;
-    }
-
 #ifndef NDEBUG
     checkLayoutState(state);
 #endif
@@ -358,6 +349,7 @@
     RenderStyle* style = rootBox->style();
     if (style->visibility() != VISIBLE
         || style->opacity() != 1
+        || style->hasFilter()
         || style->hasTransform())
         return false;
 
@@ -467,22 +459,6 @@
     }
 }
 
-void RenderView::repaintRectangleInViewAndCompositedLayers(const LayoutRect& ur)
-{
-    if (!shouldRepaint(ur))
-        return;
-
-    repaintViewRectangle(ur);
-
-    // FIXME: We don't actually know how to hit these ASSERTS.
-    DisableCompositingQueryAsserts disabler;
-
-    if (compositor()->inCompositingMode()) {
-        IntRect repaintRect = pixelSnappedIntRect(ur);
-        compositor()->repaintCompositedLayers(&repaintRect);
-    }
-}
-
 void RenderView::repaintViewAndCompositedLayers()
 {
     repaint();
@@ -868,7 +844,7 @@
     return IntRect(overflowRect);
 }
 
-int RenderView::viewHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
+int RenderView::viewHeight(IncludeScrollbarsInRect scrollbarInclusion) const
 {
     int height = 0;
     if (!shouldUsePrintingLayout() && m_frameView)
@@ -877,7 +853,7 @@
     return height;
 }
 
-int RenderView::viewWidth(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion) const
+int RenderView::viewWidth(IncludeScrollbarsInRect scrollbarInclusion) const
 {
     int width = 0;
     if (!shouldUsePrintingLayout() && m_frameView)
@@ -888,7 +864,7 @@
 
 int RenderView::viewLogicalHeight() const
 {
-    return style()->isHorizontalWritingMode() ? viewHeight(ScrollableArea::ExcludeScrollbars) : viewWidth(ScrollableArea::ExcludeScrollbars);
+    return style()->isHorizontalWritingMode() ? viewHeight(ExcludeScrollbars) : viewWidth(ExcludeScrollbars);
 }
 
 float RenderView::zoomFactor() const
@@ -896,7 +872,7 @@
     return m_frameView->frame().pageZoomFactor();
 }
 
-void RenderView::pushLayoutState(RenderObject* root)
+void RenderView::pushLayoutState(RenderObject& root)
 {
     ASSERT(m_layoutStateDisableCount == 0);
     ASSERT(m_layoutState == 0);
@@ -905,11 +881,11 @@
     m_layoutState = new LayoutState(root);
 }
 
-bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) const
+bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject& renderer) const
 {
-    RenderObject* o = renderer;
+    RenderObject* o = &renderer;
     while (o) {
-        if (o->hasColumns() || o->hasTransform() || o->hasReflection())
+        if (o->shouldDisableLayoutState())
             return true;
         o = o->container();
     }
@@ -942,7 +918,7 @@
 RenderLayerCompositor* RenderView::compositor()
 {
     if (!m_compositor)
-        m_compositor = adoptPtr(new RenderLayerCompositor(this));
+        m_compositor = adoptPtr(new RenderLayerCompositor(*this));
 
     return m_compositor.get();
 }
@@ -961,7 +937,7 @@
     return m_flowThreadController.get();
 }
 
-void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject* object)
+void RenderView::pushLayoutStateForCurrentFlowThread(const RenderObject& object)
 {
     if (!m_flowThreadController)
         return;
@@ -1004,13 +980,13 @@
 double RenderView::layoutViewportWidth() const
 {
     float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
-    return viewWidth(ScrollableArea::IncludeScrollbars) / scale;
+    return viewWidth(IncludeScrollbars) / scale;
 }
 
 double RenderView::layoutViewportHeight() const
 {
     float scale = m_frameView ? m_frameView->frame().pageZoomFactor() : 1;
-    return viewHeight(ScrollableArea::IncludeScrollbars) / scale;
+    return viewHeight(IncludeScrollbars) / scale;
 }
 
 } // namespace WebCore
diff --git a/Source/core/rendering/RenderView.h b/Source/core/rendering/RenderView.h
index 8d1f8b4..a3b2e9d 100644
--- a/Source/core/rendering/RenderView.h
+++ b/Source/core/rendering/RenderView.h
@@ -59,16 +59,14 @@
     virtual void updateLogicalWidth() OVERRIDE;
     virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const OVERRIDE;
 
-    virtual bool supportsPartialLayout() const OVERRIDE { return true; }
-
     virtual LayoutUnit availableLogicalHeight(AvailableLogicalHeightType) const OVERRIDE;
 
     // The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
-    int viewHeight(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion = ScrollableArea::ExcludeScrollbars) const;
-    int viewWidth(ScrollableArea::IncludeScrollbarsInRect scrollbarInclusion = ScrollableArea::ExcludeScrollbars) const;
+    int viewHeight(IncludeScrollbarsInRect = ExcludeScrollbars) const;
+    int viewWidth(IncludeScrollbarsInRect = ExcludeScrollbars) const;
     int viewLogicalWidth() const
     {
-        return style()->isHorizontalWritingMode() ? viewWidth(ScrollableArea::ExcludeScrollbars) : viewHeight(ScrollableArea::ExcludeScrollbars);
+        return style()->isHorizontalWritingMode() ? viewWidth(ExcludeScrollbars) : viewHeight(ExcludeScrollbars);
     }
     int viewLogicalHeight() const;
 
@@ -78,9 +76,7 @@
 
     virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
     void repaintViewRectangle(const LayoutRect&) const;
-    // Repaint the view, and all composited layers that intersect the given absolute rectangle.
-    // FIXME: ideally we'd never have to do this, if all repaints are container-relative.
-    void repaintRectangleInViewAndCompositedLayers(const LayoutRect&);
+
     void repaintViewAndCompositedLayers();
 
     virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
@@ -139,11 +135,18 @@
 
     bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
 
-    // Subtree push/pop
-    void pushLayoutState(RenderObject*);
-    void popLayoutState(RenderObject*) { return popLayoutState(); } // Just doing this to keep popLayoutState() private and to make the subtree calls symmetrical.
+    // Subtree push
+    void pushLayoutState(RenderObject&);
 
-    bool shouldDisableLayoutStateForSubtree(RenderObject*) const;
+    void popLayoutState()
+    {
+        LayoutState* state = m_layoutState;
+        m_layoutState = state->m_next;
+        delete state;
+        popLayoutStateForCurrentFlowThread();
+    }
+
+    bool shouldDisableLayoutStateForSubtree(RenderObject&) const;
 
     // Returns true if layoutState should be used for its cached offset and clip.
     bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; }
@@ -194,6 +197,14 @@
     double layoutViewportWidth() const;
     double layoutViewportHeight() const;
 
+    // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
+    // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
+    // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
+    // Note that even when disabled, LayoutState is still used to store layoutDelta.
+    // These functions may only be accessed by LayoutStateMaintainer or LayoutStateDisabler.
+    void disableLayoutState() { m_layoutStateDisableCount++; }
+    void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
+
 private:
     virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
     virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
@@ -207,12 +218,12 @@
     bool rootFillsViewportBackground(RenderBox* rootBox) const;
 
     // These functions may only be accessed by LayoutStateMaintainer.
-    bool pushLayoutState(RenderBox* renderer, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
+    bool pushLayoutState(RenderBox& renderer, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
     {
         // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
-        if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer->hasColumns() || renderer->flowThreadContainingBlock()
-            || (renderer->isRenderBlock() && toRenderBlock(renderer)->shapeInsideInfo())
-            || (m_layoutState->shapeInsideInfo() && renderer->isRenderBlock() && !toRenderBlock(renderer)->allowsShapeInsideInfoSharing(m_layoutState->shapeInsideInfo()->owner()))
+        if (!doingFullRepaint() || m_layoutState->isPaginated() || renderer.hasColumns() || renderer.flowThreadContainingBlock()
+            || (renderer.isRenderBlock() && toRenderBlock(renderer).shapeInsideInfo())
+            || (m_layoutState->shapeInsideInfo() && renderer.isRenderBlock() && !toRenderBlock(renderer).allowsShapeInsideInfoSharing(&m_layoutState->shapeInsideInfo()->owner()))
             ) {
             pushLayoutStateForCurrentFlowThread(renderer);
             m_layoutState = new LayoutState(m_layoutState, renderer, offset, pageHeight, pageHeightChanged, colInfo);
@@ -221,22 +232,6 @@
         return false;
     }
 
-    void popLayoutState()
-    {
-        LayoutState* state = m_layoutState;
-        m_layoutState = state->m_next;
-        delete state;
-        popLayoutStateForCurrentFlowThread();
-    }
-
-    // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
-    // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
-    // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
-    // Note that even when disabled, LayoutState is still used to store layoutDelta.
-    // These functions may only be accessed by LayoutStateMaintainer or LayoutStateDisabler.
-    void disableLayoutState() { m_layoutStateDisableCount++; }
-    void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
-
     void layoutContent(const LayoutState&);
 #ifndef NDEBUG
     void checkLayoutState(const LayoutState&);
@@ -245,7 +240,7 @@
     void positionDialog(RenderBox*);
     void positionDialogs();
 
-    void pushLayoutStateForCurrentFlowThread(const RenderObject*);
+    void pushLayoutStateForCurrentFlowThread(const RenderObject&);
     void popLayoutStateForCurrentFlowThread();
 
     friend class LayoutStateMaintainer;
@@ -283,9 +278,9 @@
     WTF_MAKE_NONCOPYABLE(LayoutStateMaintainer);
 public:
     // ctor to push now
-    LayoutStateMaintainer(RenderView* view, RenderBox* root, LayoutSize offset, bool disableState = false, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
-        : m_view(view)
-        , m_disabled(disableState)
+    explicit LayoutStateMaintainer(RenderBox& root, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
+        : m_view(*root.view())
+        , m_disabled(root.shouldDisableLayoutState())
         , m_didStart(false)
         , m_didEnd(false)
         , m_didCreateLayoutState(false)
@@ -294,8 +289,8 @@
     }
 
     // ctor to maybe push later
-    LayoutStateMaintainer(RenderView* view)
-        : m_view(view)
+    explicit LayoutStateMaintainer(RenderBox& root)
+        : m_view(*root.view())
         , m_disabled(false)
         , m_didStart(false)
         , m_didEnd(false)
@@ -308,13 +303,13 @@
         ASSERT(m_didStart == m_didEnd);   // if this fires, it means that someone did a push(), but forgot to pop().
     }
 
-    void push(RenderBox* root, LayoutSize offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
+    void push(RenderBox& root, const LayoutSize& offset, LayoutUnit pageHeight = 0, bool pageHeightChanged = false, ColumnInfo* colInfo = 0)
     {
         ASSERT(!m_didStart);
         // We push state even if disabled, because we still need to store layoutDelta
-        m_didCreateLayoutState = m_view->pushLayoutState(root, offset, pageHeight, pageHeightChanged, colInfo);
+        m_didCreateLayoutState = m_view.pushLayoutState(root, offset, pageHeight, pageHeightChanged, colInfo);
         if (m_disabled && m_didCreateLayoutState)
-            m_view->disableLayoutState();
+            m_view.disableLayoutState();
         m_didStart = true;
     }
 
@@ -323,9 +318,9 @@
         if (m_didStart) {
             ASSERT(!m_didEnd);
             if (m_didCreateLayoutState) {
-                m_view->popLayoutState();
+                m_view.popLayoutState();
                 if (m_disabled)
-                    m_view->enableLayoutState();
+                    m_view.enableLayoutState();
             }
 
             m_didEnd = true;
@@ -335,7 +330,7 @@
     bool didPush() const { return m_didStart; }
 
 private:
-    RenderView* m_view;
+    RenderView& m_view;
     bool m_disabled : 1;        // true if the offset and clip part of layoutState is disabled
     bool m_didStart : 1;        // true if we did a push or disable
     bool m_didEnd : 1;          // true if we popped or re-enabled
@@ -345,20 +340,18 @@
 class LayoutStateDisabler {
     WTF_MAKE_NONCOPYABLE(LayoutStateDisabler);
 public:
-    LayoutStateDisabler(RenderView* view)
-        : m_view(view)
+    LayoutStateDisabler(const RenderBox& root)
+        : m_view(*root.view())
     {
-        if (m_view)
-            m_view->disableLayoutState();
+        m_view.disableLayoutState();
     }
 
     ~LayoutStateDisabler()
     {
-        if (m_view)
-            m_view->enableLayoutState();
+        m_view.enableLayoutState();
     }
 private:
-    RenderView* m_view;
+    RenderView& m_view;
 };
 
 } // namespace WebCore
diff --git a/Source/core/rendering/RenderWidget.cpp b/Source/core/rendering/RenderWidget.cpp
index e911068..02a4dde 100644
--- a/Source/core/rendering/RenderWidget.cpp
+++ b/Source/core/rendering/RenderWidget.cpp
@@ -25,13 +25,13 @@
 #include "core/rendering/RenderWidget.h"
 
 #include "core/accessibility/AXObjectCache.h"
-#include "core/frame/Frame.h"
-#include "core/rendering/CompositedLayerMapping.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/GraphicsContextAnnotator.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
 #include "wtf/HashMap.h"
 
 namespace WebCore {
@@ -86,7 +86,7 @@
 
 RenderWidget::RenderWidget(Element* element)
     : RenderReplaced(element)
-    , m_widget(0)
+    , m_widget(nullptr)
     // Reference counting is used to prevent the widget from being
     // destroyed while inside the Widget code, which might not be
     // able to handle that.
@@ -105,7 +105,7 @@
         cache->remove(this);
     }
 
-    setWidget(0);
+    setWidget(nullptr);
 
     RenderReplaced::willBeDestroyed();
 }
@@ -343,7 +343,7 @@
 
 void RenderWidget::clearWidget()
 {
-    m_widget = 0;
+    m_widget = nullptr;
 }
 
 bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction action)
diff --git a/Source/core/rendering/RootInlineBox.cpp b/Source/core/rendering/RootInlineBox.cpp
index b110fc6..3bcc6fd 100644
--- a/Source/core/rendering/RootInlineBox.cpp
+++ b/Source/core/rendering/RootInlineBox.cpp
@@ -47,7 +47,7 @@
 typedef WTF::HashMap<const RootInlineBox*, EllipsisBox*> EllipsisBoxMap;
 static EllipsisBoxMap* gEllipsisBoxMap = 0;
 
-RootInlineBox::RootInlineBox(RenderBlockFlow* block)
+RootInlineBox::RootInlineBox(RenderBlockFlow& block)
     : InlineFlowBox(block)
     , m_lineBreakPos(0)
     , m_lineBreakObj(0)
@@ -56,7 +56,7 @@
     , m_lineTopWithLeading(0)
     , m_lineBottomWithLeading(0)
 {
-    setIsHorizontal(block->isHorizontalWritingMode());
+    setIsHorizontal(block.isHorizontalWritingMode());
 }
 
 
@@ -78,7 +78,7 @@
 
 RenderLineBoxList* RootInlineBox::rendererLineBoxes() const
 {
-    return block()->lineBoxes();
+    return block().lineBoxes();
 }
 
 void RootInlineBox::clearTruncation()
@@ -164,7 +164,7 @@
 
 void RootInlineBox::paintEllipsisBox(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) const
 {
-    if (hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(renderer()) && renderer()->style()->visibility() == VISIBLE
+    if (hasEllipsisBox() && paintInfo.shouldPaintWithinRoot(&renderer()) && renderer().style()->visibility() == VISIBLE
             && paintInfo.phase == PaintPhaseForeground)
         ellipsisBox()->paint(paintInfo, paintOffset, lineTop, lineBottom);
 }
@@ -179,7 +179,7 @@
 {
     if (hasEllipsisBox() && visibleToHitTestRequest(request)) {
         if (ellipsisBox()->nodeAtPoint(request, result, locationInContainer, accumulatedOffset, lineTop, lineBottom)) {
-            renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
+            renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
             return true;
         }
     }
@@ -200,10 +200,10 @@
 
 void RootInlineBox::childRemoved(InlineBox* box)
 {
-    if (box->renderer() == m_lineBreakObj)
+    if (&box->renderer() == m_lineBreakObj)
         setLineBreakInfo(0, 0, BidiStatus());
 
-    for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == box->renderer(); prev = prev->prevRootBox()) {
+    for (RootInlineBox* prev = prevRootBox(); prev && prev->lineBreakObj() == &box->renderer(); prev = prev->prevRootBox()) {
         prev->setLineBreakInfo(0, 0, BidiStatus());
         prev->markDirty();
     }
@@ -223,7 +223,7 @@
     bool setMaxDescent = false;
 
     // Figure out if we're in no-quirks mode.
-    bool noQuirksMode = renderer()->document().inNoQuirksMode();
+    bool noQuirksMode = renderer().document().inNoQuirksMode();
 
     m_baselineType = requiresIdeographicBaseline(textBoxDataMap) ? IdeographicBaseline : AlphabeticBaseline;
 
@@ -249,13 +249,13 @@
     maxHeight = max<LayoutUnit>(0, maxHeight); // FIXME: Is this really necessary?
 
     setLineTopBottomPositions(lineTop, lineBottom, heightOfBlock, heightOfBlock + maxHeight);
-    setPaginatedLineWidth(block()->availableLogicalWidthForContent());
+    setPaginatedLineWidth(block().availableLogicalWidthForContent());
 
     LayoutUnit annotationsAdjustment = beforeAnnotationsAdjustment();
     if (annotationsAdjustment) {
         // FIXME: Need to handle pagination here. We might have to move to the next page/column as a result of the
         // ruby expansion.
-        adjustBlockDirectionPosition(annotationsAdjustment);
+        adjustBlockDirectionPosition(annotationsAdjustment.toFloat());
         heightOfBlock += annotationsAdjustment;
     }
 
@@ -273,7 +273,7 @@
 {
     LayoutUnit result = 0;
 
-    if (!renderer()->style()->isFlippedLinesWritingMode()) {
+    if (!renderer().style()->isFlippedLinesWritingMode()) {
         // Annotations under the previous line may push us down.
         if (prevRootBox() && prevRootBox()->hasAnnotationsAfter())
             result = prevRootBox()->computeUnderAnnotationAdjustment(lineTop());
@@ -282,12 +282,12 @@
             return result;
 
         // Annotations over this line may push us further down.
-        LayoutUnit highestAllowedPosition = prevRootBox() ? min(prevRootBox()->lineBottom(), lineTop()) + result : static_cast<LayoutUnit>(block()->borderBefore());
+        LayoutUnit highestAllowedPosition = prevRootBox() ? min(prevRootBox()->lineBottom(), lineTop()) + result : static_cast<LayoutUnit>(block().borderBefore());
         result = computeOverAnnotationAdjustment(highestAllowedPosition);
     } else {
         // Annotations under this line may push us up.
         if (hasAnnotationsBefore())
-            result = computeUnderAnnotationAdjustment(prevRootBox() ? prevRootBox()->lineBottom() : static_cast<LayoutUnit>(block()->borderBefore()));
+            result = computeUnderAnnotationAdjustment(prevRootBox() ? prevRootBox()->lineBottom() : static_cast<LayoutUnit>(block().borderBefore()));
 
         if (!prevRootBox() || !prevRootBox()->hasAnnotationsAfter())
             return result;
@@ -306,18 +306,20 @@
     RenderObject::SelectionState lineState = selectionState();
 
     bool leftGap, rightGap;
-    block()->getSelectionGapInfo(lineState, leftGap, rightGap);
+    block().getSelectionGapInfo(lineState, leftGap, rightGap);
 
     GapRects result;
 
     InlineBox* firstBox = firstSelectedBox();
     InlineBox* lastBox = lastSelectedBox();
-    if (leftGap)
-        result.uniteLeft(block()->logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
-                                                          firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo));
-    if (rightGap)
-        result.uniteRight(block()->logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
-                                                            lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo));
+    if (leftGap) {
+        result.uniteLeft(block().logicalLeftSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
+            &firstBox->parent()->renderer(), firstBox->logicalLeft(), selTop, selHeight, paintInfo));
+    }
+    if (rightGap) {
+        result.uniteRight(block().logicalRightSelectionGap(rootBlock, rootBlockPhysicalPosition, offsetFromRootBlock,
+            &lastBox->parent()->renderer(), lastBox->logicalRight(), selTop, selHeight, paintInfo));
+    }
 
     // When dealing with bidi text, a non-contiguous selection region is possible.
     // e.g. The logical text aaaAAAbbb (capitals denote RTL text and non-capitals LTR) is layed out
@@ -333,11 +335,11 @@
         for (InlineBox* box = firstBox->nextLeafChild(); box; box = box->nextLeafChild()) {
             if (box->selectionState() != RenderObject::SelectionNone) {
                 LayoutRect logicalRect(lastLogicalLeft, selTop, box->logicalLeft() - lastLogicalLeft, selHeight);
-                logicalRect.move(renderer()->isHorizontalWritingMode() ? offsetFromRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
+                logicalRect.move(renderer().isHorizontalWritingMode() ? offsetFromRootBlock : LayoutSize(offsetFromRootBlock.height(), offsetFromRootBlock.width()));
                 LayoutRect gapRect = rootBlock->logicalRectToPhysicalRect(rootBlockPhysicalPosition, logicalRect);
                 if (isPreviousBoxSelected && gapRect.width() > 0 && gapRect.height() > 0) {
-                    if (paintInfo && box->parent()->renderer()->style()->visibility() == VISIBLE)
-                        paintInfo->context->fillRect(gapRect, box->parent()->renderer()->selectionBackgroundColor());
+                    if (paintInfo && box->parent()->renderer().style()->visibility() == VISIBLE)
+                        paintInfo->context->fillRect(gapRect, box->parent()->renderer().selectionBackgroundColor());
                     // VisibleSelection may be non-contiguous, see comment above.
                     result.uniteCenter(gapRect);
                 }
@@ -401,20 +403,20 @@
     LayoutUnit selectionTop = m_lineTop;
 
     if (m_hasAnnotationsBefore)
-        selectionTop -= !renderer()->style()->isFlippedLinesWritingMode() ? computeOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineTop);
+        selectionTop -= !renderer().style()->isFlippedLinesWritingMode() ? computeOverAnnotationAdjustment(m_lineTop) : computeUnderAnnotationAdjustment(m_lineTop);
 
-    if (renderer()->style()->isFlippedLinesWritingMode())
+    if (renderer().style()->isFlippedLinesWritingMode() || !prevRootBox())
         return selectionTop;
 
-    LayoutUnit prevBottom = prevRootBox() ? prevRootBox()->selectionBottom() : block()->borderBefore() + block()->paddingBefore();
-    if (prevBottom < selectionTop && block()->containsFloats()) {
+    LayoutUnit prevBottom = prevRootBox()->selectionBottom();
+    if (prevBottom < selectionTop && block().containsFloats()) {
         // This line has actually been moved further down, probably from a large line-height, but possibly because the
         // line was forced to clear floats.  If so, let's check the offsets, and only be willing to use the previous
         // line's bottom if the offsets are greater on both sides.
-        LayoutUnit prevLeft = block()->logicalLeftOffsetForLine(prevBottom, false);
-        LayoutUnit prevRight = block()->logicalRightOffsetForLine(prevBottom, false);
-        LayoutUnit newLeft = block()->logicalLeftOffsetForLine(selectionTop, false);
-        LayoutUnit newRight = block()->logicalRightOffsetForLine(selectionTop, false);
+        LayoutUnit prevLeft = block().logicalLeftOffsetForLine(prevBottom, false);
+        LayoutUnit prevRight = block().logicalRightOffsetForLine(prevBottom, false);
+        LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionTop, false);
+        LayoutUnit newRight = block().logicalRightOffsetForLine(selectionTop, false);
         if (prevLeft > newLeft || prevRight < newRight)
             return selectionTop;
     }
@@ -426,12 +428,12 @@
 {
     LayoutUnit top = selectionTop();
 
-    RenderObject::SelectionState blockSelectionState = root()->block()->selectionState();
+    RenderObject::SelectionState blockSelectionState = root().block().selectionState();
     if (blockSelectionState != RenderObject::SelectionInside && blockSelectionState != RenderObject::SelectionEnd)
         return top;
 
     LayoutSize offsetToBlockBefore;
-    if (RenderBlock* block = root()->block()->blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
+    if (RenderBlock* block = root().block().blockBeforeWithinSelectionRoot(offsetToBlockBefore)) {
         if (RootInlineBox* lastLine = block->lastRootBox()) {
             RenderObject::SelectionState lastLineSelectionState = lastLine->selectionState();
             if (lastLineSelectionState != RenderObject::SelectionInside && lastLineSelectionState != RenderObject::SelectionStart)
@@ -450,20 +452,20 @@
     LayoutUnit selectionBottom = m_lineBottom;
 
     if (m_hasAnnotationsAfter)
-        selectionBottom += !renderer()->style()->isFlippedLinesWritingMode() ? computeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m_lineBottom);
+        selectionBottom += !renderer().style()->isFlippedLinesWritingMode() ? computeUnderAnnotationAdjustment(m_lineBottom) : computeOverAnnotationAdjustment(m_lineBottom);
 
-    if (!renderer()->style()->isFlippedLinesWritingMode() || !nextRootBox())
+    if (!renderer().style()->isFlippedLinesWritingMode() || !nextRootBox())
         return selectionBottom;
 
     LayoutUnit nextTop = nextRootBox()->selectionTop();
-    if (nextTop > selectionBottom && block()->containsFloats()) {
+    if (nextTop > selectionBottom && block().containsFloats()) {
         // The next line has actually been moved further over, probably from a large line-height, but possibly because the
         // line was forced to clear floats.  If so, let's check the offsets, and only be willing to use the next
         // line's top if the offsets are greater on both sides.
-        LayoutUnit nextLeft = block()->logicalLeftOffsetForLine(nextTop, false);
-        LayoutUnit nextRight = block()->logicalRightOffsetForLine(nextTop, false);
-        LayoutUnit newLeft = block()->logicalLeftOffsetForLine(selectionBottom, false);
-        LayoutUnit newRight = block()->logicalRightOffsetForLine(selectionBottom, false);
+        LayoutUnit nextLeft = block().logicalLeftOffsetForLine(nextTop, false);
+        LayoutUnit nextRight = block().logicalRightOffsetForLine(nextTop, false);
+        LayoutUnit newLeft = block().logicalLeftOffsetForLine(selectionBottom, false);
+        LayoutUnit newRight = block().logicalRightOffsetForLine(selectionBottom, false);
         if (nextLeft > newLeft || nextRight < newRight)
             return selectionBottom;
     }
@@ -473,22 +475,22 @@
 
 int RootInlineBox::blockDirectionPointInLine() const
 {
-    return !block()->style()->isFlippedBlocksWritingMode() ? max(lineTop(), selectionTop()) : min(lineBottom(), selectionBottom());
+    return !block().style()->isFlippedBlocksWritingMode() ? max(lineTop(), selectionTop()) : min(lineBottom(), selectionBottom());
 }
 
-RenderBlockFlow* RootInlineBox::block() const
+RenderBlockFlow& RootInlineBox::block() const
 {
     return toRenderBlockFlow(renderer());
 }
 
 static bool isEditableLeaf(InlineBox* leaf)
 {
-    return leaf && leaf->renderer() && leaf->renderer()->node() && leaf->renderer()->node()->rendererIsEditable();
+    return leaf && leaf->renderer().node() && leaf->renderer().node()->rendererIsEditable();
 }
 
 InlineBox* RootInlineBox::closestLeafChildForPoint(const IntPoint& pointInContents, bool onlyEditableLeaves)
 {
-    return closestLeafChildForLogicalLeftPosition(block()->isHorizontalWritingMode() ? pointInContents.x() : pointInContents.y(), onlyEditableLeaves);
+    return closestLeafChildForLogicalLeftPosition(block().isHorizontalWritingMode() ? pointInContents.x() : pointInContents.y(), onlyEditableLeaves);
 }
 
 InlineBox* RootInlineBox::closestLeafChildForLogicalLeftPosition(int leftPosition, bool onlyEditableLeaves)
@@ -507,19 +509,19 @@
         return firstLeaf;
 
     // Avoid returning a list marker when possible.
-    if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
+    if (leftPosition <= firstLeaf->logicalLeft() && !firstLeaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(firstLeaf)))
         // The leftPosition coordinate is less or equal to left edge of the firstLeaf.
         // Return it.
         return firstLeaf;
 
-    if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
+    if (leftPosition >= lastLeaf->logicalRight() && !lastLeaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(lastLeaf)))
         // The leftPosition coordinate is greater or equal to right edge of the lastLeaf.
         // Return it.
         return lastLeaf;
 
     InlineBox* closestLeaf = 0;
     for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChildIgnoringLineBreak()) {
-        if (!leaf->renderer()->isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
+        if (!leaf->renderer().isListMarker() && (!onlyEditableLeaves || isEditableLeaf(leaf))) {
             closestLeaf = leaf;
             if (leftPosition < leaf->logicalRight())
                 // The x coordinate is less than the right edge of the box.
@@ -562,17 +564,17 @@
 
 void RootInlineBox::removeLineBoxFromRenderObject()
 {
-    block()->lineBoxes()->removeLineBox(this);
+    block().lineBoxes()->removeLineBox(this);
 }
 
 void RootInlineBox::extractLineBoxFromRenderObject()
 {
-    block()->lineBoxes()->extractLineBox(this);
+    block().lineBoxes()->extractLineBox(this);
 }
 
 void RootInlineBox::attachLineBoxToRenderObject()
 {
-    block()->lineBoxes()->attachLineBox(this);
+    block().lineBoxes()->attachLineBox(this);
 }
 
 LayoutRect RootInlineBox::paddedLayoutOverflowRect(LayoutUnit endPadding) const
@@ -615,8 +617,8 @@
 
     // Replaced boxes will return 0 for the line-height if line-box-contain says they are
     // not to be included.
-    if (box->renderer()->isReplaced()) {
-        if (renderer()->style(isFirstLineStyle())->lineBoxContain() & LineBoxContainReplaced) {
+    if (box->renderer().isReplaced()) {
+        if (renderer().style(isFirstLineStyle())->lineBoxContain() & LineBoxContainReplaced) {
             ascent = box->baselinePosition(baselineType());
             descent = box->lineHeight() - ascent;
 
@@ -641,8 +643,8 @@
     bool setUsedFont = false;
     bool setUsedFontWithLeading = false;
 
-    if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer()->style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) {
-        usedFonts->append(box->renderer()->style(isFirstLineStyle())->font().primaryFont());
+    if (usedFonts && !usedFonts->isEmpty() && (includeFont || (box->renderer().style(isFirstLineStyle())->lineHeight().isNegative() && includeLeading))) {
+        usedFonts->append(box->renderer().style(isFirstLineStyle())->font().primaryFont());
         for (size_t i = 0; i < usedFonts->size(); ++i) {
             const FontMetrics& fontMetrics = usedFonts->at(i)->fontMetrics();
             int usedFontAscent = fontMetrics.ascent(baselineType());
@@ -680,8 +682,8 @@
     }
 
     if (includeFontForBox(box) && !setUsedFont) {
-        int fontAscent = box->renderer()->style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
-        int fontDescent = box->renderer()->style(isFirstLineStyle())->fontMetrics().descent(baselineType());
+        int fontAscent = box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
+        int fontDescent = box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());
         setAscentAndDescent(ascent, descent, fontAscent, fontDescent, ascentDescentSet);
         affectsAscent = fontAscent - box->logicalTop() > 0;
         affectsDescent = fontDescent + box->logicalTop() > 0;
@@ -691,14 +693,14 @@
         setAscentAndDescent(ascent, descent, glyphOverflow->top, glyphOverflow->bottom, ascentDescentSet);
         affectsAscent = glyphOverflow->top - box->logicalTop() > 0;
         affectsDescent = glyphOverflow->bottom + box->logicalTop() > 0;
-        glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top - box->renderer()->style(isFirstLineStyle())->fontMetrics().ascent(baselineType())));
-        glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow->bottom - box->renderer()->style(isFirstLineStyle())->fontMetrics().descent(baselineType())));
+        glyphOverflow->top = min(glyphOverflow->top, max(0, glyphOverflow->top - box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType())));
+        glyphOverflow->bottom = min(glyphOverflow->bottom, max(0, glyphOverflow->bottom - box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType())));
     }
 
     if (includeMarginForBox(box)) {
-        LayoutUnit ascentWithMargin = box->renderer()->style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
-        LayoutUnit descentWithMargin = box->renderer()->style(isFirstLineStyle())->fontMetrics().descent(baselineType());
-        if (box->parent() && !box->renderer()->isText()) {
+        LayoutUnit ascentWithMargin = box->renderer().style(isFirstLineStyle())->fontMetrics().ascent(baselineType());
+        LayoutUnit descentWithMargin = box->renderer().style(isFirstLineStyle())->fontMetrics().descent(baselineType());
+        if (box->parent() && !box->renderer().isText()) {
             ascentWithMargin += box->boxModelObject()->borderBefore() + box->boxModelObject()->paddingBefore() + box->boxModelObject()->marginBefore();
             descentWithMargin += box->boxModelObject()->borderAfter() + box->boxModelObject()->paddingAfter() + box->boxModelObject()->marginAfter();
         }
@@ -712,7 +714,7 @@
 
 LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositionCache& verticalPositionCache)
 {
-    if (box->renderer()->isText())
+    if (box->renderer().isText())
         return box->parent()->logicalTop();
 
     RenderBoxModelObject* renderer = box->boxModelObject();
@@ -784,45 +786,45 @@
 
 bool RootInlineBox::includeLeadingForBox(InlineBox* box) const
 {
-    if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
         return false;
 
-    LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
     return (lineBoxContain & LineBoxContainInline) || (box == this && (lineBoxContain & LineBoxContainBlock));
 }
 
 bool RootInlineBox::includeFontForBox(InlineBox* box) const
 {
-    if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
         return false;
 
     if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTextChildren())
         return false;
 
     // For now map "glyphs" to "font" in vertical text mode until the bounds returned by glyphs aren't garbage.
-    LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
     return (lineBoxContain & LineBoxContainFont) || (!isHorizontal() && (lineBoxContain & LineBoxContainGlyphs));
 }
 
 bool RootInlineBox::includeGlyphsForBox(InlineBox* box) const
 {
-    if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
         return false;
 
     if (!box->isText() && box->isInlineFlowBox() && !toInlineFlowBox(box)->hasTextChildren())
         return false;
 
     // FIXME: We can't fit to glyphs yet for vertical text, since the bounds returned are garbage.
-    LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
     return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs);
 }
 
 bool RootInlineBox::includeMarginForBox(InlineBox* box) const
 {
-    if (box->renderer()->isReplaced() || (box->renderer()->isText() && !box->isText()))
+    if (box->renderer().isReplaced() || (box->renderer().isText() && !box->isText()))
         return false;
 
-    LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
     return lineBoxContain & LineBoxContainInlineBox;
 }
 
@@ -830,13 +832,13 @@
 bool RootInlineBox::fitsToGlyphs() const
 {
     // FIXME: We can't fit to glyphs yet for vertical text, since the bounds returned are garbage.
-    LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
     return isHorizontal() && (lineBoxContain & LineBoxContainGlyphs);
 }
 
 bool RootInlineBox::includesRootLineBoxFontOrLeading() const
 {
-    LineBoxContain lineBoxContain = renderer()->style()->lineBoxContain();
+    LineBoxContain lineBoxContain = renderer().style()->lineBoxContain();
     return (lineBoxContain & LineBoxContainBlock) || (lineBoxContain & LineBoxContainInline) || (lineBoxContain & LineBoxContainFont);
 }
 
@@ -845,9 +847,9 @@
     Vector<InlineBox*> leafBoxesInLogicalOrder;
     collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder);
     for (size_t i = 0; i < leafBoxesInLogicalOrder.size(); ++i) {
-        if (leafBoxesInLogicalOrder[i]->renderer()->node()) {
+        if (leafBoxesInLogicalOrder[i]->renderer().node()) {
             startBox = leafBoxesInLogicalOrder[i];
-            return startBox->renderer()->node();
+            return startBox->renderer().node();
         }
     }
     startBox = 0;
@@ -859,9 +861,9 @@
     Vector<InlineBox*> leafBoxesInLogicalOrder;
     collectLeafBoxesInLogicalOrder(leafBoxesInLogicalOrder);
     for (size_t i = leafBoxesInLogicalOrder.size(); i > 0; --i) {
-        if (leafBoxesInLogicalOrder[i - 1]->renderer()->node()) {
+        if (leafBoxesInLogicalOrder[i - 1]->renderer().node()) {
             endBox = leafBoxesInLogicalOrder[i - 1];
-            return endBox->renderer()->node();
+            return endBox->renderer().node();
         }
     }
     endBox = 0;
diff --git a/Source/core/rendering/RootInlineBox.h b/Source/core/rendering/RootInlineBox.h
index 92ea130..32b1c55 100644
--- a/Source/core/rendering/RootInlineBox.h
+++ b/Source/core/rendering/RootInlineBox.h
@@ -35,7 +35,7 @@
 
 class RootInlineBox : public InlineFlowBox {
 public:
-    explicit RootInlineBox(RenderBlockFlow*);
+    explicit RootInlineBox(RenderBlockFlow&);
 
     virtual void destroy() OVERRIDE FINAL;
 
@@ -125,7 +125,7 @@
 
     GapRects lineSelectionGap(RenderBlock* rootBlock, const LayoutPoint& rootBlockPhysicalPosition, const LayoutSize& offsetFromRootBlock, LayoutUnit selTop, LayoutUnit selHeight, const PaintInfo*);
 
-    RenderBlockFlow* block() const;
+    RenderBlockFlow& block() const;
 
     InlineBox* closestLeafChildForPoint(const IntPoint&, bool onlyEditableLeaves);
     InlineBox* closestLeafChildForLogicalLeftPosition(int, bool onlyEditableLeaves = false);
diff --git a/Source/core/rendering/SubtreeLayoutScope.cpp b/Source/core/rendering/SubtreeLayoutScope.cpp
index 48b1f35..5f16c8e 100644
--- a/Source/core/rendering/SubtreeLayoutScope.cpp
+++ b/Source/core/rendering/SubtreeLayoutScope.cpp
@@ -44,12 +44,6 @@
 
 SubtreeLayoutScope::~SubtreeLayoutScope()
 {
-    // Partial layout early-exits layout and will leave the tree as needing layout.
-    if (m_root->frameView()->partialLayout().isStopping()) {
-        ASSERT(m_root->needsLayout());
-        return;
-    }
-
     RELEASE_ASSERT(!m_root->needsLayout());
 
 #ifndef NDEBUG
diff --git a/Source/core/rendering/TextAutosizer.cpp b/Source/core/rendering/TextAutosizer.cpp
index b14768d..1b836df 100644
--- a/Source/core/rendering/TextAutosizer.cpp
+++ b/Source/core/rendering/TextAutosizer.cpp
@@ -24,8 +24,9 @@
 #include <algorithm>
 
 #include "core/dom/Document.h"
-#include "core/html/HTMLElement.h"
 #include "core/frame/Settings.h"
+#include "core/frame/UseCounter.h"
+#include "core/html/HTMLElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/rendering/RenderListItem.h"
 #include "core/rendering/RenderObject.h"
@@ -104,7 +105,7 @@
     // see http://www.whatwg.org/specs/web-apps/current-work/multipage/grouping-content.html#the-li-element
     for (RenderObject* ancestor = renderer->parent(); ancestor; ancestor = ancestor->parent()) {
         Node* parentNode = ancestor->generatingNode();
-        if (parentNode && (parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag)))
+        if (parentNode && (isHTMLOListElement(*parentNode) || isHTMLUListElement(*parentNode)))
             return ancestor;
     }
     return 0;
@@ -180,8 +181,7 @@
 
 bool TextAutosizer::processSubtree(RenderObject* layoutRoot)
 {
-    TRACE_EVENT0("webkit", "TextAutosizer::processSubtree");
-
+    TRACE_EVENT0("webkit", "TextAutosizer: check if needed");
     if (!m_document->settings() || layoutRoot->view()->document().printing() || !m_document->page())
         return false;
 
@@ -189,20 +189,22 @@
     if (!textAutosizingEnabled)
         return false;
 
-    InspectorInstrumentation::willAutosizeText(layoutRoot);
-
-    Frame* mainFrame = m_document->page()->mainFrame();
+    LocalFrame* mainFrame = m_document->page()->mainFrame();
     TextAutosizingWindowInfo windowInfo;
 
+    if (!mainFrame->loader().stateMachine()->committedFirstRealDocumentLoad())
+        return false;
+
+
     // Window area, in logical (density-independent) pixels.
     windowInfo.windowSize = m_document->settings()->textAutosizingWindowSizeOverride();
     if (windowInfo.windowSize.isEmpty())
-        windowInfo.windowSize = mainFrame->view()->unscaledVisibleContentSize(ScrollableArea::IncludeScrollbars);
+        windowInfo.windowSize = mainFrame->view()->unscaledVisibleContentSize(IncludeScrollbars);
 
     // Largest area of block that can be visible at once (assuming the main
     // frame doesn't get scaled to less than overview scale), in CSS pixels.
     windowInfo.minLayoutSize = mainFrame->view()->layoutSize();
-    for (Frame* frame = m_document->frame(); frame; frame = frame->tree().parent())
+    for (LocalFrame* frame = m_document->frame(); frame; frame = frame->tree().parent())
         windowInfo.minLayoutSize = windowInfo.minLayoutSize.shrunkTo(frame->view()->layoutSize());
 
     // The layoutRoot could be neither a container nor a cluster, so walk up the tree till we find each of these.
@@ -218,10 +220,12 @@
     // Note: this might suppress autosizing of an inner cluster with a different writing mode.
     // It's not clear what the correct behavior is for mixed writing modes anyway.
     if (!cluster || clusterMultiplier(cluster->style()->writingMode(), windowInfo,
-        std::numeric_limits<float>::infinity()) == 1.0f) {
-        InspectorInstrumentation::didAutosizeText(layoutRoot);
+        std::numeric_limits<float>::infinity()) == 1.0f)
         return false;
-    }
+
+    TRACE_EVENT0("webkit", "TextAutosizer: process root cluster");
+    InspectorInstrumentation::willAutosizeText(layoutRoot);
+    UseCounter::count(*m_document, UseCounter::TextAutosizing);
 
     TextAutosizingClusterInfo clusterInfo(cluster);
     processCluster(clusterInfo, container, layoutRoot, windowInfo);
@@ -329,7 +333,7 @@
     // descendant text node of the cluster (i.e. the deepest wrapper block that contains all the
     // text), and use its width instead.
     clusterInfo.blockContainingAllText = findDeepestBlockContainingAllText(clusterInfo.root);
-    float textWidth = clusterInfo.blockContainingAllText->contentLogicalWidth();
+    float textWidth = clusterInfo.blockContainingAllText->contentLogicalWidth().toFloat();
 
     Vector<TextAutosizingClusterInfo> clusterInfos(1, clusterInfo);
     float multiplier = computeMultiplier(clusterInfos, windowInfo, textWidth);
@@ -346,7 +350,7 @@
     for (size_t i = 0; i < clusterInfos.size(); ++i) {
         TextAutosizingClusterInfo& clusterInfo = clusterInfos[i];
         clusterInfo.blockContainingAllText = findDeepestBlockContainingAllText(clusterInfo.root);
-        maxTextWidth = max<float>(maxTextWidth, clusterInfo.blockContainingAllText->contentLogicalWidth());
+        maxTextWidth = max<float>(maxTextWidth, clusterInfo.blockContainingAllText->contentLogicalWidth().toFloat());
     }
 
     float multiplier =  computeMultiplier(clusterInfos, windowInfo, maxTextWidth);
@@ -444,7 +448,7 @@
 #ifndef NDEBUG
     Node* parentNode = renderer->generatingNode();
     ASSERT(parentNode);
-    ASSERT(parentNode->hasTagName(olTag) || parentNode->hasTagName(ulTag));
+    ASSERT(isHTMLOListElement(parentNode) || isHTMLUListElement(parentNode));
 #endif
     setMultiplier(renderer, multiplier);
 
@@ -494,7 +498,7 @@
     // - Must not be normal list items, as items in the same list should look
     //   consistent, unless they are floating or position:absolute/fixed.
     Node* node = renderer->generatingNode();
-    if ((node && !node->hasChildNodes())
+    if ((node && !node->hasChildren())
         || !renderer->isRenderBlock()
         || (renderer->isInline() && !renderer->style()->isDisplayReplacedType()))
         return false;
@@ -524,14 +528,14 @@
     // the enclosing cluster. This 150px limit is adjusted whenever a descendant container is
     // less than 50px narrower than the current limit.
     const float differenceFromMaxWidthDifference = 50;
-    float contentWidth = renderer->contentLogicalWidth();
-    float clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
-    float widthDifference = clusterTextWidth - contentWidth;
+    LayoutUnit contentWidth = renderer->contentLogicalWidth();
+    LayoutUnit clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
+    LayoutUnit widthDifference = clusterTextWidth - contentWidth;
 
     if (widthDifference - parentClusterInfo.maxAllowedDifferenceFromTextWidth > differenceFromMaxWidthDifference)
         return true;
 
-    parentClusterInfo.maxAllowedDifferenceFromTextWidth = std::max(widthDifference, parentClusterInfo.maxAllowedDifferenceFromTextWidth);
+    parentClusterInfo.maxAllowedDifferenceFromTextWidth = std::max(widthDifference.toFloat(), parentClusterInfo.maxAllowedDifferenceFromTextWidth);
     return false;
 }
 
@@ -541,8 +545,8 @@
 
     // Autosizing containers that are wider than the |blockContainingAllText| of their enclosing
     // cluster are treated the same way as autosizing clusters to be autosized separately.
-    float contentWidth = renderer->contentLogicalWidth();
-    float clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
+    LayoutUnit contentWidth = renderer->contentLogicalWidth();
+    LayoutUnit clusterTextWidth = parentClusterInfo.blockContainingAllText->contentLogicalWidth();
     return contentWidth > clusterTextWidth;
 }
 
@@ -833,8 +837,8 @@
         groups.last().append(clusterInfos[i]);
 
         if (i + 1 < clusterInfos.size()) {
-            float currentWidth = clusterInfos[i].root->contentLogicalWidth();
-            float nextWidth = clusterInfos[i + 1].root->contentLogicalWidth();
+            LayoutUnit currentWidth = clusterInfos[i].root->contentLogicalWidth();
+            LayoutUnit nextWidth = clusterInfos[i + 1].root->contentLogicalWidth();
             if (currentWidth - nextWidth > maxWidthDifferenceWithinGroup)
                 groups.grow(groups.size() + 1);
         }
diff --git a/Source/core/rendering/TrailingFloatsRootInlineBox.h b/Source/core/rendering/TrailingFloatsRootInlineBox.h
index ce3309f..151f0b0 100644
--- a/Source/core/rendering/TrailingFloatsRootInlineBox.h
+++ b/Source/core/rendering/TrailingFloatsRootInlineBox.h
@@ -32,7 +32,7 @@
 
 class TrailingFloatsRootInlineBox FINAL : public RootInlineBox {
 public:
-    TrailingFloatsRootInlineBox(RenderBlockFlow* block)
+    TrailingFloatsRootInlineBox(RenderBlockFlow& block)
         : RootInlineBox(block)
     {
         setHasVirtualLogicalHeight();
diff --git a/Source/core/rendering/CompositedLayerMapping.cpp b/Source/core/rendering/compositing/CompositedLayerMapping.cpp
similarity index 85%
rename from Source/core/rendering/CompositedLayerMapping.cpp
rename to Source/core/rendering/compositing/CompositedLayerMapping.cpp
index 9eb6f3c..56406ad 100644
--- a/Source/core/rendering/CompositedLayerMapping.cpp
+++ b/Source/core/rendering/compositing/CompositedLayerMapping.cpp
@@ -25,7 +25,7 @@
 
 #include "config.h"
 
-#include "core/rendering/CompositedLayerMapping.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
 
 #include "CSSPropertyNames.h"
 #include "HTMLNames.h"
@@ -46,10 +46,11 @@
 #include "core/rendering/RenderEmbeddedObject.h"
 #include "core/rendering/RenderIFrame.h"
 #include "core/rendering/RenderImage.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderLayerStackingNodeIterator.h"
 #include "core/rendering/RenderVideo.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/rendering/style/KeyframeList.h"
 #include "platform/LengthFunctions.h"
 #include "platform/fonts/FontCache.h"
@@ -143,16 +144,16 @@
 }
 
 // Get the scrolling coordinator in a way that works inside CompositedLayerMapping's destructor.
-static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer* layer)
+static ScrollingCoordinator* scrollingCoordinatorFromLayer(RenderLayer& layer)
 {
-    Page* page = layer->renderer()->frame()->page();
+    Page* page = layer.renderer()->frame()->page();
     if (!page)
         return 0;
 
     return page->scrollingCoordinator();
 }
 
-CompositedLayerMapping::CompositedLayerMapping(RenderLayer* layer)
+CompositedLayerMapping::CompositedLayerMapping(RenderLayer& layer)
     : m_owningLayer(layer)
     , m_artificiallyInflatedBounds(false)
     , m_isMainFrameRenderViewLayer(false)
@@ -160,8 +161,10 @@
     , m_requiresOwnBackingStoreForAncestorReasons(true)
     , m_canCompositeFilters(false)
     , m_backgroundLayerPaintsFixedRootBackground(false)
+    , m_needToUpdateGeometry(false)
+    , m_needToUpdateGeometryOfAllDecendants(false)
 {
-    if (layer->isRootLayer() && renderer()->frame()->isMainFrame())
+    if (layer.isRootLayer() && renderer()->frame()->isMainFrame())
         m_isMainFrameRenderViewLayer = true;
 
     createPrimaryGraphicsLayer();
@@ -173,7 +176,7 @@
     for (size_t i = 0; i < m_squashedLayers.size(); ++i) {
         RenderLayer* oldSquashedLayer = m_squashedLayers[i].renderLayer;
         if (oldSquashedLayer->groupedMapping() == this) {
-            oldSquashedLayer->setGroupedMapping(0);
+            oldSquashedLayer->setGroupedMapping(0, true);
             oldSquashedLayer->setLostGroupedMapping(true);
         }
     }
@@ -205,7 +208,7 @@
 
 void CompositedLayerMapping::createPrimaryGraphicsLayer()
 {
-    m_graphicsLayer = createGraphicsLayer(m_owningLayer->compositingReasons());
+    m_graphicsLayer = createGraphicsLayer(m_owningLayer.compositingReasons());
 
 #if !OS(ANDROID)
     if (m_isMainFrameRenderViewLayer)
@@ -215,6 +218,7 @@
     updateOpacity(renderer()->style());
     updateTransform(renderer()->style());
     updateFilters(renderer()->style());
+    updateHasGpuRasterizationHint(renderer()->style());
 
     if (RuntimeEnabledFeatures::cssCompositingEnabled()) {
         updateLayerBlendMode(renderer()->style());
@@ -247,10 +251,10 @@
 
 void CompositedLayerMapping::updateTransform(const RenderStyle* style)
 {
-    // FIXME: This could use m_owningLayer->transform(), but that currently has transform-origin
+    // FIXME: This could use m_owningLayer.transform(), but that currently has transform-origin
     // baked into it, and we don't want that.
     TransformationMatrix t;
-    if (m_owningLayer->hasTransform()) {
+    if (m_owningLayer.hasTransform()) {
         style->applyTransform(t, toRenderBox(renderer())->pixelSnappedBorderBoxRect().size(), RenderStyle::ExcludeTransformOrigin);
         makeMatrixRenderable(t, compositor()->canRender3DTransforms());
     }
@@ -261,7 +265,7 @@
 void CompositedLayerMapping::updateFilters(const RenderStyle* style)
 {
     bool didCompositeFilters = m_canCompositeFilters;
-    m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer()->computeFilterOperations(style));
+    m_canCompositeFilters = m_graphicsLayer->setFilters(owningLayer().computeFilterOperations(style));
     if (didCompositeFilters != m_canCompositeFilters) {
         //
         // If filters used to be painted in software and are now painted in the compositor, we need to:
@@ -272,7 +276,7 @@
         // (1) Create a FilterEffectRenderer.
         // (2) Repaint the layer contents to apply a software filter because the compositor won't apply it.
         //
-        m_owningLayer->updateOrRemoveFilterEffectRenderer();
+        m_owningLayer.updateOrRemoveFilterEffectRenderer();
         setContentsNeedDisplay();
     }
 }
@@ -284,23 +288,28 @@
 
 void CompositedLayerMapping::updateIsRootForIsolatedGroup()
 {
-    bool isolate = m_owningLayer->shouldIsolateCompositedDescendants();
+    bool isolate = m_owningLayer.shouldIsolateCompositedDescendants();
 
     // non stacking context layers should never isolate
-    ASSERT(m_owningLayer->stackingNode()->isStackingContext() || !isolate);
+    ASSERT(m_owningLayer.stackingNode()->isStackingContext() || !isolate);
 
     m_graphicsLayer->setIsRootForIsolatedGroup(isolate);
 }
 
+void CompositedLayerMapping::updateHasGpuRasterizationHint(const RenderStyle* style)
+{
+    m_graphicsLayer->setHasGpuRasterizationHint(style->hasWillChangeGpuRasterizationHint());
+}
+
 void CompositedLayerMapping::updateContentsOpaque()
 {
     // For non-root layers, background is always painted by the primary graphics layer.
     ASSERT(m_isMainFrameRenderViewLayer || !m_backgroundLayer);
     if (m_backgroundLayer) {
         m_graphicsLayer->setContentsOpaque(false);
-        m_backgroundLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
+        m_backgroundLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
     } else {
-        m_graphicsLayer->setContentsOpaque(m_owningLayer->backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
+        m_graphicsLayer->setContentsOpaque(m_owningLayer.backgroundIsKnownToBeOpaqueInRect(compositedBounds()));
     }
 }
 
@@ -327,32 +336,33 @@
     if (layerForHorizontalScrollbar() || layerForVerticalScrollbar())
         return false;
 
-    if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(m_owningLayer))
+    if (layerOrAncestorIsTransformedOrUsingCompositedScrolling(&m_owningLayer))
         return false;
 
     // Scrolled composited layers are clipped by their ancestor clipping layer,
     // so don't clip these, either.
-    bool hasAncestorClippingLayer = compositor()->clippedByAncestor(m_owningLayer);
-    bool clippingAncestorIsScrollParent = m_owningLayer->renderer()->containingBlock()->enclosingLayer() == m_owningLayer->ancestorScrollingLayer();
-    if (hasAncestorClippingLayer && clippingAncestorIsScrollParent)
-        return false;
+    if (!compositor()->clippedByAncestor(&m_owningLayer))
+        return true;
 
-    return true;
+    if (m_owningLayer.renderer()->containingBlock()->enclosingLayer() != m_owningLayer.ancestorScrollingLayer())
+        return true;
+
+    return false;
 }
 
 void CompositedLayerMapping::updateCompositedBounds()
 {
     // We need to know if we draw content in order to update our bounds (this has an effect
     // on whether or not descendands will paint into our backing). Update this value now.
-    updateDrawsContent(isSimpleContainerCompositingLayer());
+    updateDrawsContent();
 
-    LayoutRect layerBounds = compositor()->calculateCompositedBounds(m_owningLayer, m_owningLayer);
+    LayoutRect layerBounds = compositor()->calculateCompositedBounds(&m_owningLayer, &m_owningLayer);
 
     // Clip to the size of the document or enclosing overflow-scroll layer.
     // If this or an ancestor is transformed, we can't currently compute the correct rect to intersect with.
     // We'd need RenderObject::convertContainerToLocalQuad(), which doesn't yet exist.
     if (shouldClipCompositedBounds()) {
-        RenderView* view = m_owningLayer->renderer()->view();
+        RenderView* view = m_owningLayer.renderer()->view();
         RenderLayer* rootLayer = view->layer();
 
         LayoutRect clippingBounds;
@@ -361,11 +371,11 @@
         else
             clippingBounds = view->unscaledDocumentRect();
 
-        if (m_owningLayer != rootLayer)
-            clippingBounds.intersect(m_owningLayer->clipper().backgroundClipRect(ClipRectsContext(rootLayer, AbsoluteClipRects)).rect());
+        if (&m_owningLayer != rootLayer)
+            clippingBounds.intersect(m_owningLayer.clipper().backgroundClipRect(ClipRectsContext(rootLayer, AbsoluteClipRects)).rect());
 
         LayoutPoint delta;
-        m_owningLayer->convertToLayerCoords(rootLayer, delta);
+        m_owningLayer.convertToLayerCoords(rootLayer, delta);
         clippingBounds.move(-delta.x(), -delta.y());
 
         layerBounds.intersect(clippingBounds);
@@ -401,7 +411,7 @@
 {
     // All other layers owned by this mapping will have the same compositing reason
     // for their lifetime, so they are initialized only when created.
-    m_graphicsLayer->setCompositingReasons(m_owningLayer->compositingReasons());
+    m_graphicsLayer->setCompositingReasons(m_owningLayer.compositingReasons());
 }
 
 void CompositedLayerMapping::updateAfterLayout(UpdateAfterLayoutFlags flags)
@@ -416,13 +426,13 @@
         // The solution is to update compositing children of this layer here,
         // via updateCompositingChildrenGeometry().
         updateCompositedBounds();
-        layerCompositor->updateCompositingDescendantGeometry(m_owningLayer->stackingNode(), m_owningLayer, flags & CompositingChildrenOnly);
+        layerCompositor->updateCompositingDescendantGeometry(m_owningLayer.stackingNode(), &m_owningLayer, flags & CompositingChildrenOnly);
 
         if (flags & IsUpdateRoot) {
-            updateGraphicsLayerGeometry();
+            updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate);
             layerCompositor->updateRootLayerPosition();
-            RenderLayerStackingNode* stackingContainer = m_owningLayer->stackingNode()->enclosingStackingContainerNode();
-            if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer->stackingNode()))
+            RenderLayerStackingNode* stackingContainer = m_owningLayer.stackingNode()->enclosingStackingContainerNode();
+            if (!layerCompositor->compositingLayersNeedRebuild() && stackingContainer && (stackingContainer != m_owningLayer.stackingNode()))
                 layerCompositor->updateCompositingDescendantGeometry(stackingContainer, stackingContainer->layer(), flags & CompositingChildrenOnly);
         }
     }
@@ -436,31 +446,31 @@
     RenderLayerCompositor* compositor = this->compositor();
     RenderObject* renderer = this->renderer();
 
-    m_owningLayer->updateDescendantDependentFlags();
-    m_owningLayer->stackingNode()->updateZOrderLists();
+    m_owningLayer.updateDescendantDependentFlags();
+    m_owningLayer.stackingNode()->updateZOrderLists();
 
     bool layerConfigChanged = false;
-    setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(m_owningLayer));
+    setBackgroundLayerPaintsFixedRootBackground(compositor->needsFixedRootBackgroundLayer(&m_owningLayer));
 
     // The background layer is currently only used for fixed root backgrounds.
     if (updateBackgroundLayer(m_backgroundLayerPaintsFixedRootBackground))
         layerConfigChanged = true;
 
-    if (updateForegroundLayer(compositor->needsContentsCompositingLayer(m_owningLayer)))
+    if (updateForegroundLayer(compositor->needsContentsCompositingLayer(&m_owningLayer)))
         layerConfigChanged = true;
 
-    bool needsDescendentsClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer);
+    bool needsDescendentsClippingLayer = compositor->clipsCompositingDescendants(&m_owningLayer);
 
     // Our scrolling layer will clip.
-    if (m_owningLayer->needsCompositedScrolling())
+    if (m_owningLayer.needsCompositedScrolling())
         needsDescendentsClippingLayer = false;
 
-    RenderLayer* scrollParent = m_owningLayer->scrollParent();
-    bool needsAncestorClip = compositor->clippedByAncestor(m_owningLayer);
+    RenderLayer* scrollParent = m_owningLayer.scrollParent();
+    bool needsAncestorClip = compositor->clippedByAncestor(&m_owningLayer);
     if (scrollParent) {
         // If our containing block is our ancestor scrolling layer, then we'll already be clipped
         // to it via our scroll parent and we don't need an ancestor clipping layer.
-        if (m_owningLayer->renderer()->containingBlock()->enclosingLayer() == m_owningLayer->ancestorCompositedScrollingLayer())
+        if (m_owningLayer.renderer()->containingBlock()->enclosingLayer() == m_owningLayer.ancestorCompositedScrollingLayer())
             needsAncestorClip = false;
     }
 
@@ -470,7 +480,7 @@
     if (updateOverflowControlsLayers(requiresHorizontalScrollbarLayer(), requiresVerticalScrollbarLayer(), requiresScrollCornerLayer()))
         layerConfigChanged = true;
 
-    if (updateScrollingLayers(m_owningLayer->needsCompositedScrolling()))
+    if (updateScrollingLayers(m_owningLayer.needsCompositedScrolling()))
         layerConfigChanged = true;
 
     bool hasPerspective = false;
@@ -481,7 +491,7 @@
         layerConfigChanged = true;
 
     updateScrollParent(scrollParent);
-    updateClipParent(m_owningLayer->clipParent());
+    updateClipParent(m_owningLayer.clipParent());
 
     if (updateSquashingLayers(!m_squashedLayers.isEmpty()))
         layerConfigChanged = true;
@@ -492,7 +502,7 @@
     if (updateMaskLayer(renderer->hasMask()))
         m_graphicsLayer->setMaskLayer(m_maskLayer.get());
 
-    bool hasChildClippingLayer = compositor->clipsCompositingDescendants(m_owningLayer) && (hasClippingLayer() || hasScrollingLayer());
+    bool hasChildClippingLayer = compositor->clipsCompositingDescendants(&m_owningLayer) && (hasClippingLayer() || hasScrollingLayer());
     bool needsChildClippingMask = (renderer->style()->clipPath() || renderer->style()->hasBorderRadius()) && (hasChildClippingLayer || isAcceleratedContents(renderer));
     if (updateClippingMaskLayers(needsChildClippingMask)) {
         if (hasClippingLayer())
@@ -503,16 +513,16 @@
             m_graphicsLayer->setContentsClippingMaskLayer(m_childClippingMaskLayer.get());
     }
 
-    if (m_owningLayer->reflectionInfo()) {
-        if (m_owningLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
-            GraphicsLayer* reflectionLayer = m_owningLayer->reflectionInfo()->reflectionLayer()->compositedLayerMapping()->mainGraphicsLayer();
+    if (m_owningLayer.reflectionInfo()) {
+        if (m_owningLayer.reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
+            GraphicsLayer* reflectionLayer = m_owningLayer.reflectionInfo()->reflectionLayer()->compositedLayerMapping()->mainGraphicsLayer();
             m_graphicsLayer->setReplicatedByLayer(reflectionLayer);
         }
     } else {
         m_graphicsLayer->setReplicatedByLayer(0);
     }
 
-    updateBackgroundColor(isSimpleContainerCompositingLayer());
+    updateBackgroundColor();
 
     if (isDirectlyCompositedImage())
         updateImageContents();
@@ -555,7 +565,7 @@
 {
     LayoutRect localRawCompositingBounds = compositedBounds();
     LayoutPoint rawDelta;
-    m_owningLayer->convertToLayerCoords(compositedAncestor, rawDelta);
+    m_owningLayer.convertToLayerCoords(compositedAncestor, rawDelta);
     delta = flooredIntPoint(rawDelta);
     m_subpixelAccumulation = toLayoutSize(rawDelta).fraction();
     RELEASE_ASSERT(m_subpixelAccumulation.width() < 1 && m_subpixelAccumulation.height() < 1);
@@ -593,9 +603,6 @@
     IntPoint squashLayerPosition = pixelSnappedIntRect(totalSquashBounds).location();
     squashLayerPosition.moveBy(delta);
 
-    // FIXME: this could be skipped for accelerated overflow scrolling, somehow.
-    m_squashingLayer->setNeedsDisplay();
-
     m_squashingLayer->setPosition(squashLayerPosition);
     m_squashingLayer->setSize(totalSquashBounds.size());
 
@@ -618,11 +625,17 @@
     }
 }
 
-void CompositedLayerMapping::updateGraphicsLayerGeometry()
+GraphicsLayerUpdater::UpdateType CompositedLayerMapping::updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType updateType)
 {
     // If we haven't built z-order lists yet, wait until later.
-    if (m_owningLayer->stackingNode()->isStackingContainer() && m_owningLayer->stackingNode()->zOrderListsDirty())
-        return;
+    if (m_owningLayer.stackingNode()->isStackingContainer() && m_owningLayer.stackingNode()->zOrderListsDirty())
+        return updateType;
+
+    if (!m_needToUpdateGeometry && updateType != GraphicsLayerUpdater::ForceUpdate)
+        return updateType;
+    m_needToUpdateGeometry = false;
+    if (m_needToUpdateGeometryOfAllDecendants)
+        updateType = GraphicsLayerUpdater::ForceUpdate;
 
     // Set transform property, if it is not animating. We have to do this here because the transform
     // is affected by the layer dimensions.
@@ -633,14 +646,12 @@
     if (!hasActiveAnimationsOnCompositor(*renderer(), CSSPropertyOpacity))
         updateOpacity(renderer()->style());
 
-    bool isSimpleContainer = isSimpleContainerCompositingLayer();
-
-    m_owningLayer->updateDescendantDependentFlags();
+    m_owningLayer.updateDescendantDependentFlags();
 
     // m_graphicsLayer is the corresponding GraphicsLayer for this RenderLayer and its non-compositing
     // descendants. So, the visibility flag for m_graphicsLayer should be true if there are any
     // non-compositing visible layers.
-    bool contentsVisible = m_owningLayer->hasVisibleContent() || hasVisibleNonCompositingDescendantLayers();
+    bool contentsVisible = m_owningLayer.hasVisibleContent() || hasVisibleNonCompositingDescendantLayers();
     if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer()->isVideo()) {
         HTMLMediaElement* mediaElement = toHTMLMediaElement(renderer()->node());
         if (mediaElement->isFullscreen())
@@ -651,7 +662,7 @@
     RenderStyle* style = renderer()->style();
     m_graphicsLayer->setBackfaceVisibility(style->backfaceVisibility() == BackfaceVisibilityVisible);
 
-    RenderLayer* compAncestor = m_owningLayer->ancestorCompositingLayer();
+    RenderLayer* compAncestor = m_owningLayer.ancestorCompositingLayer();
 
     // We compute everything relative to the enclosing compositing layer.
     IntRect ancestorCompositingBounds;
@@ -685,11 +696,8 @@
     }
 
     if (compAncestor && m_ancestorClippingLayer) {
-        // Call calculateRects to get the backgroundRect which is what is used to clip the contents of this
-        // layer. Note that we call it with temporaryClipRects = true because normally when computing clip rects
-        // for a compositing layer, rootLayer is the layer itself.
-        ClipRectsContext clipRectsContext(compAncestor, TemporaryClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
-        IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer->clipper().backgroundClipRect(clipRectsContext).rect());
+        ClipRectsContext clipRectsContext(compAncestor, CompositingClipRects, IgnoreOverlayScrollbarSize, IgnoreOverflowClip);
+        IntRect parentClipRect = pixelSnappedIntRect(m_owningLayer.clipper().backgroundClipRect(clipRectsContext).rect());
         ASSERT(parentClipRect != PaintInfo::infiniteRect());
         m_ancestorClippingLayer->setPosition(FloatPoint(parentClipRect.location() - graphicsLayerParentLocation));
         m_ancestorClippingLayer->setSize(parentClipRect.size());
@@ -735,7 +743,7 @@
         m_maskLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
     }
 
-    if (m_owningLayer->hasTransform()) {
+    if (m_owningLayer.hasTransform()) {
         const IntRect borderBox = toRenderBox(renderer())->pixelSnappedBorderBoxRect();
 
         // Get layout bounds in the coords of compAncestor to match relativeCompositingBounds.
@@ -753,6 +761,9 @@
         m_graphicsLayer->setAnchorPoint(FloatPoint3D(0.5f, 0.5f, 0));
     }
 
+    if (GraphicsLayer* childrenTransformLayer = layerForChildrenTransform())
+        childrenTransformLayer->setAnchorPoint(m_graphicsLayer->anchorPoint());
+
     if (m_foregroundLayer) {
         FloatSize foregroundSize = contentsSize;
         IntSize foregroundOffset = m_graphicsLayer->offsetFromRenderer();
@@ -785,11 +796,11 @@
         m_backgroundLayer->setOffsetFromRenderer(m_graphicsLayer->offsetFromRenderer());
     }
 
-    if (m_owningLayer->reflectionInfo() && m_owningLayer->reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
-        CompositedLayerMappingPtr reflectionCompositedLayerMapping = m_owningLayer->reflectionInfo()->reflectionLayer()->compositedLayerMapping();
-        reflectionCompositedLayerMapping->updateGraphicsLayerGeometry();
+    if (m_owningLayer.reflectionInfo() && m_owningLayer.reflectionInfo()->reflectionLayer()->hasCompositedLayerMapping()) {
+        CompositedLayerMappingPtr reflectionCompositedLayerMapping = m_owningLayer.reflectionInfo()->reflectionLayer()->compositedLayerMapping();
+        reflectionCompositedLayerMapping->updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate);
 
-        // The reflection layer has the bounds of m_owningLayer->reflectionLayer(),
+        // The reflection layer has the bounds of m_owningLayer.reflectionLayer(),
         // but the reflected layer is the bounds of this layer, so we need to position it appropriately.
         FloatRect layerBounds = compositedBounds();
         FloatRect reflectionLayerBounds = reflectionCompositedLayerMapping->compositedBounds();
@@ -800,11 +811,8 @@
         ASSERT(m_scrollingContentsLayer);
         RenderBox* renderBox = toRenderBox(renderer());
         IntRect clientBox = enclosingIntRect(renderBox->clientBoxRect());
-        // FIXME: We should make RenderBox::clientBoxRect consider scrollbar placement.
-        if (style->shouldPlaceBlockDirectionScrollbarOnLogicalLeft())
-            clientBox.move(renderBox->verticalScrollbarWidth(), 0);
 
-        IntSize adjustedScrollOffset = m_owningLayer->scrollableArea()->adjustedScrollOffset();
+        IntSize adjustedScrollOffset = m_owningLayer.scrollableArea()->adjustedScrollOffset();
         m_scrollingLayer->setPosition(FloatPoint(clientBox.location() - localCompositingBounds.location() + roundedIntSize(m_subpixelAccumulation)));
         m_scrollingLayer->setSize(clientBox.size());
 
@@ -825,7 +833,7 @@
 
         IntSize scrollingContentsOffset = toIntSize(clientBox.location() - adjustedScrollOffset);
         if (scrollingContentsOffset != m_scrollingContentsLayer->offsetFromRenderer() || scrollSize != m_scrollingContentsLayer->size()) {
-            bool coordinatorHandlesOffset = compositor()->scrollingLayerDidChange(m_owningLayer);
+            bool coordinatorHandlesOffset = compositor()->scrollingLayerDidChange(&m_owningLayer);
             m_scrollingContentsLayer->setPosition(coordinatorHandlesOffset ? FloatPoint() : FloatPoint(-adjustedScrollOffset));
         }
 
@@ -843,8 +851,8 @@
 
     updateSquashingLayerGeometry(delta);
 
-    if (m_owningLayer->scrollableArea() && m_owningLayer->scrollableArea()->scrollsOverflow())
-        m_owningLayer->scrollableArea()->positionOverflowControls();
+    if (m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->scrollsOverflow())
+        m_owningLayer.scrollableArea()->positionOverflowControls();
 
     // We can't make this call in RenderLayerCompositor::allocateOrClearCompositedLayerMapping
     // since it depends on whether compAncestor draws content, which gets updated later.
@@ -855,9 +863,10 @@
         updateIsRootForIsolatedGroup();
     }
 
-    updateContentsRect(isSimpleContainer);
-    updateBackgroundColor(isSimpleContainer);
-    updateDrawsContent(isSimpleContainer);
+    updateHasGpuRasterizationHint(renderer()->style());
+    updateContentsRect();
+    updateBackgroundColor();
+    updateDrawsContent();
     updateContentsOpaque();
     updateAfterWidgetResize();
     updateRenderingContext();
@@ -866,6 +875,8 @@
     registerScrollingLayers();
 
     updateCompositingReasons();
+
+    return updateType;
 }
 
 void CompositedLayerMapping::registerScrollingLayers()
@@ -875,14 +886,14 @@
     if (!scrollingCoordinator)
         return;
 
-    compositor()->updateViewportConstraintStatus(m_owningLayer);
+    compositor()->updateViewportConstraintStatus(&m_owningLayer);
 
-    scrollingCoordinator->updateLayerPositionConstraint(m_owningLayer);
+    scrollingCoordinator->updateLayerPositionConstraint(&m_owningLayer);
 
     // Page scale is applied as a transform on the root render view layer. Because the scroll
     // layer is further up in the hierarchy, we need to avoid marking the root render view
     // layer as a container.
-    bool isContainer = m_owningLayer->hasTransform() && !m_owningLayer->isRootLayer();
+    bool isContainer = m_owningLayer.hasTransform() && !m_owningLayer.isRootLayer();
     // FIXME: we should make certain that childForSuperLayers will never be the m_squashingContainmentLayer here
     scrollingCoordinator->setLayerIsContainerForFixedPositionLayers(localRootForOwningLayer(), isContainer);
 }
@@ -942,33 +953,27 @@
     }
 }
 
-void CompositedLayerMapping::updateContentsRect(bool isSimpleContainer)
+void CompositedLayerMapping::updateContentsRect()
 {
-    LayoutRect contentsRect;
-    if (isSimpleContainer && renderer()->hasBackground())
-        contentsRect = backgroundBox();
-    else
-        contentsRect = contentsBox();
-
-    m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsRect));
+    m_graphicsLayer->setContentsRect(pixelSnappedIntRect(contentsBox()));
 }
 
-void CompositedLayerMapping::updateDrawsContent(bool isSimpleContainer)
+void CompositedLayerMapping::updateDrawsContent()
 {
     if (m_scrollingLayer) {
         // We don't have to consider overflow controls, because we know that the scrollbars are drawn elsewhere.
         // m_graphicsLayer only needs backing store if the non-scrolling parts (background, outlines, borders, shadows etc) need to paint.
         // m_scrollingLayer never has backing store.
         // m_scrollingContentsLayer only needs backing store if the scrolled contents need to paint.
-        bool hasNonScrollingPaintedContent = m_owningLayer->hasVisibleContent() && m_owningLayer->hasBoxDecorationsOrBackground();
+        bool hasNonScrollingPaintedContent = m_owningLayer.hasVisibleContent() && m_owningLayer.hasBoxDecorationsOrBackground();
         m_graphicsLayer->setDrawsContent(hasNonScrollingPaintedContent);
 
-        bool hasScrollingPaintedContent = m_owningLayer->hasVisibleContent() && (renderer()->hasBackground() || paintsChildren());
+        bool hasScrollingPaintedContent = m_owningLayer.hasVisibleContent() && (renderer()->hasBackground() || paintsChildren());
         m_scrollingContentsLayer->setDrawsContent(hasScrollingPaintedContent);
         return;
     }
 
-    bool hasPaintedContent = containsPaintedContent(isSimpleContainer);
+    bool hasPaintedContent = containsPaintedContent();
     if (hasPaintedContent && isAcceleratedCanvas(renderer())) {
         CanvasRenderingContext* context = toHTMLCanvasElement(renderer()->node())->renderingContext();
         // Content layer may be null if context is lost.
@@ -994,9 +999,9 @@
 void CompositedLayerMapping::updateChildrenTransform()
 {
     if (GraphicsLayer* childTransformLayer = layerForChildrenTransform()) {
-        childTransformLayer->setTransform(owningLayer()->perspectiveTransform());
+        childTransformLayer->setTransform(owningLayer().perspectiveTransform());
         bool hasPerspective = false;
-        if (RenderStyle* style = m_owningLayer->renderer()->style())
+        if (RenderStyle* style = m_owningLayer.renderer()->style())
             hasPerspective = style->hasPerspective();
         if (hasPerspective)
             childTransformLayer->setShouldFlattenTransform(false);
@@ -1018,7 +1023,7 @@
 
     if (needsAncestorClip) {
         if (!m_ancestorClippingLayer) {
-            m_ancestorClippingLayer = createGraphicsLayer(CompositingReasonLayerForClip);
+            m_ancestorClippingLayer = createGraphicsLayer(CompositingReasonLayerForAncestorClip);
             m_ancestorClippingLayer->setMasksToBounds(true);
             layersChanged = true;
         }
@@ -1032,7 +1037,7 @@
         // We don't need a child containment layer if we're the main frame render view
         // layer. It's redundant as the frame clip above us will handle this clipping.
         if (!m_childContainmentLayer && !m_isMainFrameRenderViewLayer) {
-            m_childContainmentLayer = createGraphicsLayer(CompositingReasonLayerForClip);
+            m_childContainmentLayer = createGraphicsLayer(CompositingReasonLayerForDescendantClip);
             m_childContainmentLayer->setMasksToBounds(true);
             layersChanged = true;
         }
@@ -1051,7 +1056,7 @@
 
     if (needsChildTransformLayer) {
         if (!m_childTransformLayer) {
-            m_childTransformLayer = createGraphicsLayer(CompositingReasonPerspective);
+            m_childTransformLayer = createGraphicsLayer(CompositingReasonLayerForPerspective);
             m_childTransformLayer->setDrawsContent(false);
             m_childTransformLayer->setShouldFlattenTransform(false);
             layersChanged = true;
@@ -1071,25 +1076,25 @@
 }
 
 // Only a member function so it can call createGraphicsLayer.
-bool CompositedLayerMapping::toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>& layer, bool needsLayer)
+bool CompositedLayerMapping::toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>& layer, bool needsLayer, CompositingReasons reason)
 {
     if (needsLayer == !!layer)
         return false;
-    layer = needsLayer ? createGraphicsLayer(CompositingReasonLayerForScrollbar) : nullptr;
+    layer = needsLayer ? createGraphicsLayer(reason) : nullptr;
     return true;
 }
 
 bool CompositedLayerMapping::updateOverflowControlsLayers(bool needsHorizontalScrollbarLayer, bool needsVerticalScrollbarLayer, bool needsScrollCornerLayer)
 {
-    bool horizontalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForHorizontalScrollbar, needsHorizontalScrollbarLayer);
-    bool verticalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForVerticalScrollbar, needsVerticalScrollbarLayer);
-    bool scrollCornerLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForScrollCorner, needsScrollCornerLayer);
+    bool horizontalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForHorizontalScrollbar, needsHorizontalScrollbarLayer, CompositingReasonLayerForHorizontalScrollbar);
+    bool verticalScrollbarLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForVerticalScrollbar, needsVerticalScrollbarLayer, CompositingReasonLayerForVerticalScrollbar);
+    bool scrollCornerLayerChanged = toggleScrollbarLayerIfNeeded(m_layerForScrollCorner, needsScrollCornerLayer, CompositingReasonLayerForScrollCorner);
 
     if (ScrollingCoordinator* scrollingCoordinator = scrollingCoordinatorFromLayer(m_owningLayer)) {
         if (horizontalScrollbarLayerChanged)
-            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer->scrollableArea(), HorizontalScrollbar);
+            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer.scrollableArea(), HorizontalScrollbar);
         if (verticalScrollbarLayerChanged)
-            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer->scrollableArea(), VerticalScrollbar);
+            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_owningLayer.scrollableArea(), VerticalScrollbar);
     }
 
     return horizontalScrollbarLayerChanged || verticalScrollbarLayerChanged || scrollCornerLayerChanged;
@@ -1099,7 +1104,7 @@
 {
     IntSize offsetFromRenderer = m_graphicsLayer->offsetFromRenderer() - roundedIntSize(m_subpixelAccumulation);
     if (GraphicsLayer* layer = layerForHorizontalScrollbar()) {
-        Scrollbar* hBar = m_owningLayer->scrollableArea()->horizontalScrollbar();
+        Scrollbar* hBar = m_owningLayer.scrollableArea()->horizontalScrollbar();
         if (hBar) {
             layer->setPosition(hBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
             layer->setSize(hBar->frameRect().size());
@@ -1110,7 +1115,7 @@
     }
 
     if (GraphicsLayer* layer = layerForVerticalScrollbar()) {
-        Scrollbar* vBar = m_owningLayer->scrollableArea()->verticalScrollbar();
+        Scrollbar* vBar = m_owningLayer.scrollableArea()->verticalScrollbar();
         if (vBar) {
             layer->setPosition(vBar->frameRect().location() - offsetFromRoot - offsetFromRenderer);
             layer->setSize(vBar->frameRect().size());
@@ -1121,7 +1126,7 @@
     }
 
     if (GraphicsLayer* layer = layerForScrollCorner()) {
-        const LayoutRect& scrollCornerAndResizer = m_owningLayer->scrollableArea()->scrollCornerAndResizerRect();
+        const LayoutRect& scrollCornerAndResizer = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect();
         layer->setPosition(scrollCornerAndResizer.location() - offsetFromRenderer);
         layer->setSize(scrollCornerAndResizer.size());
         layer->setDrawsContent(!scrollCornerAndResizer.isEmpty());
@@ -1219,7 +1224,7 @@
     // the context id other than the fact that they group a number of layers together for the
     // sake of 3d sorting. So instead we will ask the compositor to vend us an arbitrary, but
     // consistent id.
-    if (RenderLayer* root = m_owningLayer->renderingContextRoot()) {
+    if (RenderLayer* root = m_owningLayer.renderingContextRoot()) {
         if (Node* node = root->renderer()->node())
             id = static_cast<int>(WTF::PtrHash<Node*>::hash(node));
     }
@@ -1238,7 +1243,7 @@
 {
     // All CLM-managed layers that could affect a descendant layer should update their
     // should-flatten-transform value (the other layers' transforms don't matter here).
-    UpdateShouldFlattenTransformFunctor functor = { m_owningLayer->shouldFlattenTransform() };
+    UpdateShouldFlattenTransformFunctor functor = { m_owningLayer.shouldFlattenTransform() };
     ApplyToGraphicsLayersMode mode = ApplyToCoreLayers;
     ApplyToGraphicsLayers(this, functor, mode);
 }
@@ -1291,7 +1296,7 @@
         }
     }
 
-    if (layerChanged && !m_owningLayer->renderer()->documentBeingDestroyed())
+    if (layerChanged && !m_owningLayer.renderer()->documentBeingDestroyed())
         compositor()->rootFixedBackgroundsChanged();
 
     return layerChanged;
@@ -1323,7 +1328,7 @@
     bool layerChanged = false;
     if (needsChildClippingMaskLayer) {
         if (!m_childClippingMaskLayer) {
-            m_childClippingMaskLayer = createGraphicsLayer(CompositingReasonLayerForMask);
+            m_childClippingMaskLayer = createGraphicsLayer(CompositingReasonLayerForClippingMask);
             m_childClippingMaskLayer->setDrawsContent(true);
             m_childClippingMaskLayer->setPaintingPhase(GraphicsLayerPaintChildClippingMask);
             layerChanged = true;
@@ -1343,12 +1348,12 @@
     if (needsScrollingLayers) {
         if (!m_scrollingLayer) {
             // Outer layer which corresponds with the scroll view.
-            m_scrollingLayer = createGraphicsLayer(CompositingReasonLayerForClip);
+            m_scrollingLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContainer);
             m_scrollingLayer->setDrawsContent(false);
             m_scrollingLayer->setMasksToBounds(true);
 
             // Inner layer which renders the content that scrolls.
-            m_scrollingContentsLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContainer);
+            m_scrollingContentsLayer = createGraphicsLayer(CompositingReasonLayerForScrollingContents);
             m_scrollingContentsLayer->setDrawsContent(true);
             GraphicsLayerPaintingPhase paintPhase = GraphicsLayerPaintOverflowContents | GraphicsLayerPaintCompositedScroll;
             if (!m_foregroundLayer)
@@ -1358,14 +1363,14 @@
 
             layerChanged = true;
             if (scrollingCoordinator)
-                scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer->scrollableArea());
+                scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
         }
     } else if (m_scrollingLayer) {
         m_scrollingLayer = nullptr;
         m_scrollingContentsLayer = nullptr;
         layerChanged = true;
         if (scrollingCoordinator)
-            scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer->scrollableArea());
+            scrollingCoordinator->scrollableAreaScrollLayerDidChange(m_owningLayer.scrollableArea());
     }
 
     if (layerChanged) {
@@ -1373,7 +1378,7 @@
         m_graphicsLayer->setPaintingPhase(paintingPhaseForPrimaryLayer());
         m_graphicsLayer->setNeedsDisplay();
         if (renderer()->view())
-            compositor()->scrollingLayerDidChange(m_owningLayer);
+            compositor()->scrollingLayerDidChange(&m_owningLayer);
     }
 
     return layerChanged;
@@ -1417,11 +1422,11 @@
         if (!m_squashingLayer) {
             ASSERT(!m_squashingContainmentLayer);
 
-            m_squashingLayer = createGraphicsLayer(CompositingReasonOverlap);
+            m_squashingLayer = createGraphicsLayer(CompositingReasonLayerForSquashingContents);
             m_squashingLayer->setDrawsContent(true);
 
             // FIXME: containment layer needs a new CompositingReason, CompositingReasonOverlap is not appropriate.
-            m_squashingContainmentLayer = createGraphicsLayer(CompositingReasonOverlap);
+            m_squashingContainmentLayer = createGraphicsLayer(CompositingReasonLayerForSquashingContainer);
             layersChanged = true;
         }
 
@@ -1459,7 +1464,7 @@
         phase |= GraphicsLayerPaintCompositedScroll;
     }
 
-    if (m_owningLayer->compositingReasons() & CompositingReasonOverflowScrollingParent)
+    if (m_owningLayer.compositingReasons() & CompositingReasonOverflowScrollingParent)
         phase |= GraphicsLayerPaintCompositedScroll;
 
     return static_cast<GraphicsLayerPaintingPhase>(phase);
@@ -1469,7 +1474,7 @@
 {
     float finalOpacity = rendererOpacity;
 
-    for (RenderLayer* curr = m_owningLayer->parent(); curr; curr = curr->parent()) {
+    for (RenderLayer* curr = m_owningLayer.parent(); curr; curr = curr->parent()) {
         // We only care about parents that are stacking contexts.
         // Recall that opacity creates stacking context.
         if (!curr->stackingNode()->isStackingContainer())
@@ -1502,50 +1507,14 @@
     return backgroundRenderer->resolveColor(CSSPropertyBackgroundColor);
 }
 
-void CompositedLayerMapping::updateBackgroundColor(bool isSimpleContainer)
+void CompositedLayerMapping::updateBackgroundColor()
 {
-    Color backgroundColor = rendererBackgroundColor();
-    if (isSimpleContainer) {
-        m_graphicsLayer->setContentsToSolidColor(backgroundColor);
-        m_graphicsLayer->setBackgroundColor(Color::transparent);
-    } else {
-        m_graphicsLayer->setContentsToSolidColor(Color::transparent);
-        m_graphicsLayer->setBackgroundColor(backgroundColor);
-    }
-}
-
-static bool supportsDirectBoxDecorationsComposition(const RenderObject* renderer)
-{
-    if (renderer->hasClip())
-        return false;
-
-    if (hasBoxDecorationsOrBackgroundImage(renderer->style()))
-        return false;
-
-    // FIXME: we should be able to allow backgroundComposite; However since this is not a common use case it has been deferred for now.
-    if (renderer->style()->backgroundComposite() != CompositeSourceOver)
-        return false;
-
-    if (renderer->style()->backgroundClip() == TextFillBox)
-        return false;
-
-    return true;
-}
-
-bool CompositedLayerMapping::paintsBoxDecorations() const
-{
-    if (!m_owningLayer->hasVisibleBoxDecorations())
-        return false;
-
-    if (!supportsDirectBoxDecorationsComposition(renderer()))
-        return true;
-
-    return false;
+    m_graphicsLayer->setBackgroundColor(rendererBackgroundColor());
 }
 
 bool CompositedLayerMapping::paintsChildren() const
 {
-    if (m_owningLayer->hasVisibleContent() && m_owningLayer->hasNonEmptyChildRenderers())
+    if (m_owningLayer.hasVisibleContent() && m_owningLayer.hasNonEmptyChildRenderers())
         return true;
 
     if (hasVisibleNonCompositingDescendantLayers())
@@ -1559,54 +1528,11 @@
     return renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
 }
 
-// A "simple container layer" is a RenderLayer which has no visible content to render.
-// It may have no children, or all its children may be themselves composited.
-// This is a useful optimization, because it allows us to avoid allocating backing store.
-bool CompositedLayerMapping::isSimpleContainerCompositingLayer() const
-{
-    RenderObject* renderObject = renderer();
-    if (renderObject->hasMask()) // masks require special treatment
-        return false;
-
-    if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
-        return false;
-
-    if (paintsBoxDecorations() || paintsChildren())
-        return false;
-
-    if (renderObject->isRenderRegion())
-        return false;
-
-    if (renderObject->node() && renderObject->node()->isDocumentNode()) {
-        // Look to see if the root object has a non-simple background
-        RenderObject* rootObject = renderObject->document().documentElement() ? renderObject->document().documentElement()->renderer() : 0;
-        if (!rootObject)
-            return false;
-
-        RenderStyle* style = rootObject->style();
-
-        // Reject anything that has a border, a border-radius or outline,
-        // or is not a simple background (no background, or solid color).
-        if (hasBoxDecorationsOrBackgroundImage(style))
-            return false;
-
-        // Now look at the body's renderer.
-        HTMLElement* body = renderObject->document().body();
-        RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
-        if (!bodyObject)
-            return false;
-
-        style = bodyObject->style();
-
-        if (hasBoxDecorationsOrBackgroundImage(style))
-            return false;
-    }
-
-    return true;
-}
-
 static bool hasVisibleNonCompositingDescendant(RenderLayer* parent)
 {
+    if (!parent->hasVisibleDescendant())
+        return false;
+
     // FIXME: We shouldn't be called with a stale z-order lists. See bug 85512.
     parent->stackingNode()->updateLayerListsIfNeeded();
 
@@ -1614,22 +1540,12 @@
     LayerListMutationDetector mutationChecker(parent->stackingNode());
 #endif
 
-    RenderLayerStackingNodeIterator normalFlowIterator(*parent->stackingNode(), NormalFlowChildren);
+    RenderLayerStackingNodeIterator normalFlowIterator(*parent->stackingNode(), AllChildren);
     while (RenderLayerStackingNode* curNode = normalFlowIterator.next()) {
         RenderLayer* curLayer = curNode->layer();
-        if (!curLayer->hasCompositedLayerMapping()
-            && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
-            return true;
-    }
-
-    if (!parent->hasVisibleDescendant())
-        return false;
-
-    RenderLayerStackingNodeIterator zOrderIterator(*parent->stackingNode(), NegativeZOrderChildren | PositiveZOrderChildren);
-    while (RenderLayerStackingNode* curNode = zOrderIterator.next()) {
-        RenderLayer* curLayer = curNode->layer();
-        if (!curLayer->hasCompositedLayerMapping()
-            && (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer)))
+        if (curLayer->hasCompositedLayerMapping())
+            continue;
+        if (curLayer->hasVisibleContent() || hasVisibleNonCompositingDescendant(curLayer))
             return true;
     }
 
@@ -1641,23 +1557,52 @@
 // don't paint into their own backing, and instead paint into this backing.
 bool CompositedLayerMapping::hasVisibleNonCompositingDescendantLayers() const
 {
-    return hasVisibleNonCompositingDescendant(m_owningLayer);
+    return hasVisibleNonCompositingDescendant(&m_owningLayer);
 }
 
-bool CompositedLayerMapping::containsPaintedContent(bool isSimpleContainer) const
+bool CompositedLayerMapping::containsPaintedContent() const
 {
-    if (isSimpleContainer || paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer->isReflection())
+    if (paintsIntoCompositedAncestor() || m_artificiallyInflatedBounds || m_owningLayer.isReflection())
         return false;
 
     if (isDirectlyCompositedImage())
         return false;
 
+    RenderObject* renderObject = renderer();
     // FIXME: we could optimize cases where the image, video or canvas is known to fill the border box entirely,
     // and set background color on the layer in that case, instead of allocating backing store and painting.
-    if (renderer()->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
-        return m_owningLayer->hasBoxDecorationsOrBackground();
+    if (renderObject->isVideo() && toRenderVideo(renderer())->shouldDisplayVideo())
+        return m_owningLayer.hasBoxDecorationsOrBackground();
 
-    return true;
+    if (m_owningLayer.hasVisibleBoxDecorations())
+        return true;
+
+    if (renderObject->hasMask()) // masks require special treatment
+        return true;
+
+    if (renderObject->isReplaced() && !isCompositedPlugin(renderObject))
+        return true;
+
+    if (renderObject->isRenderRegion())
+        return true;
+
+    if (renderObject->node() && renderObject->node()->isDocumentNode()) {
+        // Look to see if the root object has a non-simple background
+        RenderObject* rootObject = renderObject->document().documentElement() ? renderObject->document().documentElement()->renderer() : 0;
+        // Reject anything that has a border, a border-radius or outline,
+        // or is not a simple background (no background, or solid color).
+        if (rootObject && hasBoxDecorationsOrBackgroundImage(rootObject->style()))
+            return true;
+
+        // Now look at the body's renderer.
+        HTMLElement* body = renderObject->document().body();
+        RenderObject* bodyObject = (body && body->hasLocalName(bodyTag)) ? body->renderer() : 0;
+        if (bodyObject && hasBoxDecorationsOrBackgroundImage(bodyObject->style()))
+            return true;
+    }
+
+    // FIXME: it's O(n^2). A better solution is needed.
+    return paintsChildren();
 }
 
 // An image can be directly compositing if it's the sole content of the layer, and has no box decorations
@@ -1666,7 +1611,7 @@
 {
     RenderObject* renderObject = renderer();
 
-    if (!renderObject->isImage() || m_owningLayer->hasBoxDecorationsOrBackground() || renderObject->hasClip())
+    if (!renderObject->isImage() || m_owningLayer.hasBoxDecorationsOrBackground() || renderObject->hasClip())
         return false;
 
     RenderImage* imageRenderer = toRenderImage(renderObject);
@@ -1688,12 +1633,6 @@
         return;
     }
 
-    if ((changeType == MaskImageChanged) && m_maskLayer) {
-        // The composited layer bounds relies on box->maskClipRect(), which changes
-        // when the mask image becomes available.
-        updateAfterLayout(CompositingChildrenOnly | IsUpdateRoot);
-    }
-
     if ((changeType == CanvasChanged || changeType == CanvasPixelsChanged) && isAcceleratedCanvas(renderer())) {
         m_graphicsLayer->setContentsNeedsDisplay();
         return;
@@ -1719,8 +1658,7 @@
 
     // This is a no-op if the layer doesn't have an inner layer for the image.
     m_graphicsLayer->setContentsToImage(image);
-    bool isSimpleContainer = false;
-    updateDrawsContent(isSimpleContainer);
+    updateDrawsContent();
 
     // Image animation is "lazy", in that it automatically stops unless someone is drawing
     // the image. So we have to kick the animation each time; this has the downside that the
@@ -1767,13 +1705,6 @@
     return contentsBox;
 }
 
-IntRect CompositedLayerMapping::backgroundBox() const
-{
-    LayoutRect backgroundBox = backgroundRect(renderer());
-    backgroundBox.move(contentOffsetInCompostingLayer());
-    return pixelSnappedIntRect(backgroundBox);
-}
-
 GraphicsLayer* CompositedLayerMapping::parentForSublayers() const
 {
     if (m_scrollingContentsLayer)
@@ -1831,11 +1762,11 @@
 {
     bool previousRequiresOwnBackingStoreForIntrinsicReasons = m_requiresOwnBackingStoreForIntrinsicReasons;
     bool previousPaintsIntoCompositedAncestor = paintsIntoCompositedAncestor();
-    RenderObject* renderer = m_owningLayer->renderer();
-    m_requiresOwnBackingStoreForIntrinsicReasons = m_owningLayer->isRootLayer()
-        || (m_owningLayer->compositingReasons() & CompositingReasonComboReasonsThatRequireOwnBacking)
-        || m_owningLayer->transform()
-        || m_owningLayer->clipsCompositingDescendantsWithBorderRadius() // FIXME: Revisit this if the paintsIntoCompositedAncestor state is removed.
+    RenderObject* renderer = m_owningLayer.renderer();
+    m_requiresOwnBackingStoreForIntrinsicReasons = m_owningLayer.isRootLayer()
+        || (m_owningLayer.compositingReasons() & CompositingReasonComboReasonsThatRequireOwnBacking)
+        || m_owningLayer.transform()
+        || m_owningLayer.clipsCompositingDescendantsWithBorderRadius() // FIXME: Revisit this if the paintsIntoCompositedAncestor state is removed.
         || renderer->isTransparent()
         || renderer->hasMask()
         || renderer->hasReflection()
@@ -1850,10 +1781,10 @@
 {
     // The answer to paintsIntoCompositedAncestor() affects cached clip rects, so when
     // it changes we have to clear clip rects on descendants.
-    m_owningLayer->clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
-    m_owningLayer->repainter().computeRepaintRectsIncludingDescendants();
+    m_owningLayer.clipper().clearClipRectsIncludingDescendants(PaintingClipRects);
+    m_owningLayer.repainter().computeRepaintRectsIncludingDescendants();
 
-    compositor()->repaintInCompositedAncestor(m_owningLayer, compositedBounds());
+    compositor()->repaintInCompositedAncestor(&m_owningLayer, compositedBounds());
 }
 
 void CompositedLayerMapping::setBlendMode(blink::WebBlendMode blendMode)
@@ -1866,6 +1797,28 @@
     }
 }
 
+void CompositedLayerMapping::setNeedsGeometryUpdate()
+{
+    m_needToUpdateGeometryOfAllDecendants = true;
+
+    for (RenderLayer* current = &m_owningLayer; current; current = current->ancestorCompositingLayer()) {
+        // FIXME: We should be able to return early from this function once we
+        // find a CompositedLayerMapping that has m_needToUpdateGeometry set.
+        // However, we can't do that until we remove the incremental compositing
+        // updates because they can clear m_needToUpdateGeometry without walking
+        // the whole tree.
+        ASSERT(current->hasCompositedLayerMapping());
+        CompositedLayerMappingPtr mapping = current->compositedLayerMapping();
+        mapping->m_needToUpdateGeometry = true;
+    }
+}
+
+void CompositedLayerMapping::clearNeedsGeometryUpdate()
+{
+    m_needToUpdateGeometry = false;
+    m_needToUpdateGeometryOfAllDecendants = false;
+}
+
 struct SetContentsNeedsDisplayFunctor {
     void operator() (GraphicsLayer* layer) const
     {
@@ -2002,7 +1955,7 @@
     if (Page* page = renderer()->frame()->page())
         page->setIsPainting(true);
 #endif
-    InspectorInstrumentation::willPaint(m_owningLayer->renderer(), graphicsLayer);
+    InspectorInstrumentation::willPaint(m_owningLayer.renderer(), graphicsLayer);
 
     if (graphicsLayer == m_graphicsLayer.get()
         || graphicsLayer == m_foregroundLayer.get()
@@ -2012,7 +1965,7 @@
         || graphicsLayer == m_scrollingContentsLayer.get()) {
 
         GraphicsLayerPaintInfo paintInfo;
-        paintInfo.renderLayer = m_owningLayer;
+        paintInfo.renderLayer = &m_owningLayer;
         paintInfo.compositedBounds = compositedBounds();
         paintInfo.offsetFromRenderer = graphicsLayer->offsetFromRenderer();
         paintInfo.paintingPhase = paintingPhase;
@@ -2025,20 +1978,20 @@
         for (size_t i = 0; i < m_squashedLayers.size(); ++i)
             doPaintTask(m_squashedLayers[i], &context, clip);
     } else if (graphicsLayer == layerForHorizontalScrollbar()) {
-        paintScrollbar(m_owningLayer->scrollableArea()->horizontalScrollbar(), context, clip);
+        paintScrollbar(m_owningLayer.scrollableArea()->horizontalScrollbar(), context, clip);
     } else if (graphicsLayer == layerForVerticalScrollbar()) {
-        paintScrollbar(m_owningLayer->scrollableArea()->verticalScrollbar(), context, clip);
+        paintScrollbar(m_owningLayer.scrollableArea()->verticalScrollbar(), context, clip);
     } else if (graphicsLayer == layerForScrollCorner()) {
-        const IntRect& scrollCornerAndResizer = m_owningLayer->scrollableArea()->scrollCornerAndResizerRect();
+        const IntRect& scrollCornerAndResizer = m_owningLayer.scrollableArea()->scrollCornerAndResizerRect();
         context.save();
         context.translate(-scrollCornerAndResizer.x(), -scrollCornerAndResizer.y());
         IntRect transformedClip = clip;
         transformedClip.moveBy(scrollCornerAndResizer.location());
-        m_owningLayer->scrollableArea()->paintScrollCorner(&context, IntPoint(), transformedClip);
-        m_owningLayer->scrollableArea()->paintResizer(&context, IntPoint(), transformedClip);
+        m_owningLayer.scrollableArea()->paintScrollCorner(&context, IntPoint(), transformedClip);
+        m_owningLayer.scrollableArea()->paintResizer(&context, IntPoint(), transformedClip);
         context.restore();
     }
-    InspectorInstrumentation::didPaint(m_owningLayer->renderer(), graphicsLayer, &context, clip);
+    InspectorInstrumentation::didPaint(m_owningLayer.renderer(), graphicsLayer, &context, clip);
 #ifndef NDEBUG
     if (Page* page = renderer()->frame()->page())
         page->setIsPainting(false);
@@ -2071,7 +2024,7 @@
 }
 #endif
 
-void CompositedLayerMapping::notifyAnimationStarted(const GraphicsLayer*, double wallClockTime, double monotonicTime)
+void CompositedLayerMapping::notifyAnimationStarted(const GraphicsLayer*, double monotonicTime)
 {
     renderer()->node()->document().cssPendingAnimations().notifyCompositorAnimationStarted(monotonicTime);
 }
@@ -2140,22 +2093,11 @@
         m_squashedLayers.remove(nextSquashedLayerIndex, m_squashedLayers.size() - nextSquashedLayerIndex);
 }
 
-CompositingLayerType CompositedLayerMapping::compositingLayerType() const
-{
-    if (m_graphicsLayer->hasContentsLayer())
-        return MediaCompositingLayer;
-
-    if (m_graphicsLayer->drawsContent())
-        return NormalCompositingLayer;
-
-    return ContainerCompositingLayer;
-}
-
 String CompositedLayerMapping::debugName(const GraphicsLayer* graphicsLayer)
 {
     String name;
     if (graphicsLayer == m_graphicsLayer.get()) {
-        name = m_owningLayer->debugName();
+        name = m_owningLayer.debugName();
     } else if (graphicsLayer == m_squashingContainmentLayer.get()) {
         name = "Squashing Containment Layer";
     } else if (graphicsLayer == m_squashingLayer.get()) {
@@ -2163,9 +2105,9 @@
     } else if (graphicsLayer == m_ancestorClippingLayer.get()) {
         name = "Ancestor Clipping Layer";
     } else if (graphicsLayer == m_foregroundLayer.get()) {
-        name = m_owningLayer->debugName() + " (foreground) Layer";
+        name = m_owningLayer.debugName() + " (foreground) Layer";
     } else if (graphicsLayer == m_backgroundLayer.get()) {
-        name = m_owningLayer->debugName() + " (background) Layer";
+        name = m_owningLayer.debugName() + " (background) Layer";
     } else if (graphicsLayer == m_childContainmentLayer.get()) {
         name = "Child Containment Layer";
     } else if (graphicsLayer == m_childTransformLayer.get()) {
diff --git a/Source/core/rendering/CompositedLayerMapping.h b/Source/core/rendering/compositing/CompositedLayerMapping.h
similarity index 90%
rename from Source/core/rendering/CompositedLayerMapping.h
rename to Source/core/rendering/compositing/CompositedLayerMapping.h
index a1f39e8..a22b28b 100644
--- a/Source/core/rendering/CompositedLayerMapping.h
+++ b/Source/core/rendering/compositing/CompositedLayerMapping.h
@@ -27,6 +27,7 @@
 #define CompositedLayerMapping_h
 
 #include "core/rendering/RenderLayer.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
 #include "platform/geometry/FloatPoint.h"
 #include "platform/geometry/FloatPoint3D.h"
 #include "platform/graphics/GraphicsLayer.h"
@@ -38,13 +39,6 @@
 class KeyframeList;
 class RenderLayerCompositor;
 
-enum CompositingLayerType {
-    NormalCompositingLayer, // non-tiled layer with backing store
-    MediaCompositingLayer, // layer that contains an image, video, webGL or plugin
-    ContainerCompositingLayer // layer with no backing store
-};
-
-
 // A GraphicsLayerPaintInfo contains all the info needed to paint a partial subtree of RenderLayers into a GraphicsLayer.
 struct GraphicsLayerPaintInfo {
     RenderLayer* renderLayer;
@@ -85,10 +79,10 @@
 class CompositedLayerMapping FINAL : public GraphicsLayerClient {
     WTF_MAKE_NONCOPYABLE(CompositedLayerMapping); WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit CompositedLayerMapping(RenderLayer*);
+    explicit CompositedLayerMapping(RenderLayer&);
     virtual ~CompositedLayerMapping();
 
-    RenderLayer* owningLayer() const { return m_owningLayer; }
+    RenderLayer& owningLayer() const { return m_owningLayer; }
 
     enum UpdateAfterLayoutFlag {
         CompositingChildrenOnly = 1 << 0,
@@ -101,7 +95,7 @@
     // Returns true if layer configuration changed.
     bool updateGraphicsLayerConfiguration();
     // Update graphics layer position and bounds.
-    void updateGraphicsLayerGeometry(); // make private
+    GraphicsLayerUpdater::UpdateType updateGraphicsLayerGeometry(GraphicsLayerUpdater::UpdateType);
     // Update whether layer needs blending.
     void updateContentsOpaque();
 
@@ -180,7 +174,7 @@
     void updateShouldFlattenTransform();
 
     // GraphicsLayerClient interface
-    virtual void notifyAnimationStarted(const GraphicsLayer*, double wallClockTime, double monotonicTime) OVERRIDE;
+    virtual void notifyAnimationStarted(const GraphicsLayer*, double monotonicTime) OVERRIDE;
     virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect& clip) OVERRIDE;
     virtual bool isTrackingRepaints() const OVERRIDE;
 
@@ -191,10 +185,6 @@
 #endif
 
     LayoutRect contentsBox() const;
-    IntRect backgroundBox() const;
-
-    // For informative purposes only.
-    CompositingLayerType compositingLayerType() const;
 
     GraphicsLayer* layerForHorizontalScrollbar() const { return m_layerForHorizontalScrollbar.get(); }
     GraphicsLayer* layerForVerticalScrollbar() const { return m_layerForVerticalScrollbar.get(); }
@@ -205,6 +195,9 @@
 
     void setBlendMode(blink::WebBlendMode);
 
+    void setNeedsGeometryUpdate();
+    void clearNeedsGeometryUpdate();
+
     virtual String debugName(const GraphicsLayer*) OVERRIDE;
 
     LayoutSize subpixelAccumulation() const { return m_subpixelAccumulation; }
@@ -213,10 +206,10 @@
     void destroyGraphicsLayers();
 
     PassOwnPtr<GraphicsLayer> createGraphicsLayer(CompositingReasons);
-    bool toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>&, bool needsLayer);
+    bool toggleScrollbarLayerIfNeeded(OwnPtr<GraphicsLayer>&, bool needsLayer, CompositingReasons);
 
-    RenderLayerModelObject* renderer() const { return m_owningLayer->renderer(); }
-    RenderLayerCompositor* compositor() const { return m_owningLayer->compositor(); }
+    RenderLayerModelObject* renderer() const { return m_owningLayer.renderer(); }
+    RenderLayerCompositor* compositor() const { return m_owningLayer.compositor(); }
 
     void updateInternalHierarchy();
     bool updateClippingLayers(bool needsAncestorClip, bool needsDescendantClip);
@@ -226,14 +219,14 @@
     bool updateBackgroundLayer(bool needsBackgroundLayer);
     bool updateMaskLayer(bool needsMaskLayer);
     bool updateClippingMaskLayers(bool needsChildClippingMaskLayer);
-    bool requiresHorizontalScrollbarLayer() const { return m_owningLayer->scrollableArea() && m_owningLayer->scrollableArea()->horizontalScrollbar(); }
-    bool requiresVerticalScrollbarLayer() const { return m_owningLayer->scrollableArea() && m_owningLayer->scrollableArea()->verticalScrollbar(); }
-    bool requiresScrollCornerLayer() const { return m_owningLayer->scrollableArea() && !m_owningLayer->scrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
+    bool requiresHorizontalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->horizontalScrollbar(); }
+    bool requiresVerticalScrollbarLayer() const { return m_owningLayer.scrollableArea() && m_owningLayer.scrollableArea()->verticalScrollbar(); }
+    bool requiresScrollCornerLayer() const { return m_owningLayer.scrollableArea() && !m_owningLayer.scrollableArea()->scrollCornerAndResizerRect().isEmpty(); }
     bool updateScrollingLayers(bool scrollingLayers);
     void updateScrollParent(RenderLayer*);
     void updateClipParent(RenderLayer*);
     bool updateSquashingLayers(bool needsSquashingLayers);
-    void updateDrawsContent(bool isSimpleContainer);
+    void updateDrawsContent();
     void updateChildrenTransform();
     void registerScrollingLayers();
 
@@ -255,25 +248,23 @@
     void updateTransform(const RenderStyle*);
     void updateLayerBlendMode(const RenderStyle*);
     void updateIsRootForIsolatedGroup();
+    void updateHasGpuRasterizationHint(const RenderStyle*);
     // Return the opacity value that this layer should use for compositing.
     float compositingOpacity(float rendererOpacity) const;
 
     bool isMainFrameRenderViewLayer() const;
 
-    bool paintsBoxDecorations() const;
     bool paintsChildren() const;
 
-    // Returns true if this compositing layer has no visible content.
-    bool isSimpleContainerCompositingLayer() const;
     // Returns true if this layer has content that needs to be rendered by painting into the backing store.
-    bool containsPaintedContent(bool isSimpleContainer) const;
+    bool containsPaintedContent() const;
     // Returns true if the RenderLayer just contains an image that we can composite directly.
     bool isDirectlyCompositedImage() const;
     void updateImageContents();
 
     Color rendererBackgroundColor() const;
-    void updateBackgroundColor(bool isSimpleContainer);
-    void updateContentsRect(bool isSimpleContainer);
+    void updateBackgroundColor();
+    void updateContentsRect();
 
     void updateCompositingReasons();
 
@@ -285,7 +276,7 @@
 
     void doPaintTask(GraphicsLayerPaintInfo&, GraphicsContext*, const IntRect& clip);
 
-    RenderLayer* m_owningLayer;
+    RenderLayer& m_owningLayer;
 
     // The hierarchy of layers that is maintained by the CompositedLayerMapping looks like this:
     //
@@ -363,12 +354,14 @@
     LayoutRect m_compositedBounds;
     LayoutSize m_subpixelAccumulation; // The accumulated subpixel offset of the compositedBounds compared to absolute coordinates.
 
-    bool m_artificiallyInflatedBounds; // bounds had to be made non-zero to make transform-origin work
-    bool m_isMainFrameRenderViewLayer;
-    bool m_requiresOwnBackingStoreForIntrinsicReasons;
-    bool m_requiresOwnBackingStoreForAncestorReasons;
-    bool m_canCompositeFilters;
-    bool m_backgroundLayerPaintsFixedRootBackground;
+    bool m_artificiallyInflatedBounds : 1; // bounds had to be made non-zero to make transform-origin work
+    bool m_isMainFrameRenderViewLayer : 1;
+    bool m_requiresOwnBackingStoreForIntrinsicReasons : 1;
+    bool m_requiresOwnBackingStoreForAncestorReasons : 1;
+    bool m_canCompositeFilters : 1;
+    bool m_backgroundLayerPaintsFixedRootBackground : 1;
+    bool m_needToUpdateGeometry : 1;
+    bool m_needToUpdateGeometryOfAllDecendants : 1;
 };
 
 } // namespace WebCore
diff --git a/Source/core/rendering/CompositedLayerMappingPtr.h b/Source/core/rendering/compositing/CompositedLayerMappingPtr.h
similarity index 100%
rename from Source/core/rendering/CompositedLayerMappingPtr.h
rename to Source/core/rendering/compositing/CompositedLayerMappingPtr.h
diff --git a/Source/core/rendering/compositing/CompositingReasonFinder.cpp b/Source/core/rendering/compositing/CompositingReasonFinder.cpp
new file mode 100644
index 0000000..a65ae90
--- /dev/null
+++ b/Source/core/rendering/compositing/CompositingReasonFinder.cpp
@@ -0,0 +1,401 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/rendering/compositing/CompositingReasonFinder.h"
+
+#include "CSSPropertyNames.h"
+#include "HTMLNames.h"
+#include "core/animation/ActiveAnimations.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLCanvasElement.h"
+#include "core/html/HTMLIFrameElement.h"
+#include "core/html/HTMLMediaElement.h"
+#include "core/html/canvas/CanvasRenderingContext.h"
+#include "core/page/Chrome.h"
+#include "core/page/Page.h"
+#include "core/rendering/RenderApplet.h"
+#include "core/rendering/RenderEmbeddedObject.h"
+#include "core/rendering/RenderFullScreen.h"
+#include "core/rendering/RenderGeometryMap.h"
+#include "core/rendering/RenderIFrame.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderLayerStackingNode.h"
+#include "core/rendering/RenderLayerStackingNodeIterator.h"
+#include "core/rendering/RenderReplica.h"
+#include "core/rendering/RenderVideo.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+
+namespace WebCore {
+
+CompositingReasonFinder::CompositingReasonFinder(RenderView& renderView)
+    : m_renderView(renderView)
+    , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
+{
+}
+
+void CompositingReasonFinder::updateTriggers()
+{
+    m_compositingTriggers = m_renderView.document().page()->chrome().client().allowedCompositingTriggers();
+}
+
+bool CompositingReasonFinder::has3DTransformTrigger() const
+{
+    return m_compositingTriggers & ChromeClient::ThreeDTransformTrigger;
+}
+
+bool CompositingReasonFinder::hasAnimationTrigger() const
+{
+    return m_compositingTriggers & ChromeClient::AnimationTrigger;
+}
+
+bool CompositingReasonFinder::isMainFrame() const
+{
+    // FIXME: LocalFrame::isMainFrame() is probably better.
+    return !m_renderView.document().ownerElement();
+}
+
+CompositingReasons CompositingReasonFinder::directReasons(const RenderLayer* layer, bool* needToRecomputeCompositingRequirements) const
+{
+    RenderObject* renderer = layer->renderer();
+    CompositingReasons directReasons = CompositingReasonNone;
+
+    if (requiresCompositingForTransform(renderer))
+        directReasons |= CompositingReason3DTransform;
+
+    // Only zero or one of the following conditions will be true for a given RenderLayer.
+    if (requiresCompositingForVideo(renderer))
+        directReasons |= CompositingReasonVideo;
+    else if (requiresCompositingForCanvas(renderer))
+        directReasons |= CompositingReasonCanvas;
+    else if (requiresCompositingForPlugin(renderer, needToRecomputeCompositingRequirements))
+        directReasons |= CompositingReasonPlugin;
+    else if (requiresCompositingForFrame(renderer, needToRecomputeCompositingRequirements))
+        directReasons |= CompositingReasonIFrame;
+
+    if (requiresCompositingForBackfaceVisibilityHidden(renderer))
+        directReasons |= CompositingReasonBackfaceVisibilityHidden;
+
+    if (requiresCompositingForAnimation(renderer))
+        directReasons |= CompositingReasonActiveAnimation;
+
+    if (requiresCompositingForTransition(renderer))
+        directReasons |= CompositingReasonTransitionProperty;
+
+    if (requiresCompositingForFilters(renderer))
+        directReasons |= CompositingReasonFilters;
+
+    if (requiresCompositingForPosition(renderer, layer, 0, needToRecomputeCompositingRequirements))
+        directReasons |= renderer->style()->position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
+
+    if (requiresCompositingForOverflowScrolling(layer))
+        directReasons |= CompositingReasonOverflowScrollingTouch;
+
+    if (requiresCompositingForOverflowScrollingParent(layer))
+        directReasons |= CompositingReasonOverflowScrollingParent;
+
+    if (requiresCompositingForOutOfFlowClipping(layer))
+        directReasons |= CompositingReasonOutOfFlowClipping;
+
+    if (requiresCompositingForWillChange(renderer))
+        directReasons |= CompositingReasonWillChange;
+
+    return directReasons;
+}
+
+bool CompositingReasonFinder::requiresCompositingForScrollableFrame() const
+{
+    // Need this done first to determine overflow.
+    ASSERT(!m_renderView.needsLayout());
+    if (isMainFrame())
+        return false;
+
+    if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger))
+        return false;
+
+    FrameView* frameView = m_renderView.frameView();
+    return frameView->isScrollable();
+}
+
+bool CompositingReasonFinder::requiresCompositingForTransform(RenderObject* renderer) const
+{
+    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
+        return false;
+
+    RenderStyle* style = renderer->style();
+    // Note that we ask the renderer if it has a transform, because the style may have transforms,
+    // but the renderer may be an inline that doesn't suppport them.
+    return renderer->hasTransform() && style->transform().has3DOperation();
+}
+
+bool CompositingReasonFinder::requiresCompositingForVideo(RenderObject* renderer) const
+{
+    if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer->isVideo()) {
+        HTMLMediaElement* media = toHTMLMediaElement(renderer->node());
+        if (media->isFullscreen())
+            return true;
+    }
+
+    if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
+        return false;
+
+    if (renderer->isVideo()) {
+        RenderVideo* video = toRenderVideo(renderer);
+        return video->shouldDisplayVideo() && video->supportsAcceleratedRendering();
+    }
+    return false;
+}
+
+bool CompositingReasonFinder::requiresCompositingForCanvas(RenderObject* renderer) const
+{
+    if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
+        return false;
+
+    if (renderer->isCanvas()) {
+        HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
+        return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
+    }
+    return false;
+}
+
+bool CompositingReasonFinder::requiresCompositingForPlugin(RenderObject* renderer, bool* needToRecomputeCompositingRequirements) const
+{
+    if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
+        return false;
+
+    if (!renderer->isEmbeddedObject() || !toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing())
+        return false;
+
+    // FIXME: this seems bogus. If we don't know the layout position/size of the plugin yet, would't that be handled elsewhere?
+    *needToRecomputeCompositingRequirements = true;
+
+    RenderWidget* pluginRenderer = toRenderWidget(renderer);
+    // If we can't reliably know the size of the plugin yet, don't change compositing state.
+    if (pluginRenderer->needsLayout())
+        return pluginRenderer->hasLayer() && pluginRenderer->layer()->hasCompositedLayerMapping();
+
+    // Don't go into compositing mode if height or width are zero, or size is 1x1.
+    IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
+    return contentBox.height() * contentBox.width() > 1;
+}
+
+bool CompositingReasonFinder::requiresCompositingForFrame(RenderObject* renderer, bool* needToRecomputeCompositingRequirements) const
+{
+    if (!renderer->isRenderPart())
+        return false;
+
+    RenderPart* frameRenderer = toRenderPart(renderer);
+
+    if (!frameRenderer->requiresAcceleratedCompositing())
+        return false;
+
+    if (frameRenderer->node() && frameRenderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame()->remotePlatformLayer())
+        return true;
+
+    // FIXME: this seems bogus. If we don't know the layout position/size of the frame yet, wouldn't that be handled elsehwere?
+    *needToRecomputeCompositingRequirements = true;
+
+    RenderLayerCompositor* innerCompositor = RenderLayerCompositor::frameContentsCompositor(frameRenderer);
+    if (!innerCompositor)
+        return false;
+
+    // If we can't reliably know the size of the iframe yet, don't change compositing state.
+    if (renderer->needsLayout())
+        return frameRenderer->hasLayer() && frameRenderer->layer()->hasCompositedLayerMapping();
+
+    // Don't go into compositing mode if height or width are zero.
+    IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
+    return contentBox.height() * contentBox.width() > 0;
+}
+
+bool CompositingReasonFinder::requiresCompositingForBackfaceVisibilityHidden(RenderObject* renderer) const
+{
+    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
+        return false;
+
+    return renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden;
+}
+
+bool CompositingReasonFinder::requiresCompositingForAnimation(RenderObject* renderer) const
+{
+    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
+        return false;
+
+    return shouldCompositeForActiveAnimations(*renderer);
+}
+
+bool CompositingReasonFinder::requiresCompositingForTransition(RenderObject* renderer) const
+{
+    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
+        return false;
+
+    if (Settings* settings = m_renderView.document().settings()) {
+        if (!settings->acceleratedCompositingForTransitionEnabled())
+            return false;
+    }
+
+    return renderer->style()->transitionForProperty(CSSPropertyOpacity)
+        || renderer->style()->transitionForProperty(CSSPropertyWebkitFilter)
+        || renderer->style()->transitionForProperty(CSSPropertyWebkitTransform);
+}
+
+bool CompositingReasonFinder::requiresCompositingForFilters(RenderObject* renderer) const
+{
+    if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
+        return false;
+
+    return renderer->hasFilter();
+}
+
+bool CompositingReasonFinder::requiresCompositingForOverflowScrollingParent(const RenderLayer* layer) const
+{
+    return !!layer->scrollParent();
+}
+
+bool CompositingReasonFinder::requiresCompositingForOutOfFlowClipping(const RenderLayer* layer) const
+{
+    return m_renderView.compositorDrivenAcceleratedScrollingEnabled() && layer->isUnclippedDescendant();
+}
+
+bool CompositingReasonFinder::requiresCompositingForWillChange(const RenderObject* renderer) const
+{
+    if (renderer->style()->hasWillChangeCompositingHint())
+        return true;
+
+    if (Settings* settings = m_renderView.document().settings()) {
+        if (!settings->acceleratedCompositingForGpuRasterizationHintEnabled())
+            return false;
+    }
+
+    return renderer->style()->hasWillChangeGpuRasterizationHint();
+}
+
+bool CompositingReasonFinder::isViewportConstrainedFixedOrStickyLayer(const RenderLayer* layer)
+{
+    if (layer->renderer()->isStickyPositioned())
+        return !layer->enclosingOverflowClipLayer(ExcludeSelf);
+
+    if (layer->renderer()->style()->position() != FixedPosition)
+        return false;
+
+    for (const RenderLayerStackingNode* stackingContainer = layer->stackingNode(); stackingContainer;
+        stackingContainer = stackingContainer->ancestorStackingContainerNode()) {
+        if (stackingContainer->layer()->compositingState() != NotComposited
+            && stackingContainer->layer()->renderer()->style()->position() == FixedPosition)
+            return false;
+    }
+
+    return true;
+}
+
+bool CompositingReasonFinder::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason, bool* needToRecomputeCompositingRequirements) const
+{
+    // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
+    // opacity, transform) can get their own composited layer. A stacking context is required otherwise
+    // z-index and clipping will be broken.
+    if (!renderer->isPositioned())
+        return false;
+
+    EPosition position = renderer->style()->position();
+    bool isFixed = renderer->isOutOfFlowPositioned() && position == FixedPosition;
+    if (isFixed && !layer->stackingNode()->isStackingContainer())
+        return false;
+
+    bool isSticky = renderer->isInFlowPositioned() && position == StickyPosition;
+    if (!isFixed && !isSticky)
+        return false;
+
+    // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
+    if (Settings* settings = m_renderView.document().settings()) {
+        if (!settings->acceleratedCompositingForFixedPositionEnabled())
+            return false;
+    }
+
+    if (isSticky)
+        return isViewportConstrainedFixedOrStickyLayer(layer);
+
+    RenderObject* container = renderer->container();
+    // If the renderer is not hooked up yet then we have to wait until it is.
+    if (!container) {
+        *needToRecomputeCompositingRequirements = true;
+        return false;
+    }
+
+    // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
+    // They will stay fixed wrt the container rather than the enclosing frame.
+    if (container != &m_renderView) {
+        if (viewportConstrainedNotCompositedReason)
+            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
+        return false;
+    }
+
+    // If the fixed-position element does not have any scrollable ancestor between it and
+    // its container, then we do not need to spend compositor resources for it. Start by
+    // assuming we can opt-out (i.e. no scrollable ancestor), and refine the answer below.
+    bool hasScrollableAncestor = false;
+
+    // The FrameView has the scrollbars associated with the top level viewport, so we have to
+    // check the FrameView in addition to the hierarchy of ancestors.
+    FrameView* frameView = m_renderView.frameView();
+    if (frameView && frameView->isScrollable())
+        hasScrollableAncestor = true;
+
+    RenderLayer* ancestor = layer->parent();
+    while (ancestor && !hasScrollableAncestor) {
+        if (frameView->containsScrollableArea(ancestor->scrollableArea()))
+            hasScrollableAncestor = true;
+        if (ancestor->renderer() == &m_renderView)
+            break;
+        ancestor = ancestor->parent();
+    }
+
+    if (!hasScrollableAncestor) {
+        if (viewportConstrainedNotCompositedReason)
+            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForUnscrollableAncestors;
+        return false;
+    }
+
+    // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
+    if (m_renderView.document().lifecycle().state() < DocumentLifecycle::LayoutClean) {
+        *needToRecomputeCompositingRequirements = true;
+        return layer->hasCompositedLayerMapping();
+    }
+
+    bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant();
+    if (!paintsContent) {
+        if (viewportConstrainedNotCompositedReason)
+            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
+        return false;
+    }
+
+    // Fixed position elements that are invisible in the current view don't get their own layer.
+    if (FrameView* frameView = m_renderView.frameView()) {
+        LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect();
+        LayoutRect layerBounds = layer->calculateLayerBounds(layer->compositor()->rootRenderLayer(), 0,
+            RenderLayer::DefaultCalculateLayerBoundsFlags
+            | RenderLayer::ExcludeHiddenDescendants
+            | RenderLayer::DontConstrainForMask
+            | RenderLayer::IncludeCompositedDescendants
+            | RenderLayer::PretendLayerHasOwnBacking);
+        if (!viewBounds.intersects(enclosingIntRect(layerBounds))) {
+            if (viewportConstrainedNotCompositedReason) {
+                *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
+                *needToRecomputeCompositingRequirements = true;
+            }
+            return false;
+        }
+    }
+
+    return true;
+}
+
+bool CompositingReasonFinder::requiresCompositingForOverflowScrolling(const RenderLayer* layer) const
+{
+    return layer->needsCompositedScrolling();
+}
+
+}
diff --git a/Source/core/rendering/compositing/CompositingReasonFinder.h b/Source/core/rendering/compositing/CompositingReasonFinder.h
new file mode 100644
index 0000000..b4fdece
--- /dev/null
+++ b/Source/core/rendering/compositing/CompositingReasonFinder.h
@@ -0,0 +1,58 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CompositingReasonFinder_h
+#define CompositingReasonFinder_h
+
+#include "core/page/ChromeClient.h"
+#include "core/rendering/RenderLayer.h"
+#include "platform/graphics/CompositingReasons.h"
+
+namespace WebCore {
+
+class RenderLayer;
+class RenderObject;
+class RenderView;
+
+class CompositingReasonFinder {
+public:
+    explicit CompositingReasonFinder(RenderView&);
+
+    CompositingReasons directReasons(const RenderLayer*, bool* needToRecomputeCompositingRequirements) const;
+
+    void updateTriggers();
+    bool hasTriggers() const { return m_compositingTriggers; }
+
+    bool has3DTransformTrigger() const;
+    bool hasAnimationTrigger() const;
+
+    bool requiresCompositingForScrollableFrame() const;
+    bool requiresCompositingForPosition(RenderObject*, const RenderLayer*, RenderLayer::ViewportConstrainedNotCompositedReason*, bool* needToRecomputeCompositingRequirements) const;
+
+    static bool isViewportConstrainedFixedOrStickyLayer(const RenderLayer*);
+
+private:
+    bool isMainFrame() const;
+
+    bool requiresCompositingForAnimation(RenderObject*) const;
+    bool requiresCompositingForTransition(RenderObject*) const;
+    bool requiresCompositingForTransform(RenderObject*) const;
+    bool requiresCompositingForVideo(RenderObject*) const;
+    bool requiresCompositingForCanvas(RenderObject*) const;
+    bool requiresCompositingForPlugin(RenderObject*, bool* needToRecomputeCompositingRequirements) const;
+    bool requiresCompositingForFrame(RenderObject*, bool* needToRecomputeCompositingRequirements) const;
+    bool requiresCompositingForBackfaceVisibilityHidden(RenderObject*) const;
+    bool requiresCompositingForFilters(RenderObject*) const;
+    bool requiresCompositingForOverflowScrollingParent(const RenderLayer*) const;
+    bool requiresCompositingForOutOfFlowClipping(const RenderLayer*) const;
+    bool requiresCompositingForOverflowScrolling(const RenderLayer*) const;
+    bool requiresCompositingForWillChange(const RenderObject*) const;
+
+    RenderView& m_renderView;
+    ChromeClient::CompositingTriggerFlags m_compositingTriggers;
+};
+
+} // namespace WebCore
+
+#endif // CompositingReasonFinder_h
diff --git a/Source/core/rendering/CompositingState.h b/Source/core/rendering/compositing/CompositingState.h
similarity index 100%
rename from Source/core/rendering/CompositingState.h
rename to Source/core/rendering/compositing/CompositingState.h
diff --git a/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp b/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp
new file mode 100644
index 0000000..db56c33
--- /dev/null
+++ b/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp
@@ -0,0 +1,189 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
+
+#include "core/html/HTMLMediaElement.h"
+#include "core/rendering/RenderLayer.h"
+#include "core/rendering/RenderLayerReflectionInfo.h"
+#include "core/rendering/RenderPart.h"
+#include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
+#include "public/platform/Platform.h"
+
+namespace WebCore {
+
+bool shouldAppendLayer(const RenderLayer& layer)
+{
+    if (!RuntimeEnabledFeatures::overlayFullscreenVideoEnabled())
+        return true;
+    Node* node = layer.renderer()->node();
+    if (node && isHTMLMediaElement(*node) && toHTMLMediaElement(node)->isFullscreen())
+        return false;
+    return true;
+}
+
+GraphicsLayerUpdater::GraphicsLayerUpdater(RenderView& renderView)
+    : m_renderView(renderView)
+    , m_pixelsWithoutPromotingAllTransitions(0.0)
+    , m_pixelsAddedByPromotingAllTransitions(0.0)
+{
+}
+
+GraphicsLayerUpdater::~GraphicsLayerUpdater()
+{
+}
+
+void GraphicsLayerUpdater::rebuildTree(RenderLayer& layer, UpdateType updateType, GraphicsLayerVector& childLayersOfEnclosingLayer, int depth)
+{
+    // Make the layer compositing if necessary, and set up clipping and content layers.
+    // Note that we can only do work here that is independent of whether the descendant layers
+    // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
+
+    layer.stackingNode()->updateLayerListsIfNeeded();
+    layer.update3dRenderingContext();
+
+    const bool hasCompositedLayerMapping = layer.hasCompositedLayerMapping();
+    CompositedLayerMappingPtr currentCompositedLayerMapping = layer.compositedLayerMapping();
+
+    updateType = update(layer, updateType);
+
+    // Grab some stats for histograms.
+    if (hasCompositedLayerMapping) {
+        m_pixelsWithoutPromotingAllTransitions += layer.size().height() * layer.size().width();
+    } else {
+        if ((layer.renderer()->style()->transitionForProperty(CSSPropertyOpacity) ||
+             layer.renderer()->style()->transitionForProperty(CSSPropertyWebkitTransform)) &&
+            m_renderView.viewRect().intersects(layer.absoluteBoundingBox()))
+            m_pixelsAddedByPromotingAllTransitions += layer.size().height() * layer.size().width();
+    }
+
+    // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
+    // Otherwise children continue to append to the child list of the enclosing layer.
+    GraphicsLayerVector layerChildren;
+    GraphicsLayerVector& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer;
+
+#if !ASSERT_DISABLED
+    LayerListMutationDetector mutationChecker(layer.stackingNode());
+#endif
+
+    if (layer.stackingNode()->isStackingContainer()) {
+        RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NegativeZOrderChildren);
+        while (RenderLayerStackingNode* curNode = iterator.next())
+            rebuildTree(*curNode->layer(), updateType, childList, depth + 1);
+
+        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
+        if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
+            childList.append(currentCompositedLayerMapping->foregroundLayer());
+    }
+
+    RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
+    while (RenderLayerStackingNode* curNode = iterator.next())
+        rebuildTree(*curNode->layer(), updateType, childList, depth + 1);
+
+    if (hasCompositedLayerMapping) {
+        bool parented = false;
+        if (layer.renderer()->isRenderPart())
+            parented = RenderLayerCompositor::parentFrameContentLayers(toRenderPart(layer.renderer()));
+
+        if (!parented)
+            currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren);
+
+        // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
+        // Otherwise, the overflow control layers are normal children.
+        if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) {
+            if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) {
+                overflowControlLayer->removeFromParent();
+                currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
+            }
+
+            if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) {
+                overflowControlLayer->removeFromParent();
+                currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
+            }
+
+            if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) {
+                overflowControlLayer->removeFromParent();
+                currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
+            }
+        }
+
+        if (shouldAppendLayer(layer))
+            childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers());
+    }
+
+    if (!depth) {
+        int percentageIncreaseInPixels = static_cast<int>(m_pixelsAddedByPromotingAllTransitions / m_pixelsWithoutPromotingAllTransitions * 100);
+        blink::Platform::current()->histogramCustomCounts("Renderer.PixelIncreaseFromTransitions", percentageIncreaseInPixels, 0, 1000, 50);
+    }
+}
+
+// This just updates layer geometry without changing the hierarchy.
+void GraphicsLayerUpdater::updateRecursive(RenderLayer& layer, UpdateType updateType)
+{
+    updateType = update(layer, updateType);
+
+#if !ASSERT_DISABLED
+    LayerListMutationDetector mutationChecker(layer.stackingNode());
+#endif
+
+    RenderLayerStackingNodeIterator iterator(*layer.stackingNode(), AllChildren);
+    while (RenderLayerStackingNode* curNode = iterator.next())
+        updateRecursive(*curNode->layer(), updateType);
+}
+
+GraphicsLayerUpdater::UpdateType GraphicsLayerUpdater::update(RenderLayer& layer, UpdateType updateType)
+{
+    if (!layer.hasCompositedLayerMapping())
+        return updateType;
+
+    CompositedLayerMappingPtr mapping = layer.compositedLayerMapping();
+
+    // Note carefully: here we assume that the compositing state of all descendants have been updated already,
+    // so it is legitimate to compute and cache the composited bounds for this layer.
+    mapping->updateCompositedBounds();
+
+    if (RenderLayerReflectionInfo* reflection = layer.reflectionInfo()) {
+        if (reflection->reflectionLayer()->hasCompositedLayerMapping())
+            reflection->reflectionLayer()->compositedLayerMapping()->updateCompositedBounds();
+    }
+
+    mapping->updateGraphicsLayerConfiguration();
+    updateType = mapping->updateGraphicsLayerGeometry(updateType);
+    mapping->clearNeedsGeometryUpdate();
+
+    if (!layer.parent())
+        layer.compositor()->updateRootLayerPosition();
+
+    if (mapping->hasUnpositionedOverflowControlsLayers())
+        layer.scrollableArea()->positionOverflowControls();
+
+    return updateType;
+}
+
+} // namespace WebCore
diff --git a/Source/core/rendering/compositing/GraphicsLayerUpdater.h b/Source/core/rendering/compositing/GraphicsLayerUpdater.h
new file mode 100644
index 0000000..c374c03
--- /dev/null
+++ b/Source/core/rendering/compositing/GraphicsLayerUpdater.h
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2009, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef GraphicsLayerUpdater_h
+#define GraphicsLayerUpdater_h
+
+#include "platform/graphics/GraphicsLayer.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class RenderLayer;
+class RenderPart;
+class RenderView;
+
+class GraphicsLayerUpdater {
+public:
+    explicit GraphicsLayerUpdater(RenderView&);
+    ~GraphicsLayerUpdater();
+
+    enum UpdateType {
+        DoNotForceUpdate,
+        ForceUpdate,
+    };
+
+    void updateRecursive(RenderLayer&, UpdateType);
+    void rebuildTree(RenderLayer&, UpdateType, GraphicsLayerVector& childLayersOfEnclosingLayer, int depth);
+
+private:
+    UpdateType update(RenderLayer&, UpdateType);
+
+    RenderView& m_renderView;
+
+    // Used for gathering UMA data about the effect on memory usage of promoting all layers
+    // that have a webkit-transition on opacity or transform and intersect the viewport.
+    double m_pixelsWithoutPromotingAllTransitions;
+    double m_pixelsAddedByPromotingAllTransitions;
+};
+
+} // namespace WebCore
+
+#endif // GraphicsLayerUpdater_h
diff --git a/Source/core/rendering/RenderLayerCompositor.cpp b/Source/core/rendering/compositing/RenderLayerCompositor.cpp
similarity index 71%
rename from Source/core/rendering/RenderLayerCompositor.cpp
rename to Source/core/rendering/compositing/RenderLayerCompositor.cpp
index 137d720..ba9ca58 100644
--- a/Source/core/rendering/RenderLayerCompositor.cpp
+++ b/Source/core/rendering/compositing/RenderLayerCompositor.cpp
@@ -25,7 +25,7 @@
 
 #include "config.h"
 
-#include "core/rendering/RenderLayerCompositor.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 
 #include "CSSPropertyNames.h"
 #include "HTMLNames.h"
@@ -35,8 +35,8 @@
 #include "core/dom/FullscreenElementStack.h"
 #include "core/dom/NodeList.h"
 #include "core/frame/DeprecatedScheduleStyleRecalcDuringCompositingUpdate.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/html/HTMLCanvasElement.h"
 #include "core/html/HTMLIFrameElement.h"
@@ -47,7 +47,6 @@
 #include "core/page/Page.h"
 #include "core/page/scrolling/ScrollingConstraints.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/RenderApplet.h"
 #include "core/rendering/RenderEmbeddedObject.h"
@@ -59,6 +58,8 @@
 #include "core/rendering/RenderReplica.h"
 #include "core/rendering/RenderVideo.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
 #include "platform/OverscrollTheme.h"
 #include "platform/TraceEvent.h"
 #include "platform/geometry/TransformState.h"
@@ -99,11 +100,11 @@
 
     void unite(const OverlapMapContainer& otherContainer)
     {
-        m_layerRects.append(otherContainer.m_layerRects);
+        m_layerRects.appendVector(otherContainer.m_layerRects);
         m_boundingBox.unite(otherContainer.m_boundingBox);
     }
 private:
-    Vector<IntRect> m_layerRects;
+    Vector<IntRect, 64> m_layerRects;
     IntRect m_boundingBox;
 };
 
@@ -119,19 +120,13 @@
         beginNewOverlapTestingContext();
     }
 
-    void add(const RenderLayer* layer, const IntRect& bounds)
+    void add(const IntRect& bounds)
     {
         // Layers do not contribute to overlap immediately--instead, they will
         // contribute to overlap as soon as they have been recursively processed
         // and popped off the stack.
         ASSERT(m_overlapStack.size() >= 2);
         m_overlapStack[m_overlapStack.size() - 2].add(bounds);
-        m_layers.add(layer);
-    }
-
-    bool contains(const RenderLayer* layer)
-    {
-        return m_layers.contains(layer);
     }
 
     bool overlapsLayers(const IntRect& bounds) const
@@ -139,11 +134,6 @@
         return m_overlapStack.last().overlapsLayers(bounds);
     }
 
-    bool isEmpty()
-    {
-        return m_layers.isEmpty();
-    }
-
     void beginNewOverlapTestingContext()
     {
         // This effectively creates a new "clean slate" for overlap state.
@@ -169,7 +159,6 @@
 
 private:
     Vector<OverlapMapContainer> m_overlapStack;
-    HashSet<const RenderLayer*> m_layers;
     RenderGeometryMap m_geometryMap;
 };
 
@@ -208,18 +197,17 @@
 #endif
 };
 
-
-RenderLayerCompositor::RenderLayerCompositor(RenderView* renderView)
+RenderLayerCompositor::RenderLayerCompositor(RenderView& renderView)
     : m_renderView(renderView)
+    , m_compositingReasonFinder(renderView)
     , m_hasAcceleratedCompositing(true)
-    , m_compositingTriggers(static_cast<ChromeClient::CompositingTriggerFlags>(ChromeClient::AllTriggers))
     , m_showRepaintCounter(false)
     , m_needsToRecomputeCompositingRequirements(false)
     , m_needsToUpdateLayerTreeGeometry(false)
+    , m_pendingUpdateType(GraphicsLayerUpdater::DoNotForceUpdate)
     , m_compositing(false)
     , m_compositingLayersNeedRebuild(false)
     , m_forceCompositingMode(false)
-    , m_inPostLayoutUpdate(false)
     , m_needsUpdateCompositingRequirementsState(false)
     , m_isTrackingRepaints(false)
     , m_rootLayerAttachment(RootLayerUnattached)
@@ -250,15 +238,15 @@
     bool showRepaintCounter = false;
     bool forceCompositingMode = false;
 
-    if (Settings* settings = m_renderView->document().settings()) {
+    if (Settings* settings = m_renderView.document().settings()) {
         hasAcceleratedCompositing = settings->acceleratedCompositingEnabled();
 
         // We allow the chrome to override the settings, in case the page is rendered
         // on a chrome that doesn't allow accelerated compositing.
         if (hasAcceleratedCompositing) {
-            if (Page* page = this->page()) {
-                m_compositingTriggers = page->chrome().client().allowedCompositingTriggers();
-                hasAcceleratedCompositing = m_compositingTriggers;
+            if (page()) {
+                m_compositingReasonFinder.updateTriggers();
+                hasAcceleratedCompositing = m_compositingReasonFinder.hasTriggers();
             }
         }
 
@@ -266,7 +254,7 @@
         forceCompositingMode = settings->forceCompositingMode() && hasAcceleratedCompositing;
 
         if (forceCompositingMode && !isMainFrame())
-            forceCompositingMode = requiresCompositingForScrollableFrame();
+            forceCompositingMode = m_compositingReasonFinder.requiresCompositingForScrollableFrame();
     }
 
     if (hasAcceleratedCompositing != m_hasAcceleratedCompositing || showRepaintCounter != m_showRepaintCounter || forceCompositingMode != m_forceCompositingMode)
@@ -279,7 +267,9 @@
 
 bool RenderLayerCompositor::layerSquashingEnabled() const
 {
-    if (Settings* settings = m_renderView->document().settings())
+    if (RuntimeEnabledFeatures::bleedingEdgeFastPathsEnabled())
+        return true;
+    if (Settings* settings = m_renderView.document().settings())
         return settings->layerSquashingEnabled();
 
     return false;
@@ -287,16 +277,16 @@
 
 bool RenderLayerCompositor::canRender3DTransforms() const
 {
-    return hasAcceleratedCompositing() && (m_compositingTriggers & ChromeClient::ThreeDTransformTrigger);
+    return hasAcceleratedCompositing() && m_compositingReasonFinder.has3DTransformTrigger();
 }
 
-void RenderLayerCompositor::setCompositingLayersNeedRebuild(bool needRebuild)
+void RenderLayerCompositor::setCompositingLayersNeedRebuild()
 {
     // FIXME: crbug,com/332248 ideally this could be merged with setNeedsCompositingUpdate().
     if (inCompositingMode())
-        m_compositingLayersNeedRebuild = needRebuild;
+        m_compositingLayersNeedRebuild = true;
 
-    m_renderView->frameView()->scheduleAnimation();
+    m_renderView.frameView()->scheduleAnimation();
 }
 
 void RenderLayerCompositor::updateCompositingRequirementsState()
@@ -308,13 +298,13 @@
 
     m_needsUpdateCompositingRequirementsState = false;
 
-    if (!rootRenderLayer() || !m_renderView->acceleratedCompositingForOverflowScrollEnabled())
+    if (!rootRenderLayer() || !m_renderView.acceleratedCompositingForOverflowScrollEnabled())
         return;
 
     for (HashSet<RenderLayer*>::iterator it = m_outOfFlowPositionedLayers.begin(); it != m_outOfFlowPositionedLayers.end(); ++it)
         (*it)->updateHasUnclippedDescendant();
 
-    const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas();
+    const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas();
     if (!scrollableAreas)
         return;
 
@@ -322,16 +312,16 @@
         (*it)->updateNeedsCompositedScrolling();
 }
 
-static RenderVideo* findFullscreenVideoRenderer(Document* document)
+static RenderVideo* findFullscreenVideoRenderer(Document& document)
 {
-    Element* fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document);
+    Element* fullscreenElement = FullscreenElementStack::fullscreenElementFrom(document);
     while (fullscreenElement && fullscreenElement->isFrameOwnerElement()) {
-        document = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
-        if (!document)
+        Document* contentDocument = toHTMLFrameOwnerElement(fullscreenElement)->contentDocument();
+        if (!contentDocument)
             return 0;
-        fullscreenElement = FullscreenElementStack::currentFullScreenElementFrom(document);
+        fullscreenElement = FullscreenElementStack::fullscreenElementFrom(*contentDocument);
     }
-    if (!fullscreenElement || !fullscreenElement->hasTagName(videoTag))
+    if (!isHTMLVideoElement(fullscreenElement))
         return 0;
     RenderObject* renderer = fullscreenElement->renderer();
     if (!renderer)
@@ -339,9 +329,9 @@
     return toRenderVideo(renderer);
 }
 
-void RenderLayerCompositor::finishCompositingUpdateForFrameTree(Frame* frame)
+void RenderLayerCompositor::finishCompositingUpdateForFrameTree(LocalFrame* frame)
 {
-    for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
+    for (LocalFrame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling())
         finishCompositingUpdateForFrameTree(child);
 
     // Update compositing for current frame after all descendant frames are updated.
@@ -361,7 +351,7 @@
     // necessary updates.
 
     // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
-    if (m_renderView->needsLayout())
+    if (m_renderView.needsLayout())
         return;
 
     if (m_forceCompositingMode && !m_compositing)
@@ -372,19 +362,30 @@
 
     switch (updateType) {
     case CompositingUpdateAfterStyleChange:
+        m_needsToRecomputeCompositingRequirements = true;
+        break;
     case CompositingUpdateAfterLayout:
         m_needsToRecomputeCompositingRequirements = true;
+        // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
+        m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate;
         break;
     case CompositingUpdateOnScroll:
         m_needsToRecomputeCompositingRequirements = true; // Overlap can change with scrolling, so need to check for hierarchy updates.
         m_needsToUpdateLayerTreeGeometry = true;
+        // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
+        m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate;
         break;
     case CompositingUpdateOnCompositedScroll:
         m_needsToUpdateLayerTreeGeometry = true;
+        // FIXME: Ideally we'd be smarter about tracking dirtiness and wouldn't need a ForceUpdate here.
+        m_pendingUpdateType = GraphicsLayerUpdater::ForceUpdate;
+        break;
+    case CompositingUpdateAfterCanvasContextChange:
+        m_needsToUpdateLayerTreeGeometry = true;
         break;
     }
 
-    m_renderView->frameView()->scheduleAnimation();
+    m_renderView.frameView()->scheduleAnimation();
 }
 
 void RenderLayerCompositor::updateCompositingLayers()
@@ -397,14 +398,23 @@
 
     // Avoid updating the layers with old values. Compositing layers will be updated after the layout is finished.
     // FIXME: Can we assert that we never return here?
-    if (m_renderView->needsLayout())
+    if (m_renderView.needsLayout())
         return;
 
     lifecycle().advanceTo(DocumentLifecycle::InCompositingUpdate);
-    DocumentLifecycle::Scope lifecycleScope(lifecycle(), DocumentLifecycle::CompositingClean);
 
-    if (isMainFrame() && m_renderView->frameView())
-        finishCompositingUpdateForFrameTree(&m_renderView->frameView()->frame());
+    updateCompositingLayersInternal();
+
+    lifecycle().advanceTo(DocumentLifecycle::CompositingClean);
+
+    DocumentAnimations::startPendingAnimations(m_renderView.document());
+    ASSERT(m_renderView.document().lifecycle().state() == DocumentLifecycle::CompositingClean);
+}
+
+void RenderLayerCompositor::updateCompositingLayersInternal()
+{
+    if (isMainFrame() && m_renderView.frameView())
+        finishCompositingUpdateForFrameTree(&m_renderView.frameView()->frame());
 
     if (m_forceCompositingMode && !m_compositing)
         enableCompositingMode(true);
@@ -412,8 +422,6 @@
     if (!m_needsToRecomputeCompositingRequirements && !m_compositing)
         return;
 
-    TemporaryChange<bool> postLayoutChange(m_inPostLayoutUpdate, true);
-
     bool needCompositingRequirementsUpdate = m_needsToRecomputeCompositingRequirements;
     bool needHierarchyAndGeometryUpdate = m_compositingLayersNeedRebuild;
     bool needGeometryUpdate = m_needsToUpdateLayerTreeGeometry;
@@ -422,10 +430,14 @@
     if (!needCompositingRequirementsUpdate && !needHierarchyAndGeometryUpdate && !needGeometryUpdate && !needsToUpdateScrollingCoordinator)
         return;
 
+    GraphicsLayerUpdater::UpdateType updateType = m_pendingUpdateType;
+
     // Only clear the flags if we're updating the entire hierarchy.
     m_compositingLayersNeedRebuild = false;
     m_needsToUpdateLayerTreeGeometry = false;
     m_needsToRecomputeCompositingRequirements = false;
+    m_pendingUpdateType = GraphicsLayerUpdater::DoNotForceUpdate;
+
     RenderLayer* updateRoot = rootRenderLayer();
 
     if (needCompositingRequirementsUpdate) {
@@ -443,7 +455,8 @@
             // should be removed as soon as proper overlap testing based on
             // scrolling and animation bounds is implemented (crbug.com/252472).
             Vector<RenderLayer*> unclippedDescendants;
-            computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants);
+            IntRect absoluteDecendantBoundingBox;
+            computeCompositingRequirements(0, updateRoot, &overlapTestRequestMap, recursionData, saw3DTransform, unclippedDescendants, absoluteDecendantBoundingBox);
         }
 
         {
@@ -453,27 +466,28 @@
 
         {
             TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateHasVisibleNonLayerContentLoop");
-            const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView->frameView()->scrollableAreas();
+            const FrameView::ScrollableAreaSet* scrollableAreas = m_renderView.frameView()->scrollableAreas();
             if (scrollableAreas) {
                 for (FrameView::ScrollableAreaSet::iterator it = scrollableAreas->begin(); it != scrollableAreas->end(); ++it)
                     (*it)->updateHasVisibleNonLayerContent();
             }
         }
 
-        needHierarchyAndGeometryUpdate |= layersChanged;
+        if (layersChanged)
+            needHierarchyAndGeometryUpdate = true;
     }
 
     if (needHierarchyAndGeometryUpdate) {
         // Update the hierarchy of the compositing layers.
-        Vector<GraphicsLayer*> childList;
+        GraphicsLayerVector childList;
         {
-            TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::rebuildCompositingLayerTree");
-            rebuildCompositingLayerTree(updateRoot, childList, 0);
+            TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::rebuildTree");
+            GraphicsLayerUpdater(m_renderView).rebuildTree(*updateRoot, updateType, childList, 0);
         }
 
         // Host the document layer in the RenderView's root layer.
         if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && isMainFrame()) {
-            RenderVideo* video = findFullscreenVideoRenderer(&m_renderView->document());
+            RenderVideo* video = findFullscreenVideoRenderer(m_renderView.document());
             if (video && video->hasCompositedLayerMapping()) {
                 childList.clear();
                 childList.append(video->compositedLayerMapping()->mainGraphicsLayer());
@@ -487,8 +501,8 @@
     } else if (needGeometryUpdate) {
         // We just need to do a geometry update. This is only used for position:fixed scrolling;
         // most of the time, geometry is updated via RenderLayer::styleChanged().
-        TRACE_EVENT0("blink_rendering", "RenderLayerCompositor::updateLayerTreeGeometry");
-        updateLayerTreeGeometry(updateRoot);
+        TRACE_EVENT0("blink_rendering", "GraphicsLayerUpdater::updateRecursive");
+        GraphicsLayerUpdater(m_renderView).updateRecursive(*updateRoot, updateType);
     }
 
     ASSERT(updateRoot || !m_compositingLayersNeedRebuild);
@@ -538,11 +552,10 @@
     m_outOfFlowPositionedLayers.remove(layer);
 }
 
-bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer)
+bool RenderLayerCompositor::allocateOrClearCompositedLayerMapping(RenderLayer* layer, const CompositingStateTransitionType compositedLayerUpdate)
 {
     bool compositedLayerMappingChanged = false;
     bool nonCompositedReasonChanged = updateLayerIfViewportConstrained(layer);
-    CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
 
     // FIXME: It would be nice to directly use the layer's compositing reason,
     // but allocateOrClearCompositedLayerMapping also gets called without having updated compositing
@@ -560,7 +573,7 @@
         // At this time, the ScrollingCooridnator only supports the top-level frame.
         if (layer->isRootLayer() && isMainFrame()) {
             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-                scrollingCoordinator->frameViewRootLayerDidChange(m_renderView->frameView());
+                scrollingCoordinator->frameViewRootLayerDidChange(m_renderView.frameView());
         }
 
         // If this layer was previously squashed, we need to remove its reference to a groupedMapping right away, so
@@ -629,7 +642,7 @@
     // the scrolling coordinator needs to recalculate whether it can do fast scrolling.
     if (compositedLayerMappingChanged || nonCompositedReasonChanged) {
         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-            scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView->frameView());
+            scrollingCoordinator->frameViewFixedObjectsDidChange(m_renderView.frameView());
     }
 
     return compositedLayerMappingChanged || nonCompositedReasonChanged;
@@ -643,9 +656,8 @@
     return roundedIntPoint(transformState.lastPlanarPoint());
 }
 
-bool RenderLayerCompositor::updateSquashingAssignment(RenderLayer* layer, SquashingState& squashingState)
+bool RenderLayerCompositor::updateSquashingAssignment(RenderLayer* layer, SquashingState& squashingState, const CompositingStateTransitionType compositedLayerUpdate)
 {
-    CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
 
     // NOTE: In the future as we generalize this, the background of this layer may need to be assigned to a different backing than
     // the squashed RenderLayer's own primary contents. This would happen when we have a composited negative z-index element that needs
@@ -701,7 +713,7 @@
 bool RenderLayerCompositor::updateLayerIfViewportConstrained(RenderLayer* layer)
 {
     RenderLayer::ViewportConstrainedNotCompositedReason viewportConstrainedNotCompositedReason = RenderLayer::NoNotCompositedReason;
-    requiresCompositingForPosition(layer->renderer(), layer, &viewportConstrainedNotCompositedReason);
+    m_compositingReasonFinder.requiresCompositingForPosition(layer->renderer(), layer, &viewportConstrainedNotCompositedReason, &m_needsToRecomputeCompositingRequirements);
 
     if (layer->viewportConstrainedNotCompositedReason() != viewportConstrainedNotCompositedReason) {
         ASSERT(layer->renderer()->style()->position() == FixedPosition);
@@ -712,7 +724,13 @@
     return false;
 }
 
-RenderLayerCompositor::CompositingStateTransitionType RenderLayerCompositor::computeCompositedLayerUpdate(const RenderLayer* layer)
+bool RenderLayerCompositor::canSquashIntoCurrentSquashingOwner(const RenderLayer* layer, const RenderLayerCompositor::SquashingState& squashingState, const RenderLayer* clippingAncestor)
+{
+    ASSERT(clippingAncestor);
+    return clippingAncestor == squashingState.clippingAncestorForMostRecentMapping;
+}
+
+RenderLayerCompositor::CompositingStateTransitionType RenderLayerCompositor::computeCompositedLayerUpdate(RenderLayer* layer)
 {
     CompositingStateTransitionType update = NoCompositingStateChange;
     if (needsOwnBacking(layer)) {
@@ -740,20 +758,6 @@
 // See crbug.com/339892 for a list of tests that fail if this method is removed.
 void RenderLayerCompositor::applyUpdateLayerCompositingStateChickenEggHacks(RenderLayer* layer, CompositingStateTransitionType compositedLayerUpdate)
 {
-    if (compositedLayerUpdate != NoCompositingStateChange)
-        allocateOrClearCompositedLayerMapping(layer);
-}
-
-void RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer)
-{
-    updateDirectCompositingReasons(layer);
-    CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
-
-    if (compositedLayerUpdate != NoCompositingStateChange) {
-        setCompositingLayersNeedRebuild();
-        setNeedsToRecomputeCompositingRequirements();
-    }
-
     // See if we need content or clipping layers. Methods called here should assume
     // that the compositing state of descendant layers has not been updated yet.
     if (layer->hasCompositedLayerMapping() && layer->compositedLayerMapping()->updateGraphicsLayerConfiguration()) {
@@ -763,18 +767,33 @@
             setCompositingLayersNeedRebuild();
     }
 
-    applyUpdateLayerCompositingStateChickenEggHacks(layer, compositedLayerUpdate);
+    if (compositedLayerUpdate != NoCompositingStateChange)
+        allocateOrClearCompositedLayerMapping(layer, computeCompositedLayerUpdate(layer));
+}
+
+void RenderLayerCompositor::updateLayerCompositingState(RenderLayer* layer, UpdateLayerCompositingStateOptions options)
+{
+    updateDirectCompositingReasons(layer);
+    CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
+
+    if (compositedLayerUpdate != NoCompositingStateChange) {
+        setCompositingLayersNeedRebuild();
+        setNeedsToRecomputeCompositingRequirements();
+    }
+
+    if (options == UseChickenEggHacks)
+        applyUpdateLayerCompositingStateChickenEggHacks(layer, compositedLayerUpdate);
 }
 
 void RenderLayerCompositor::repaintOnCompositingChange(RenderLayer* layer)
 {
     // If the renderer is not attached yet, no need to repaint.
-    if (layer->renderer() != m_renderView && !layer->renderer()->parent())
+    if (layer->renderer() != &m_renderView && !layer->renderer()->parent())
         return;
 
     RenderLayerModelObject* repaintContainer = layer->renderer()->containerForRepaint();
     if (!repaintContainer)
-        repaintContainer = m_renderView;
+        repaintContainer = &m_renderView;
 
     layer->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
 }
@@ -810,11 +829,6 @@
         return LayoutRect();
 
     RenderLayer::CalculateLayerBoundsFlags flags = RenderLayer::DefaultCalculateLayerBoundsFlags | RenderLayer::ExcludeHiddenDescendants | RenderLayer::DontConstrainForMask;
-#if HAVE(COMPOSITOR_FILTER_OUTSETS)
-    // If the compositor computes its own filter outsets, don't include them in the composited bounds.
-    if (!layer->paintsWithFilters())
-        flags &= ~RenderLayer::IncludeLayerFilterOutsets;
-#endif
     return layer->calculateLayerBounds(ancestorLayer, 0, flags);
 }
 
@@ -841,61 +855,14 @@
     setCompositingLayersNeedRebuild();
 }
 
-RenderLayer* RenderLayerCompositor::enclosingNonStackingClippingLayer(const RenderLayer* layer) const
-{
-    for (RenderLayer* curr = layer->parent(); curr != 0; curr = curr->parent()) {
-        if (curr->stackingNode()->isStackingContainer())
-            return 0;
-
-        if (curr->renderer()->hasClipOrOverflowClip())
-            return curr;
-    }
-    return 0;
-}
-
-void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
+void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds)
 {
     if (layer->isRootLayer())
         return;
 
-    if (!boundsComputed) {
-        // FIXME: If this layer's overlap bounds include its children, we don't need to add its
-        // children's bounds to the overlap map.
-        layerBounds = enclosingIntRect(overlapMap.geometryMap().absoluteRect(layer->overlapBounds()));
-        // Empty rects never intersect, but we need them to for the purposes of overlap testing.
-        if (layerBounds.isEmpty())
-            layerBounds.setSize(IntSize(1, 1));
-        boundsComputed = true;
-    }
-
     IntRect clipRect = pixelSnappedIntRect(layer->clipper().backgroundClipRect(ClipRectsContext(rootRenderLayer(), AbsoluteClipRects)).rect());
     clipRect.intersect(layerBounds);
-    overlapMap.add(layer, clipRect);
-}
-
-void RenderLayerCompositor::addToOverlapMapRecursive(OverlapMap& overlapMap, RenderLayer* layer, RenderLayer* ancestorLayer)
-{
-    if (!canBeComposited(layer) || overlapMap.contains(layer))
-        return;
-
-    // A null ancestorLayer is an indication that 'layer' has already been pushed.
-    if (ancestorLayer)
-        overlapMap.geometryMap().pushMappingsToAncestor(layer, ancestorLayer);
-
-    IntRect bounds;
-    bool haveComputedBounds = false;
-    addToOverlapMap(overlapMap, layer, bounds, haveComputedBounds);
-
-#if !ASSERT_DISABLED
-    LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
-    RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
-    while (RenderLayerStackingNode* curNode = iterator.next())
-        addToOverlapMapRecursive(overlapMap, curNode->layer(), layer);
-
-    if (ancestorLayer)
-        overlapMap.geometryMap().popMappingsToAncestor(ancestorLayer);
+    overlapMap.add(clipRect);
 }
 
 //  Recurse through the layers in z-index and overflow order (which is equivalent to painting order)
@@ -907,7 +874,7 @@
 //      must be compositing so that its contents render over that child.
 //      This implies that its positive z-index children must also be compositing.
 //
-void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingRecursionData& currentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants)
+void RenderLayerCompositor::computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer* layer, OverlapMap* overlapMap, CompositingRecursionData& currentRecursionData, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants, IntRect& absoluteDecendantBoundingBox)
 {
     layer->stackingNode()->updateLayerListsIfNeeded();
 
@@ -922,14 +889,14 @@
     CompositingReasons reasonsToComposite = CompositingReasonNone;
 
     // First accumulate the straightforward compositing reasons.
-    CompositingReasons directReasons = directReasonsForCompositing(layer);
+    CompositingReasons directReasons = m_compositingReasonFinder.directReasons(layer, &m_needsToRecomputeCompositingRequirements);
 
     // Video is special. It's the only RenderLayer type that can both have
     // RenderLayer children and whose children can't use its backing to render
     // into. These children (the controls) always need to be promoted into their
     // own layers to draw on top of the accelerated video.
     if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->renderer()->isVideo())
-        directReasons |= CompositingReasonLayerForVideoOverlay;
+        directReasons |= CompositingReasonVideoOverlay;
 
     if (canBeComposited(layer))
         reasonsToComposite |= directReasons;
@@ -939,7 +906,7 @@
     // used, we must assume we overlap if there is anything composited behind us in paint-order.
     CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone;
 
-    if (m_renderView->compositorDrivenAcceleratedScrollingEnabled()) {
+    if (m_renderView.compositorDrivenAcceleratedScrollingEnabled()) {
         Vector<size_t> unclippedDescendantsToRemove;
         for (size_t i = 0; i < unclippedDescendants.size(); i++) {
             RenderLayer* unclippedDescendant = unclippedDescendants.at(i);
@@ -964,19 +931,19 @@
             unclippedDescendants.append(layer);
     }
 
-    bool haveComputedBounds = false;
     IntRect absBounds;
-    // If we know for sure the layer is going to be composited, don't bother looking it up in the overlap map.
-    if (overlapMap && !overlapMap->isEmpty() && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons)) {
-        // If we're testing for overlap, we only need to composite if we overlap something that is already composited.
+    if (overlapMap && !layer->isRootLayer()) {
         absBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(layer->overlapBounds()));
-
-        // Empty rects never intersect, but we need them to for the purposes of overlap testing.
+        // Setting the absBounds to 1x1 instead of 0x0 makes very little sense,
+        // but removing this code will make JSGameBench sad.
+        // See https://codereview.chromium.org/13912020/
         if (absBounds.isEmpty())
             absBounds.setSize(IntSize(1, 1));
-        haveComputedBounds = true;
-        overlapCompositingReason = overlapMap->overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;
     }
+    absoluteDecendantBoundingBox = absBounds;
+
+    if (overlapMap && currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons))
+        overlapCompositingReason = overlapMap->overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;
 
     reasonsToComposite |= overlapCompositingReason;
 
@@ -1022,7 +989,9 @@
     if (layer->stackingNode()->isStackingContainer()) {
         RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
         while (RenderLayerStackingNode* curNode = iterator.next()) {
-            computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants);
+            IntRect absoluteChildDecendantBoundingBox;
+            computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDecendantBoundingBox);
+            absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox);
 
             // If we have to make a layer for this child, make one now so we can have a contents layer
             // (since we need to ensure that the -ve z-order child renders underneath our contents).
@@ -1032,7 +1001,8 @@
                 if (!willBeCompositedOrSquashed) {
                     // make layer compositing
                     childRecursionData.m_compositingAncestor = layer;
-                    overlapMap->beginNewOverlapTestingContext();
+                    if (overlapMap)
+                        overlapMap->beginNewOverlapTestingContext();
                     willBeCompositedOrSquashed = true;
                     willHaveForegroundLayer = true;
 
@@ -1042,9 +1012,8 @@
                     if (overlapMap) {
                         overlapMap->geometryMap().pushMappingsToAncestor(curNode->layer(), layer);
                         IntRect childAbsBounds = enclosingIntRect(overlapMap->geometryMap().absoluteRect(curNode->layer()->overlapBounds()));
-                        bool boundsComputed = true;
                         overlapMap->beginNewOverlapTestingContext();
-                        addToOverlapMap(*overlapMap, curNode->layer(), childAbsBounds, boundsComputed);
+                        addToOverlapMap(*overlapMap, curNode->layer(), childAbsBounds);
                         overlapMap->finishCurrentOverlapTestingContext();
                         overlapMap->geometryMap().popMappingsToAncestor(layer);
                     }
@@ -1072,8 +1041,11 @@
     }
 
     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
-    while (RenderLayerStackingNode* curNode = iterator.next())
-        computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants);
+    while (RenderLayerStackingNode* curNode = iterator.next()) {
+        IntRect absoluteChildDecendantBoundingBox;
+        computeCompositingRequirements(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDecendantBoundingBox);
+        absoluteDecendantBoundingBox.unite(absoluteChildDecendantBoundingBox);
+    }
 
     currentRecursionData.m_mostRecentCompositedLayer = childRecursionData.m_mostRecentCompositedLayer;
 
@@ -1089,7 +1061,7 @@
     // the overlap map. Layers that are not separately composited will paint into their
     // compositing ancestor's backing, and so are still considered for overlap.
     if (overlapMap && childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer())
-        addToOverlapMap(*overlapMap, layer, absBounds, haveComputedBounds);
+        addToOverlapMap(*overlapMap, layer, absBounds);
 
     if (layer->stackingNode()->isStackingContext()) {
         layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUnisolatedCompositedBlendingDescendant);
@@ -1108,7 +1080,7 @@
             // now, because the code is designed to push overlap information to the
             // second-from-top context of the stack.
             overlapMap->beginNewOverlapTestingContext();
-            addToOverlapMapRecursive(*overlapMap, layer);
+            addToOverlapMap(*overlapMap, layer, absoluteDecendantBoundingBox);
         }
         willBeCompositedOrSquashed = true;
     }
@@ -1168,7 +1140,7 @@
         overlapMap->geometryMap().popMappingsToAncestor(ancestorLayer);
 }
 
-void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsoluteForSquashingCLM)
+void RenderLayerCompositor::SquashingState::updateSquashingStateForNewMapping(CompositedLayerMappingPtr newCompositedLayerMapping, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsoluteForSquashingCLM, RenderLayer* newClippingAncestorForMostRecentMapping)
 {
     // The most recent backing is done accumulating any more squashing layers.
     if (hasMostRecentMapping)
@@ -1178,46 +1150,57 @@
     mostRecentMapping = newCompositedLayerMapping;
     hasMostRecentMapping = hasNewCompositedLayerMapping;
     offsetFromAbsoluteForSquashingCLM = newOffsetFromAbsoluteForSquashingCLM;
+    clippingAncestorForMostRecentMapping = newClippingAncestorForMostRecentMapping;
 }
 
 void RenderLayerCompositor::assignLayersToBackings(RenderLayer* updateRoot, bool& layersChanged)
 {
     SquashingState squashingState;
-    assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged);
+    assignLayersToBackingsInternal(updateRoot, squashingState, layersChanged, updateRoot);
     if (squashingState.hasMostRecentMapping)
         squashingState.mostRecentMapping->finishAccumulatingSquashingLayers(squashingState.nextSquashedLayerIndex);
 }
 
 void RenderLayerCompositor::assignLayersToBackingsForReflectionLayer(RenderLayer* reflectionLayer, bool& layersChanged)
 {
-    if (computeCompositedLayerUpdate(reflectionLayer) != NoCompositingStateChange) {
+    CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(reflectionLayer);
+    if (compositedLayerUpdate != NoCompositingStateChange) {
         layersChanged = true;
-        allocateOrClearCompositedLayerMapping(reflectionLayer);
+        allocateOrClearCompositedLayerMapping(reflectionLayer, compositedLayerUpdate);
     }
     updateDirectCompositingReasons(reflectionLayer);
     if (reflectionLayer->hasCompositedLayerMapping())
         reflectionLayer->compositedLayerMapping()->updateGraphicsLayerConfiguration();
 }
 
-void RenderLayerCompositor::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged)
+void RenderLayerCompositor::assignLayersToBackingsInternal(RenderLayer* layer, SquashingState& squashingState, bool& layersChanged, RenderLayer* clippingAncestor)
 {
-    if (allocateOrClearCompositedLayerMapping(layer))
+    if (layer->renderer()->hasClipOrOverflowClip())
+        clippingAncestor = layer;
+
+    if (layerSquashingEnabled() && requiresSquashing(layer->compositingReasons()) && !canSquashIntoCurrentSquashingOwner(layer, squashingState, clippingAncestor))
+        layer->setCompositingReasons(layer->compositingReasons() | CompositingReasonOverlapsWithoutSquashingTarget);
+
+    CompositingStateTransitionType compositedLayerUpdate = computeCompositedLayerUpdate(layer);
+
+    if (allocateOrClearCompositedLayerMapping(layer, compositedLayerUpdate))
         layersChanged = true;
 
     // FIXME: special-casing reflection layers here is not right.
     if (layer->reflectionInfo())
         assignLayersToBackingsForReflectionLayer(layer->reflectionInfo()->reflectionLayer(), layersChanged);
 
+
     // Add this layer to a squashing backing if needed.
     if (layerSquashingEnabled()) {
-        if (updateSquashingAssignment(layer, squashingState))
+        if (updateSquashingAssignment(layer, squashingState, compositedLayerUpdate))
             layersChanged = true;
     }
 
     if (layer->stackingNode()->isStackingContainer()) {
         RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
         while (RenderLayerStackingNode* curNode = iterator.next())
-            assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
+            assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged, clippingAncestor);
     }
 
     if (layerSquashingEnabled()) {
@@ -1225,13 +1208,13 @@
         if (layer->compositingState() == PaintsIntoOwnBacking || layer->compositingState() == HasOwnBackingButPaintsIntoAncestor) {
             ASSERT(!requiresSquashing(layer->compositingReasons()));
             IntPoint offsetFromAbsoluteForSquashingCLM = computeOffsetFromAbsolute(layer);
-            squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping(), offsetFromAbsoluteForSquashingCLM);
+            squashingState.updateSquashingStateForNewMapping(layer->compositedLayerMapping(), layer->hasCompositedLayerMapping(), offsetFromAbsoluteForSquashingCLM, clippingAncestor);
         }
     }
 
     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
     while (RenderLayerStackingNode* curNode = iterator.next())
-        assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged);
+        assignLayersToBackingsInternal(curNode->layer(), squashingState, layersChanged, clippingAncestor);
 }
 
 void RenderLayerCompositor::setCompositingParent(RenderLayer* childLayer, RenderLayer* parentLayer)
@@ -1263,135 +1246,6 @@
     hostingLayer->removeAllChildren();
 }
 
-bool RenderLayerCompositor::canAccelerateVideoRendering(RenderVideo* o) const
-{
-    if (!m_hasAcceleratedCompositing)
-        return false;
-
-    return o->supportsAcceleratedRendering();
-}
-
-void RenderLayerCompositor::updateGraphicsLayersMappedToRenderLayer(RenderLayer* layer)
-{
-    if (!layer->hasCompositedLayerMapping())
-        return;
-
-    CompositedLayerMappingPtr compositedLayerMapping = layer->compositedLayerMapping();
-
-    // Note carefully: here we assume that the compositing state of all descendants have been updated already,
-    // so it is legitimate to compute and cache the composited bounds for this layer.
-    compositedLayerMapping->updateCompositedBounds();
-
-    if (layer->reflectionInfo()) {
-        RenderLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
-        ASSERT(reflectionLayer);
-        if (reflectionLayer->hasCompositedLayerMapping())
-            reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
-    }
-
-    compositedLayerMapping->updateGraphicsLayerConfiguration();
-    compositedLayerMapping->updateGraphicsLayerGeometry();
-
-    if (!layer->parent())
-        updateRootLayerPosition();
-
-    if (compositedLayerMapping->hasUnpositionedOverflowControlsLayers())
-        layer->scrollableArea()->positionOverflowControls();
-}
-
-void RenderLayerCompositor::rebuildCompositingLayerTree(RenderLayer* layer, Vector<GraphicsLayer*>& childLayersOfEnclosingLayer, int depth)
-{
-    // Make the layer compositing if necessary, and set up clipping and content layers.
-    // Note that we can only do work here that is independent of whether the descendant layers
-    // have been processed. computeCompositingRequirements() will already have done the repaint if necessary.
-
-    layer->stackingNode()->updateLayerListsIfNeeded();
-    layer->update3dRenderingContext();
-
-    // Used for gathering UMA data about the effect on memory usage of promoting all layers
-    // that have a webkit-transition on opacity or transform and intersect the viewport.
-    static double pixelsWithoutPromotingAllTransitions = 0.0;
-    static double pixelsAddedByPromotingAllTransitions = 0.0;
-
-    if (!depth) {
-        pixelsWithoutPromotingAllTransitions = 0.0;
-        pixelsAddedByPromotingAllTransitions = 0.0;
-    }
-
-    const bool hasCompositedLayerMapping = layer->hasCompositedLayerMapping();
-    CompositedLayerMappingPtr currentCompositedLayerMapping = layer->compositedLayerMapping();
-
-    updateGraphicsLayersMappedToRenderLayer(layer);
-
-    // Grab some stats for histograms.
-    if (hasCompositedLayerMapping) {
-        pixelsWithoutPromotingAllTransitions += layer->size().height() * layer->size().width();
-    } else {
-        if ((layer->renderer()->style()->transitionForProperty(CSSPropertyOpacity) ||
-             layer->renderer()->style()->transitionForProperty(CSSPropertyWebkitTransform)) &&
-            m_renderView->viewRect().intersects(layer->absoluteBoundingBox()))
-            pixelsAddedByPromotingAllTransitions += layer->size().height() * layer->size().width();
-    }
-
-    // If this layer has a compositedLayerMapping, then that is where we place subsequent children GraphicsLayers.
-    // Otherwise children continue to append to the child list of the enclosing layer.
-    Vector<GraphicsLayer*> layerChildren;
-    Vector<GraphicsLayer*>& childList = hasCompositedLayerMapping ? layerChildren : childLayersOfEnclosingLayer;
-
-#if !ASSERT_DISABLED
-    LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
-    if (layer->stackingNode()->isStackingContainer()) {
-        RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
-        while (RenderLayerStackingNode* curNode = iterator.next())
-            rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1);
-
-        // If a negative z-order child is compositing, we get a foreground layer which needs to get parented.
-        if (hasCompositedLayerMapping && currentCompositedLayerMapping->foregroundLayer())
-            childList.append(currentCompositedLayerMapping->foregroundLayer());
-    }
-
-    RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
-    while (RenderLayerStackingNode* curNode = iterator.next())
-        rebuildCompositingLayerTree(curNode->layer(), childList, depth + 1);
-
-    if (hasCompositedLayerMapping) {
-        bool parented = false;
-        if (layer->renderer()->isRenderPart())
-            parented = parentFrameContentLayers(toRenderPart(layer->renderer()));
-
-        if (!parented)
-            currentCompositedLayerMapping->parentForSublayers()->setChildren(layerChildren);
-
-        // If the layer has a clipping layer the overflow controls layers will be siblings of the clipping layer.
-        // Otherwise, the overflow control layers are normal children.
-        if (!currentCompositedLayerMapping->hasClippingLayer() && !currentCompositedLayerMapping->hasScrollingLayer()) {
-            if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForHorizontalScrollbar()) {
-                overflowControlLayer->removeFromParent();
-                currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
-            }
-
-            if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForVerticalScrollbar()) {
-                overflowControlLayer->removeFromParent();
-                currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
-            }
-
-            if (GraphicsLayer* overflowControlLayer = currentCompositedLayerMapping->layerForScrollCorner()) {
-                overflowControlLayer->removeFromParent();
-                currentCompositedLayerMapping->parentForSublayers()->addChild(overflowControlLayer);
-            }
-        }
-
-        childLayersOfEnclosingLayer.append(currentCompositedLayerMapping->childForSuperlayers());
-    }
-
-    if (!depth) {
-        int percentageIncreaseInPixels = static_cast<int>(pixelsAddedByPromotingAllTransitions / pixelsWithoutPromotingAllTransitions * 100);
-        blink::Platform::current()->histogramCustomCounts("Renderer.PixelIncreaseFromTransitions", percentageIncreaseInPixels, 0, 1000, 50);
-    }
-}
-
 void RenderLayerCompositor::frameViewDidChangeLocation(const IntPoint& contentsOffset)
 {
     if (m_overflowControlsHostLayer)
@@ -1401,7 +1255,7 @@
 void RenderLayerCompositor::frameViewDidChangeSize()
 {
     if (m_containerLayer) {
-        FrameView* frameView = m_renderView->frameView();
+        FrameView* frameView = m_renderView.frameView();
         m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
 
         frameViewDidScroll();
@@ -1418,7 +1272,7 @@
 
 void RenderLayerCompositor::frameViewDidScroll()
 {
-    FrameView* frameView = m_renderView->frameView();
+    FrameView* frameView = m_renderView.frameView();
     IntPoint scrollPosition = frameView->scrollPosition();
 
     if (!m_scrollLayer)
@@ -1426,7 +1280,7 @@
 
     bool scrollingCoordinatorHandlesOffset = false;
     if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator()) {
-        if (Settings* settings = m_renderView->document().settings()) {
+        if (Settings* settings = m_renderView.document().settings()) {
             if (isMainFrame() || settings->compositedScrollingForFramesEnabled())
                 scrollingCoordinatorHandlesOffset = scrollingCoordinator->scrollableAreaScrollLayerDidChange(frameView);
         }
@@ -1446,10 +1300,6 @@
         AcceleratedFixedRootBackgroundHistogramMax);
 }
 
-void RenderLayerCompositor::frameViewDidLayout()
-{
-}
-
 void RenderLayerCompositor::frameViewScrollbarsExistenceDidChange()
 {
     if (m_containerLayer)
@@ -1461,13 +1311,16 @@
     if (!supportsFixedRootBackgroundCompositing())
         return;
 
+    // crbug.com/343132.
+    DisableCompositingQueryAsserts disabler;
+
     // To avoid having to make the fixed root background layer fixed positioned to
     // stay put, we position it in the layer tree as follows:
     //
     // + Overflow controls host
-    //   + Frame clip
+    //   + LocalFrame clip
     //     + (Fixed root background) <-- Here.
-    //     + Frame scroll
+    //     + LocalFrame scroll
     //       + Root content layer
     //   + Scrollbars
     //
@@ -1505,7 +1358,7 @@
     // The true root layer is not included in the dump, so if we want to report
     // its repaint rects, they must be included here.
     if (flags & LayerTreeIncludesRepaintRects)
-        return m_renderView->frameView()->trackedRepaintRectsAsText() + layerTreeText;
+        return m_renderView.frameView()->trackedRepaintRectsAsText() + layerTreeText;
 
     return layerTreeText;
 }
@@ -1523,6 +1376,7 @@
     return 0;
 }
 
+// FIXME: What does this function do? It needs a clearer name.
 bool RenderLayerCompositor::parentFrameContentLayers(RenderPart* renderer)
 {
     RenderLayerCompositor* innerCompositor = frameContentsCompositor(renderer);
@@ -1543,20 +1397,6 @@
     return true;
 }
 
-// This just updates layer geometry without changing the hierarchy.
-void RenderLayerCompositor::updateLayerTreeGeometry(RenderLayer* layer)
-{
-    updateGraphicsLayersMappedToRenderLayer(layer);
-
-#if !ASSERT_DISABLED
-    LayerListMutationDetector mutationChecker(layer->stackingNode());
-#endif
-
-    RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), AllChildren);
-    while (RenderLayerStackingNode* curNode = iterator.next())
-        updateLayerTreeGeometry(curNode->layer());
-}
-
 // Recurs down the RenderLayer tree until its finds the compositing descendants of compositingAncestor and updates their geometry.
 void RenderLayerCompositor::updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer* layer, bool compositedChildrenOnly)
 {
@@ -1571,7 +1411,7 @@
                     reflectionLayer->compositedLayerMapping()->updateCompositedBounds();
             }
 
-            compositedLayerMapping->updateGraphicsLayerGeometry();
+            compositedLayerMapping->updateGraphicsLayerGeometry(GraphicsLayerUpdater::ForceUpdate);
             if (compositedChildrenOnly)
                 return;
         }
@@ -1593,20 +1433,16 @@
 }
 
 
-void RenderLayerCompositor::repaintCompositedLayers(const IntRect* absRect)
+void RenderLayerCompositor::repaintCompositedLayers()
 {
-    recursiveRepaintLayer(rootRenderLayer(), absRect);
+    recursiveRepaintLayer(rootRenderLayer());
 }
 
-void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer, const IntRect* rect)
+void RenderLayerCompositor::recursiveRepaintLayer(RenderLayer* layer)
 {
     // FIXME: This method does not work correctly with transforms.
-    if (layer->compositingState() == PaintsIntoOwnBacking) {
-        if (rect)
-            layer->repainter().setBackingNeedsRepaintInRect(*rect);
-        else
-            layer->repainter().setBackingNeedsRepaint();
-    }
+    if (layer->compositingState() == PaintsIntoOwnBacking)
+        layer->repainter().setBackingNeedsRepaint();
 
 #if !ASSERT_DISABLED
     LayerListMutationDetector mutationChecker(layer->stackingNode());
@@ -1616,20 +1452,13 @@
     if (layer->hasCompositingDescendant())
         childrenToVisit |= PositiveZOrderChildren | NegativeZOrderChildren;
     RenderLayerStackingNodeIterator iterator(*layer->stackingNode(), childrenToVisit);
-    while (RenderLayerStackingNode* curNode = iterator.next()) {
-        if (rect) {
-            IntRect childRect(*rect);
-            curNode->layer()->convertToPixelSnappedLayerCoords(layer, childRect);
-            recursiveRepaintLayer(curNode->layer(), &childRect);
-        } else {
-            recursiveRepaintLayer(curNode->layer());
-        }
-    }
+    while (RenderLayerStackingNode* curNode = iterator.next())
+        recursiveRepaintLayer(curNode->layer());
 }
 
 RenderLayer* RenderLayerCompositor::rootRenderLayer() const
 {
-    return m_renderView->layer();
+    return m_renderView.layer();
 }
 
 GraphicsLayer* RenderLayerCompositor::rootGraphicsLayer() const
@@ -1649,6 +1478,20 @@
     return m_containerLayer.get();
 }
 
+GraphicsLayer* RenderLayerCompositor::ensureRootTransformLayer()
+{
+    ASSERT(rootGraphicsLayer());
+
+    if (!m_rootTransformLayer.get()) {
+        m_rootTransformLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
+        m_overflowControlsHostLayer->addChild(m_rootTransformLayer.get());
+        m_rootTransformLayer->addChild(m_containerLayer.get());
+        updateOverflowControlsLayers();
+    }
+
+    return m_rootTransformLayer.get();
+}
+
 void RenderLayerCompositor::setIsInWindow(bool isInWindow)
 {
     if (!inCompositingMode())
@@ -1684,13 +1527,13 @@
 
 void RenderLayerCompositor::clearMappingForAllRenderLayers()
 {
-    clearMappingForRenderLayerIncludingDescendants(m_renderView->layer());
+    clearMappingForRenderLayerIncludingDescendants(m_renderView.layer());
 }
 
 void RenderLayerCompositor::updateRootLayerPosition()
 {
     if (m_rootContentLayer) {
-        const IntRect& documentRect = m_renderView->documentRect();
+        const IntRect& documentRect = m_renderView.documentRect();
         m_rootContentLayer->setSize(documentRect.size());
         m_rootContentLayer->setPosition(documentRect.location());
 #if USE(RUBBER_BANDING)
@@ -1699,7 +1542,7 @@
 #endif
     }
     if (m_containerLayer) {
-        FrameView* frameView = m_renderView->frameView();
+        FrameView* frameView = m_renderView.frameView();
         m_containerLayer->setSize(frameView->unscaledVisibleContentSize());
     }
 }
@@ -1714,7 +1557,7 @@
     CompositingReasons layerReasons = layer->compositingReasons();
 
     layerReasons &= ~CompositingReasonComboAllDirectReasons;
-    layerReasons |= directReasonsForCompositing(layer);
+    layerReasons |= m_compositingReasonFinder.directReasons(layer, &m_needsToRecomputeCompositingRequirements);
     layer->setCompositingReasons(layerReasons);
 }
 
@@ -1736,51 +1579,6 @@
     return m_hasAcceleratedCompositing && layer->isSelfPaintingLayer() && layer->renderer()->flowThreadState() == RenderObject::NotInsideFlowThread;
 }
 
-CompositingReasons RenderLayerCompositor::directReasonsForCompositing(const RenderLayer* layer) const
-{
-    RenderObject* renderer = layer->renderer();
-    CompositingReasons directReasons = CompositingReasonNone;
-
-    if (requiresCompositingForTransform(renderer))
-        directReasons |= CompositingReason3DTransform;
-
-    // Only zero or one of the following conditions will be true for a given RenderLayer.
-    if (requiresCompositingForVideo(renderer))
-        directReasons |= CompositingReasonVideo;
-    else if (requiresCompositingForCanvas(renderer))
-        directReasons |= CompositingReasonCanvas;
-    else if (requiresCompositingForPlugin(renderer))
-        directReasons |= CompositingReasonPlugin;
-    else if (requiresCompositingForFrame(renderer))
-        directReasons |= CompositingReasonIFrame;
-
-    if (requiresCompositingForBackfaceVisibilityHidden(renderer))
-        directReasons |= CompositingReasonBackfaceVisibilityHidden;
-
-    if (requiresCompositingForAnimation(renderer))
-        directReasons |= CompositingReasonAnimation;
-
-    if (requiresCompositingForTransition(renderer))
-        directReasons |= CompositingReasonAnimation;
-
-    if (requiresCompositingForFilters(renderer))
-        directReasons |= CompositingReasonFilters;
-
-    if (requiresCompositingForPosition(renderer, layer))
-        directReasons |= renderer->style()->position() == FixedPosition ? CompositingReasonPositionFixed : CompositingReasonPositionSticky;
-
-    if (requiresCompositingForOverflowScrolling(layer))
-        directReasons |= CompositingReasonOverflowScrollingTouch;
-
-    if (requiresCompositingForOverflowScrollingParent(layer))
-        directReasons |= CompositingReasonOverflowScrollingParent;
-
-    if (requiresCompositingForOutOfFlowClipping(layer))
-        directReasons |= CompositingReasonOutOfFlowClipping;
-
-    return directReasons;
-}
-
 // Return true if the given layer has some ancestor in the RenderLayer hierarchy that clips,
 // up to the enclosing compositing ancestor. This is required because compositing layers are parented
 // according to the z-order hierarchy, yet clipping goes down the renderer hierarchy.
@@ -1791,29 +1589,18 @@
     if (!layer->hasCompositedLayerMapping() || !layer->parent())
         return false;
 
-    // FIXME: need to double-check if semantics of ancestorCompositingLayer() work correctly here?
     const RenderLayer* compositingAncestor = layer->ancestorCompositingLayer();
     if (!compositingAncestor)
         return false;
 
-    // If the compositingAncestor clips, that will be taken care of by clipsCompositingDescendants(),
-    // so we only care about clipping between its first child that is our ancestor (the computeClipRoot),
-    // and layer.
-    const RenderLayer* computeClipRoot = 0;
-    const RenderLayer* curr = layer;
-    while (curr) {
-        const RenderLayer* next = curr->parent();
-        if (next == compositingAncestor) {
-            computeClipRoot = curr;
-            break;
-        }
-        curr = next;
-    }
-
-    if (!computeClipRoot || computeClipRoot == layer)
+    RenderObject* clippingContainer = layer->renderer()->clippingContainer();
+    if (!clippingContainer)
         return false;
 
-    return layer->clipper().backgroundClipRect(ClipRectsContext(computeClipRoot, TemporaryClipRects)).rect() != PaintInfo::infiniteRect();
+    if (compositingAncestor->renderer()->isDescendantOf(clippingContainer))
+        return false;
+
+    return true;
 }
 
 // Return true if the given layer is a stacking context and has compositing child
@@ -1824,140 +1611,6 @@
     return layer->hasCompositingDescendant() && layer->renderer()->hasClipOrOverflowClip();
 }
 
-bool RenderLayerCompositor::requiresCompositingForScrollableFrame() const
-{
-    // Need this done first to determine overflow.
-    ASSERT(!m_renderView->needsLayout());
-    if (isMainFrame())
-        return false;
-
-    if (!(m_compositingTriggers & ChromeClient::ScrollableInnerFrameTrigger))
-        return false;
-
-    FrameView* frameView = m_renderView->frameView();
-    return frameView->isScrollable();
-}
-
-bool RenderLayerCompositor::requiresCompositingForTransform(RenderObject* renderer) const
-{
-    if (!(m_compositingTriggers & ChromeClient::ThreeDTransformTrigger))
-        return false;
-
-    RenderStyle* style = renderer->style();
-    // Note that we ask the renderer if it has a transform, because the style may have transforms,
-    // but the renderer may be an inline that doesn't suppport them.
-    return renderer->hasTransform() && style->transform().has3DOperation();
-}
-
-bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer) const
-{
-    if (RuntimeEnabledFeatures::overlayFullscreenVideoEnabled() && renderer->isVideo()) {
-        HTMLMediaElement* media = toHTMLMediaElement(renderer->node());
-        if (media->isFullscreen())
-            return true;
-    }
-
-    if (!(m_compositingTriggers & ChromeClient::VideoTrigger))
-        return false;
-
-    if (renderer->isVideo()) {
-        RenderVideo* video = toRenderVideo(renderer);
-        return video->shouldDisplayVideo() && canAccelerateVideoRendering(video);
-    }
-    return false;
-}
-
-bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
-{
-    if (!(m_compositingTriggers & ChromeClient::CanvasTrigger))
-        return false;
-
-    if (renderer->isCanvas()) {
-        HTMLCanvasElement* canvas = toHTMLCanvasElement(renderer->node());
-        return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
-    }
-    return false;
-}
-
-bool RenderLayerCompositor::requiresCompositingForPlugin(RenderObject* renderer) const
-{
-    if (!(m_compositingTriggers & ChromeClient::PluginTrigger))
-        return false;
-
-    bool composite = renderer->isEmbeddedObject() && toRenderEmbeddedObject(renderer)->allowsAcceleratedCompositing();
-    if (!composite)
-        return false;
-
-    // FIXME: this seems bogus. If we don't know the layout position/size of the plugin yet, would't that be handled elsewhere?
-    m_needsToRecomputeCompositingRequirements = true;
-
-    RenderWidget* pluginRenderer = toRenderWidget(renderer);
-    // If we can't reliably know the size of the plugin yet, don't change compositing state.
-    if (pluginRenderer->needsLayout())
-        return pluginRenderer->hasLayer() && pluginRenderer->layer()->hasCompositedLayerMapping();
-
-    // Don't go into compositing mode if height or width are zero, or size is 1x1.
-    IntRect contentBox = pixelSnappedIntRect(pluginRenderer->contentBoxRect());
-    return contentBox.height() * contentBox.width() > 1;
-}
-
-bool RenderLayerCompositor::requiresCompositingForFrame(RenderObject* renderer) const
-{
-    if (!renderer->isRenderPart())
-        return false;
-
-    RenderPart* frameRenderer = toRenderPart(renderer);
-
-    if (!frameRenderer->requiresAcceleratedCompositing())
-        return false;
-
-    if (frameRenderer->node() && frameRenderer->node()->isFrameOwnerElement() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame() && toHTMLFrameOwnerElement(frameRenderer->node())->contentFrame()->remotePlatformLayer())
-        return true;
-
-    // FIXME: this seems bogus. If we don't know the layout position/size of the frame yet, wouldn't that be handled elsehwere?
-    m_needsToRecomputeCompositingRequirements = true;
-
-    RenderLayerCompositor* innerCompositor = frameContentsCompositor(frameRenderer);
-    if (!innerCompositor)
-        return false;
-
-    // If we can't reliably know the size of the iframe yet, don't change compositing state.
-    if (renderer->needsLayout())
-        return frameRenderer->hasLayer() && frameRenderer->layer()->hasCompositedLayerMapping();
-
-    // Don't go into compositing mode if height or width are zero.
-    IntRect contentBox = pixelSnappedIntRect(frameRenderer->contentBoxRect());
-    return contentBox.height() * contentBox.width() > 0;
-}
-
-bool RenderLayerCompositor::requiresCompositingForBackfaceVisibilityHidden(RenderObject* renderer) const
-{
-    return canRender3DTransforms() && renderer->style()->backfaceVisibility() == BackfaceVisibilityHidden;
-}
-
-bool RenderLayerCompositor::requiresCompositingForAnimation(RenderObject* renderer) const
-{
-    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
-        return false;
-
-    return shouldCompositeForActiveAnimations(*renderer);
-}
-
-bool RenderLayerCompositor::requiresCompositingForTransition(RenderObject* renderer) const
-{
-    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
-        return false;
-
-    if (Settings* settings = m_renderView->document().settings()) {
-        if (!settings->acceleratedCompositingForTransitionEnabled())
-            return false;
-    }
-
-    return renderer->style()->transitionForProperty(CSSPropertyOpacity)
-        || renderer->style()->transitionForProperty(CSSPropertyWebkitFilter)
-        || renderer->style()->transitionForProperty(CSSPropertyWebkitTransform);
-}
-
 CompositingReasons RenderLayerCompositor::subtreeReasonsForCompositing(RenderObject* renderer, bool hasCompositedDescendants, bool has3DTransformedDescendants) const
 {
     CompositingReasons subtreeReasons = CompositingReasonNone;
@@ -1999,160 +1652,18 @@
     // will be affected by the preserve-3d or perspective.
     if (has3DTransformedDescendants) {
         if (renderer->style()->transformStyle3D() == TransformStyle3DPreserve3D)
-            subtreeReasons |= CompositingReasonPreserve3D;
+            subtreeReasons |= CompositingReasonPreserve3DWith3DDescendants;
 
         if (renderer->style()->hasPerspective())
-            subtreeReasons |= CompositingReasonPerspective;
+            subtreeReasons |= CompositingReasonPerspectiveWith3DDescendants;
     }
 
     return subtreeReasons;
 }
 
-bool RenderLayerCompositor::requiresCompositingForFilters(RenderObject* renderer) const
-{
-    if (!(m_compositingTriggers & ChromeClient::FilterTrigger))
-        return false;
-
-    return renderer->hasFilter();
-}
-
-bool RenderLayerCompositor::requiresCompositingForOverflowScrollingParent(const RenderLayer* layer) const
-{
-    return !!layer->scrollParent();
-}
-
-bool RenderLayerCompositor::requiresCompositingForOutOfFlowClipping(const RenderLayer* layer) const
-{
-    return m_renderView->compositorDrivenAcceleratedScrollingEnabled() && layer->isUnclippedDescendant();
-}
-
-static bool isViewportConstrainedFixedOrStickyLayer(const RenderLayer* layer)
-{
-    if (layer->renderer()->isStickyPositioned())
-        return !layer->enclosingOverflowClipLayer(ExcludeSelf);
-
-    if (layer->renderer()->style()->position() != FixedPosition)
-        return false;
-
-    for (const RenderLayerStackingNode* stackingContainer = layer->stackingNode(); stackingContainer;
-        stackingContainer = stackingContainer->ancestorStackingContainerNode()) {
-        if (stackingContainer->layer()->compositingState() != NotComposited
-            && stackingContainer->layer()->renderer()->style()->position() == FixedPosition)
-            return false;
-    }
-
-    return true;
-}
-
-bool RenderLayerCompositor::requiresCompositingForPosition(RenderObject* renderer, const RenderLayer* layer, RenderLayer::ViewportConstrainedNotCompositedReason* viewportConstrainedNotCompositedReason) const
-{
-    // position:fixed elements that create their own stacking context (e.g. have an explicit z-index,
-    // opacity, transform) can get their own composited layer. A stacking context is required otherwise
-    // z-index and clipping will be broken.
-    if (!renderer->isPositioned())
-        return false;
-
-    EPosition position = renderer->style()->position();
-    bool isFixed = renderer->isOutOfFlowPositioned() && position == FixedPosition;
-    if (isFixed && !layer->stackingNode()->isStackingContainer())
-        return false;
-
-    bool isSticky = renderer->isInFlowPositioned() && position == StickyPosition;
-    if (!isFixed && !isSticky)
-        return false;
-
-    // FIXME: acceleratedCompositingForFixedPositionEnabled should probably be renamed acceleratedCompositingForViewportConstrainedPositionEnabled().
-    if (Settings* settings = m_renderView->document().settings()) {
-        if (!settings->acceleratedCompositingForFixedPositionEnabled())
-            return false;
-    }
-
-    if (isSticky)
-        return isViewportConstrainedFixedOrStickyLayer(layer);
-
-    RenderObject* container = renderer->container();
-    // If the renderer is not hooked up yet then we have to wait until it is.
-    if (!container) {
-        m_needsToRecomputeCompositingRequirements = true;
-        return false;
-    }
-
-    // Don't promote fixed position elements that are descendants of a non-view container, e.g. transformed elements.
-    // They will stay fixed wrt the container rather than the enclosing frame.
-    if (container != m_renderView) {
-        if (viewportConstrainedNotCompositedReason)
-            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNonViewContainer;
-        return false;
-    }
-
-    // If the fixed-position element does not have any scrollable ancestor between it and
-    // its container, then we do not need to spend compositor resources for it. Start by
-    // assuming we can opt-out (i.e. no scrollable ancestor), and refine the answer below.
-    bool hasScrollableAncestor = false;
-
-    // The FrameView has the scrollbars associated with the top level viewport, so we have to
-    // check the FrameView in addition to the hierarchy of ancestors.
-    FrameView* frameView = m_renderView->frameView();
-    if (frameView && frameView->isScrollable())
-        hasScrollableAncestor = true;
-
-    RenderLayer* ancestor = layer->parent();
-    while (ancestor && !hasScrollableAncestor) {
-        if (frameView->containsScrollableArea(ancestor->scrollableArea()))
-            hasScrollableAncestor = true;
-        if (ancestor->renderer() == m_renderView)
-            break;
-        ancestor = ancestor->parent();
-    }
-
-    if (!hasScrollableAncestor) {
-        if (viewportConstrainedNotCompositedReason)
-            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForUnscrollableAncestors;
-        return false;
-    }
-
-    // Subsequent tests depend on layout. If we can't tell now, just keep things the way they are until layout is done.
-    if (!m_inPostLayoutUpdate) {
-        m_needsToRecomputeCompositingRequirements = true;
-        return layer->hasCompositedLayerMapping();
-    }
-
-    bool paintsContent = layer->isVisuallyNonEmpty() || layer->hasVisibleDescendant();
-    if (!paintsContent) {
-        if (viewportConstrainedNotCompositedReason)
-            *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForNoVisibleContent;
-        return false;
-    }
-
-    // Fixed position elements that are invisible in the current view don't get their own layer.
-    if (FrameView* frameView = m_renderView->frameView()) {
-        LayoutRect viewBounds = frameView->viewportConstrainedVisibleContentRect();
-        LayoutRect layerBounds = layer->calculateLayerBounds(rootRenderLayer(), 0,
-            RenderLayer::DefaultCalculateLayerBoundsFlags
-            | RenderLayer::ExcludeHiddenDescendants
-            | RenderLayer::DontConstrainForMask
-            | RenderLayer::IncludeCompositedDescendants
-            | RenderLayer::PretendLayerHasOwnBacking);
-        if (!viewBounds.intersects(enclosingIntRect(layerBounds))) {
-            if (viewportConstrainedNotCompositedReason) {
-                *viewportConstrainedNotCompositedReason = RenderLayer::NotCompositedForBoundsOutOfView;
-                m_needsToRecomputeCompositingRequirements = true;
-            }
-            return false;
-        }
-    }
-
-    return true;
-}
-
-bool RenderLayerCompositor::requiresCompositingForOverflowScrolling(const RenderLayer* layer) const
-{
-    return layer->needsCompositedScrolling();
-}
-
 bool RenderLayerCompositor::isRunningAcceleratedTransformAnimation(RenderObject* renderer) const
 {
-    if (!(m_compositingTriggers & ChromeClient::AnimationTrigger))
+    if (!m_compositingReasonFinder.hasAnimationTrigger())
         return false;
     return hasActiveAnimations(*renderer, CSSPropertyWebkitTransform);
 }
@@ -2182,23 +1693,23 @@
 void RenderLayerCompositor::paintContents(const GraphicsLayer* graphicsLayer, GraphicsContext& context, GraphicsLayerPaintingPhase, const IntRect& clip)
 {
     if (graphicsLayer == layerForHorizontalScrollbar())
-        paintScrollbar(m_renderView->frameView()->horizontalScrollbar(), context, clip);
+        paintScrollbar(m_renderView.frameView()->horizontalScrollbar(), context, clip);
     else if (graphicsLayer == layerForVerticalScrollbar())
-        paintScrollbar(m_renderView->frameView()->verticalScrollbar(), context, clip);
+        paintScrollbar(m_renderView.frameView()->verticalScrollbar(), context, clip);
     else if (graphicsLayer == layerForScrollCorner()) {
-        const IntRect& scrollCorner = m_renderView->frameView()->scrollCornerRect();
+        const IntRect& scrollCorner = m_renderView.frameView()->scrollCornerRect();
         context.save();
         context.translate(-scrollCorner.x(), -scrollCorner.y());
         IntRect transformedClip = clip;
         transformedClip.moveBy(scrollCorner.location());
-        m_renderView->frameView()->paintScrollCorner(&context, transformedClip);
+        m_renderView.frameView()->paintScrollCorner(&context, transformedClip);
         context.restore();
     }
 }
 
 bool RenderLayerCompositor::supportsFixedRootBackgroundCompositing() const
 {
-    if (Settings* settings = m_renderView->document().settings()) {
+    if (Settings* settings = m_renderView.document().settings()) {
         if (settings->acceleratedCompositingForFixedRootBackgroundEnabled())
             return true;
     }
@@ -2207,16 +1718,16 @@
 
 bool RenderLayerCompositor::needsFixedRootBackgroundLayer(const RenderLayer* layer) const
 {
-    if (layer != m_renderView->layer())
+    if (layer != m_renderView.layer())
         return false;
 
-    return supportsFixedRootBackgroundCompositing() && m_renderView->rootBackgroundIsEntirelyFixed();
+    return supportsFixedRootBackgroundCompositing() && m_renderView.rootBackgroundIsEntirelyFixed();
 }
 
 GraphicsLayer* RenderLayerCompositor::fixedRootBackgroundLayer() const
 {
     // Get the fixed root background from the RenderView layer's compositedLayerMapping.
-    RenderLayer* viewLayer = m_renderView->layer();
+    RenderLayer* viewLayer = m_renderView.layer();
     if (!viewLayer)
         return 0;
 
@@ -2276,19 +1787,19 @@
 
 bool RenderLayerCompositor::requiresHorizontalScrollbarLayer() const
 {
-    FrameView* view = m_renderView->frameView();
+    FrameView* view = m_renderView.frameView();
     return shouldCompositeOverflowControls(view) && view->horizontalScrollbar();
 }
 
 bool RenderLayerCompositor::requiresVerticalScrollbarLayer() const
 {
-    FrameView* view = m_renderView->frameView();
+    FrameView* view = m_renderView.frameView();
     return shouldCompositeOverflowControls(view) && view->verticalScrollbar();
 }
 
 bool RenderLayerCompositor::requiresScrollCornerLayer() const
 {
-    FrameView* view = m_renderView->frameView();
+    FrameView* view = m_renderView.frameView();
     return shouldCompositeOverflowControls(view) && view->isScrollCornerVisible();
 }
 
@@ -2300,7 +1811,7 @@
         return false;
 
     // We do want a layer if we have a scrolling coordinator and can scroll.
-    if (scrollingCoordinator() && m_renderView->frameView()->hasOpaqueBackground())
+    if (scrollingCoordinator() && m_renderView.frameView()->hasOpaqueBackground())
         return true;
 
     // Chromium always wants a layer.
@@ -2325,50 +1836,51 @@
         }
     }
 #endif
+    GraphicsLayer* controlsParent = m_rootTransformLayer.get() ? m_rootTransformLayer.get() : m_overflowControlsHostLayer.get();
 
     if (requiresHorizontalScrollbarLayer()) {
         if (!m_layerForHorizontalScrollbar) {
             m_layerForHorizontalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
-            m_overflowControlsHostLayer->addChild(m_layerForHorizontalScrollbar.get());
+            controlsParent->addChild(m_layerForHorizontalScrollbar.get());
 
             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
+                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
         }
     } else if (m_layerForHorizontalScrollbar) {
         m_layerForHorizontalScrollbar->removeFromParent();
         m_layerForHorizontalScrollbar = nullptr;
 
         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
+            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
     }
 
     if (requiresVerticalScrollbarLayer()) {
         if (!m_layerForVerticalScrollbar) {
             m_layerForVerticalScrollbar = GraphicsLayer::create(graphicsLayerFactory(), this);
-            m_overflowControlsHostLayer->addChild(m_layerForVerticalScrollbar.get());
+            controlsParent->addChild(m_layerForVerticalScrollbar.get());
 
             if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
+                scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
         }
     } else if (m_layerForVerticalScrollbar) {
         m_layerForVerticalScrollbar->removeFromParent();
         m_layerForVerticalScrollbar = nullptr;
 
         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
+            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
     }
 
     if (requiresScrollCornerLayer()) {
         if (!m_layerForScrollCorner) {
             m_layerForScrollCorner = GraphicsLayer::create(graphicsLayerFactory(), this);
-            m_overflowControlsHostLayer->addChild(m_layerForScrollCorner.get());
+            controlsParent->addChild(m_layerForScrollCorner.get());
         }
     } else if (m_layerForScrollCorner) {
         m_layerForScrollCorner->removeFromParent();
         m_layerForScrollCorner = nullptr;
     }
 
-    m_renderView->frameView()->positionScrollbarLayers();
+    m_renderView.frameView()->positionScrollbarLayers();
 }
 
 void RenderLayerCompositor::ensureRootLayer()
@@ -2379,7 +1891,7 @@
 
     if (!m_rootContentLayer) {
         m_rootContentLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
-        IntRect overflowRect = m_renderView->pixelSnappedLayoutOverflowRect();
+        IntRect overflowRect = m_renderView.pixelSnappedLayoutOverflowRect();
         m_rootContentLayer->setSize(FloatSize(overflowRect.maxX(), overflowRect.maxY()));
         m_rootContentLayer->setPosition(FloatPoint());
 
@@ -2397,7 +1909,7 @@
         // Create a clipping layer if this is an iframe or settings require to clip.
         m_containerLayer = GraphicsLayer::create(graphicsLayerFactory(), this);
         bool containerMasksToBounds = !isMainFrame();
-        if (Settings* settings = m_renderView->document().settings()) {
+        if (Settings* settings = m_renderView.document().settings()) {
             if (settings->mainFrameClipsContent())
                 containerMasksToBounds = true;
         }
@@ -2441,23 +1953,23 @@
         m_layerForHorizontalScrollbar->removeFromParent();
         m_layerForHorizontalScrollbar = nullptr;
         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), HorizontalScrollbar);
-        if (Scrollbar* horizontalScrollbar = m_renderView->frameView()->verticalScrollbar())
-            m_renderView->frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
+            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), HorizontalScrollbar);
+        if (Scrollbar* horizontalScrollbar = m_renderView.frameView()->verticalScrollbar())
+            m_renderView.frameView()->invalidateScrollbar(horizontalScrollbar, IntRect(IntPoint(0, 0), horizontalScrollbar->frameRect().size()));
     }
 
     if (m_layerForVerticalScrollbar) {
         m_layerForVerticalScrollbar->removeFromParent();
         m_layerForVerticalScrollbar = nullptr;
         if (ScrollingCoordinator* scrollingCoordinator = this->scrollingCoordinator())
-            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView->frameView(), VerticalScrollbar);
-        if (Scrollbar* verticalScrollbar = m_renderView->frameView()->verticalScrollbar())
-            m_renderView->frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
+            scrollingCoordinator->scrollableAreaScrollbarLayerDidChange(m_renderView.frameView(), VerticalScrollbar);
+        if (Scrollbar* verticalScrollbar = m_renderView.frameView()->verticalScrollbar())
+            m_renderView.frameView()->invalidateScrollbar(verticalScrollbar, IntRect(IntPoint(0, 0), verticalScrollbar->frameRect().size()));
     }
 
     if (m_layerForScrollCorner) {
         m_layerForScrollCorner = nullptr;
-        m_renderView->frameView()->invalidateScrollCorner(m_renderView->frameView()->scrollCornerRect());
+        m_renderView.frameView()->invalidateScrollCorner(m_renderView.frameView()->scrollCornerRect());
     }
 
     if (m_overflowControlsHostLayer) {
@@ -2467,6 +1979,7 @@
     }
     ASSERT(!m_scrollLayer);
     m_rootContentLayer = nullptr;
+    m_rootTransformLayer = nullptr;
 }
 
 void RenderLayerCompositor::attachRootLayer(RootLayerAttachment attachment)
@@ -2479,15 +1992,15 @@
             ASSERT_NOT_REACHED();
             break;
         case RootLayerAttachedViaChromeClient: {
-            Frame& frame = m_renderView->frameView()->frame();
+            LocalFrame& frame = m_renderView.frameView()->frame();
             Page* page = frame.page();
             if (!page)
                 return;
-            page->chrome().client().attachRootGraphicsLayer(&frame, rootGraphicsLayer());
+            page->chrome().client().attachRootGraphicsLayer(rootGraphicsLayer());
             break;
         }
         case RootLayerAttachedViaEnclosingFrame: {
-            HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement();
+            HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement();
             ASSERT(ownerElement);
             DeprecatedScheduleStyleRecalcDuringCompositingUpdate marker(ownerElement->document().lifecycle());
             // The layer will get hooked up via CompositedLayerMapping::updateGraphicsLayerConfiguration()
@@ -2514,18 +2027,18 @@
         else
             m_rootContentLayer->removeFromParent();
 
-        if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement()) {
+        if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
             DeprecatedScheduleStyleRecalcDuringCompositingUpdate marker(ownerElement->document().lifecycle());
             ownerElement->scheduleLayerUpdate();
         }
         break;
     }
     case RootLayerAttachedViaChromeClient: {
-        Frame& frame = m_renderView->frameView()->frame();
+        LocalFrame& frame = m_renderView.frameView()->frame();
         Page* page = frame.page();
         if (!page)
             return;
-        page->chrome().client().attachRootGraphicsLayer(&frame, 0);
+        page->chrome().client().attachRootGraphicsLayer(0);
     }
     break;
     case RootLayerUnattached:
@@ -2542,8 +2055,8 @@
 
 bool RenderLayerCompositor::isMainFrame() const
 {
-    // FIXME: Frame::isMainFrame() is probably better.
-    return !m_renderView->document().ownerElement();
+    // FIXME: LocalFrame::isMainFrame() is probably better.
+    return !m_renderView.document().ownerElement();
 }
 
 // IFrames are special, because we hook compositing layers together across iframe boundaries
@@ -2551,11 +2064,11 @@
 // to use a synthetic style change to get the iframes into RenderLayers in order to allow them to composite.
 void RenderLayerCompositor::notifyIFramesOfCompositingChange()
 {
-    if (!m_renderView->frameView())
+    if (!m_renderView.frameView())
         return;
-    Frame& frame = m_renderView->frameView()->frame();
+    LocalFrame& frame = m_renderView.frameView()->frame();
 
-    for (Frame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) {
+    for (LocalFrame* child = frame.tree().firstChild(); child; child = child->tree().traverseNext(&frame)) {
         if (!child->document())
             continue; // FIXME: Can this happen?
         if (HTMLFrameOwnerElement* ownerElement = child->document()->ownerElement()) {
@@ -2566,7 +2079,7 @@
 
     // Compositing also affects the answer to RenderIFrame::requiresAcceleratedCompositing(), so
     // we need to schedule a style recalc in our parent document.
-    if (HTMLFrameOwnerElement* ownerElement = m_renderView->document().ownerElement()) {
+    if (HTMLFrameOwnerElement* ownerElement = m_renderView.document().ownerElement()) {
         ownerElement->document().renderView()->compositor()->setNeedsToRecomputeCompositingRequirements();
         DeprecatedScheduleStyleRecalcDuringCompositingUpdate marker(ownerElement->document().lifecycle());
         ownerElement->scheduleLayerUpdate();
@@ -2601,7 +2114,7 @@
 
 void RenderLayerCompositor::updateViewportConstraintStatus(RenderLayer* layer)
 {
-    if (isViewportConstrainedFixedOrStickyLayer(layer))
+    if (CompositingReasonFinder::isViewportConstrainedFixedOrStickyLayer(layer))
         addViewportConstrainedLayer(layer);
     else
         removeViewportConstrainedLayer(layer);
@@ -2624,7 +2137,7 @@
 {
     ASSERT(layer->hasCompositedLayerMapping());
 
-    FrameView* frameView = m_renderView->frameView();
+    FrameView* frameView = m_renderView.frameView();
     LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect();
 
     FixedPositionViewportConstraints constraints;
@@ -2664,7 +2177,7 @@
     // We should never get here for stickies constrained by an enclosing clipping layer.
     ASSERT(!layer->enclosingOverflowClipLayer(ExcludeSelf));
 
-    FrameView* frameView = m_renderView->frameView();
+    FrameView* frameView = m_renderView.frameView();
     LayoutRect viewportRect = frameView->viewportConstrainedVisibleContentRect();
 
     StickyPositionViewportConstraints constraints;
@@ -2698,12 +2211,12 @@
 
 Page* RenderLayerCompositor::page() const
 {
-    return m_renderView->frameView()->frame().page();
+    return m_renderView.frameView()->frame().page();
 }
 
 DocumentLifecycle& RenderLayerCompositor::lifecycle() const
 {
-    return m_renderView->document().lifecycle();
+    return m_renderView.document().lifecycle();
 }
 
 String RenderLayerCompositor::debugName(const GraphicsLayer* graphicsLayer)
@@ -2711,6 +2224,8 @@
     String name;
     if (graphicsLayer == m_rootContentLayer.get()) {
         name = "Content Root Layer";
+    } else if (graphicsLayer == m_rootTransformLayer.get()) {
+        name = "Root Transform Layer";
 #if USE(RUBBER_BANDING)
     } else if (graphicsLayer == m_layerForOverhangShadow.get()) {
         name = "Overhang Areas Shadow";
@@ -2724,9 +2239,9 @@
     } else if (graphicsLayer == m_layerForScrollCorner.get()) {
         name = "Scroll Corner Layer";
     } else if (graphicsLayer == m_containerLayer.get()) {
-        name = "Frame Clipping Layer";
+        name = "LocalFrame Clipping Layer";
     } else if (graphicsLayer == m_scrollLayer.get()) {
-        name = "Frame Scrolling Layer";
+        name = "LocalFrame Scrolling Layer";
     } else {
         ASSERT_NOT_REACHED();
     }
diff --git a/Source/core/rendering/RenderLayerCompositor.h b/Source/core/rendering/compositing/RenderLayerCompositor.h
similarity index 81%
rename from Source/core/rendering/RenderLayerCompositor.h
rename to Source/core/rendering/compositing/RenderLayerCompositor.h
index dcac830..00cfd63 100644
--- a/Source/core/rendering/RenderLayerCompositor.h
+++ b/Source/core/rendering/compositing/RenderLayerCompositor.h
@@ -28,6 +28,8 @@
 
 #include "core/page/ChromeClient.h"
 #include "core/rendering/RenderLayer.h"
+#include "core/rendering/compositing/CompositingReasonFinder.h"
+#include "core/rendering/compositing/GraphicsLayerUpdater.h"
 #include "platform/graphics/GraphicsLayerClient.h"
 #include "wtf/HashMap.h"
 
@@ -42,12 +44,12 @@
 class ScrollingCoordinator;
 class StickyPositionViewportConstraints;
 
-
 enum CompositingUpdateType {
     CompositingUpdateAfterStyleChange,
     CompositingUpdateAfterLayout,
     CompositingUpdateOnScroll,
     CompositingUpdateOnCompositedScroll,
+    CompositingUpdateAfterCanvasContextChange
 };
 
 // RenderLayerCompositor manages the hierarchy of
@@ -60,7 +62,8 @@
 class RenderLayerCompositor FINAL : public GraphicsLayerClient {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit RenderLayerCompositor(RenderView*);
+    // FIXME: This constructor should take a reference.
+    explicit RenderLayerCompositor(RenderView&);
     virtual ~RenderLayerCompositor();
 
     // Return true if this RenderView is in "compositing mode" (i.e. has one or more
@@ -83,7 +86,7 @@
 
     // Called when the layer hierarchy needs to be updated (compositing layers have been
     // created, destroyed or re-parented).
-    void setCompositingLayersNeedRebuild(bool needRebuild = true);
+    void setCompositingLayersNeedRebuild();
     bool compositingLayersNeedRebuild() const { return m_compositingLayersNeedRebuild; }
 
     // Updating properties required for determining if compositing is necessary.
@@ -98,9 +101,14 @@
     // composited layer tree.
     void updateCompositingLayers();
 
+    enum UpdateLayerCompositingStateOptions {
+        Normal,
+        UseChickenEggHacks, // Use this to trigger temporary chicken-egg hacks. See crbug.com/339892.
+    };
+
     // Update the compositing dirty bits, based on the compositing-impacting properties of the layer.
     // (At the moment, it also has some legacy compatibility hacks.)
-    void updateLayerCompositingState(RenderLayer*);
+    void updateLayerCompositingState(RenderLayer*, UpdateLayerCompositingStateOptions = Normal);
 
     // Update the geometry for compositing children of compositingAncestor.
     void updateCompositingDescendantGeometry(RenderLayerStackingNode* compositingAncestor, RenderLayer*, bool compositedChildrenOnly);
@@ -130,17 +138,17 @@
     void layerWasAdded(RenderLayer* parent, RenderLayer* child);
     void layerWillBeRemoved(RenderLayer* parent, RenderLayer* child);
 
-    // Get the nearest ancestor layer that has overflow or clip, but is not a stacking context
-    RenderLayer* enclosingNonStackingClippingLayer(const RenderLayer* layer) const;
-
-    // Repaint parts of all composited layers that intersect the given absolute rectangle (or the entire layer if the pointer is null).
-    void repaintCompositedLayers(const IntRect* = 0);
+    void repaintCompositedLayers();
 
     RenderLayer* rootRenderLayer() const;
     GraphicsLayer* rootGraphicsLayer() const;
     GraphicsLayer* scrollLayer() const;
     GraphicsLayer* containerLayer() const;
 
+    // We don't always have a root transform layer. This function lazily allocates one
+    // and returns it as required.
+    GraphicsLayer* ensureRootTransformLayer();
+
     enum RootLayerAttachment {
         RootLayerUnattached,
         RootLayerAttachedViaChromeClient,
@@ -155,9 +163,6 @@
 
     void clearMappingForAllRenderLayers();
 
-    // Use by RenderVideo to ask if it should try to use accelerated compositing.
-    bool canAccelerateVideoRendering(RenderVideo*) const;
-
     // Walk the tree looking for layers with 3d transforms. Useful in case you need
     // to know if there is non-affine content, e.g. for drawing into an image.
     bool has3DContent() const;
@@ -170,7 +175,6 @@
     void frameViewDidChangeLocation(const IntPoint& contentsOffset);
     void frameViewDidChangeSize();
     void frameViewDidScroll();
-    void frameViewDidLayout();
     void frameViewScrollbarsExistenceDidChange();
     void rootFixedBackgroundsChanged();
 
@@ -210,9 +214,10 @@
         SquashingState()
             : mostRecentMapping(0)
             , hasMostRecentMapping(false)
-            , nextSquashedLayerIndex(0) { }
+            , nextSquashedLayerIndex(0)
+            , clippingAncestorForMostRecentMapping(0) { }
 
-        void updateSquashingStateForNewMapping(CompositedLayerMappingPtr, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsoluteForSquashingCLM);
+        void updateSquashingStateForNewMapping(CompositedLayerMappingPtr, bool hasNewCompositedLayerMapping, IntPoint newOffsetFromAbsoluteForSquashingCLM, RenderLayer* clippingAncestorForMostRecentMapping);
 
         // The most recent composited backing that the layer should squash onto if needed.
         CompositedLayerMappingPtr mostRecentMapping;
@@ -224,15 +229,19 @@
 
         // Counter that tracks what index the next RenderLayer would be if it gets squashed to the current squashing layer.
         size_t nextSquashedLayerIndex;
+
+        RenderLayer* clippingAncestorForMostRecentMapping;
     };
 
-    CompositingStateTransitionType computeCompositedLayerUpdate(const RenderLayer*);
+    bool canSquashIntoCurrentSquashingOwner(const RenderLayer* candidate, const SquashingState&, const RenderLayer* clippingAncestor);
+
+    CompositingStateTransitionType computeCompositedLayerUpdate(RenderLayer*);
     // Make updates to the layer based on viewport-constrained properties such as position:fixed. This can in turn affect
     // compositing.
     bool updateLayerIfViewportConstrained(RenderLayer*);
 
     // GraphicsLayerClient implementation
-    virtual void notifyAnimationStarted(const GraphicsLayer*, double, double) OVERRIDE { }
+    virtual void notifyAnimationStarted(const GraphicsLayer*, double) OVERRIDE { }
     virtual void paintContents(const GraphicsLayer*, GraphicsContext&, GraphicsLayerPaintingPhase, const IntRect&) OVERRIDE;
 
     virtual bool isTrackingRepaints() const OVERRIDE;
@@ -242,44 +251,37 @@
     // Whether the layer could ever be composited.
     bool canBeComposited(const RenderLayer*) const;
 
-    // Returns all direct reasons that a layer should be composited.
-    CompositingReasons directReasonsForCompositing(const RenderLayer*) const;
-
     void updateDirectCompositingReasons(RenderLayer*);
 
+    void updateCompositingLayersInternal();
+
     // Returns indirect reasons that a layer should be composited because of something in its subtree.
     CompositingReasons subtreeReasonsForCompositing(RenderObject*, bool hasCompositedDescendants, bool has3DTransformedDescendants) const;
 
     // Make or destroy the CompositedLayerMapping for this layer; returns true if the compositedLayerMapping changed.
-    bool allocateOrClearCompositedLayerMapping(RenderLayer*);
-    bool updateSquashingAssignment(RenderLayer*, SquashingState&);
+    bool allocateOrClearCompositedLayerMapping(RenderLayer*, CompositingStateTransitionType compositedLayerUpdate);
+    bool updateSquashingAssignment(RenderLayer*, SquashingState&, CompositingStateTransitionType compositedLayerUpdate);
 
     void clearMappingForRenderLayerIncludingDescendants(RenderLayer*);
 
-    // Repaint the given rect (which is layer's coords), and regions of child layers that intersect that rect.
-    void recursiveRepaintLayer(RenderLayer*, const IntRect* = 0);
+    void recursiveRepaintLayer(RenderLayer*);
 
-    void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds, bool& boundsComputed);
-    void addToOverlapMapRecursive(OverlapMap&, RenderLayer*, RenderLayer* ancestorLayer = 0);
+    void addToOverlapMap(OverlapMap&, RenderLayer*, IntRect& layerBounds);
 
     // Forces an update for all frames of frame tree recursively. Used only when the mainFrame compositor is ready to
     // finish all deferred work.
-    static void finishCompositingUpdateForFrameTree(Frame*);
+    static void finishCompositingUpdateForFrameTree(LocalFrame*);
 
-    // Returns true if any layer's compositing changed
-    void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingRecursionData&, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants);
+    void computeCompositingRequirements(RenderLayer* ancestorLayer, RenderLayer*, OverlapMap*, struct CompositingRecursionData&, bool& descendantHas3DTransform, Vector<RenderLayer*>& unclippedDescendants, IntRect& absoluteDecendantBoundingBox);
 
     // Defines which RenderLayers will paint into which composited backings, by allocating and destroying CompositedLayerMappings as needed.
     void assignLayersToBackings(RenderLayer*, bool& layersChanged);
-    void assignLayersToBackingsInternal(RenderLayer*, SquashingState&, bool& layersChanged);
+    void assignLayersToBackingsInternal(RenderLayer*, SquashingState&, bool& layersChanged, RenderLayer* clippingAncestor);
 
     // Allocates, sets up hierarchy, and sets appropriate properties for the GraphicsLayers that correspond to a given
     // composited RenderLayer. Does nothing if the given RenderLayer does not have a CompositedLayerMapping.
     void updateGraphicsLayersMappedToRenderLayer(RenderLayer*);
 
-    // Recurses down the tree, parenting descendant compositing layers and collecting an array of child layers for the current compositing layer.
-    void rebuildCompositingLayerTree(RenderLayer*, Vector<GraphicsLayer*>& childGraphicsLayersOfEnclosingLayer, int depth);
-
     // Recurses down the tree, updating layer geometry only.
     void updateLayerTreeGeometry(RenderLayer*);
 
@@ -309,23 +311,6 @@
     GraphicsLayerFactory* graphicsLayerFactory() const;
     ScrollingCoordinator* scrollingCoordinator() const;
 
-    // Whether a running transition or animation enforces the need for a compositing layer.
-    bool requiresCompositingForAnimation(RenderObject*) const;
-    // Whether a (not necessarily running) transition enforces the need for a compositing layer.
-    bool requiresCompositingForTransition(RenderObject*) const;
-    bool requiresCompositingForTransform(RenderObject*) const;
-    bool requiresCompositingForVideo(RenderObject*) const;
-    bool requiresCompositingForCanvas(RenderObject*) const;
-    bool requiresCompositingForPlugin(RenderObject*) const;
-    bool requiresCompositingForFrame(RenderObject*) const;
-    bool requiresCompositingForBackfaceVisibilityHidden(RenderObject*) const;
-    bool requiresCompositingForFilters(RenderObject*) const;
-    bool requiresCompositingForOverflowScrollingParent(const RenderLayer*) const;
-    bool requiresCompositingForOutOfFlowClipping(const RenderLayer*) const;
-    bool requiresCompositingForScrollableFrame() const;
-    bool requiresCompositingForPosition(RenderObject*, const RenderLayer*, RenderLayer::ViewportConstrainedNotCompositedReason* = 0) const;
-    bool requiresCompositingForOverflowScrolling(const RenderLayer*) const;
-
     void addViewportConstrainedLayer(RenderLayer*);
 
     FixedPositionViewportConstraints computeFixedViewportConstraints(RenderLayer*) const;
@@ -344,22 +329,23 @@
 private:
     DocumentLifecycle& lifecycle() const;
 
-    RenderView* m_renderView;
+    RenderView& m_renderView;
     OwnPtr<GraphicsLayer> m_rootContentLayer;
+    OwnPtr<GraphicsLayer> m_rootTransformLayer;
+
+    CompositingReasonFinder m_compositingReasonFinder;
 
     bool m_hasAcceleratedCompositing;
-    ChromeClient::CompositingTriggerFlags m_compositingTriggers;
-
     bool m_showRepaintCounter;
 
     // FIXME: This should absolutely not be mutable.
     mutable bool m_needsToRecomputeCompositingRequirements;
     bool m_needsToUpdateLayerTreeGeometry;
+    GraphicsLayerUpdater::UpdateType m_pendingUpdateType;
 
     bool m_compositing;
     bool m_compositingLayersNeedRebuild;
     bool m_forceCompositingMode;
-    bool m_inPostLayoutUpdate; // true when it's OK to trust layout information (e.g. layer sizes and positions)
     bool m_needsUpdateCompositingRequirementsState;
 
     bool m_isTrackingRepaints; // Used for testing.
diff --git a/Source/core/rendering/line/BreakingContextInlineHeaders.h b/Source/core/rendering/line/BreakingContextInlineHeaders.h
index 5d74124..c7de49c 100644
--- a/Source/core/rendering/line/BreakingContextInlineHeaders.h
+++ b/Source/core/rendering/line/BreakingContextInlineHeaders.h
@@ -367,7 +367,7 @@
     } else {
         positionedObjects.append(box);
     }
-    m_width.addUncommittedWidth(inlineLogicalWidth(box));
+    m_width.addUncommittedWidth(inlineLogicalWidth(box).toFloat());
     // Reset prior line break context characters.
     m_renderTextInfo.m_lineBreakIterator.resetPriorContext();
 }
@@ -380,7 +380,7 @@
     // If it does, position it now, otherwise, position
     // it after moving to next line (in newLine() func)
     // FIXME: Bug 110372: Properly position multiple stacked floats with non-rectangular shape outside.
-    if (m_floatsFitOnLine && m_width.fitsOnLine(m_block->logicalWidthForFloat(floatingObject))) {
+    if (m_floatsFitOnLine && m_width.fitsOnLine(m_block->logicalWidthForFloat(floatingObject).toFloat())) {
         m_block->positionNewFloatOnLine(floatingObject, m_lastFloatFromPreviousLine, m_lineInfo, m_width);
         if (m_lineBreak.object() == m_current.object()) {
             ASSERT(!m_lineBreak.offset());
@@ -442,7 +442,7 @@
         }
     }
 
-    m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox));
+    m_width.addUncommittedWidth((inlineLogicalWidth(m_current.object()) + borderPaddingMarginStart(flowBox) + borderPaddingMarginEnd(flowBox)).toFloat());
 }
 
 inline void BreakingContext::handleReplaced()
@@ -477,9 +477,9 @@
             m_ignoringSpaces = true;
         }
         if (toRenderListMarker(m_current.object())->isInside())
-            m_width.addUncommittedWidth(replacedLogicalWidth);
+            m_width.addUncommittedWidth(replacedLogicalWidth.toFloat());
     } else {
-        m_width.addUncommittedWidth(replacedLogicalWidth);
+        m_width.addUncommittedWidth(replacedLogicalWidth.toFloat());
     }
     if (m_current.object()->isRubyRun())
         m_width.applyOverhang(toRenderRubyRun(m_current.object()), m_lastObject, m_nextObject);
@@ -516,7 +516,7 @@
         return;
 
     bool isHorizontalWritingMode = block->isHorizontalWritingMode();
-    LayoutUnit logicalOffsetFromShapeContainer = block->logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner()).height();
+    LayoutUnit logicalOffsetFromShapeContainer = block->logicalOffsetFromShapeAncestorContainer(&shapeInsideInfo->owner()).height();
 
     LayoutUnit lineLogicalTop = block->logicalHeight() + logicalOffsetFromShapeContainer;
     LayoutUnit lineLogicalHeight = block->lineHeight(isFirstLine, isHorizontalWritingMode ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
@@ -529,6 +529,10 @@
     if (!lineOverlapsWithFloat)
         return;
 
+    // FIXME: We need to remove this once we support multiple-segment polygons
+    if (shapeInsideInfo->segments().size() > 1)
+        return;
+
     float minSegmentWidth = firstPositiveWidth(wordMeasurements);
 
     LayoutUnit floatLogicalWidth = block->logicalWidthForFloat(lastFloatFromPreviousLine);
@@ -552,7 +556,7 @@
 {
     RenderStyle* style = renderer->style();
     return font.width(RenderBlockFlow::constructTextRun(renderer, font,
-        style->hyphenString().string(), style, textDirection));
+        style->hyphenString().string(), style, style->direction()));
 }
 
 ALWAYS_INLINE TextDirection textDirectionFromUnicode(WTF::Unicode::Direction direction)
@@ -561,17 +565,13 @@
         || direction == WTF::Unicode::RightToLeftArabic ? RTL : LTR;
 }
 
-ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, WTF::Unicode::Direction direction, bool collapseWhiteSpace, HashSet<const SimpleFontData*>* fallbackFonts = 0)
+ALWAYS_INLINE float textWidth(RenderText* text, unsigned from, unsigned len, const Font& font, float xPos, bool isFixedPitch, bool collapseWhiteSpace, HashSet<const SimpleFontData*>* fallbackFonts = 0)
 {
-    TextDirection textDirection = textDirectionFromUnicode(direction);
     GlyphOverflow glyphOverflow;
     if (isFixedPitch || (!from && len == text->textLength()) || text->style()->hasTextCombine())
-        return text->width(from, len, font, xPos, textDirection, fallbackFonts, &glyphOverflow);
+        return text->width(from, len, font, xPos, text->style()->direction(), fallbackFonts, &glyphOverflow);
 
-    TextRun run = RenderBlockFlow::constructTextRun(text, font, text, from, len, text->style(), textDirection);
-    run.setCharactersLength(text->textLength() - from);
-    ASSERT(run.charactersLength() >= run.length());
-
+    TextRun run = RenderBlockFlow::constructTextRun(text, font, text, from, len, text->style());
     run.setCharacterScanForCodePath(!text->canUseSimpleFontCodePath());
     run.setTabSize(!collapseWhiteSpace, text->style()->tabSize());
     run.setXPos(xPos);
@@ -647,7 +647,7 @@
     float wordTrailingSpaceWidth = (font.fontDescription().typesettingFeatures() & Kerning) ?
         font.width(RenderBlockFlow::constructTextRun(
             renderText, font, &space, 1, style,
-            textDirectionFromUnicode(m_resolver.position().direction()))) + wordSpacing
+            style->direction())) + wordSpacing
         : 0;
 
     UChar lastCharacter = m_renderTextInfo.m_lineBreakIterator.lastCharacter();
@@ -671,7 +671,7 @@
         if ((breakAll || breakWords) && !midWordBreak) {
             wrapW += charWidth;
             bool midWordBreakIsBeforeSurrogatePair = U16_IS_LEAD(c) && m_current.offset() + 1 < renderText->textLength() && U16_IS_TRAIL((*renderText)[m_current.offset() + 1]);
-            charWidth = textWidth(renderText, m_current.offset(), midWordBreakIsBeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch, m_resolver.position().direction(), m_collapseWhiteSpace, 0);
+            charWidth = textWidth(renderText, m_current.offset(), midWordBreakIsBeforeSurrogatePair ? 2 : 1, font, m_width.committedWidth() + wrapW, isFixedPitch, m_collapseWhiteSpace, 0);
             midWordBreak = m_width.committedWidth() + wrapW + charWidth > m_width.availableWidth();
         }
 
@@ -707,15 +707,15 @@
 
             float additionalTmpW;
             if (wordTrailingSpaceWidth && c == ' ')
-                additionalTmpW = textWidth(renderText, lastSpace, m_current.offset() + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_resolver.position().direction(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts) - wordTrailingSpaceWidth;
+                additionalTmpW = textWidth(renderText, lastSpace, m_current.offset() + 1 - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts) - wordTrailingSpaceWidth;
             else
-                additionalTmpW = textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_resolver.position().direction(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts);
+                additionalTmpW = textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts);
 
             wordMeasurement.width = additionalTmpW + wordSpacingForWordMeasurement;
             additionalTmpW += lastSpaceWordSpacing;
             m_width.addUncommittedWidth(additionalTmpW);
             if (!m_appliedStartWidth) {
-                m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object(), true, false));
+                m_width.addUncommittedWidth(inlineLogicalWidth(m_current.object(), true, false).toFloat());
                 m_appliedStartWidth = true;
             }
 
@@ -725,14 +725,14 @@
             applyWordSpacing = wordSpacing && m_currentCharacterIsSpace;
 
             if (!m_width.committedWidth() && m_autoWrap && !m_width.fitsOnLine())
-                m_width.fitBelowFloats();
+                m_width.fitBelowFloats(m_lineInfo.isFirstLine());
 
             if (m_autoWrap || breakWords) {
                 // If we break only after white-space, consider the current character
                 // as candidate width for this line.
                 bool lineWasTooWide = false;
                 if (m_width.fitsOnLine() && m_currentCharacterIsSpace && m_currentStyle->breakOnlyAfterWhiteSpace() && !midWordBreak) {
-                    float charWidth = textWidth(renderText, m_current.offset(), 1, font, m_width.currentWidth(), isFixedPitch, m_resolver.position().direction(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts) + (applyWordSpacing ? wordSpacing : 0);
+                    float charWidth = textWidth(renderText, m_current.offset(), 1, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts) + (applyWordSpacing ? wordSpacing : 0);
                     // Check if line is too big even without the extra space
                     // at the end of the line. If it is not, do nothing.
                     // If the line needs the extra whitespace to be too long,
@@ -863,7 +863,7 @@
     wordMeasurement.renderer = renderText;
 
     // IMPORTANT: current.m_pos is > length here!
-    float additionalTmpW = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_resolver.position().direction(), m_collapseWhiteSpace, &wordMeasurement.fallbackFonts);
+    float additionalTmpW = m_ignoringSpaces ? 0 : textWidth(renderText, lastSpace, m_current.offset() - lastSpace, font, m_width.currentWidth(), isFixedPitch, m_collapseWhiteSpace, &wordMeasurement.fallbackFonts);
     wordMeasurement.startOffset = lastSpace;
     wordMeasurement.endOffset = m_current.offset();
     wordMeasurement.width = m_ignoringSpaces ? 0 : additionalTmpW + wordSpacingForWordMeasurement;
@@ -901,7 +901,7 @@
             }
 
             if (!m_width.fitsOnLine() && !m_width.committedWidth())
-                m_width.fitBelowFloats();
+                m_width.fitBelowFloats(m_lineInfo.isFirstLine());
 
             bool canPlaceOnLine = m_width.fitsOnLine() || !m_autoWrapWasEverTrueOnLine;
             if (canPlaceOnLine && checkForBreak) {
@@ -921,7 +921,7 @@
             return;
         }
 
-        m_width.fitBelowFloats();
+        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
 
         // |width| may have been adjusted because we got shoved down past a float (thus
         // giving us more room), so we need to retest, and only jump to
@@ -933,7 +933,7 @@
     } else if (m_blockStyle->autoWrap() && !m_width.fitsOnLine() && !m_width.committedWidth()) {
         // If the container autowraps but the current child does not then we still need to ensure that it
         // wraps and moves below any floats.
-        m_width.fitBelowFloats();
+        m_width.fitBelowFloats(m_lineInfo.isFirstLine());
     }
 
     if (!m_current.object()->isFloatingOrOutOfFlowPositioned()) {
diff --git a/Source/core/rendering/line/LineWidth.cpp b/Source/core/rendering/line/LineWidth.cpp
index 194267a..d5fc96c 100644
--- a/Source/core/rendering/line/LineWidth.cpp
+++ b/Source/core/rendering/line/LineWidth.cpp
@@ -55,8 +55,8 @@
 {
     LayoutUnit height = m_block.logicalHeight();
     LayoutUnit logicalHeight = m_block.minLineHeightForReplacedRenderer(m_isFirstLine, replacedHeight);
-    m_left = m_block.logicalLeftOffsetForLine(height, shouldIndentText(), logicalHeight);
-    m_right = m_block.logicalRightOffsetForLine(height, shouldIndentText(), logicalHeight);
+    m_left = m_block.logicalLeftOffsetForLine(height, shouldIndentText(), logicalHeight).toFloat();
+    m_right = m_block.logicalRightOffsetForLine(height, shouldIndentText(), logicalHeight).toFloat();
 
     if (m_segment) {
         m_left = std::max<float>(m_segment->logicalLeft, m_left);
@@ -72,47 +72,31 @@
     if (height < m_block.logicalTopForFloat(newFloat) || height >= m_block.logicalBottomForFloat(newFloat))
         return;
 
-    // When floats with shape outside are stacked, the floats are positioned based on the margin box of the float,
-    // not the shape's contour. Since we computed the width based on the shape contour when we added the float,
-    // when we add a subsequent float on the same line, we need to undo the shape delta in order to position
-    // based on the margin box. In order to do this, we need to walk back through the floating object list to find
-    // the first previous float that is on the same side as our newFloat.
-    ShapeOutsideInfo* previousShapeOutsideInfo = 0;
-    const FloatingObjectSet& floatingObjectSet = m_block.m_floatingObjects->set();
-    FloatingObjectSetIterator it = floatingObjectSet.end();
-    FloatingObjectSetIterator begin = floatingObjectSet.begin();
-    LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
-    for (--it; it != begin; --it) {
-        FloatingObject* previousFloat = *it;
-        if (previousFloat != newFloat && previousFloat->type() == newFloat->type()) {
-            previousShapeOutsideInfo = previousFloat->renderer()->shapeOutsideInfo();
-            if (previousShapeOutsideInfo)
-                previousShapeOutsideInfo->updateDeltasForContainingBlockLine(&m_block, previousFloat, m_block.logicalHeight(), lineHeight);
-            break;
-        }
+    ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->shapeOutsideInfo();
+    if (shapeOutsideInfo) {
+        LayoutUnit lineHeight = m_block.lineHeight(m_isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
+        shapeOutsideInfo->updateDeltasForContainingBlockLine(m_block, *newFloat, m_block.logicalHeight(), lineHeight);
     }
 
-    ShapeOutsideInfo* shapeOutsideInfo = newFloat->renderer()->shapeOutsideInfo();
-    if (shapeOutsideInfo)
-        shapeOutsideInfo->updateDeltasForContainingBlockLine(&m_block, newFloat, m_block.logicalHeight(), lineHeight);
-
     if (newFloat->type() == FloatingObject::FloatLeft) {
-        float newLeft = m_block.logicalRightForFloat(newFloat);
-        if (previousShapeOutsideInfo)
-            newLeft -= previousShapeOutsideInfo->rightMarginBoxDelta();
-        if (shapeOutsideInfo)
-            newLeft += shapeOutsideInfo->rightMarginBoxDelta();
-
+        float newLeft = m_block.logicalRightForFloat(newFloat).toFloat();
+        if (shapeOutsideInfo) {
+            if (shapeOutsideInfo->lineOverlapsShape())
+                newLeft += shapeOutsideInfo->rightMarginBoxDelta();
+            else // Per the CSS Shapes spec, If the line doesn't overlap the shape, then ignore this shape for this line.
+                newLeft = m_left;
+        }
         if (shouldIndentText() && m_block.style()->isLeftToRightDirection())
             newLeft += floorToInt(m_block.textIndentOffset());
         m_left = std::max<float>(m_left, newLeft);
     } else {
-        float newRight = m_block.logicalLeftForFloat(newFloat);
-        if (previousShapeOutsideInfo)
-            newRight -= previousShapeOutsideInfo->leftMarginBoxDelta();
-        if (shapeOutsideInfo)
-            newRight += shapeOutsideInfo->leftMarginBoxDelta();
-
+        float newRight = m_block.logicalLeftForFloat(newFloat).toFloat();
+        if (shapeOutsideInfo) {
+            if (shapeOutsideInfo->lineOverlapsShape())
+                newRight += shapeOutsideInfo->leftMarginBoxDelta();
+            else // Per the CSS Shapes spec, If the line doesn't overlap the shape, then ignore this shape for this line.
+                newRight = m_right;
+        }
         if (shouldIndentText() && !m_block.style()->isLeftToRightDirection())
             newRight -= floorToInt(m_block.textIndentOffset());
         m_right = std::min<float>(m_right, newRight);
@@ -141,7 +125,65 @@
     m_overhangWidth += startOverhang + endOverhang;
 }
 
-void LineWidth::fitBelowFloats()
+inline static float availableWidthAtOffset(const RenderBlockFlow& block, const LayoutUnit& offset, bool shouldIndentText, float& newLineLeft, float& newLineRight)
+{
+    newLineLeft = block.logicalLeftOffsetForLine(offset, shouldIndentText).toFloat();
+    newLineRight = block.logicalRightOffsetForLine(offset, shouldIndentText).toFloat();
+    return std::max(0.0f, newLineRight - newLineLeft);
+}
+
+inline static float availableWidthAtOffset(const RenderBlockFlow& block, const LayoutUnit& offset, bool shouldIndentText)
+{
+    float newLineLeft = block.logicalLeftOffsetForLine(offset, shouldIndentText).toFloat();
+    float newLineRight = block.logicalRightOffsetForLine(offset, shouldIndentText).toFloat();
+    return std::max(0.0f, newLineRight - newLineLeft);
+}
+
+void LineWidth::updateLineDimension(LayoutUnit newLineTop, LayoutUnit newLineWidth, const float& newLineLeft, const float& newLineRight)
+{
+    if (newLineWidth <= m_availableWidth)
+        return;
+
+    m_block.setLogicalHeight(newLineTop);
+    m_availableWidth = newLineWidth + m_overhangWidth;
+    m_left = newLineLeft;
+    m_right = newLineRight;
+}
+
+inline static bool isWholeLineFit(const RenderBlockFlow& block, const LayoutUnit& lineTop, LayoutUnit lineHeight, float uncommittedWidth, bool shouldIndentText)
+{
+    for (LayoutUnit lineBottom = lineTop; lineBottom <= lineTop + lineHeight; lineBottom++) {
+        LayoutUnit availableWidthAtBottom = availableWidthAtOffset(block, lineBottom, shouldIndentText);
+        if (availableWidthAtBottom < uncommittedWidth)
+            return false;
+    }
+    return true;
+}
+
+void LineWidth::wrapNextToShapeOutside(bool isFirstLine)
+{
+    LayoutUnit lineHeight = m_block.lineHeight(isFirstLine, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
+    LayoutUnit lineLogicalTop = m_block.logicalHeight();
+    LayoutUnit newLineTop = lineLogicalTop;
+    LayoutUnit floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lineLogicalTop);
+
+    float newLineWidth;
+    float newLineLeft = m_left;
+    float newLineRight = m_right;
+    while (true) {
+        newLineWidth = availableWidthAtOffset(m_block, newLineTop, shouldIndentText(), newLineLeft, newLineRight);
+        if (newLineWidth >= m_uncommittedWidth && isWholeLineFit(m_block, newLineTop, lineHeight, m_uncommittedWidth, shouldIndentText()))
+            break;
+
+        if (newLineTop >= floatLogicalBottom)
+            break;
+
+        newLineTop++;
+    }
+    updateLineDimension(newLineTop, newLineWidth, newLineLeft, newLineRight);
+}
+
+void LineWidth::fitBelowFloats(bool isFirstLine)
 {
     ASSERT(!m_committedWidth);
     ASSERT(!fitsOnLine());
@@ -151,36 +193,35 @@
     float newLineWidth = m_availableWidth;
     float newLineLeft = m_left;
     float newLineRight = m_right;
+
+    FloatingObject* lastFloatFromPreviousLine = (m_block.containsFloats() ? m_block.m_floatingObjects->set().last() : 0);
+        if (lastFloatFromPreviousLine && lastFloatFromPreviousLine->renderer()->shapeOutsideInfo())
+            return wrapNextToShapeOutside(isFirstLine);
+
     while (true) {
         floatLogicalBottom = m_block.nextFloatLogicalBottomBelow(lastFloatLogicalBottom, ShapeOutsideFloatShapeOffset);
         if (floatLogicalBottom <= lastFloatLogicalBottom)
             break;
 
-        newLineLeft = m_block.logicalLeftOffsetForLine(floatLogicalBottom, shouldIndentText());
-        newLineRight = m_block.logicalRightOffsetForLine(floatLogicalBottom, shouldIndentText());
-        newLineWidth = max(0.0f, newLineRight - newLineLeft);
+        newLineWidth = availableWidthAtOffset(m_block, floatLogicalBottom, shouldIndentText(), newLineLeft, newLineRight);
         lastFloatLogicalBottom = floatLogicalBottom;
 
-        // FIXME: This code should be refactored to incorporate with the code above.
-        ShapeInsideInfo* shapeInsideInfo = m_block.layoutShapeInsideInfo();
-        if (shapeInsideInfo) {
-            LayoutUnit logicalOffsetFromShapeContainer = m_block.logicalOffsetFromShapeAncestorContainer(shapeInsideInfo->owner()).height();
-            LayoutUnit lineHeight = m_block.lineHeight(false, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
-            shapeInsideInfo->updateSegmentsForLine(lastFloatLogicalBottom + logicalOffsetFromShapeContainer, lineHeight);
-            updateCurrentShapeSegment();
-            updateAvailableWidth();
-        }
+        if (newLineWidth >= m_uncommittedWidth) {
+            ShapeInsideInfo* shapeInsideInfo = m_block.layoutShapeInsideInfo();
+            if (shapeInsideInfo) {
+                // To safely update our shape segments, the current segment must be the first in this line, so committedWidth has to be 0
+                ASSERT(!m_committedWidth);
 
-        if (newLineWidth >= m_uncommittedWidth)
+                LayoutUnit logicalOffsetFromShapeContainer = m_block.logicalOffsetFromShapeAncestorContainer(&shapeInsideInfo->owner()).height();
+                LayoutUnit lineHeight = m_block.lineHeight(false, m_block.isHorizontalWritingMode() ? HorizontalLine : VerticalLine, PositionOfInteriorLineBoxes);
+                shapeInsideInfo->updateSegmentsForLine(lastFloatLogicalBottom + logicalOffsetFromShapeContainer, lineHeight);
+                updateCurrentShapeSegment();
+                updateAvailableWidth();
+            }
             break;
+        }
     }
-
-    if (newLineWidth > m_availableWidth) {
-        m_block.setLogicalHeight(lastFloatLogicalBottom);
-        m_availableWidth = newLineWidth + m_overhangWidth;
-        m_left = newLineLeft;
-        m_right = newLineRight;
-    }
+    updateLineDimension(lastFloatLogicalBottom, newLineWidth, newLineLeft, newLineRight);
 }
 
 void LineWidth::updateCurrentShapeSegment()
diff --git a/Source/core/rendering/line/LineWidth.h b/Source/core/rendering/line/LineWidth.h
index 59e1442..4a33ba1 100644
--- a/Source/core/rendering/line/LineWidth.h
+++ b/Source/core/rendering/line/LineWidth.h
@@ -62,7 +62,7 @@
     void addUncommittedWidth(float delta) { m_uncommittedWidth += delta; }
     void commit();
     void applyOverhang(RenderRubyRun*, RenderObject* startRenderer, RenderObject* endRenderer);
-    void fitBelowFloats();
+    void fitBelowFloats(bool isFirstLine = false);
 
     void updateCurrentShapeSegment();
 
@@ -70,6 +70,8 @@
 
 private:
     void computeAvailableWidthFromLeftAndRight();
+    void updateLineDimension(LayoutUnit newLineTop, LayoutUnit newLineWidth, const float& newLineLeft, const float& newLineRight);
+    void wrapNextToShapeOutside(bool isFirstLine);
 
     RenderBlockFlow& m_block;
     float m_uncommittedWidth;
diff --git a/Source/core/rendering/shapes/PolygonShape.cpp b/Source/core/rendering/shapes/PolygonShape.cpp
index 041440b..512ae14 100644
--- a/Source/core/rendering/shapes/PolygonShape.cpp
+++ b/Source/core/rendering/shapes/PolygonShape.cpp
@@ -114,14 +114,13 @@
 {
     float startAngle = atan2(startArcVertex.y() - arcCenter.y(), startArcVertex.x() - arcCenter.x());
     float endAngle = atan2(endArcVertex.y() - arcCenter.y(), endArcVertex.x() - arcCenter.x());
-    const float twoPI = piFloat * 2;
     if (startAngle < 0)
-        startAngle += twoPI;
+        startAngle += twoPiFloat;
     if (endAngle < 0)
-        endAngle += twoPI;
-    float angle = (startAngle > endAngle) ? (startAngle - endAngle) : (startAngle + twoPI - endAngle);
+        endAngle += twoPiFloat;
+    float angle = (startAngle > endAngle) ? (startAngle - endAngle) : (startAngle + twoPiFloat - endAngle);
     const float arcSegmentCount = 6; // An even number so that one arc vertex will be eactly arcRadius from arcCenter.
-    float arcSegmentAngle =  ((padding) ? -angle : twoPI - angle) / arcSegmentCount;
+    float arcSegmentAngle =  ((padding) ? -angle : twoPiFloat - angle) / arcSegmentCount;
 
     vertices.append(startArcVertex);
     for (unsigned i = 1; i < arcSegmentCount; ++i) {
diff --git a/Source/core/rendering/shapes/RasterShape.cpp b/Source/core/rendering/shapes/RasterShape.cpp
index 32a0511..996a8b8 100644
--- a/Source/core/rendering/shapes/RasterShape.cpp
+++ b/Source/core/rendering/shapes/RasterShape.cpp
@@ -216,25 +216,23 @@
     }
 }
 
-PassOwnPtr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginIntervals(unsigned shapeMargin) const
+PassOwnPtr<RasterShapeIntervals> RasterShapeIntervals::computeShapeMarginIntervals(int shapeMargin) const
 {
-    OwnPtr<RasterShapeIntervals> result = adoptPtr(new RasterShapeIntervals(size(), shapeMargin));
+    int marginIntervalsSize = (offset() > shapeMargin) ? size() : size() - offset() * 2 + shapeMargin * 2;
+    OwnPtr<RasterShapeIntervals> result = adoptPtr(new RasterShapeIntervals(marginIntervalsSize, std::max(shapeMargin, offset())));
     MarginIntervalGenerator marginIntervalGenerator(shapeMargin);
 
-    int minY = bounds().y();
-    int maxY = bounds().maxY();
-
-    for (int y = minY; y < maxY; ++y) {
+    for (int y = bounds().y(); y < bounds().maxY(); ++y) {
         const IntShapeInterval& intervalAtY = limitIntervalAt(y);
         if (intervalAtY.isEmpty())
             continue;
 
         marginIntervalGenerator.set(y, intervalAtY);
-        int marginY0 = y - clampToInteger(shapeMargin);
-        int marginY1 = y + clampToInteger(shapeMargin);
+        int marginY0 = std::max(minY(), y - shapeMargin);
+        int marginY1 = std::min(maxY(), y + shapeMargin);
 
         for (int marginY = y - 1; marginY >= marginY0; --marginY) {
-            if (marginY > minY && limitIntervalAt(marginY).contains(intervalAtY))
+            if (marginY > bounds().y() && limitIntervalAt(marginY).contains(intervalAtY))
                 break;
             result->uniteMarginInterval(marginY, marginIntervalGenerator.intervalAt(marginY));
         }
@@ -242,7 +240,7 @@
         result->uniteMarginInterval(y, marginIntervalGenerator.intervalAt(y));
 
         for (int marginY = y + 1; marginY <= marginY1; ++marginY) {
-            if (marginY < maxY && limitIntervalAt(marginY).contains(intervalAtY))
+            if (marginY < bounds().maxY() && limitIntervalAt(marginY).contains(intervalAtY))
                 break;
             result->uniteMarginInterval(marginY, marginIntervalGenerator.intervalAt(marginY));
         }
@@ -257,9 +255,11 @@
     if (!shapeMargin())
         return *m_intervals;
 
-    unsigned marginBoundaryRadius = std::min(clampToUnsigned(ceil(shapeMargin())), std::max<unsigned>(m_imageSize.width(), m_imageSize.height()));
-    if (!m_marginIntervals)
+    int marginBoundaryRadius = std::min(clampToInteger(ceil(shapeMargin())), std::max(m_imageSize.width(), m_imageSize.height()));
+    if (!m_marginIntervals) {
+        ASSERT(marginBoundaryRadius >= 0);
         m_marginIntervals = m_intervals->computeShapeMarginIntervals(marginBoundaryRadius);
+    }
 
     return *m_marginIntervals;
 }
diff --git a/Source/core/rendering/shapes/RasterShape.h b/Source/core/rendering/shapes/RasterShape.h
index 4b178fd..5da5442 100644
--- a/Source/core/rendering/shapes/RasterShape.h
+++ b/Source/core/rendering/shapes/RasterShape.h
@@ -40,10 +40,10 @@
 
 class RasterShapeIntervals {
 public:
-    RasterShapeIntervals(unsigned size, unsigned shapeMargin = 0)
-        : m_shapeMargin(shapeMargin)
+    RasterShapeIntervals(unsigned size, int offset = 0)
+        : m_offset(offset)
     {
-        m_intervalLists.resize(size + shapeMargin * 2);
+        m_intervalLists.resize(size);
     }
 
     const IntRect& bounds() const { return m_bounds; }
@@ -53,21 +53,26 @@
     void getIncludedIntervals(int y1, int y2, IntShapeIntervals& result) const;
     void getExcludedIntervals(int y1, int y2, IntShapeIntervals& result) const;
     bool firstIncludedIntervalY(int minY, const IntSize& minSize, LayoutUnit& result) const;
-    PassOwnPtr<RasterShapeIntervals> computeShapeMarginIntervals(unsigned shapeMargin) const;
+    PassOwnPtr<RasterShapeIntervals> computeShapeMarginIntervals(int shapeMargin) const;
+
+    void buildBoundsPath(Path&) const;
 
 private:
     int size() const { return m_intervalLists.size(); }
+    int offset() const { return m_offset; }
+    int minY() const { return -m_offset; }
+    int maxY() const { return -m_offset + m_intervalLists.size(); }
 
     IntShapeIntervals& intervalsAt(int y)
     {
-        ASSERT(y + m_shapeMargin >= 0 && y + m_shapeMargin < m_intervalLists.size());
-        return m_intervalLists[y + m_shapeMargin];
+        ASSERT(y + m_offset >= 0 && static_cast<unsigned>(y + m_offset) < m_intervalLists.size());
+        return m_intervalLists[y + m_offset];
     }
 
     const IntShapeIntervals& intervalsAt(int y) const
     {
-        ASSERT(y + m_shapeMargin >= 0 && y + m_shapeMargin < m_intervalLists.size());
-        return m_intervalLists[y + m_shapeMargin];
+        ASSERT(y + m_offset >= 0 && static_cast<unsigned>(y + m_offset) < m_intervalLists.size());
+        return m_intervalLists[y + m_offset];
     }
 
     IntShapeInterval limitIntervalAt(int y) const
@@ -81,15 +86,14 @@
     void uniteMarginInterval(int y, const IntShapeInterval&);
     IntRect m_bounds;
     Vector<IntShapeIntervals> m_intervalLists;
-    unsigned m_shapeMargin;
+    int m_offset;
 };
 
 class RasterShape FINAL : public Shape {
     WTF_MAKE_NONCOPYABLE(RasterShape);
 public:
     RasterShape(PassOwnPtr<RasterShapeIntervals> intervals, const IntSize& imageSize)
-        : Shape()
-        , m_intervals(intervals)
+        : m_intervals(intervals)
         , m_imageSize(imageSize)
     {
     }
diff --git a/Source/core/rendering/shapes/RectangleShape.cpp b/Source/core/rendering/shapes/RectangleShape.cpp
index 3e1e9c9..329cebf7 100644
--- a/Source/core/rendering/shapes/RectangleShape.cpp
+++ b/Source/core/rendering/shapes/RectangleShape.cpp
@@ -79,8 +79,8 @@
     if (bounds.isEmpty())
         return;
 
-    float y1 = logicalTop;
-    float y2 = logicalTop + logicalHeight;
+    float y1 = logicalTop.toFloat();
+    float y2 = (logicalTop + logicalHeight).toFloat();
 
     if (y2 < bounds.y() || y1 >= bounds.maxY())
         return;
@@ -114,8 +114,8 @@
     if (bounds.isEmpty())
         return;
 
-    float y1 = logicalTop;
-    float y2 = logicalTop + logicalHeight;
+    float y1 = logicalTop.toFloat();
+    float y2 = (logicalTop + logicalHeight).toFloat();
 
     if (y1 < bounds.y() || y2 > bounds.maxY())
         return;
@@ -165,7 +165,7 @@
 
 bool RectangleShape::firstIncludedIntervalLogicalTop(LayoutUnit minLogicalIntervalTop, const FloatSize& minLogicalIntervalSize, LayoutUnit& result) const
 {
-    float minIntervalTop = minLogicalIntervalTop;
+    float minIntervalTop = minLogicalIntervalTop.toFloat();
     float minIntervalHeight = minLogicalIntervalSize.height();
     float minIntervalWidth = minLogicalIntervalSize.width();
 
@@ -173,7 +173,8 @@
     if (bounds.isEmpty() || minIntervalWidth > bounds.width())
         return false;
 
-    float minY = LayoutUnit::fromFloatCeil(std::max(bounds.y(), minIntervalTop));
+    // FIXME: Shapes should be made to use LayoutUnits to avoid broken constructs like this.
+    float minY = LayoutUnit::fromFloatCeil(std::max(bounds.y(), minIntervalTop)).toFloat();
     float maxY = minY + minIntervalHeight;
 
     if (maxY > bounds.maxY())
diff --git a/Source/core/rendering/shapes/Shape.cpp b/Source/core/rendering/shapes/Shape.cpp
index 6db8939..27a5593 100644
--- a/Source/core/rendering/shapes/Shape.cpp
+++ b/Source/core/rendering/shapes/Shape.cpp
@@ -36,8 +36,8 @@
 #include "core/rendering/shapes/PolygonShape.h"
 #include "core/rendering/shapes/RasterShape.h"
 #include "core/rendering/shapes/RectangleShape.h"
+#include "core/rendering/style/RenderStyle.h"
 #include "platform/LengthFunctions.h"
-#include "platform/geometry/FloatRoundedRect.h"
 #include "platform/geometry/FloatSize.h"
 #include "platform/graphics/ImageBuffer.h"
 #include "platform/graphics/WindRule.h"
@@ -100,7 +100,7 @@
     return size.transposedSize();
 }
 
-static inline void ensureRadiiDoNotOverlap(FloatRect &bounds, FloatSize &radii)
+static inline void ensureRadiiDoNotOverlap(FloatRect& bounds, FloatSize& radii)
 {
     float widthRatio = bounds.width() / (2 * radii.width());
     float heightRatio = bounds.height() / (2 * radii.height());
@@ -208,11 +208,13 @@
         const BasicShapeInsetRectangle* rectangle = static_cast<const BasicShapeInsetRectangle*>(basicShape);
         float left = floatValueForLength(rectangle->left(), boxWidth);
         float top = floatValueForLength(rectangle->top(), boxHeight);
+        float right = floatValueForLength(rectangle->right(), boxWidth);
+        float bottom = floatValueForLength(rectangle->bottom(), boxHeight);
         FloatRect bounds(
             left,
             top,
-            boxWidth - left - floatValueForLength(rectangle->right(), boxWidth),
-            boxHeight - top - floatValueForLength(rectangle->bottom(), boxHeight));
+            std::max<float>(boxWidth - left - right, 0),
+            std::max<float>(boxHeight - top - bottom, 0));
         FloatSize cornerRadii(
             floatValueForLength(rectangle->cornerRadiusX(), boxWidth),
             floatValueForLength(rectangle->cornerRadiusY(), boxHeight));
@@ -229,15 +231,17 @@
         float top = floatValueForLength(inset.top(), boxHeight);
         float right = floatValueForLength(inset.right(), boxWidth);
         float bottom = floatValueForLength(inset.bottom(), boxHeight);
-        FloatRect rect(left, top, boxWidth - left - right, boxHeight - top - bottom);
+        FloatRect rect(left, top, std::max<float>(boxWidth - left - right, 0), std::max<float>(boxHeight - top - bottom, 0));
         FloatRect logicalRect = physicalRectToLogical(rect, logicalBoxSize.height(), writingMode);
 
         FloatSize boxSize(boxWidth, boxHeight);
-        FloatRoundedRect::Radii cornerRadii(
-            floatSizeForLengthSize(inset.topLeftRadius(), boxSize),
-            floatSizeForLengthSize(inset.topRightRadius(), boxSize),
-            floatSizeForLengthSize(inset.bottomLeftRadius(), boxSize),
-            floatSizeForLengthSize(inset.bottomRightRadius(), boxSize));
+        FloatSize topLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topLeftRadius(), boxSize), writingMode);
+        FloatSize topRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.topRightRadius(), boxSize), writingMode);
+        FloatSize bottomLeftRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomLeftRadius(), boxSize), writingMode);
+        FloatSize bottomRightRadius = physicalSizeToLogical(floatSizeForLengthSize(inset.bottomRightRadius(), boxSize), writingMode);
+        FloatRoundedRect::Radii cornerRadii(topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
+
+        cornerRadii.scale(calcBorderRadiiConstraintScaleFor(logicalRect, cornerRadii));
 
         shape = createInsetShape(FloatRoundedRect(logicalRect, cornerRadii));
         break;
@@ -254,43 +258,42 @@
     return shape.release();
 }
 
-PassOwnPtr<Shape> Shape::createRasterShape(const StyleImage& styleImage, float threshold, const LayoutRect& imageRect, const LayoutSize&, WritingMode writingMode, Length margin, Length padding)
+PassOwnPtr<Shape> Shape::createRasterShape(Image* image, float threshold, const LayoutRect& imageR, const LayoutRect& marginR, WritingMode writingMode, Length margin, Length padding)
 {
-    ASSERT(styleImage.cachedImage());
-    ASSERT(styleImage.cachedImage()->hasImage());
-
-    IntRect toRect = pixelSnappedIntRect(imageRect);
-    IntSize bufferSize = toRect.size();
-    IntSize rasterSize = IntSize(toRect.maxX(), toRect.maxY());
-    OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(rasterSize.height()));
-    OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(bufferSize);
+    IntRect imageRect = pixelSnappedIntRect(imageR);
+    IntRect marginRect = pixelSnappedIntRect(marginR);
+    OwnPtr<RasterShapeIntervals> intervals = adoptPtr(new RasterShapeIntervals(marginRect.height(), -marginRect.y()));
+    OwnPtr<ImageBuffer> imageBuffer = ImageBuffer::create(imageRect.size());
 
     if (imageBuffer) {
         GraphicsContext* graphicsContext = imageBuffer->context();
-        graphicsContext->drawImage(styleImage.cachedImage()->image(), FloatRect(0, 0, bufferSize.width(), bufferSize.height()));
+        graphicsContext->drawImage(image, IntRect(IntPoint(), imageRect.size()));
 
-        RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), bufferSize));
-        unsigned pixelArrayLength = pixelArray->length();
+        RefPtr<Uint8ClampedArray> pixelArray = imageBuffer->getUnmultipliedImageData(IntRect(IntPoint(), imageRect.size()));
         unsigned pixelArrayOffset = 3; // Each pixel is four bytes: RGBA.
         uint8_t alphaPixelThreshold = threshold * 255;
 
-        ASSERT(static_cast<unsigned>(bufferSize.width() * bufferSize.height() * 4) == pixelArrayLength);
+        ASSERT(static_cast<unsigned>(imageRect.width() * imageRect.height() * 4) == pixelArray->length());
 
-        for (int y = 0; y < bufferSize.height(); ++y) {
+        int minBufferY = std::max(0, marginRect.y() - imageRect.y());
+        int maxBufferY = std::min(imageRect.height(), marginRect.maxY() - imageRect.y());
+
+        for (int y = minBufferY; y < maxBufferY; ++y) {
             int startX = -1;
-            for (int x = 0; x < bufferSize.width() && pixelArrayOffset < pixelArrayLength; ++x, pixelArrayOffset += 4) {
+            for (int x = 0; x < imageRect.width(); ++x, pixelArrayOffset += 4) {
                 uint8_t alpha = pixelArray->item(pixelArrayOffset);
-                if ((startX == -1) && alpha > alphaPixelThreshold) {
+                bool alphaAboveThreshold = alpha > alphaPixelThreshold;
+                if (startX == -1 && alphaAboveThreshold) {
                     startX = x;
-                } else if (startX != -1 && (alpha <= alphaPixelThreshold || x == bufferSize.width() - 1)) {
-                    intervals->appendInterval(y + toRect.y(), startX + toRect.x(), x + toRect.x());
+                } else if (startX != -1 && (!alphaAboveThreshold || x == imageRect.width() - 1)) {
+                    intervals->appendInterval(y + imageRect.y(), startX + imageRect.x(), x + imageRect.x());
                     startX = -1;
                 }
             }
         }
     }
 
-    OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release(), rasterSize));
+    OwnPtr<RasterShape> rasterShape = adoptPtr(new RasterShape(intervals.release(), marginRect.size()));
     rasterShape->m_writingMode = writingMode;
     rasterShape->m_margin = floatValueForLength(margin, 0);
     rasterShape->m_padding = floatValueForLength(padding, 0);
diff --git a/Source/core/rendering/shapes/Shape.h b/Source/core/rendering/shapes/Shape.h
index 53bd379..2a54027 100644
--- a/Source/core/rendering/shapes/Shape.h
+++ b/Source/core/rendering/shapes/Shape.h
@@ -62,7 +62,7 @@
 class Shape {
 public:
     static PassOwnPtr<Shape> createShape(const BasicShape*, const LayoutSize& logicalBoxSize, WritingMode, Length margin, Length padding);
-    static PassOwnPtr<Shape> createRasterShape(const StyleImage&, float threshold, const LayoutRect& imageRect, const LayoutSize& logicalBoxSize, WritingMode, Length margin, Length padding);
+    static PassOwnPtr<Shape> createRasterShape(Image*, float threshold, const LayoutRect& drawRect, const LayoutRect& clipRect, WritingMode, Length margin, Length padding);
     static PassOwnPtr<Shape> createLayoutBoxShape(const RoundedRect&, WritingMode, const Length& margin, const Length& padding);
 
     virtual ~Shape() { }
diff --git a/Source/core/rendering/shapes/ShapeInfo.cpp b/Source/core/rendering/shapes/ShapeInfo.cpp
index 72020e6..e9b81db 100644
--- a/Source/core/rendering/shapes/ShapeInfo.cpp
+++ b/Source/core/rendering/shapes/ShapeInfo.cpp
@@ -35,6 +35,42 @@
 
 namespace WebCore {
 
+template<class RenderType>
+void ShapeInfo<RenderType>::setReferenceBoxLogicalSize(LayoutSize newReferenceBoxLogicalSize)
+{
+    bool isHorizontalWritingMode = this->styleForWritingMode()->isHorizontalWritingMode();
+    switch (referenceBox()) {
+    case MarginBox:
+        if (isHorizontalWritingMode)
+            newReferenceBoxLogicalSize.expand(m_renderer.marginWidth(), m_renderer.marginHeight());
+        else
+            newReferenceBoxLogicalSize.expand(m_renderer.marginHeight(), m_renderer.marginWidth());
+        break;
+    case BorderBox:
+        break;
+    case PaddingBox:
+        if (isHorizontalWritingMode)
+            newReferenceBoxLogicalSize.shrink(m_renderer.borderWidth(), m_renderer.borderHeight());
+        else
+            newReferenceBoxLogicalSize.shrink(m_renderer.borderHeight(), m_renderer.borderWidth());
+        break;
+    case ContentBox:
+        if (isHorizontalWritingMode)
+            newReferenceBoxLogicalSize.shrink(m_renderer.borderAndPaddingWidth(), m_renderer.borderAndPaddingHeight());
+        else
+            newReferenceBoxLogicalSize.shrink(m_renderer.borderAndPaddingHeight(), m_renderer.borderAndPaddingWidth());
+        break;
+    case BoxMissing:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+
+    if (m_referenceBoxLogicalSize == newReferenceBoxLogicalSize)
+        return;
+    markShapeAsDirty();
+    m_referenceBoxLogicalSize = newReferenceBoxLogicalSize;
+}
+
 bool checkShapeImageOrigin(Document& document, ImageResource& imageResource)
 {
     if (imageResource.isAccessAllowed(document.securityOrigin()))
@@ -47,42 +83,56 @@
     return false;
 }
 
-static LayoutRect getShapeImageRect(const StyleImage& styleImage, const RenderBox* renderBox)
+static void getShapeImageAndRect(const ShapeValue* shapeValue, const RenderBox* renderBox, const LayoutSize& referenceBoxSize, Image*& image, LayoutRect& rect)
 {
-    if (renderBox->isRenderImage())
-        return toRenderImage(renderBox)->replacedContentRect();
+    ASSERT(shapeValue->isImageValid());
+    StyleImage* styleImage = shapeValue->image();
 
-    ASSERT(styleImage.cachedImage());
-    ASSERT(styleImage.cachedImage()->hasImage());
-    return LayoutRect(LayoutPoint(), styleImage.cachedImage()->image()->size());
+    const IntSize& imageSize = renderBox->calculateImageIntrinsicDimensions(styleImage, roundedIntSize(referenceBoxSize), RenderImage::ScaleByEffectiveZoom);
+    styleImage->setContainerSizeForRenderer(renderBox, imageSize, renderBox->style()->effectiveZoom());
+
+    image = styleImage->cachedImage()->imageForRenderer(renderBox);
+    if (renderBox->isRenderImage())
+        rect = toRenderImage(renderBox)->replacedContentRect();
+    else
+        rect = LayoutRect(LayoutPoint(), imageSize);
+}
+
+static LayoutRect getShapeImageMarginRect(const RenderBox& renderBox, const LayoutSize& referenceBoxLogicalSize)
+{
+    LayoutPoint marginBoxOrigin(-renderBox.marginLogicalLeft() - renderBox.borderAndPaddingLogicalLeft(), -renderBox.marginBefore() - renderBox.borderBefore() - renderBox.paddingBefore());
+    LayoutSize marginBoxSizeDelta(renderBox.marginLogicalWidth() + renderBox.borderAndPaddingLogicalWidth(), renderBox.marginLogicalHeight() + renderBox.borderAndPaddingLogicalHeight());
+    return LayoutRect(marginBoxOrigin, referenceBoxLogicalSize + marginBoxSizeDelta);
 }
 
 template<class RenderType>
-const Shape* ShapeInfo<RenderType>::computedShape() const
+const Shape& ShapeInfo<RenderType>::computedShape() const
 {
     if (Shape* shape = m_shape.get())
-        return shape;
+        return *shape;
 
-    WritingMode writingMode = m_renderer->style()->writingMode();
-    Length margin = m_renderer->style()->shapeMargin();
-    Length padding = m_renderer->style()->shapePadding();
-    float shapeImageThreshold = m_renderer->style()->shapeImageThreshold();
+    WritingMode writingMode = this->styleForWritingMode()->writingMode();
+    Length margin = m_renderer.style()->shapeMargin();
+    Length padding = m_renderer.style()->shapePadding();
+    float shapeImageThreshold = m_renderer.style()->shapeImageThreshold();
     const ShapeValue* shapeValue = this->shapeValue();
     ASSERT(shapeValue);
 
     switch (shapeValue->type()) {
     case ShapeValue::Shape:
         ASSERT(shapeValue->shape());
-        m_shape = Shape::createShape(shapeValue->shape(), m_shapeLogicalSize, writingMode, margin, padding);
+        m_shape = Shape::createShape(shapeValue->shape(), m_referenceBoxLogicalSize, writingMode, margin, padding);
         break;
     case ShapeValue::Image: {
-        ASSERT(shapeValue->image());
-        const StyleImage& styleImage = *(shapeValue->image());
-        m_shape = Shape::createRasterShape(styleImage, shapeImageThreshold, getShapeImageRect(styleImage, m_renderer), m_shapeLogicalSize, writingMode, margin, padding);
+        Image* image;
+        LayoutRect imageRect;
+        getShapeImageAndRect(shapeValue, &m_renderer, m_referenceBoxLogicalSize, image, imageRect);
+        const LayoutRect& marginRect = getShapeImageMarginRect(m_renderer, m_referenceBoxLogicalSize);
+        m_shape = Shape::createRasterShape(image, shapeImageThreshold, imageRect, marginRect, writingMode, margin, padding);
         break;
     }
     case ShapeValue::Box: {
-        const RoundedRect& shapeRect = m_renderer->style()->getRoundedBorderFor(LayoutRect(LayoutPoint(), m_shapeLogicalSize), m_renderer->view());
+        const RoundedRect& shapeRect = m_renderer.style()->getRoundedBorderFor(LayoutRect(LayoutPoint(), m_referenceBoxLogicalSize), m_renderer.view());
         m_shape = Shape::createLayoutBoxShape(shapeRect, writingMode, margin, padding);
         break;
     }
@@ -92,7 +142,7 @@
     }
 
     ASSERT(m_shape);
-    return m_shape.get();
+    return *m_shape;
 }
 
 template<class RenderType>
@@ -111,6 +161,94 @@
     return segments;
 }
 
+template<class RenderType>
+inline LayoutUnit borderBeforeInWritingMode(const RenderType& renderer, WritingMode writingMode)
+{
+    switch (writingMode) {
+    case TopToBottomWritingMode: return renderer.borderTop();
+    case BottomToTopWritingMode: return renderer.borderBottom();
+    case LeftToRightWritingMode: return renderer.borderLeft();
+    case RightToLeftWritingMode: return renderer.borderRight();
+    }
+
+    ASSERT_NOT_REACHED();
+    return renderer.borderBefore();
+}
+
+template<class RenderType>
+inline LayoutUnit borderAndPaddingBeforeInWritingMode(const RenderType& renderer, WritingMode writingMode)
+{
+    switch (writingMode) {
+    case TopToBottomWritingMode: return renderer.borderTop() + renderer.paddingTop();
+    case BottomToTopWritingMode: return renderer.borderBottom() + renderer.paddingBottom();
+    case LeftToRightWritingMode: return renderer.borderLeft() + renderer.paddingLeft();
+    case RightToLeftWritingMode: return renderer.borderRight() + renderer.paddingRight();
+    }
+
+    ASSERT_NOT_REACHED();
+    return renderer.borderAndPaddingBefore();
+}
+
+template<class RenderType>
+LayoutUnit ShapeInfo<RenderType>::logicalTopOffset() const
+{
+    switch (referenceBox()) {
+    case MarginBox: return -m_renderer.marginBefore(styleForWritingMode());
+    case BorderBox: return LayoutUnit();
+    case PaddingBox: return borderBeforeInWritingMode(m_renderer, styleForWritingMode()->writingMode());
+    case ContentBox: return borderAndPaddingBeforeInWritingMode(m_renderer, styleForWritingMode()->writingMode());
+    case BoxMissing: break;
+    }
+
+    ASSERT_NOT_REACHED();
+    return LayoutUnit();
+}
+
+template<class RenderType>
+inline LayoutUnit borderStartWithStyleForWritingMode(const RenderType& renderer, const RenderStyle* style)
+{
+    if (style->isHorizontalWritingMode()) {
+        if (style->isLeftToRightDirection())
+            return renderer.borderLeft();
+
+        return renderer.borderRight();
+    }
+    if (style->isLeftToRightDirection())
+        return renderer.borderTop();
+
+    return renderer.borderBottom();
+}
+
+template<class RenderType>
+inline LayoutUnit borderAndPaddingStartWithStyleForWritingMode(const RenderType& renderer, const RenderStyle* style)
+{
+    if (style->isHorizontalWritingMode()) {
+        if (style->isLeftToRightDirection())
+            return renderer.borderLeft() + renderer.paddingLeft();
+
+        return renderer.borderRight() + renderer.paddingRight();
+    }
+    if (style->isLeftToRightDirection())
+        return renderer.borderTop() + renderer.paddingTop();
+
+    return renderer.borderBottom() + renderer.paddingBottom();
+}
+
+template<class RenderType>
+LayoutUnit ShapeInfo<RenderType>::logicalLeftOffset() const
+{
+    switch (referenceBox()) {
+    case MarginBox: return -m_renderer.marginStart(styleForWritingMode());
+    case BorderBox: return LayoutUnit();
+    case PaddingBox: return borderStartWithStyleForWritingMode(m_renderer, styleForWritingMode());
+    case ContentBox: return borderAndPaddingStartWithStyleForWritingMode(m_renderer, styleForWritingMode());
+    case BoxMissing: break;
+    }
+
+    ASSERT_NOT_REACHED();
+    return LayoutUnit();
+}
+
 template class ShapeInfo<RenderBlock>;
 template class ShapeInfo<RenderBox>;
 }
diff --git a/Source/core/rendering/shapes/ShapeInfo.h b/Source/core/rendering/shapes/ShapeInfo.h
index 00f9a02..977e6c4 100644
--- a/Source/core/rendering/shapes/ShapeInfo.h
+++ b/Source/core/rendering/shapes/ShapeInfo.h
@@ -43,16 +43,16 @@
 template<class KeyType, class InfoType>
 class MappedInfo {
 public:
-    static InfoType* ensureInfo(const KeyType* key)
+    static InfoType& ensureInfo(const KeyType& key)
     {
         InfoMap& infoMap = MappedInfo<KeyType, InfoType>::infoMap();
-        if (InfoType* info = infoMap.get(key))
-            return info;
-        typename InfoMap::AddResult result = infoMap.add(key, InfoType::createInfo(key));
-        return result.storedValue->value.get();
+        if (InfoType* info = infoMap.get(&key))
+            return *info;
+        typename InfoMap::AddResult result = infoMap.add(&key, InfoType::createInfo(key));
+        return *result.storedValue->value;
     }
-    static void removeInfo(const KeyType* key) { infoMap().remove(key); }
-    static InfoType* info(const KeyType* key) { return infoMap().get(key); }
+    static void removeInfo(const KeyType& key) { infoMap().remove(&key); }
+    static InfoType* info(const KeyType& key) { return infoMap().get(&key); }
 private:
     typedef HashMap<const KeyType*, OwnPtr<InfoType> > InfoMap;
     static InfoMap& infoMap()
@@ -68,34 +68,7 @@
 public:
     virtual ~ShapeInfo() { }
 
-    void setShapeSize(LayoutUnit logicalWidth, LayoutUnit logicalHeight)
-    {
-        switch (resolvedLayoutBox()) {
-        case MarginBox:
-            logicalHeight += m_renderer->marginLogicalHeight();
-            logicalWidth += m_renderer->marginLogicalWidth();
-            break;
-        case BorderBox:
-            break;
-        case PaddingBox:
-            logicalHeight -= m_renderer->borderLogicalHeight();
-            logicalWidth -= m_renderer->borderLogicalWidth();
-            break;
-        case ContentBox:
-            logicalHeight -= m_renderer->borderAndPaddingLogicalHeight();
-            logicalWidth -= m_renderer->borderAndPaddingLogicalWidth();
-            break;
-        case BoxMissing:
-            // A non-missing box value must be supplied.
-            ASSERT_NOT_REACHED();
-        }
-
-        LayoutSize newLogicalSize(logicalWidth, logicalHeight);
-        if (m_shapeLogicalSize == newLogicalSize)
-            return;
-        dirtyShapeSize();
-        m_shapeLogicalSize = newLogicalSize;
-    }
+    void setReferenceBoxLogicalSize(LayoutSize);
 
     SegmentList computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const;
 
@@ -106,72 +79,41 @@
     LayoutUnit shapeLogicalWidth() const { return computedShapeLogicalBoundingBox().width(); }
     LayoutUnit shapeLogicalHeight() const { return computedShapeLogicalBoundingBox().height(); }
 
-    LayoutUnit logicalLineTop() const { return m_shapeLineTop + logicalTopOffset(); }
-    LayoutUnit logicalLineBottom() const { return m_shapeLineTop + m_lineHeight + logicalTopOffset(); }
+    LayoutUnit logicalLineTop() const { return m_referenceBoxLineTop + logicalTopOffset(); }
+    LayoutUnit logicalLineBottom() const { return m_referenceBoxLineTop + m_lineHeight + logicalTopOffset(); }
 
-    LayoutUnit shapeContainingBlockHeight() const { return (m_renderer->style()->boxSizing() == CONTENT_BOX) ? (m_shapeLogicalSize.height() + m_renderer->borderAndPaddingLogicalHeight()) : m_shapeLogicalSize.height(); }
+    LayoutUnit shapeContainingBlockHeight() const { return (m_renderer.style()->boxSizing() == CONTENT_BOX) ? (m_referenceBoxLogicalSize.height() + m_renderer.borderAndPaddingLogicalHeight()) : m_referenceBoxLogicalSize.height(); }
 
     virtual bool lineOverlapsShapeBounds() const = 0;
 
-    void dirtyShapeSize() { m_shape.clear(); }
-    bool shapeSizeDirty() { return !m_shape.get(); }
-    const RenderType* owner() const { return m_renderer; }
-    LayoutSize shapeSize() const { return m_shapeLogicalSize; }
+    void markShapeAsDirty() { m_shape.clear(); }
+    bool isShapeDirty() { return !m_shape.get(); }
+    const RenderType& owner() const { return m_renderer; }
+    LayoutSize shapeSize() const { return m_referenceBoxLogicalSize; }
 
 protected:
-    ShapeInfo(const RenderType* renderer): m_renderer(renderer) { }
+    ShapeInfo(const RenderType& renderer): m_renderer(renderer) { }
 
-    const Shape* computedShape() const;
+    const Shape& computedShape() const;
 
-    virtual LayoutBox resolvedLayoutBox() const = 0;
+    virtual LayoutBox referenceBox() const = 0;
     virtual LayoutRect computedShapeLogicalBoundingBox() const = 0;
     virtual ShapeValue* shapeValue() const = 0;
     virtual void getIntervals(LayoutUnit, LayoutUnit, SegmentList&) const = 0;
 
-    LayoutUnit logicalTopOffset() const
-    {
-        switch (resolvedLayoutBox()) {
-        case MarginBox:
-            return -m_renderer->marginBefore();
-        case BorderBox:
-            return LayoutUnit();
-        case PaddingBox:
-            return m_renderer->borderBefore();
-        case ContentBox:
-            return m_renderer->borderAndPaddingBefore();
-        case BoxMissing:
-            // A non-missing box value must be supplied.
-            ASSERT_NOT_REACHED();
-        }
-        return LayoutUnit();
-    }
+    virtual const RenderStyle* styleForWritingMode() const = 0;
 
-    LayoutUnit logicalLeftOffset() const
-    {
-        switch (resolvedLayoutBox()) {
-        case MarginBox:
-            return -m_renderer->marginStart();
-        case BorderBox:
-            return LayoutUnit();
-        case PaddingBox:
-            return m_renderer->borderStart();
-        case ContentBox:
-            return m_renderer->borderAndPaddingStart();
-        case BoxMissing:
-            // A non-missing box value must be supplied.
-            ASSERT_NOT_REACHED();
-        }
-        return LayoutUnit();
-    }
+    LayoutUnit logicalTopOffset() const;
+    LayoutUnit logicalLeftOffset() const;
 
-    LayoutUnit m_shapeLineTop;
+    LayoutUnit m_referenceBoxLineTop;
     LayoutUnit m_lineHeight;
 
-    const RenderType* m_renderer;
+    const RenderType& m_renderer;
 
 private:
     mutable OwnPtr<Shape> m_shape;
-    LayoutSize m_shapeLogicalSize;
+    LayoutSize m_referenceBoxLogicalSize;
 };
 
 bool checkShapeImageOrigin(Document&, ImageResource&);
diff --git a/Source/core/rendering/shapes/ShapeInsideInfo.cpp b/Source/core/rendering/shapes/ShapeInsideInfo.cpp
index 13da8af..76bc0b7 100644
--- a/Source/core/rendering/shapes/ShapeInsideInfo.cpp
+++ b/Source/core/rendering/shapes/ShapeInsideInfo.cpp
@@ -41,9 +41,9 @@
     {
     }
 
-bool ShapeInsideInfo::isEnabledFor(const RenderBlock* renderer)
+bool ShapeInsideInfo::isEnabledFor(const RenderBlock& renderer)
 {
-    ShapeValue* shapeValue = renderer->style()->resolvedShapeInside();
+    ShapeValue* shapeValue = renderer.style()->resolvedShapeInside();
     if (!shapeValue)
         return false;
 
@@ -51,7 +51,7 @@
     case ShapeValue::Shape:
         return shapeValue->shape() && shapeValue->shape()->type() != BasicShape::BasicShapeInsetRectangleType && shapeValue->shape()->type() != BasicShape::BasicShapeInsetType;
     case ShapeValue::Image:
-        return shapeValue->isImageValid() && checkShapeImageOrigin(renderer->document(), *(shapeValue->image()->cachedImage()));
+        return shapeValue->isImageValid() && checkShapeImageOrigin(renderer.document(), *(shapeValue->image()->cachedImage()));
     case ShapeValue::Box:
         return true;
     case ShapeValue::Outside:
@@ -74,7 +74,7 @@
 bool ShapeInsideInfo::updateSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight)
 {
     ASSERT(lineHeight >= 0);
-    m_shapeLineTop = lineTop - logicalTopOffset();
+    m_referenceBoxLineTop = lineTop - logicalTopOffset();
     m_lineHeight = lineHeight;
     m_segments.clear();
     m_segmentRanges.clear();
@@ -87,14 +87,14 @@
 
 bool ShapeInsideInfo::adjustLogicalLineTop(float minSegmentWidth)
 {
-    const Shape* shape = computedShape();
-    if (!shape || m_lineHeight <= 0 || logicalLineTop() > shapeLogicalBottom())
+    const Shape& shape = computedShape();
+    if (m_lineHeight <= 0 || logicalLineTop() > shapeLogicalBottom())
         return false;
 
     LayoutUnit newLineTop;
-    if (shape->firstIncludedIntervalLogicalTop(m_shapeLineTop, FloatSize(minSegmentWidth, m_lineHeight), newLineTop)) {
-        if (newLineTop > m_shapeLineTop) {
-            m_shapeLineTop = newLineTop;
+    if (shape.firstIncludedIntervalLogicalTop(m_referenceBoxLineTop, FloatSize(minSegmentWidth, m_lineHeight.toFloat()), newLineTop)) {
+        if (newLineTop > m_referenceBoxLineTop) {
+            m_referenceBoxLineTop = newLineTop;
             return true;
         }
     }
@@ -104,16 +104,21 @@
 
 ShapeValue* ShapeInsideInfo::shapeValue() const
 {
-    return m_renderer->style()->resolvedShapeInside();
+    return m_renderer.style()->resolvedShapeInside();
+}
+
+const RenderStyle* ShapeInsideInfo::styleForWritingMode() const
+{
+    return m_renderer.style();
 }
 
 LayoutUnit ShapeInsideInfo::computeFirstFitPositionForFloat(const FloatSize& floatSize) const
 {
-    if (!computedShape() || !floatSize.width() || shapeLogicalBottom() < logicalLineTop())
+    if (!floatSize.width() || shapeLogicalBottom() < logicalLineTop())
         return 0;
 
     LayoutUnit firstFitPosition = 0;
-    if (computedShape()->firstIncludedIntervalLogicalTop(m_shapeLineTop, floatSize, firstFitPosition) && (m_shapeLineTop <= firstFitPosition))
+    if (computedShape().firstIncludedIntervalLogicalTop(m_referenceBoxLineTop, floatSize, firstFitPosition) && (m_referenceBoxLineTop <= firstFitPosition))
         return firstFitPosition;
 
     return 0;
diff --git a/Source/core/rendering/shapes/ShapeInsideInfo.h b/Source/core/rendering/shapes/ShapeInsideInfo.h
index 7828c05..ff618a2 100644
--- a/Source/core/rendering/shapes/ShapeInsideInfo.h
+++ b/Source/core/rendering/shapes/ShapeInsideInfo.h
@@ -62,9 +62,8 @@
 
 class ShapeInsideInfo FINAL : public ShapeInfo<RenderBlock> {
 public:
-    static PassOwnPtr<ShapeInsideInfo> createInfo(const RenderBlock* renderer) { return adoptPtr(new ShapeInsideInfo(renderer)); }
-
-    static bool isEnabledFor(const RenderBlock* renderer);
+    static PassOwnPtr<ShapeInsideInfo> createInfo(const RenderBlock& renderer) { return adoptPtr(new ShapeInsideInfo(renderer)); }
+    static bool isEnabledFor(const RenderBlock& renderer);
 
     bool updateSegmentsForLine(LayoutSize lineOffset, LayoutUnit lineHeight);
     bool updateSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight);
@@ -96,25 +95,27 @@
 
     virtual bool lineOverlapsShapeBounds() const OVERRIDE
     {
-        return computedShape()->lineOverlapsShapePaddingBounds(m_shapeLineTop, m_lineHeight);
+        return computedShape().lineOverlapsShapePaddingBounds(m_referenceBoxLineTop, m_lineHeight);
     }
 
 protected:
-    virtual LayoutBox resolvedLayoutBox() const OVERRIDE
+    virtual LayoutBox referenceBox() const OVERRIDE
     {
         if (shapeValue()->layoutBox() == BoxMissing)
             return ContentBox;
         return shapeValue()->layoutBox();
     }
-    virtual LayoutRect computedShapeLogicalBoundingBox() const OVERRIDE { return computedShape()->shapePaddingLogicalBoundingBox(); }
+    virtual LayoutRect computedShapeLogicalBoundingBox() const OVERRIDE { return computedShape().shapePaddingLogicalBoundingBox(); }
     virtual ShapeValue* shapeValue() const OVERRIDE;
     virtual void getIntervals(LayoutUnit lineTop, LayoutUnit lineHeight, SegmentList& segments) const OVERRIDE
     {
-        return computedShape()->getIncludedIntervals(lineTop, lineHeight, segments);
+        return computedShape().getIncludedIntervals(lineTop, lineHeight, segments);
     }
 
+    virtual const RenderStyle* styleForWritingMode() const OVERRIDE;
+
 private:
-    ShapeInsideInfo(const RenderBlock* renderer)
+    ShapeInsideInfo(const RenderBlock& renderer)
     : ShapeInfo<RenderBlock> (renderer)
     , m_needsLayout(false)
     { }
diff --git a/Source/core/rendering/shapes/ShapeOutsideInfo.cpp b/Source/core/rendering/shapes/ShapeOutsideInfo.cpp
index 98bea9a..22fb187 100644
--- a/Source/core/rendering/shapes/ShapeOutsideInfo.cpp
+++ b/Source/core/rendering/shapes/ShapeOutsideInfo.cpp
@@ -35,17 +35,17 @@
 #include "core/rendering/RenderBox.h"
 
 namespace WebCore {
-bool ShapeOutsideInfo::isEnabledFor(const RenderBox* box)
+bool ShapeOutsideInfo::isEnabledFor(const RenderBox& box)
 {
-    ShapeValue* shapeValue = box->style()->shapeOutside();
-    if (!box->isFloating() || !shapeValue)
+    ShapeValue* shapeValue = box.style()->shapeOutside();
+    if (!box.isFloating() || !shapeValue)
         return false;
 
     switch (shapeValue->type()) {
     case ShapeValue::Shape:
         return shapeValue->shape();
     case ShapeValue::Image:
-        return shapeValue->isImageValid() && checkShapeImageOrigin(box->document(), *(shapeValue->image()->cachedImage()));
+        return shapeValue->isImageValid() && checkShapeImageOrigin(box.document(), *(shapeValue->image()->cachedImage()));
     case ShapeValue::Box:
         return true;
     case ShapeValue::Outside:
@@ -55,26 +55,29 @@
     return false;
 }
 
-void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow* containingBlock, const FloatingObject* floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight)
+void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow& containingBlock, const FloatingObject& floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight)
 {
-    LayoutUnit shapeTop = containingBlock->logicalTopForFloat(floatingObject) + std::max(LayoutUnit(), containingBlock->marginBeforeForChild(m_renderer));
-    LayoutUnit floatRelativeLineTop = lineTop - shapeTop;
+    LayoutUnit borderBoxTop = containingBlock.logicalTopForFloat(&floatingObject) + containingBlock.marginBeforeForChild(&m_renderer);
+    LayoutUnit borderBoxLineTop = lineTop - borderBoxTop;
 
-    if (shapeSizeDirty() || m_lineTop != floatRelativeLineTop || m_lineHeight != lineHeight) {
-        m_lineTop = floatRelativeLineTop;
-        m_shapeLineTop = floatRelativeLineTop - logicalTopOffset();
+    if (isShapeDirty() || m_borderBoxLineTop != borderBoxLineTop || m_lineHeight != lineHeight) {
+        m_borderBoxLineTop = borderBoxLineTop;
+        m_referenceBoxLineTop = borderBoxLineTop - logicalTopOffset();
         m_lineHeight = lineHeight;
 
-        LayoutUnit floatMarginBoxWidth = containingBlock->logicalWidthForFloat(floatingObject);
+        LayoutUnit floatMarginBoxWidth = containingBlock.logicalWidthForFloat(&floatingObject);
 
         if (lineOverlapsShapeBounds()) {
-            SegmentList segments = computeSegmentsForLine(floatRelativeLineTop, lineHeight);
+            SegmentList segments = computeSegmentsForLine(borderBoxLineTop, lineHeight);
             if (segments.size()) {
-                LayoutUnit rawLeftMarginBoxDelta = segments.first().logicalLeft + containingBlock->marginStartForChild(m_renderer);
-                m_leftMarginBoxDelta = clampTo<LayoutUnit>(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth);
+                LayoutUnit logicalLeftMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginStartForChild(&m_renderer) : containingBlock.marginEndForChild(&m_renderer);
+                LayoutUnit rawLeftMarginBoxDelta = segments.first().logicalLeft + logicalLeftMargin;
+                m_leftMarginBoxDelta = clampToLayoutUnit(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth);
 
-                LayoutUnit rawRightMarginBoxDelta = segments.last().logicalRight - containingBlock->logicalWidthForChild(m_renderer) - containingBlock->marginEndForChild(m_renderer);
-                m_rightMarginBoxDelta = clampTo<LayoutUnit>(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit());
+                LayoutUnit logicalRightMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginEndForChild(&m_renderer) : containingBlock.marginStartForChild(&m_renderer);
+                LayoutUnit rawRightMarginBoxDelta = segments.last().logicalRight - containingBlock.logicalWidthForChild(&m_renderer) - logicalRightMargin;
+                m_rightMarginBoxDelta = clampToLayoutUnit(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit());
+                m_lineOverlapsShape = true;
                 return;
             }
         }
@@ -82,19 +85,21 @@
         // Lines that do not overlap the shape should act as if the float
         // wasn't there for layout purposes. So we set the deltas to remove the
         // entire width of the float.
-        // FIXME: The latest CSS Shapes spec says that in this case, the
-        // content should interact with previously stacked floats on the line
-        // as if this outermost float did not exist. Perhaps obviously, this
-        // solution cannot do that, and will be revisted when that part of the
-        // spec is implemented.
         m_leftMarginBoxDelta = floatMarginBoxWidth;
         m_rightMarginBoxDelta = -floatMarginBoxWidth;
+        m_lineOverlapsShape = false;
     }
 }
 
 ShapeValue* ShapeOutsideInfo::shapeValue() const
 {
-    return m_renderer->style()->shapeOutside();
+    return m_renderer.style()->shapeOutside();
+}
+
+const RenderStyle* ShapeOutsideInfo::styleForWritingMode() const
+{
+    ASSERT(m_renderer.containingBlock());
+    return m_renderer.containingBlock()->style();
 }
 
 }
diff --git a/Source/core/rendering/shapes/ShapeOutsideInfo.h b/Source/core/rendering/shapes/ShapeOutsideInfo.h
index 17f5ddb..b76d83d 100644
--- a/Source/core/rendering/shapes/ShapeOutsideInfo.h
+++ b/Source/core/rendering/shapes/ShapeOutsideInfo.h
@@ -43,37 +43,43 @@
 public:
     LayoutUnit leftMarginBoxDelta() const { return m_leftMarginBoxDelta; }
     LayoutUnit rightMarginBoxDelta() const { return m_rightMarginBoxDelta; }
+    bool lineOverlapsShape() const { return m_lineOverlapsShape; }
 
-    void updateDeltasForContainingBlockLine(const RenderBlockFlow*, const FloatingObject*, LayoutUnit lineTop, LayoutUnit lineHeight);
-
-    static PassOwnPtr<ShapeOutsideInfo> createInfo(const RenderBox* renderer) { return adoptPtr(new ShapeOutsideInfo(renderer)); }
-    static bool isEnabledFor(const RenderBox*);
+    static PassOwnPtr<ShapeOutsideInfo> createInfo(const RenderBox& renderer) { return adoptPtr(new ShapeOutsideInfo(renderer)); }
+    static bool isEnabledFor(const RenderBox&);
+    void updateDeltasForContainingBlockLine(const RenderBlockFlow&, const FloatingObject&, LayoutUnit lineTop, LayoutUnit lineHeight);
 
     virtual bool lineOverlapsShapeBounds() const OVERRIDE
     {
-        return computedShape()->lineOverlapsShapeMarginBounds(m_shapeLineTop, m_lineHeight);
+        return computedShape().lineOverlapsShapeMarginBounds(m_referenceBoxLineTop, m_lineHeight);
     }
 
 protected:
-    virtual LayoutBox resolvedLayoutBox() const OVERRIDE
+    virtual LayoutBox referenceBox() const OVERRIDE
     {
         if (shapeValue()->layoutBox() == BoxMissing)
             return MarginBox;
         return shapeValue()->layoutBox();
     }
-    virtual LayoutRect computedShapeLogicalBoundingBox() const OVERRIDE { return computedShape()->shapeMarginLogicalBoundingBox(); }
+    virtual LayoutRect computedShapeLogicalBoundingBox() const OVERRIDE { return computedShape().shapeMarginLogicalBoundingBox(); }
     virtual ShapeValue* shapeValue() const OVERRIDE;
     virtual void getIntervals(LayoutUnit lineTop, LayoutUnit lineHeight, SegmentList& segments) const OVERRIDE
     {
-        return computedShape()->getExcludedIntervals(lineTop, lineHeight, segments);
+        return computedShape().getExcludedIntervals(lineTop, lineHeight, segments);
     }
 
+    virtual const RenderStyle* styleForWritingMode() const OVERRIDE;
+
 private:
-    ShapeOutsideInfo(const RenderBox* renderer) : ShapeInfo<RenderBox>(renderer) { }
+    ShapeOutsideInfo(const RenderBox& renderer)
+        : ShapeInfo<RenderBox>(renderer)
+        , m_lineOverlapsShape(false)
+    { }
 
     LayoutUnit m_leftMarginBoxDelta;
     LayoutUnit m_rightMarginBoxDelta;
-    LayoutUnit m_lineTop;
+    LayoutUnit m_borderBoxLineTop;
+    bool m_lineOverlapsShape;
 };
 
 }
diff --git a/Source/core/rendering/style/BasicShapes.cpp b/Source/core/rendering/style/BasicShapes.cpp
index 8b9cbc5..94d0056 100644
--- a/Source/core/rendering/style/BasicShapes.cpp
+++ b/Source/core/rendering/style/BasicShapes.cpp
@@ -31,12 +31,30 @@
 #include "core/rendering/style/BasicShapes.h"
 
 #include "core/css/BasicShapeFunctions.h"
+#include "platform/CalculationValue.h"
 #include "platform/LengthFunctions.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/graphics/Path.h"
 
 namespace WebCore {
 
+void BasicShapeCenterCoordinate::updateComputedLength()
+{
+    if (m_direction == TopLeft) {
+        m_computedLength = m_length.isUndefined() ? Length(0, Fixed) : m_length;
+        return;
+    }
+    if (m_length.isUndefined()) {
+        m_computedLength = Length(100, Percent);
+        return;
+    }
+
+    OwnPtr<CalcExpressionLength> lhs = adoptPtr(new CalcExpressionLength(Length(100, Percent)));
+    OwnPtr<CalcExpressionLength> rhs = adoptPtr(new CalcExpressionLength(m_length));
+    OwnPtr<CalcExpressionBinaryOperation> op = adoptPtr(new CalcExpressionBinaryOperation(lhs.release(), rhs.release(), CalcSubtract));
+    m_computedLength = Length(CalculationValue::create(op.release(), ValueRangeAll));
+}
+
 bool BasicShape::canBlend(const BasicShape* other) const
 {
     // FIXME: Support animations between different shapes in the future.
@@ -53,9 +71,7 @@
     if (type() == BasicShape::BasicShapeCircleType) {
         const BasicShapeCircle* thisCircle = static_cast<const BasicShapeCircle*>(this);
         const BasicShapeCircle* otherCircle = static_cast<const BasicShapeCircle*>(other);
-        if (!thisCircle->radius().canBlend(otherCircle->radius())
-            || !thisCircle->centerX().canBlend(otherCircle->centerX())
-            || !thisCircle->centerY().canBlend(otherCircle->centerY()))
+        if (!thisCircle->radius().canBlend(otherCircle->radius()))
             return false;
     }
 
@@ -66,9 +82,7 @@
     const BasicShapeEllipse* thisEllipse = static_cast<const BasicShapeEllipse*>(this);
     const BasicShapeEllipse* otherEllipse = static_cast<const BasicShapeEllipse*>(other);
     return (thisEllipse->radiusX().canBlend(otherEllipse->radiusX())
-        && thisEllipse->radiusY().canBlend(otherEllipse->radiusY())
-        && thisEllipse->centerX().canBlend(otherEllipse->centerX())
-        && thisEllipse->centerY().canBlend(otherEllipse->centerY()));
+        && thisEllipse->radiusY().canBlend(otherEllipse->radiusY()));
 }
 
 void BasicShapeRectangle::path(Path& path, const FloatRect& boundingBox)
@@ -405,7 +419,7 @@
 {
     ASSERT(type() == other->type());
     // FIXME: Implement blend for BasicShapeInset.
-    return 0;
+    return nullptr;
 }
 
 bool BasicShapeInset::operator==(const BasicShape& o) const
diff --git a/Source/core/rendering/style/BasicShapes.h b/Source/core/rendering/style/BasicShapes.h
index 683ec38..4d9455e 100644
--- a/Source/core/rendering/style/BasicShapes.h
+++ b/Source/core/rendering/style/BasicShapes.h
@@ -69,17 +69,11 @@
 
     virtual Type type() const = 0;
 
-    LayoutBox layoutBox() const { return m_layoutBox; }
-    void setLayoutBox(LayoutBox layoutBox) { m_layoutBox = layoutBox; }
-
 protected:
     BasicShape()
-        : m_layoutBox(BoxMissing)
     {
     }
 
-private:
-    LayoutBox m_layoutBox;
 };
 
 #define DEFINE_BASICSHAPE_TYPE_CASTS(thisType) \
@@ -129,39 +123,48 @@
 
 class BasicShapeCenterCoordinate {
 public:
-    enum Keyword {
-        None,
-        Top,
-        Right,
-        Bottom,
-        Left
+    enum Direction {
+        TopLeft,
+        BottomRight
     };
-    BasicShapeCenterCoordinate() : m_keyword(None), m_length(Undefined) { }
-    explicit BasicShapeCenterCoordinate(Length length) : m_keyword(None), m_length(length) { }
-    BasicShapeCenterCoordinate(Keyword keyword, Length length) : m_keyword(keyword), m_length(length) { }
-    BasicShapeCenterCoordinate(const BasicShapeCenterCoordinate& other) : m_keyword(other.keyword()), m_length(other.length()) { }
-    bool operator==(const BasicShapeCenterCoordinate& other) const { return m_keyword == other.m_keyword && m_length == other.m_length; }
-
-    Keyword keyword() const { return m_keyword; }
-    const Length& length() const { return m_length; }
-
-    bool canBlend(const BasicShapeCenterCoordinate& other) const
+    BasicShapeCenterCoordinate()
+        : m_direction(TopLeft)
+        , m_length(Undefined)
     {
-        // FIXME determine how to interpolate between keywords. See issue 330248.
-        return m_keyword == None && other.keyword() == None;
+        updateComputedLength();
     }
 
+    BasicShapeCenterCoordinate(Direction direction, Length length)
+        : m_direction(direction)
+        , m_length(length)
+    {
+        updateComputedLength();
+    }
+
+    BasicShapeCenterCoordinate(const BasicShapeCenterCoordinate& other)
+        : m_direction(other.direction())
+        , m_length(other.length())
+        , m_computedLength(other.m_computedLength)
+    {
+    }
+
+    bool operator==(const BasicShapeCenterCoordinate& other) const { return m_direction == other.m_direction && m_length == other.m_length && m_computedLength == other.m_computedLength; }
+
+    Direction direction() const { return m_direction; }
+    const Length& length() const { return m_length; }
+    const Length& computedLength() const { return m_computedLength; }
+
     BasicShapeCenterCoordinate blend(const BasicShapeCenterCoordinate& other, double progress) const
     {
-        if (m_keyword != None || other.keyword() != None)
-            return BasicShapeCenterCoordinate(other);
-
-        return BasicShapeCenterCoordinate(m_length.blend(other.length(), progress, ValueRangeAll));
+        return BasicShapeCenterCoordinate(TopLeft, m_computedLength.blend(other.m_computedLength, progress, ValueRangeAll));
     }
 
 private:
-    Keyword m_keyword;
+    Direction m_direction;
     Length m_length;
+    Length m_computedLength;
+
+    void updateComputedLength();
 };
 
 class BasicShapeRadius {
diff --git a/Source/core/rendering/style/FillLayer.h b/Source/core/rendering/style/FillLayer.h
index 790f202..1027f9c 100644
--- a/Source/core/rendering/style/FillLayer.h
+++ b/Source/core/rendering/style/FillLayer.h
@@ -66,8 +66,8 @@
     ~FillLayer();
 
     StyleImage* image() const { return m_image.get(); }
-    Length xPosition() const { return m_xPosition; }
-    Length yPosition() const { return m_yPosition; }
+    const Length& xPosition() const { return m_xPosition; }
+    const Length& yPosition() const { return m_yPosition; }
     BackgroundEdgeOrigin backgroundXOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundXOrigin); }
     BackgroundEdgeOrigin backgroundYOrigin() const { return static_cast<BackgroundEdgeOrigin>(m_backgroundYOrigin); }
     EFillAttachment attachment() const { return static_cast<EFillAttachment>(m_attachment); }
@@ -77,7 +77,7 @@
     EFillRepeat repeatY() const { return static_cast<EFillRepeat>(m_repeatY); }
     CompositeOperator composite() const { return static_cast<CompositeOperator>(m_composite); }
     blink::WebBlendMode blendMode() const { return static_cast<blink::WebBlendMode>(m_blendMode); }
-    LengthSize sizeLength() const { return m_sizeLength; }
+    const LengthSize& sizeLength() const { return m_sizeLength; }
     EFillSizeType sizeType() const { return static_cast<EFillSizeType>(m_sizeType); }
     FillSize size() const { return FillSize(static_cast<EFillSizeType>(m_sizeType), m_sizeLength); }
     EMaskSourceType maskSourceType() const { return static_cast<EMaskSourceType>(m_maskSourceType); }
diff --git a/Source/core/rendering/style/GridCoordinate.h b/Source/core/rendering/style/GridCoordinate.h
index 937d3f0..1e3421e 100644
--- a/Source/core/rendering/style/GridCoordinate.h
+++ b/Source/core/rendering/style/GridCoordinate.h
@@ -74,8 +74,12 @@
         // is already converted to an index in our grid representation (ie one was removed from the grid line to account for the side).
         size_t firstLineBeforeOppositePositionIndex = 0;
         const size_t* firstLineBeforeOppositePosition = std::lower_bound(gridLines.begin(), gridLines.end(), resolvedOppositePosition);
-        if (firstLineBeforeOppositePosition != gridLines.end())
+        if (firstLineBeforeOppositePosition != gridLines.end()) {
+            if (*firstLineBeforeOppositePosition > resolvedOppositePosition && firstLineBeforeOppositePosition != gridLines.begin())
+                --firstLineBeforeOppositePosition;
+
             firstLineBeforeOppositePositionIndex = firstLineBeforeOppositePosition - gridLines.begin();
+        }
 
         size_t gridLineIndex = std::max<int>(0, firstLineBeforeOppositePositionIndex - position.spanPosition() + 1);
         size_t resolvedGridLinePosition = gridLines[gridLineIndex];
diff --git a/Source/core/rendering/style/GridPosition.h b/Source/core/rendering/style/GridPosition.h
index 133cdd5..778e453 100644
--- a/Source/core/rendering/style/GridPosition.h
+++ b/Source/core/rendering/style/GridPosition.h
@@ -85,6 +85,12 @@
         m_namedGridLine = namedGridLine;
     }
 
+    void setAutoPosition()
+    {
+        m_type = AutoPosition;
+        m_integerPosition = 0;
+    }
+
     // 'span' values cannot be negative, yet we reuse the <integer> position which can
     // be. This means that we have to convert the span position to an integer, losing
     // some precision here. It shouldn't be an issue in practice though.
diff --git a/Source/core/rendering/style/KeyframeList.h b/Source/core/rendering/style/KeyframeList.h
index ee2d237..eaf03c6 100644
--- a/Source/core/rendering/style/KeyframeList.h
+++ b/Source/core/rendering/style/KeyframeList.h
@@ -71,8 +71,8 @@
     KeyframeList(RenderObject&, const AtomicString& animationName)
         : m_animationName(animationName)
     {
-        insert(KeyframeValue(0, 0));
-        insert(KeyframeValue(1, 0));
+        insert(KeyframeValue(0, nullptr));
+        insert(KeyframeValue(1, nullptr));
     }
     ~KeyframeList();
 
diff --git a/Source/core/rendering/style/NinePieceImage.cpp b/Source/core/rendering/style/NinePieceImage.cpp
index 383ca14..7dc3446 100644
--- a/Source/core/rendering/style/NinePieceImage.cpp
+++ b/Source/core/rendering/style/NinePieceImage.cpp
@@ -55,7 +55,7 @@
     : fill(false)
     , horizontalRule(StretchImageRule)
     , verticalRule(StretchImageRule)
-    , image(0)
+    , image(nullptr)
     , imageSlices(Length(100, Percent), Length(100, Percent), Length(100, Percent), Length(100, Percent))
     , borderSlices(1.0, 1.0, 1.0, 1.0)
     , outset(Length(0, Fixed), Length(0, Fixed), Length(0, Fixed), Length(0, Fixed))
diff --git a/Source/core/rendering/style/RenderStyle.cpp b/Source/core/rendering/style/RenderStyle.cpp
index 3744a0c..fbbe571 100644
--- a/Source/core/rendering/style/RenderStyle.cpp
+++ b/Source/core/rendering/style/RenderStyle.cpp
@@ -37,6 +37,7 @@
 #include "platform/LengthFunctions.h"
 #include "platform/fonts/Font.h"
 #include "platform/fonts/FontSelector.h"
+#include "platform/geometry/FloatRoundedRect.h"
 #include "wtf/MathExtras.h"
 
 using namespace std;
@@ -125,6 +126,7 @@
     rareNonInheritedData.access()->m_marquee.init();
     rareNonInheritedData.access()->m_multiCol.init();
     rareNonInheritedData.access()->m_transform.init();
+    rareNonInheritedData.access()->m_willChange.init();
     rareNonInheritedData.access()->m_filter.init();
     rareNonInheritedData.access()->m_grid.init();
     rareNonInheritedData.access()->m_gridItem.init();
@@ -649,7 +651,9 @@
             || rareNonInheritedData->m_backfaceVisibility != other->rareNonInheritedData->m_backfaceVisibility
             || rareNonInheritedData->m_perspective != other->rareNonInheritedData->m_perspective
             || rareNonInheritedData->m_perspectiveOriginX != other->rareNonInheritedData->m_perspectiveOriginX
-            || rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY)
+            || rareNonInheritedData->m_perspectiveOriginY != other->rareNonInheritedData->m_perspectiveOriginY
+            || hasWillChangeCompositingHint() != other->hasWillChangeCompositingHint()
+            || hasWillChangeGpuRasterizationHint() != other->hasWillChangeGpuRasterizationHint())
             return StyleDifferenceRecompositeLayer;
     }
 
@@ -703,7 +707,7 @@
 void RenderStyle::clearCursorList()
 {
     if (rareInheritedData->cursorData)
-        rareInheritedData.access()->cursorData = 0;
+        rareInheritedData.access()->cursorData = nullptr;
 }
 
 void RenderStyle::addCallbackSelector(const String& selector)
@@ -830,6 +834,44 @@
     return false;
 }
 
+bool RenderStyle::hasWillChangeCompositingHint() const
+{
+    for (size_t i = 0; i < rareNonInheritedData->m_willChange->m_properties.size(); ++i) {
+        switch (rareNonInheritedData->m_willChange->m_properties[i]) {
+        case CSSPropertyOpacity:
+        case CSSPropertyWebkitTransform:
+        case CSSPropertyLeft:
+        case CSSPropertyTop:
+        case CSSPropertyRight:
+        case CSSPropertyBottom:
+        case CSSPropertyWebkitFilter:
+            return true;
+        default:
+            break;
+        }
+    }
+    return false;
+}
+
+bool RenderStyle::hasWillChangeGpuRasterizationHint() const
+{
+    if (willChangeContents())
+        return true;
+
+    for (size_t i = 0; i < rareNonInheritedData->m_willChange->m_properties.size(); ++i) {
+        switch (rareNonInheritedData->m_willChange->m_properties[i]) {
+        case CSSPropertyWidth:
+        case CSSPropertyHeight:
+        case CSSPropertyBackgroundColor:
+        case CSSPropertyBackgroundPosition:
+            return true;
+        default:
+            break;
+        }
+    }
+    return false;
+}
+
 inline bool requireTransformOrigin(const Vector<RefPtr<TransformOperation> >& transformOperations, RenderStyle::ApplyTransformOrigin applyOrigin)
 {
     // transform-origin brackets the transform with translate operations.
@@ -905,38 +947,6 @@
             valueForLength(border.bottomRight().height(), size.height())));
 }
 
-static float calcConstraintScaleFor(const IntRect& rect, const RoundedRect::Radii& radii)
-{
-    // Constrain corner radii using CSS3 rules:
-    // http://www.w3.org/TR/css3-background/#the-border-radius
-
-    float factor = 1;
-    unsigned radiiSum;
-
-    // top
-    radiiSum = static_cast<unsigned>(radii.topLeft().width()) + static_cast<unsigned>(radii.topRight().width()); // Casts to avoid integer overflow.
-    if (radiiSum > static_cast<unsigned>(rect.width()))
-        factor = min(static_cast<float>(rect.width()) / radiiSum, factor);
-
-    // bottom
-    radiiSum = static_cast<unsigned>(radii.bottomLeft().width()) + static_cast<unsigned>(radii.bottomRight().width());
-    if (radiiSum > static_cast<unsigned>(rect.width()))
-        factor = min(static_cast<float>(rect.width()) / radiiSum, factor);
-
-    // left
-    radiiSum = static_cast<unsigned>(radii.topLeft().height()) + static_cast<unsigned>(radii.bottomLeft().height());
-    if (radiiSum > static_cast<unsigned>(rect.height()))
-        factor = min(static_cast<float>(rect.height()) / radiiSum, factor);
-
-    // right
-    radiiSum = static_cast<unsigned>(radii.topRight().height()) + static_cast<unsigned>(radii.bottomRight().height());
-    if (radiiSum > static_cast<unsigned>(rect.height()))
-        factor = min(static_cast<float>(rect.height()) / radiiSum, factor);
-
-    ASSERT(factor <= 1);
-    return factor;
-}
-
 StyleImage* RenderStyle::listStyleImage() const { return rareInheritedData->listStyleImage.get(); }
 void RenderStyle::setListStyleImage(PassRefPtr<StyleImage> v)
 {
@@ -960,7 +970,7 @@
     RoundedRect roundedRect(snappedBorderRect);
     if (hasBorderRadius()) {
         RoundedRect::Radii radii = calcRadiiFor(surround->border, snappedBorderRect.size());
-        radii.scale(calcConstraintScaleFor(snappedBorderRect, radii));
+        radii.scale(calcBorderRadiiConstraintScaleFor(borderRect, radii));
         roundedRect.includeLogicalEdges(radii, isHorizontalWritingMode(), includeLogicalLeftEdge, includeLogicalRightEdge);
     }
     return roundedRect;
@@ -1175,6 +1185,7 @@
 float RenderStyle::specifiedFontSize() const { return fontDescription().specifiedSize(); }
 float RenderStyle::computedFontSize() const { return fontDescription().computedSize(); }
 int RenderStyle::fontSize() const { return fontDescription().computedPixelSize(); }
+FontWeight RenderStyle::fontWeight() const { return fontDescription().weight(); }
 
 float RenderStyle::wordSpacing() const { return fontDescription().wordSpacing(); }
 float RenderStyle::letterSpacing() const { return fontDescription().letterSpacing(); }
@@ -1188,7 +1199,7 @@
     return false;
 }
 
-Length RenderStyle::specifiedLineHeight() const { return inherited->line_height; }
+const Length& RenderStyle::specifiedLineHeight() const { return inherited->line_height; }
 Length RenderStyle::lineHeight() const
 {
     const Length& lh = inherited->line_height;
@@ -1247,6 +1258,15 @@
     font().update(currentFontSelector);
 }
 
+void RenderStyle::setFontWeight(FontWeight weight)
+{
+    FontSelector* currentFontSelector = font().fontSelector();
+    FontDescription desc(fontDescription());
+    desc.setWeight(weight);
+    setFontDescription(desc);
+    font().update(currentFontSelector);
+}
+
 void RenderStyle::getShadowExtent(const ShadowList* shadowList, LayoutUnit &top, LayoutUnit &right, LayoutUnit &bottom, LayoutUnit &left) const
 {
     top = 0;
@@ -1594,4 +1614,36 @@
     surround.access()->border.m_image.setOutset(outset);
 }
 
+float calcBorderRadiiConstraintScaleFor(const FloatRect& rect, const FloatRoundedRect::Radii& radii)
+{
+    // Constrain corner radii using CSS3 rules:
+    // http://www.w3.org/TR/css3-background/#the-border-radius
+
+    float factor = 1;
+    float radiiSum;
+
+    // top
+    radiiSum = radii.topLeft().width() + radii.topRight().width(); // Casts to avoid integer overflow.
+    if (radiiSum > rect.width())
+        factor = std::min(rect.width() / radiiSum, factor);
+
+    // bottom
+    radiiSum = radii.bottomLeft().width() + radii.bottomRight().width();
+    if (radiiSum > rect.width())
+        factor = std::min(rect.width() / radiiSum, factor);
+
+    // left
+    radiiSum = radii.topLeft().height() + radii.bottomLeft().height();
+    if (radiiSum > rect.height())
+        factor = std::min(rect.height() / radiiSum, factor);
+
+    // right
+    radiiSum = radii.topRight().height() + radii.bottomRight().height();
+    if (radiiSum > rect.height())
+        factor = std::min(rect.height() / radiiSum, factor);
+
+    ASSERT(factor <= 1);
+    return factor;
+}
+
 } // namespace WebCore
diff --git a/Source/core/rendering/style/RenderStyle.h b/Source/core/rendering/style/RenderStyle.h
index 147734e..0ef9eb2 100644
--- a/Source/core/rendering/style/RenderStyle.h
+++ b/Source/core/rendering/style/RenderStyle.h
@@ -53,6 +53,7 @@
 #include "core/rendering/style/StyleSurroundData.h"
 #include "core/rendering/style/StyleTransformData.h"
 #include "core/rendering/style/StyleVisualData.h"
+#include "core/rendering/style/StyleWillChangeData.h"
 #include "core/svg/SVGPaint.h"
 #include "platform/Length.h"
 #include "platform/LengthBox.h"
@@ -60,6 +61,7 @@
 #include "platform/ThemeTypes.h"
 #include "platform/fonts/FontBaseline.h"
 #include "platform/fonts/FontDescription.h"
+#include "platform/geometry/FloatRoundedRect.h"
 #include "platform/geometry/LayoutBoxExtent.h"
 #include "platform/geometry/RoundedRect.h"
 #include "platform/graphics/Color.h"
@@ -110,7 +112,7 @@
 class RenderStyle: public RefCounted<RenderStyle> {
     friend class AnimatedStyleBuilder; // Used by Web Animations CSS. Sets the color styles
     friend class CSSAnimatableValueFactory; // Used by Web Animations CSS. Gets visited and unvisited colors separately.
-    friend class CSSPropertyAnimation; // Used by CSS animations. We can't allow them to animate based off visited colors.
+    friend class CSSPropertyEquality; // Used by CSS animations. We can't allow them to animate based off visited colors.
     friend class ApplyStyleCommand; // Editing has to only reveal unvisited info.
     friend class EditingStyle; // Editing has to only reveal unvisited info.
     friend class CSSComputedStyleDeclaration; // Ignores visited styles, so needs to be able to see unvisited info.
@@ -441,16 +443,16 @@
     EDisplay display() const { return static_cast<EDisplay>(noninherited_flags._effectiveDisplay); }
     EDisplay originalDisplay() const { return static_cast<EDisplay>(noninherited_flags._originalDisplay); }
 
-    Length left() const { return surround->offset.left(); }
-    Length right() const { return surround->offset.right(); }
-    Length top() const { return surround->offset.top(); }
-    Length bottom() const { return surround->offset.bottom(); }
+    const Length& left() const { return surround->offset.left(); }
+    const Length& right() const { return surround->offset.right(); }
+    const Length& top() const { return surround->offset.top(); }
+    const Length& bottom() const { return surround->offset.bottom(); }
 
     // Accessors for positioned object edges that take into account writing mode.
-    Length logicalLeft() const { return surround->offset.logicalLeft(writingMode()); }
-    Length logicalRight() const { return surround->offset.logicalRight(writingMode()); }
-    Length logicalTop() const { return surround->offset.before(writingMode()); }
-    Length logicalBottom() const { return surround->offset.after(writingMode()); }
+    const Length& logicalLeft() const { return surround->offset.logicalLeft(writingMode()); }
+    const Length& logicalRight() const { return surround->offset.logicalRight(writingMode()); }
+    const Length& logicalTop() const { return surround->offset.before(writingMode()); }
+    const Length& logicalBottom() const { return surround->offset.after(writingMode()); }
 
     // Whether or not a positioned element requires normal flow x/y to be computed
     // to determine its position.
@@ -465,19 +467,19 @@
     bool hasViewportConstrainedPosition() const { return position() == FixedPosition || position() == StickyPosition; }
     EFloat floating() const { return static_cast<EFloat>(noninherited_flags._floating); }
 
-    Length width() const { return m_box->width(); }
-    Length height() const { return m_box->height(); }
-    Length minWidth() const { return m_box->minWidth(); }
-    Length maxWidth() const { return m_box->maxWidth(); }
-    Length minHeight() const { return m_box->minHeight(); }
-    Length maxHeight() const { return m_box->maxHeight(); }
+    const Length& width() const { return m_box->width(); }
+    const Length& height() const { return m_box->height(); }
+    const Length& minWidth() const { return m_box->minWidth(); }
+    const Length& maxWidth() const { return m_box->maxWidth(); }
+    const Length& minHeight() const { return m_box->minHeight(); }
+    const Length& maxHeight() const { return m_box->maxHeight(); }
 
-    Length logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); }
-    Length logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); }
-    Length logicalMinWidth() const { return isHorizontalWritingMode() ? minWidth() : minHeight(); }
-    Length logicalMaxWidth() const { return isHorizontalWritingMode() ? maxWidth() : maxHeight(); }
-    Length logicalMinHeight() const { return isHorizontalWritingMode() ? minHeight() : minWidth(); }
-    Length logicalMaxHeight() const { return isHorizontalWritingMode() ? maxHeight() : maxWidth(); }
+    const Length& logicalWidth() const { return isHorizontalWritingMode() ? width() : height(); }
+    const Length& logicalHeight() const { return isHorizontalWritingMode() ? height() : width(); }
+    const Length& logicalMinWidth() const { return isHorizontalWritingMode() ? minWidth() : minHeight(); }
+    const Length& logicalMaxWidth() const { return isHorizontalWritingMode() ? maxWidth() : maxHeight(); }
+    const Length& logicalMinHeight() const { return isHorizontalWritingMode() ? minHeight() : minWidth(); }
+    const Length& logicalMaxHeight() const { return isHorizontalWritingMode() ? maxHeight() : maxWidth(); }
 
     const BorderData& border() const { return surround->border; }
     const BorderValue& borderLeft() const { return surround->border.left(); }
@@ -492,14 +494,14 @@
 
     const NinePieceImage& borderImage() const { return surround->border.image(); }
     StyleImage* borderImageSource() const { return surround->border.image().image(); }
-    LengthBox borderImageSlices() const { return surround->border.image().imageSlices(); }
+    const LengthBox& borderImageSlices() const { return surround->border.image().imageSlices(); }
     const BorderImageLengthBox& borderImageWidth() const { return surround->border.image().borderSlices(); }
     const BorderImageLengthBox& borderImageOutset() const { return surround->border.image().outset(); }
 
-    LengthSize borderTopLeftRadius() const { return surround->border.topLeft(); }
-    LengthSize borderTopRightRadius() const { return surround->border.topRight(); }
-    LengthSize borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
-    LengthSize borderBottomRightRadius() const { return surround->border.bottomRight(); }
+    const LengthSize& borderTopLeftRadius() const { return surround->border.topLeft(); }
+    const LengthSize& borderTopRightRadius() const { return surround->border.topRight(); }
+    const LengthSize& borderBottomLeftRadius() const { return surround->border.bottomLeft(); }
+    const LengthSize& borderBottomRightRadius() const { return surround->border.bottomRight(); }
     bool hasBorderRadius() const { return surround->border.hasBorderRadius(); }
 
     unsigned borderLeftWidth() const { return surround->border.borderLeftWidth(); }
@@ -539,13 +541,13 @@
 
     EVisibility visibility() const { return static_cast<EVisibility>(inherited_flags._visibility); }
     EVerticalAlign verticalAlign() const { return static_cast<EVerticalAlign>(noninherited_flags._vertical_align); }
-    Length verticalAlignLength() const { return m_box->verticalAlign(); }
+    const Length& verticalAlignLength() const { return m_box->verticalAlign(); }
 
-    Length clipLeft() const { return visual->clip.left(); }
-    Length clipRight() const { return visual->clip.right(); }
-    Length clipTop() const { return visual->clip.top(); }
-    Length clipBottom() const { return visual->clip.bottom(); }
-    LengthBox clip() const { return visual->clip; }
+    const Length& clipLeft() const { return visual->clip.left(); }
+    const Length& clipRight() const { return visual->clip.right(); }
+    const Length& clipTop() const { return visual->clip.top(); }
+    const Length& clipBottom() const { return visual->clip.bottom(); }
+    const LengthBox& clip() const { return visual->clip; }
     bool hasClip() const { return visual->hasClip; }
 
     EUnicodeBidi unicodeBidi() const { return static_cast<EUnicodeBidi>(noninherited_flags._unicodeBidi); }
@@ -559,10 +561,11 @@
     float specifiedFontSize() const;
     float computedFontSize() const;
     int fontSize() const;
+    FontWeight fontWeight() const;
 
     float textAutosizingMultiplier() const { return visual->m_textAutosizingMultiplier; }
 
-    Length textIndent() const { return rareInheritedData->indent; }
+    const Length& textIndent() const { return rareInheritedData->indent; }
     TextIndentLine textIndentLine() const { return static_cast<TextIndentLine>(rareInheritedData->m_textIndentLine); }
     ETextAlign textAlign() const { return static_cast<ETextAlign>(inherited_flags._text_align); }
     TextAlignLast textAlignLast() const { return static_cast<TextAlignLast>(rareInheritedData->m_textAlignLast); }
@@ -581,7 +584,7 @@
     TextDirection direction() const { return static_cast<TextDirection>(inherited_flags._direction); }
     bool isLeftToRightDirection() const { return direction() == LTR; }
 
-    Length specifiedLineHeight() const;
+    const Length& specifiedLineHeight() const;
     Length lineHeight() const;
     int computedLineHeight() const;
 
@@ -647,10 +650,10 @@
     EFillAttachment backgroundAttachment() const { return static_cast<EFillAttachment>(m_background->background().attachment()); }
     EFillBox backgroundClip() const { return static_cast<EFillBox>(m_background->background().clip()); }
     EFillBox backgroundOrigin() const { return static_cast<EFillBox>(m_background->background().origin()); }
-    Length backgroundXPosition() const { return m_background->background().xPosition(); }
-    Length backgroundYPosition() const { return m_background->background().yPosition(); }
+    const Length& backgroundXPosition() const { return m_background->background().xPosition(); }
+    const Length& backgroundYPosition() const { return m_background->background().yPosition(); }
     EFillSizeType backgroundSizeType() const { return m_background->background().sizeType(); }
-    LengthSize backgroundSizeLength() const { return m_background->background().sizeLength(); }
+    const LengthSize& backgroundSizeLength() const { return m_background->background().sizeLength(); }
     FillLayer* accessBackgroundLayers() { return &(m_background.access()->m_background); }
     const FillLayer* backgroundLayers() const { return &(m_background->background()); }
 
@@ -660,16 +663,16 @@
     CompositeOperator maskComposite() const { return static_cast<CompositeOperator>(rareNonInheritedData->m_mask.composite()); }
     EFillBox maskClip() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.clip()); }
     EFillBox maskOrigin() const { return static_cast<EFillBox>(rareNonInheritedData->m_mask.origin()); }
-    Length maskXPosition() const { return rareNonInheritedData->m_mask.xPosition(); }
-    Length maskYPosition() const { return rareNonInheritedData->m_mask.yPosition(); }
+    const Length& maskXPosition() const { return rareNonInheritedData->m_mask.xPosition(); }
+    const Length& maskYPosition() const { return rareNonInheritedData->m_mask.yPosition(); }
     EFillSizeType maskSizeType() const { return rareNonInheritedData->m_mask.sizeType(); }
-    LengthSize maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); }
+    const LengthSize& maskSizeLength() const { return rareNonInheritedData->m_mask.sizeLength(); }
     FillLayer* accessMaskLayers() { return &(rareNonInheritedData.access()->m_mask); }
     const FillLayer* maskLayers() const { return &(rareNonInheritedData->m_mask); }
 
     const NinePieceImage& maskBoxImage() const { return rareNonInheritedData->m_maskBoxImage; }
     StyleImage* maskBoxImageSource() const { return rareNonInheritedData->m_maskBoxImage.image(); }
-    LengthBox maskBoxImageSlices() const { return rareNonInheritedData->m_maskBoxImage.imageSlices(); }
+    const LengthBox& maskBoxImageSlices() const { return rareNonInheritedData->m_maskBoxImage.imageSlices(); }
     bool maskBoxImageSlicesFill() const { return rareNonInheritedData->m_maskBoxImage.fill(); }
     const BorderImageLengthBox& maskBoxImageWidth() const { return rareNonInheritedData->m_maskBoxImage.borderSlices(); }
     const BorderImageLengthBox& maskBoxImageOutset() const { return rareNonInheritedData->m_maskBoxImage.outset(); }
@@ -684,28 +687,28 @@
     StyleImage* listStyleImage() const;
     EListStylePosition listStylePosition() const { return static_cast<EListStylePosition>(inherited_flags._list_style_position); }
 
-    Length marginTop() const { return surround->margin.top(); }
-    Length marginBottom() const { return surround->margin.bottom(); }
-    Length marginLeft() const { return surround->margin.left(); }
-    Length marginRight() const { return surround->margin.right(); }
-    Length marginBefore() const { return surround->margin.before(writingMode()); }
-    Length marginAfter() const { return surround->margin.after(writingMode()); }
-    Length marginStart() const { return surround->margin.start(writingMode(), direction()); }
-    Length marginEnd() const { return surround->margin.end(writingMode(), direction()); }
-    Length marginStartUsing(const RenderStyle* otherStyle) const { return surround->margin.start(otherStyle->writingMode(), otherStyle->direction()); }
-    Length marginEndUsing(const RenderStyle* otherStyle) const { return surround->margin.end(otherStyle->writingMode(), otherStyle->direction()); }
-    Length marginBeforeUsing(const RenderStyle* otherStyle) const { return surround->margin.before(otherStyle->writingMode()); }
-    Length marginAfterUsing(const RenderStyle* otherStyle) const { return surround->margin.after(otherStyle->writingMode()); }
+    const Length& marginTop() const { return surround->margin.top(); }
+    const Length& marginBottom() const { return surround->margin.bottom(); }
+    const Length& marginLeft() const { return surround->margin.left(); }
+    const Length& marginRight() const { return surround->margin.right(); }
+    const Length& marginBefore() const { return surround->margin.before(writingMode()); }
+    const Length& marginAfter() const { return surround->margin.after(writingMode()); }
+    const Length& marginStart() const { return surround->margin.start(writingMode(), direction()); }
+    const Length& marginEnd() const { return surround->margin.end(writingMode(), direction()); }
+    const Length& marginStartUsing(const RenderStyle* otherStyle) const { return surround->margin.start(otherStyle->writingMode(), otherStyle->direction()); }
+    const Length& marginEndUsing(const RenderStyle* otherStyle) const { return surround->margin.end(otherStyle->writingMode(), otherStyle->direction()); }
+    const Length& marginBeforeUsing(const RenderStyle* otherStyle) const { return surround->margin.before(otherStyle->writingMode()); }
+    const Length& marginAfterUsing(const RenderStyle* otherStyle) const { return surround->margin.after(otherStyle->writingMode()); }
 
-    LengthBox paddingBox() const { return surround->padding; }
-    Length paddingTop() const { return surround->padding.top(); }
-    Length paddingBottom() const { return surround->padding.bottom(); }
-    Length paddingLeft() const { return surround->padding.left(); }
-    Length paddingRight() const { return surround->padding.right(); }
-    Length paddingBefore() const { return surround->padding.before(writingMode()); }
-    Length paddingAfter() const { return surround->padding.after(writingMode()); }
-    Length paddingStart() const { return surround->padding.start(writingMode(), direction()); }
-    Length paddingEnd() const { return surround->padding.end(writingMode(), direction()); }
+    const LengthBox& paddingBox() const { return surround->padding; }
+    const Length& paddingTop() const { return surround->padding.top(); }
+    const Length& paddingBottom() const { return surround->padding.bottom(); }
+    const Length& paddingLeft() const { return surround->padding.left(); }
+    const Length& paddingRight() const { return surround->padding.right(); }
+    const Length& paddingBefore() const { return surround->padding.before(writingMode()); }
+    const Length& paddingAfter() const { return surround->padding.after(writingMode()); }
+    const Length& paddingStart() const { return surround->padding.start(writingMode(), direction()); }
+    const Length& paddingEnd() const { return surround->padding.end(writingMode(), direction()); }
 
     ECursor cursor() const { return static_cast<ECursor>(inherited_flags._cursor_style); }
     CursorList* cursors() const { return rareInheritedData->cursorData.get(); }
@@ -758,7 +761,7 @@
     const Vector<String>& callbackSelectors() const { return rareNonInheritedData->m_callbackSelectors; }
     float flexGrow() const { return rareNonInheritedData->m_flexibleBox->m_flexGrow; }
     float flexShrink() const { return rareNonInheritedData->m_flexibleBox->m_flexShrink; }
-    Length flexBasis() const { return rareNonInheritedData->m_flexibleBox->m_flexBasis; }
+    const Length& flexBasis() const { return rareNonInheritedData->m_flexibleBox->m_flexBasis; }
     EAlignContent alignContent() const { return static_cast<EAlignContent>(rareNonInheritedData->m_alignContent); }
     ItemPosition alignItems() const { return static_cast<ItemPosition>(rareNonInheritedData->m_alignItems); }
     OverflowAlignment alignItemsOverflowAlignment() const { return static_cast<OverflowAlignment>(rareNonInheritedData->m_alignItemsOverflowAlignment); }
@@ -803,7 +806,7 @@
     bool reflectionDataEquivalent(const RenderStyle* otherStyle) const { return rareNonInheritedData->reflectionDataEquivalent(*otherStyle->rareNonInheritedData); }
 
     EBoxSizing boxSizing() const { return m_box->boxSizing(); }
-    Length marqueeIncrement() const { return rareNonInheritedData->m_marquee->increment; }
+    const Length& marqueeIncrement() const { return rareNonInheritedData->m_marquee->increment; }
     int marqueeSpeed() const { return rareNonInheritedData->m_marquee->speed; }
     int marqueeLoopCount() const { return rareNonInheritedData->m_marquee->loops; }
     EMarqueeBehavior marqueeBehavior() const { return static_cast<EMarqueeBehavior>(rareNonInheritedData->m_marquee->behavior); }
@@ -854,8 +857,8 @@
     EPageBreak columnBreakInside() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakInside); }
     EPageBreak columnBreakAfter() const { return static_cast<EPageBreak>(rareNonInheritedData->m_multiCol->m_breakAfter); }
     const TransformOperations& transform() const { return rareNonInheritedData->m_transform->m_operations; }
-    Length transformOriginX() const { return rareNonInheritedData->m_transform->m_x; }
-    Length transformOriginY() const { return rareNonInheritedData->m_transform->m_y; }
+    const Length& transformOriginX() const { return rareNonInheritedData->m_transform->m_x; }
+    const Length& transformOriginY() const { return rareNonInheritedData->m_transform->m_y; }
     float transformOriginZ() const { return rareNonInheritedData->m_transform->m_z; }
     bool hasTransform() const { return !rareNonInheritedData->m_transform->m_operations.operations().isEmpty(); }
     bool transformDataEquivalent(const RenderStyle* otherStyle) const { return rareNonInheritedData->m_transform == otherStyle->rareNonInheritedData->m_transform; }
@@ -912,9 +915,9 @@
     EBackfaceVisibility backfaceVisibility() const { return static_cast<EBackfaceVisibility>(rareNonInheritedData->m_backfaceVisibility); }
     float perspective() const { return rareNonInheritedData->m_perspective; }
     bool hasPerspective() const { return rareNonInheritedData->m_perspective > 0; }
-    Length perspectiveOriginX() const { return rareNonInheritedData->m_perspectiveOriginX; }
-    Length perspectiveOriginY() const { return rareNonInheritedData->m_perspectiveOriginY; }
-    LengthSize pageSize() const { return rareNonInheritedData->m_pageSize; }
+    const Length& perspectiveOriginX() const { return rareNonInheritedData->m_perspectiveOriginX; }
+    const Length& perspectiveOriginY() const { return rareNonInheritedData->m_perspectiveOriginY; }
+    const LengthSize& pageSize() const { return rareNonInheritedData->m_pageSize; }
     PageSizeType pageSizeType() const { return static_cast<PageSizeType>(rareNonInheritedData->m_pageSizeType); }
 
     // When set, this ensures that styles compare as different. Used during accelerated animations.
@@ -953,6 +956,12 @@
 
     ScrollBehavior scrollBehavior() const { return static_cast<ScrollBehavior>(rareNonInheritedData->m_scrollBehavior); }
 
+    const Vector<CSSPropertyID>& willChangeProperties() const { return rareNonInheritedData->m_willChange->m_properties; }
+    bool willChangeContents() const { return rareNonInheritedData->m_willChange->m_contents; }
+    bool willChangeScrollPosition() const { return rareNonInheritedData->m_willChange->m_scrollPosition; }
+    bool hasWillChangeCompositingHint() const;
+    bool hasWillChangeGpuRasterizationHint() const;
+
 // attribute setter methods
 
     void setDisplay(EDisplay v) { noninherited_flags._effectiveDisplay = v; }
@@ -1082,6 +1091,7 @@
     bool setFontDescription(const FontDescription&);
     // Only used for blending font sizes when animating and for text autosizing.
     void setFontSize(float);
+    void setFontWeight(FontWeight);
 
     void setTextAutosizingMultiplier(float v)
     {
@@ -1375,6 +1385,10 @@
 
     void setScrollBehavior(ScrollBehavior b) { SET_VAR(rareNonInheritedData, m_scrollBehavior, b); }
 
+    void setWillChangeProperties(const Vector<CSSPropertyID>& properties) { SET_VAR(rareNonInheritedData.access()->m_willChange, m_properties, properties); }
+    void setWillChangeContents(bool b) { SET_VAR(rareNonInheritedData.access()->m_willChange, m_contents, b); }
+    void setWillChangeScrollPosition(bool b) { SET_VAR(rareNonInheritedData.access()->m_willChange, m_scrollPosition, b); }
+
     const SVGRenderStyle* svgStyle() const { return m_svgStyle.get(); }
     SVGRenderStyle* accessSVGStyle() { return m_svgStyle.access(); }
 
@@ -1448,11 +1462,11 @@
 
     static ClipPathOperation* initialClipPath() { return 0; }
 
-    Length shapePadding() const { return rareNonInheritedData->m_shapePadding; }
+    const Length& shapePadding() const { return rareNonInheritedData->m_shapePadding; }
     void setShapePadding(Length shapePadding) { SET_VAR(rareNonInheritedData, m_shapePadding, shapePadding); }
     static Length initialShapePadding() { return Length(0, Fixed); }
 
-    Length shapeMargin() const { return rareNonInheritedData->m_shapeMargin; }
+    const Length& shapeMargin() const { return rareNonInheritedData->m_shapeMargin; }
     void setShapeMargin(Length shapeMargin) { SET_VAR(rareNonInheritedData, m_shapeMargin, shapeMargin); }
     static Length initialShapeMargin() { return Length(0, Fixed); }
 
@@ -1873,6 +1887,8 @@
     return noninherited_flags._pseudoBits & PSEUDO_ELEMENT_MASK;
 }
 
+float calcBorderRadiiConstraintScaleFor(const FloatRect&, const FloatRoundedRect::Radii&);
+
 } // namespace WebCore
 
 #endif // RenderStyle_h
diff --git a/Source/core/rendering/style/RenderStyleConstants.h b/Source/core/rendering/style/RenderStyleConstants.h
index 020ed1c..010e084 100644
--- a/Source/core/rendering/style/RenderStyleConstants.h
+++ b/Source/core/rendering/style/RenderStyleConstants.h
@@ -35,6 +35,7 @@
     Inherit,
     Force,
     Reattach,
+    ReattachNoRenderer
 };
 
 static const size_t PrintColorAdjustBits = 1;
@@ -511,12 +512,13 @@
 
 enum DraggableRegionMode { DraggableRegionNone, DraggableRegionDrag, DraggableRegionNoDrag };
 
-static const size_t TouchActionBits = 3;
+static const size_t TouchActionBits = 4;
 enum TouchAction {
     TouchActionAuto = 0x0,
     TouchActionNone = 0x1,
     TouchActionPanX = 0x2,
-    TouchActionPanY = 0x4
+    TouchActionPanY = 0x4,
+    TouchActionPinchZoom = 0x8,
 };
 inline TouchAction operator| (TouchAction a, TouchAction b) { return TouchAction(int(a) | int(b)); }
 inline TouchAction& operator|= (TouchAction& a, TouchAction b) { return a = a | b; }
diff --git a/Source/core/rendering/style/ShadowList.cpp b/Source/core/rendering/style/ShadowList.cpp
index 8874d24..b0f414a 100644
--- a/Source/core/rendering/style/ShadowList.cpp
+++ b/Source/core/rendering/style/ShadowList.cpp
@@ -76,7 +76,7 @@
     size_t fromLength = from ? from->shadows().size() : 0;
     size_t toLength = to ? to->shadows().size() : 0;
     if (!fromLength && !toLength)
-        return 0;
+        return nullptr;
 
     ShadowDataVector shadows;
 
diff --git a/Source/core/rendering/style/ShapeValue.h b/Source/core/rendering/style/ShapeValue.h
index 72c2cb9..a8db549 100644
--- a/Source/core/rendering/style/ShapeValue.h
+++ b/Source/core/rendering/style/ShapeValue.h
@@ -48,9 +48,9 @@
         Image
     };
 
-    static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape)
+    static PassRefPtr<ShapeValue> createShapeValue(PassRefPtr<BasicShape> shape, LayoutBox layoutBox)
     {
-        return adoptRef(new ShapeValue(shape));
+        return adoptRef(new ShapeValue(shape, layoutBox));
     }
 
     static PassRefPtr<ShapeValue> createOutsideValue()
@@ -85,10 +85,10 @@
     bool operator==(const ShapeValue& other) const;
 
 private:
-    ShapeValue(PassRefPtr<BasicShape> shape)
+    ShapeValue(PassRefPtr<BasicShape> shape, LayoutBox layoutBox)
         : m_type(Shape)
         , m_shape(shape)
-        , m_layoutBox(m_shape->layoutBox())
+        , m_layoutBox(layoutBox)
     {
     }
     ShapeValue(ShapeValueType type)
diff --git a/Source/core/rendering/style/StyleBoxData.h b/Source/core/rendering/style/StyleBoxData.h
index 9b22966..6814b3a 100644
--- a/Source/core/rendering/style/StyleBoxData.h
+++ b/Source/core/rendering/style/StyleBoxData.h
@@ -43,16 +43,16 @@
         return !(*this == o);
     }
 
-    Length width() const { return m_width; }
-    Length height() const { return m_height; }
+    const Length& width() const { return m_width; }
+    const Length& height() const { return m_height; }
 
-    Length minWidth() const { return m_minWidth; }
-    Length minHeight() const { return m_minHeight; }
+    const Length& minWidth() const { return m_minWidth; }
+    const Length& minHeight() const { return m_minHeight; }
 
-    Length maxWidth() const { return m_maxWidth; }
-    Length maxHeight() const { return m_maxHeight; }
+    const Length& maxWidth() const { return m_maxWidth; }
+    const Length& maxHeight() const { return m_maxHeight; }
 
-    Length verticalAlign() const { return m_verticalAlign; }
+    const Length& verticalAlign() const { return m_verticalAlign; }
 
     int zIndex() const { return m_zIndex; }
     bool hasAutoZIndex() const { return m_hasAutoZIndex; }
diff --git a/Source/core/rendering/style/StyleFetchedImage.cpp b/Source/core/rendering/style/StyleFetchedImage.cpp
index 31dc65a..59566a9 100644
--- a/Source/core/rendering/style/StyleFetchedImage.cpp
+++ b/Source/core/rendering/style/StyleFetchedImage.cpp
@@ -41,7 +41,7 @@
     m_image->removeClient(this);
 }
 
-PassRefPtr<CSSValue> StyleFetchedImage::cssValue() const
+PassRefPtrWillBeRawPtr<CSSValue> StyleFetchedImage::cssValue() const
 {
     return CSSPrimitiveValue::create(m_image->url().string(), CSSPrimitiveValue::CSS_URI);
 }
diff --git a/Source/core/rendering/style/StyleFetchedImage.h b/Source/core/rendering/style/StyleFetchedImage.h
index 1a2e507..1eee433 100644
--- a/Source/core/rendering/style/StyleFetchedImage.h
+++ b/Source/core/rendering/style/StyleFetchedImage.h
@@ -40,7 +40,7 @@
 
     virtual WrappedImagePtr data() const OVERRIDE { return m_image.get(); }
 
-    virtual PassRefPtr<CSSValue> cssValue() const OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE;
 
     virtual bool canRender(const RenderObject*, float multiplier) const OVERRIDE;
     virtual bool isLoaded() const OVERRIDE;
diff --git a/Source/core/rendering/style/StyleFetchedImageSet.cpp b/Source/core/rendering/style/StyleFetchedImageSet.cpp
index 04a8d9d..c0cc004 100644
--- a/Source/core/rendering/style/StyleFetchedImageSet.cpp
+++ b/Source/core/rendering/style/StyleFetchedImageSet.cpp
@@ -47,7 +47,7 @@
     m_bestFitImage->removeClient(this);
 }
 
-PassRefPtr<CSSValue> StyleFetchedImageSet::cssValue() const
+PassRefPtrWillBeRawPtr<CSSValue> StyleFetchedImageSet::cssValue() const
 {
     return m_imageSetValue;
 }
diff --git a/Source/core/rendering/style/StyleFetchedImageSet.h b/Source/core/rendering/style/StyleFetchedImageSet.h
index 3f137ab..9fd3c97 100644
--- a/Source/core/rendering/style/StyleFetchedImageSet.h
+++ b/Source/core/rendering/style/StyleFetchedImageSet.h
@@ -47,7 +47,7 @@
     }
     virtual ~StyleFetchedImageSet();
 
-    virtual PassRefPtr<CSSValue> cssValue() const OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE;
 
     // FIXME: This is used by StyleImage for equals comparison, but this implementation
     // only looks at the image from the set that we have loaded. I'm not sure if that is
diff --git a/Source/core/rendering/style/StyleGeneratedImage.cpp b/Source/core/rendering/style/StyleGeneratedImage.cpp
index 6a50c14..f675fa5 100644
--- a/Source/core/rendering/style/StyleGeneratedImage.cpp
+++ b/Source/core/rendering/style/StyleGeneratedImage.cpp
@@ -37,7 +37,7 @@
     m_isGeneratedImage = true;
 }
 
-PassRefPtr<CSSValue> StyleGeneratedImage::cssValue() const
+PassRefPtrWillBeRawPtr<CSSValue> StyleGeneratedImage::cssValue() const
 {
     return m_imageGeneratorValue.get();
 }
diff --git a/Source/core/rendering/style/StyleGeneratedImage.h b/Source/core/rendering/style/StyleGeneratedImage.h
index 69c3f9b..219f47e 100644
--- a/Source/core/rendering/style/StyleGeneratedImage.h
+++ b/Source/core/rendering/style/StyleGeneratedImage.h
@@ -40,7 +40,7 @@
 
     virtual WrappedImagePtr data() const OVERRIDE { return m_imageGeneratorValue.get(); }
 
-    virtual PassRefPtr<CSSValue> cssValue() const OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE;
 
     virtual LayoutSize imageSize(const RenderObject*, float multiplier) const OVERRIDE;
     virtual bool imageHasRelativeWidth() const OVERRIDE { return !m_fixedSize; }
diff --git a/Source/core/rendering/style/StyleImage.h b/Source/core/rendering/style/StyleImage.h
index bca329a..96c14ad 100644
--- a/Source/core/rendering/style/StyleImage.h
+++ b/Source/core/rendering/style/StyleImage.h
@@ -49,7 +49,7 @@
         return data() == other.data();
     }
 
-    virtual PassRefPtr<CSSValue> cssValue() const = 0;
+    virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const = 0;
 
     virtual bool canRender(const RenderObject*, float /*multiplier*/) const { return true; }
     virtual bool isLoaded() const { return true; }
diff --git a/Source/core/rendering/style/StylePendingImage.h b/Source/core/rendering/style/StylePendingImage.h
index a52481d..d735175 100644
--- a/Source/core/rendering/style/StylePendingImage.h
+++ b/Source/core/rendering/style/StylePendingImage.h
@@ -45,7 +45,7 @@
 
     virtual WrappedImagePtr data() const OVERRIDE { return m_value; }
 
-    virtual PassRefPtr<CSSValue> cssValue() const OVERRIDE { return m_value; }
+    virtual PassRefPtrWillBeRawPtr<CSSValue> cssValue() const OVERRIDE { return m_value; }
     CSSImageValue* cssImageValue() const { return m_value->isImageValue() ? toCSSImageValue(m_value) : 0; }
     CSSImageGeneratorValue* cssImageGeneratorValue() const { return m_value->isImageGeneratorValue() ? toCSSImageGeneratorValue(m_value) : 0; }
     CSSCursorImageValue* cssCursorImageValue() const { return m_value->isCursorImageValue() ? toCSSCursorImageValue(m_value) : 0; }
@@ -62,7 +62,7 @@
     virtual PassRefPtr<Image> image(RenderObject*, const IntSize&) const OVERRIDE
     {
         ASSERT_NOT_REACHED();
-        return 0;
+        return nullptr;
     }
     virtual bool knownToBeOpaque(const RenderObject*) const OVERRIDE { return false; }
 
diff --git a/Source/core/rendering/style/StyleRareNonInheritedData.cpp b/Source/core/rendering/style/StyleRareNonInheritedData.cpp
index 820c3dc..6698b81 100644
--- a/Source/core/rendering/style/StyleRareNonInheritedData.cpp
+++ b/Source/core/rendering/style/StyleRareNonInheritedData.cpp
@@ -105,6 +105,7 @@
     , m_marquee(o.m_marquee)
     , m_multiCol(o.m_multiCol)
     , m_transform(o.m_transform)
+    , m_willChange(o.m_willChange)
     , m_filter(o.m_filter)
     , m_grid(o.m_grid)
     , m_gridItem(o.m_gridItem)
@@ -186,6 +187,7 @@
         && m_marquee == o.m_marquee
         && m_multiCol == o.m_multiCol
         && m_transform == o.m_transform
+        && m_willChange == o.m_willChange
         && m_filter == o.m_filter
         && m_grid == o.m_grid
         && m_gridItem == o.m_gridItem
diff --git a/Source/core/rendering/style/StyleRareNonInheritedData.h b/Source/core/rendering/style/StyleRareNonInheritedData.h
index de00e62..09cbf6a 100644
--- a/Source/core/rendering/style/StyleRareNonInheritedData.h
+++ b/Source/core/rendering/style/StyleRareNonInheritedData.h
@@ -57,6 +57,7 @@
 class StyleReflection;
 class StyleResolver;
 class StyleTransformData;
+class StyleWillChangeData;
 
 // Page size type.
 // StyleRareNonInheritedData::m_pageSize is meaningful only when
@@ -106,6 +107,7 @@
     DataRef<StyleMarqueeData> m_marquee; // Marquee properties
     DataRef<StyleMultiColData> m_multiCol; //  CSS3 multicol properties
     DataRef<StyleTransformData> m_transform; // Transform properties (rotate, scale, skew, etc.)
+    DataRef<StyleWillChangeData> m_willChange; // CSS Will Change
 
     DataRef<StyleFilterData> m_filter; // Filter operations (url, sepia, blur, etc.)
 
diff --git a/Source/core/rendering/style/StyleWillChangeData.cpp b/Source/core/rendering/style/StyleWillChangeData.cpp
new file mode 100644
index 0000000..7cd2bcb
--- /dev/null
+++ b/Source/core/rendering/style/StyleWillChangeData.cpp
@@ -0,0 +1,24 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#include "core/rendering/style/StyleWillChangeData.h"
+
+namespace WebCore {
+
+StyleWillChangeData::StyleWillChangeData()
+    : m_contents(false)
+    , m_scrollPosition(false)
+{
+}
+
+StyleWillChangeData::StyleWillChangeData(const StyleWillChangeData& o)
+    : RefCounted<StyleWillChangeData>()
+    , m_properties(o.m_properties)
+    , m_contents(o.m_contents)
+    , m_scrollPosition(o.m_scrollPosition)
+{
+}
+
+} // namespace WebCore
diff --git a/Source/core/rendering/style/StyleWillChangeData.h b/Source/core/rendering/style/StyleWillChangeData.h
new file mode 100644
index 0000000..7c62f57
--- /dev/null
+++ b/Source/core/rendering/style/StyleWillChangeData.h
@@ -0,0 +1,42 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef StyleWillChangeData_h
+#define StyleWillChangeData_h
+
+#include "CSSPropertyNames.h"
+#include "CSSValueKeywords.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefCounted.h"
+#include "wtf/Vector.h"
+
+namespace WebCore {
+
+class StyleWillChangeData : public RefCounted<StyleWillChangeData> {
+public:
+    static PassRefPtr<StyleWillChangeData> create() { return adoptRef(new StyleWillChangeData); }
+    PassRefPtr<StyleWillChangeData> copy() const { return adoptRef(new StyleWillChangeData(*this)); }
+
+    bool operator==(const StyleWillChangeData& o) const
+    {
+        return m_properties == o.m_properties && m_contents == o.m_contents && m_scrollPosition == o.m_scrollPosition;
+    }
+
+    bool operator!=(const StyleWillChangeData& o) const
+    {
+        return !(*this == o);
+    }
+
+    Vector<CSSPropertyID> m_properties;
+    unsigned m_contents : 1;
+    unsigned m_scrollPosition : 1;
+
+private:
+    StyleWillChangeData();
+    StyleWillChangeData(const StyleWillChangeData&);
+};
+
+} // namespace WebCore
+
+#endif // StyleWillChangeData_h
diff --git a/Source/core/rendering/svg/ReferenceFilterBuilder.cpp b/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
index 4dca2dd..f135c1a 100644
--- a/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
+++ b/Source/core/rendering/svg/ReferenceFilterBuilder.cpp
@@ -82,7 +82,7 @@
         eColorInterpolation = svgStyle->colorInterpolationFilters();
     } else {
         // Otherwise, use the slow path by using string comparison (used by external svg files)
-        RefPtr<CSSValue> cssValue = svgElement->getPresentationAttribute(AtomicString(SVGNames::color_interpolation_filtersAttr.toString()));
+        RefPtrWillBeRawPtr<CSSValue> cssValue = svgElement->getPresentationAttribute(AtomicString(SVGNames::color_interpolation_filtersAttr.toString()));
         if (cssValue.get() && cssValue->isPrimitiveValue()) {
             const CSSPrimitiveValue& primitiveValue = *((CSSPrimitiveValue*)cssValue.get());
             eColorInterpolation = (EColorInterpolation)primitiveValue;
@@ -109,7 +109,7 @@
 PassRefPtr<FilterEffect> ReferenceFilterBuilder::build(Filter* parentFilter, RenderObject* renderer, FilterEffect* previousEffect, const ReferenceFilterOperation* filterOperation)
 {
     if (!renderer)
-        return 0;
+        return nullptr;
 
     Document* document = &renderer->document();
 
@@ -123,21 +123,21 @@
     }
 
     if (!document)
-        return 0;
+        return nullptr;
 
     Element* filter = document->getElementById(filterOperation->fragment());
 
     if (!filter) {
         // Although we did not find the referenced filter, it might exist later
         // in the document
-        document->accessSVGExtensions()->addPendingResource(filterOperation->fragment(), toElement(renderer->node()));
-        return 0;
+        document->accessSVGExtensions().addPendingResource(filterOperation->fragment(), toElement(renderer->node()));
+        return nullptr;
     }
 
-    if (!filter->isSVGElement() || !filter->hasTagName(SVGNames::filterTag))
-        return 0;
+    if (!isSVGFilterElement(*filter))
+        return nullptr;
 
-    SVGFilterElement* filterElement = toSVGFilterElement(toSVGElement(filter));
+    SVGFilterElement& filterElement = toSVGFilterElement(*filter);
 
     // FIXME: Figure out what to do with SourceAlpha. Right now, we're
     // using the alpha of the original input layer, which is obviously
@@ -147,13 +147,9 @@
     RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(previousEffect, SourceAlpha::create(parentFilter));
 
     ColorSpace filterColorSpace = ColorSpaceDeviceRGB;
-    bool useFilterColorSpace = getSVGElementColorSpace(filterElement, filterColorSpace);
+    bool useFilterColorSpace = getSVGElementColorSpace(&filterElement, filterColorSpace);
 
-    for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
-        if (!node->isSVGElement())
-            continue;
-
-        SVGElement* element = toSVGElement(node);
+    for (SVGElement* element = Traversal<SVGElement>::firstChild(filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) {
         if (!element->isFilterEffect())
             continue;
 
@@ -164,7 +160,7 @@
             continue;
 
         effectElement->setStandardAttributes(effect.get());
-        effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnitsCurrentValue(), parentFilter->sourceImageRect()));
+        effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement.primitiveUnits()->currentValue()->enumValue(), parentFilter->sourceImageRect()));
         ColorSpace colorSpace = filterColorSpace;
         if (useFilterColorSpace || getSVGElementColorSpace(effectElement, colorSpace))
             effect->setOperatingColorSpace(colorSpace);
diff --git a/Source/core/rendering/svg/RenderSVGBlock.h b/Source/core/rendering/svg/RenderSVGBlock.h
index c503536..8602a72 100644
--- a/Source/core/rendering/svg/RenderSVGBlock.h
+++ b/Source/core/rendering/svg/RenderSVGBlock.h
@@ -52,8 +52,6 @@
 
     virtual bool isSVG() const OVERRIDE FINAL { return true; }
 
-    virtual bool supportsPartialLayout() const OVERRIDE FINAL { return false; }
-
     virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const OVERRIDE FINAL;
 
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE FINAL;
diff --git a/Source/core/rendering/svg/RenderSVGEllipse.cpp b/Source/core/rendering/svg/RenderSVGEllipse.cpp
index 1b09e25..bcd2900 100644
--- a/Source/core/rendering/svg/RenderSVGEllipse.cpp
+++ b/Source/core/rendering/svg/RenderSVGEllipse.cpp
@@ -76,21 +76,21 @@
 void RenderSVGEllipse::calculateRadiiAndCenter()
 {
     ASSERT(element());
-    if (element()->hasTagName(SVGNames::circleTag)) {
-        SVGCircleElement* circle = toSVGCircleElement(element());
+    if (isSVGCircleElement(*element())) {
+        SVGCircleElement& circle = toSVGCircleElement(*element());
 
-        SVGLengthContext lengthContext(circle);
-        float radius = circle->r()->currentValue()->value(lengthContext);
+        SVGLengthContext lengthContext(&circle);
+        float radius = circle.r()->currentValue()->value(lengthContext);
         m_radii = FloatSize(radius, radius);
-        m_center = FloatPoint(circle->cx()->currentValue()->value(lengthContext), circle->cy()->currentValue()->value(lengthContext));
+        m_center = FloatPoint(circle.cx()->currentValue()->value(lengthContext), circle.cy()->currentValue()->value(lengthContext));
         return;
     }
 
-    SVGEllipseElement* ellipse = toSVGEllipseElement(element());
+    SVGEllipseElement& ellipse = toSVGEllipseElement(*element());
 
-    SVGLengthContext lengthContext(ellipse);
-    m_radii = FloatSize(ellipse->rx()->currentValue()->value(lengthContext), ellipse->ry()->currentValue()->value(lengthContext));
-    m_center = FloatPoint(ellipse->cx()->currentValue()->value(lengthContext), ellipse->cy()->currentValue()->value(lengthContext));
+    SVGLengthContext lengthContext(&ellipse);
+    m_radii = FloatSize(ellipse.rx()->currentValue()->value(lengthContext), ellipse.ry()->currentValue()->value(lengthContext));
+    m_center = FloatPoint(ellipse.cx()->currentValue()->value(lengthContext), ellipse.cy()->currentValue()->value(lengthContext));
 }
 
 void RenderSVGEllipse::fillShape(GraphicsContext* context) const
diff --git a/Source/core/rendering/svg/RenderSVGEllipse.h b/Source/core/rendering/svg/RenderSVGEllipse.h
index c26cd02..b73b552 100644
--- a/Source/core/rendering/svg/RenderSVGEllipse.h
+++ b/Source/core/rendering/svg/RenderSVGEllipse.h
@@ -40,7 +40,7 @@
     virtual const char* renderName() const OVERRIDE { return "RenderSVGEllipse"; }
 
     virtual void updateShapeFromElement() OVERRIDE;
-    virtual bool isEmpty() const OVERRIDE { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); }
+    virtual bool isShapeEmpty() const OVERRIDE { return m_usePathFallback ? RenderSVGShape::isShapeEmpty() : m_fillBoundingBox.isEmpty(); }
     virtual void fillShape(GraphicsContext*) const OVERRIDE;
     virtual void strokeShape(GraphicsContext*) const OVERRIDE;
     virtual bool shapeDependentStrokeContains(const FloatPoint&) OVERRIDE;
diff --git a/Source/core/rendering/svg/RenderSVGGradientStop.cpp b/Source/core/rendering/svg/RenderSVGGradientStop.cpp
index ca5f315..2d66b5d 100644
--- a/Source/core/rendering/svg/RenderSVGGradientStop.cpp
+++ b/Source/core/rendering/svg/RenderSVGGradientStop.cpp
@@ -67,9 +67,8 @@
 SVGGradientElement* RenderSVGGradientStop::gradientElement() const
 {
     ContainerNode* parentNode = node()->parentNode();
-    if (parentNode->hasTagName(linearGradientTag) || parentNode->hasTagName(radialGradientTag))
-        return toSVGGradientElement(parentNode);
-    return 0;
+    ASSERT(parentNode);
+    return isSVGGradientElement(*parentNode) ? toSVGGradientElement(parentNode) : 0;
 }
 
 }
diff --git a/Source/core/rendering/svg/RenderSVGImage.cpp b/Source/core/rendering/svg/RenderSVGImage.cpp
index 0eebb39..584bacb 100644
--- a/Source/core/rendering/svg/RenderSVGImage.cpp
+++ b/Source/core/rendering/svg/RenderSVGImage.cpp
@@ -142,7 +142,9 @@
             childPaintInfo.applyTransform(m_localTransform, false);
         }
         if (childPaintInfo.phase == PaintPhaseForeground && !m_objectBoundingBox.isEmpty()) {
-            SVGRenderingContext renderingContext(this, childPaintInfo);
+            // SVGRenderingContext may taint the state - make sure we're always saving.
+            SVGRenderingContext renderingContext(this, childPaintInfo, stateSaver.saved() ?
+                SVGRenderingContext::DontSaveGraphicsContext : SVGRenderingContext::SaveGraphicsContext);
 
             if (renderingContext.isRenderingPrepared()) {
                 if (style()->svgStyle()->bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
diff --git a/Source/core/rendering/svg/RenderSVGInline.cpp b/Source/core/rendering/svg/RenderSVGInline.cpp
index 64f6b4d..4861230 100644
--- a/Source/core/rendering/svg/RenderSVGInline.cpp
+++ b/Source/core/rendering/svg/RenderSVGInline.cpp
@@ -28,6 +28,7 @@
 #include "core/rendering/svg/SVGInlineFlowBox.h"
 #include "core/rendering/svg/SVGRenderSupport.h"
 #include "core/rendering/svg/SVGResourcesCache.h"
+#include "core/svg/SVGAElement.h"
 
 namespace WebCore {
 
@@ -36,9 +37,9 @@
     if (child->isText())
         return SVGRenderSupport::isRenderableTextNode(child);
 
-    if (node()->hasTagName(SVGNames::aTag)) {
+    if (isSVGAElement(*node())) {
         // Disallow direct descendant 'a'.
-        if (child->node()->hasTagName(SVGNames::aTag))
+        if (isSVGAElement(*child->node()))
             return false;
     }
 
@@ -56,7 +57,7 @@
 
 InlineFlowBox* RenderSVGInline::createInlineFlowBox()
 {
-    InlineFlowBox* box = new SVGInlineFlowBox(this);
+    InlineFlowBox* box = new SVGInlineFlowBox(*this);
     box->setHasVirtualLogicalHeight();
     return box;
 }
diff --git a/Source/core/rendering/svg/RenderSVGInlineText.cpp b/Source/core/rendering/svg/RenderSVGInlineText.cpp
index 5a6420c..a296392 100644
--- a/Source/core/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/core/rendering/svg/RenderSVGInlineText.cpp
@@ -94,12 +94,12 @@
 
     // The text metrics may be influenced by style changes.
     if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
-        textRenderer->subtreeStyleDidChange(this);
+        textRenderer->setNeedsLayout();
 }
 
 InlineTextBox* RenderSVGInlineText::createTextBox()
 {
-    InlineTextBox* box = new SVGInlineTextBox(this);
+    InlineTextBox* box = new SVGInlineTextBox(*this);
     box->setHasVirtualLogicalHeight();
     return box;
 }
@@ -186,8 +186,7 @@
             const SVGTextFragment& fragment = fragments.at(i);
             FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
             fragment.buildFragmentTransform(fragmentTransform);
-            if (!fragmentTransform.isIdentity())
-                fragmentRect = fragmentTransform.mapRect(fragmentRect);
+            fragmentRect = fragmentTransform.mapRect(fragmentRect);
 
             float distance = powf(fragmentRect.x() - absolutePoint.x(), 2) +
                              powf(fragmentRect.y() + fragmentRect.height() / 2 - absolutePoint.y(), 2);
@@ -226,7 +225,7 @@
         return;
     }
 
-    if (style->fontDescription().textRenderingMode() == GeometricPrecision)
+    if (style->fontDescription().textRendering() == GeometricPrecision)
         scalingFactor = 1;
 
     FontDescription fontDescription(style->fontDescription());
diff --git a/Source/core/rendering/svg/RenderSVGModelObject.cpp b/Source/core/rendering/svg/RenderSVGModelObject.cpp
index 294dfda..a928465 100644
--- a/Source/core/rendering/svg/RenderSVGModelObject.cpp
+++ b/Source/core/rendering/svg/RenderSVGModelObject.cpp
@@ -75,7 +75,7 @@
 LayoutRect RenderSVGModelObject::outlineBoundsForRepaint(const RenderLayerModelObject* repaintContainer, const RenderGeometryMap*) const
 {
     LayoutRect box = enclosingLayoutRect(repaintRectInLocalCoordinates());
-    adjustRectForOutlineAndShadow(box);
+    adjustRectForOutline(box);
 
     FloatQuad containerRelativeQuad = localToContainerQuad(FloatRect(box), repaintContainer);
     return containerRelativeQuad.enclosingBoundingBox();
@@ -128,51 +128,6 @@
     return false;
 }
 
-static void getElementCTM(SVGGraphicsElement* element, AffineTransform& transform)
-{
-    ASSERT(element);
-    element->document().updateLayoutIgnorePendingStylesheets();
-
-    SVGElement* stopAtElement = element->nearestViewportElement();
-    ASSERT(stopAtElement);
-
-    AffineTransform localTransform;
-    Node* current = element;
-
-    while (current && current->isSVGElement()) {
-        SVGElement* currentElement = toSVGElement(current);
-        localTransform = currentElement->renderer()->localToParentTransform();
-        transform = localTransform.multiply(transform);
-        // For getCTM() computation, stop at the nearest viewport element
-        if (currentElement == stopAtElement)
-            break;
-
-        current = current->parentOrShadowHostNode();
-    }
-}
-
-// FloatRect::intersects does not consider horizontal or vertical lines (because of isEmpty()).
-// So special-case handling of such lines.
-static bool intersectsAllowingEmpty(const FloatRect& r, const FloatRect& other)
-{
-    if (r.isEmpty() && other.isEmpty())
-        return false;
-    if (r.isEmpty() && !other.isEmpty()) {
-        return (other.contains(r.x(), r.y()) && !other.contains(r.maxX(), r.maxY()))
-               || (!other.contains(r.x(), r.y()) && other.contains(r.maxX(), r.maxY()));
-    }
-    if (other.isEmpty() && !r.isEmpty())
-        return intersectsAllowingEmpty(other, r);
-    return r.intersects(other);
-}
-
-// One of the element types that can cause graphics to be drawn onto the target canvas. Specifically: circle, ellipse,
-// image, line, path, polygon, polyline, rect, text and use.
-static bool isGraphicsElement(RenderObject* renderer)
-{
-    return renderer->isSVGShape() || renderer->isSVGText() || renderer->isSVGImage() || renderer->node()->hasTagName(SVGNames::useTag);
-}
-
 // The SVG addFocusRingRects() method adds rects in local coordinates so the default absoluteFocusRingQuads
 // returns incorrect values for SVG objects. Overriding this method provides access to the absolute bounds.
 void RenderSVGModelObject::absoluteFocusRingQuads(Vector<FloatQuad>& quads)
@@ -180,30 +135,4 @@
     quads.append(localToAbsoluteQuad(FloatQuad(repaintRectInLocalCoordinates())));
 }
 
-bool RenderSVGModelObject::checkIntersection(RenderObject* renderer, const FloatRect& rect)
-{
-    if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
-        return false;
-    if (!isGraphicsElement(renderer))
-        return false;
-    AffineTransform ctm;
-    SVGGraphicsElement* svgElement = toSVGGraphicsElement(renderer->node());
-    getElementCTM(svgElement, ctm);
-    ASSERT(svgElement->renderer());
-    return intersectsAllowingEmpty(rect, ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
-}
-
-bool RenderSVGModelObject::checkEnclosure(RenderObject* renderer, const FloatRect& rect)
-{
-    if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
-        return false;
-    if (!isGraphicsElement(renderer))
-        return false;
-    AffineTransform ctm;
-    SVGGraphicsElement* svgElement = toSVGGraphicsElement(renderer->node());
-    getElementCTM(svgElement, ctm);
-    ASSERT(svgElement->renderer());
-    return rect.contains(ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
-}
-
 } // namespace WebCore
diff --git a/Source/core/rendering/svg/RenderSVGModelObject.h b/Source/core/rendering/svg/RenderSVGModelObject.h
index e9370e6..94b0bd8 100644
--- a/Source/core/rendering/svg/RenderSVGModelObject.h
+++ b/Source/core/rendering/svg/RenderSVGModelObject.h
@@ -63,9 +63,6 @@
     virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE FINAL;
     virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) OVERRIDE;
 
-    static bool checkIntersection(RenderObject*, const FloatRect&);
-    static bool checkEnclosure(RenderObject*, const FloatRect&);
-
     virtual void computeLayerHitTestRects(LayerHitTestRects&) const OVERRIDE FINAL;
 
     SVGElement* element() const { return toSVGElement(RenderObject::node()); }
diff --git a/Source/core/rendering/svg/RenderSVGRect.h b/Source/core/rendering/svg/RenderSVGRect.h
index afc65e3..7ae3962 100644
--- a/Source/core/rendering/svg/RenderSVGRect.h
+++ b/Source/core/rendering/svg/RenderSVGRect.h
@@ -42,7 +42,7 @@
     virtual const char* renderName() const OVERRIDE { return "RenderSVGRect"; }
 
     virtual void updateShapeFromElement() OVERRIDE;
-    virtual bool isEmpty() const OVERRIDE { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); }
+    virtual bool isShapeEmpty() const OVERRIDE { return m_usePathFallback ? RenderSVGShape::isShapeEmpty() : m_fillBoundingBox.isEmpty(); }
     virtual void fillShape(GraphicsContext*) const OVERRIDE;
     virtual void strokeShape(GraphicsContext*) const OVERRIDE;
     virtual bool shapeDependentStrokeContains(const FloatPoint&) OVERRIDE;
diff --git a/Source/core/rendering/svg/RenderSVGResource.cpp b/Source/core/rendering/svg/RenderSVGResource.cpp
index f6e7b7b..eef6059 100644
--- a/Source/core/rendering/svg/RenderSVGResource.cpp
+++ b/Source/core/rendering/svg/RenderSVGResource.cpp
@@ -24,8 +24,8 @@
 
 #include "core/rendering/svg/RenderSVGResource.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/svg/RenderSVGResourceClipper.h"
 #include "core/rendering/svg/RenderSVGResourceFilter.h"
 #include "core/rendering/svg/RenderSVGResourceMasker.h"
@@ -81,8 +81,7 @@
 
     bool applyToFill = mode == ApplyToFillMode;
     SVGPaint::SVGPaintType paintType = applyToFill ? svgStyle->fillPaintType() : svgStyle->strokePaintType();
-    if (paintType == SVGPaint::SVG_PAINTTYPE_NONE)
-        return 0;
+    ASSERT(paintType != SVGPaint::SVG_PAINTTYPE_NONE);
 
     Color color;
     bool hasColor = false;
@@ -184,7 +183,7 @@
 
     if (!object->node() || !object->node()->isSVGElement())
         return;
-    HashSet<SVGElement*>* dependencies = object->document().accessSVGExtensions()->setOfElementsReferencingTarget(toSVGElement(object->node()));
+    HashSet<SVGElement*>* dependencies = object->document().accessSVGExtensions().setOfElementsReferencingTarget(toSVGElement(object->node()));
     if (!dependencies)
         return;
     HashSet<SVGElement*>::iterator end = dependencies->end();
diff --git a/Source/core/rendering/svg/RenderSVGResourceClipper.cpp b/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
index 104230d..3c7b67d 100644
--- a/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceClipper.cpp
@@ -26,8 +26,8 @@
 
 #include "RuntimeEnabledFeatures.h"
 #include "SVGNames.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/svg/SVGRenderingContext.h"
 #include "core/rendering/svg/SVGResources.h"
@@ -89,16 +89,16 @@
     WindRule clipRule = RULE_NONZERO;
     Path clipPath = Path();
 
-    for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
-        RenderObject* renderer = childNode->renderer();
+    for (Element* childElement = ElementTraversal::firstWithin(*element()); childElement; childElement = ElementTraversal::nextSibling(*childElement)) {
+        RenderObject* renderer = childElement->renderer();
         if (!renderer)
             continue;
         // Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts.
         if (renderer->isSVGText())
             return false;
-        if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGGraphicsElement())
+        if (!childElement->isSVGElement() || !toSVGElement(childElement)->isSVGGraphicsElement())
             continue;
-        SVGGraphicsElement* styled = toSVGGraphicsElement(childNode);
+        SVGGraphicsElement* styled = toSVGGraphicsElement(childElement);
         RenderStyle* style = renderer->style();
         if (!style || style->display() == NONE || style->visibility() != VISIBLE)
              continue;
@@ -127,7 +127,7 @@
         }
     }
     // Only one visible shape/path was found. Directly continue clipping and transform the content to userspace if necessary.
-    if (toSVGClipPathElement(element())->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+    if (toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         AffineTransform transform;
         transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
         transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
@@ -162,7 +162,7 @@
     // In this case, we need to apply the zoom scale explicitly - but only for clips with
     // userSpaceOnUse units (the zoom is accounted for objectBoundingBox-resolved lengths).
     if (!target->node()->isSVGElement()
-        && toSVGClipPathElement(element())->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
+        && toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE) {
         ASSERT(style());
         animatedLocalTransform.scale(style()->effectiveZoom());
     }
@@ -238,7 +238,7 @@
     ASSERT(context);
 
     AffineTransform contentTransformation;
-    SVGUnitTypes::SVGUnitType contentUnits = toSVGClipPathElement(element())->clipPathUnitsCurrentValue();
+    SVGUnitTypes::SVGUnitType contentUnits = toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue();
     if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y());
         contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height());
@@ -271,9 +271,9 @@
     PaintBehavior oldBehavior = frame()->view()->paintBehavior();
     frame()->view()->setPaintBehavior(oldBehavior | PaintBehaviorRenderingSVGMask);
 
-    for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
-        RenderObject* renderer = childNode->renderer();
-        if (!childNode->isSVGElement() || !renderer)
+    for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+        RenderObject* renderer = childElement->renderer();
+        if (!renderer)
             continue;
 
         RenderStyle* style = renderer->style();
@@ -281,13 +281,13 @@
             continue;
 
         WindRule newClipRule = style->svgStyle()->clipRule();
-        bool isUseElement = childNode->hasTagName(SVGNames::useTag);
+        bool isUseElement = isSVGUseElement(*childElement);
         if (isUseElement) {
-            SVGUseElement* useElement = toSVGUseElement(childNode);
-            renderer = useElement->rendererClipChild();
+            SVGUseElement& useElement = toSVGUseElement(*childElement);
+            renderer = useElement.rendererClipChild();
             if (!renderer)
                 continue;
-            if (!useElement->hasAttribute(SVGNames::clip_ruleAttr))
+            if (!useElement.hasAttribute(SVGNames::clip_ruleAttr))
                 newClipRule = renderer->style()->svgStyle()->clipRule();
         }
 
@@ -298,7 +298,7 @@
         context->setFillRule(newClipRule);
 
         if (isUseElement)
-            renderer = childNode->renderer();
+            renderer = childElement->renderer();
 
         SVGRenderingContext::renderSubtree(context, renderer, contentTransformation);
     }
@@ -311,11 +311,11 @@
 void RenderSVGResourceClipper::calculateClipContentRepaintRect()
 {
     // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip.
-    for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
-        RenderObject* renderer = childNode->renderer();
-        if (!childNode->isSVGElement() || !renderer)
+    for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+        RenderObject* renderer = childElement->renderer();
+        if (!renderer)
             continue;
-        if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
+        if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElement(*childElement))
             continue;
         RenderStyle* style = renderer->style();
         if (!style || style->display() == NONE || style->visibility() != VISIBLE)
@@ -332,7 +332,7 @@
         return false;
 
     SVGClipPathElement* clipPathElement = toSVGClipPathElement(element());
-    if (clipPathElement->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+    if (clipPathElement->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         AffineTransform transform;
         transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
         transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
@@ -341,11 +341,11 @@
 
     point = clipPathElement->animatedLocalTransform().inverse().mapPoint(point);
 
-    for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
-        RenderObject* renderer = childNode->renderer();
-        if (!childNode->isSVGElement() || !renderer)
+    for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+        RenderObject* renderer = childElement->renderer();
+        if (!renderer)
             continue;
-        if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
+        if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElement(*childElement))
             continue;
         IntPoint hitPoint;
         HitTestResult result(hitPoint);
@@ -365,7 +365,7 @@
     if (m_clipBoundaries.isEmpty())
         calculateClipContentRepaintRect();
 
-    if (toSVGClipPathElement(element())->clipPathUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+    if (toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         FloatRect objectBoundingBox = object->objectBoundingBox();
         AffineTransform transform;
         transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
diff --git a/Source/core/rendering/svg/RenderSVGResourceClipper.h b/Source/core/rendering/svg/RenderSVGResourceClipper.h
index 26da827..75a8058 100644
--- a/Source/core/rendering/svg/RenderSVGResourceClipper.h
+++ b/Source/core/rendering/svg/RenderSVGResourceClipper.h
@@ -70,7 +70,7 @@
 
     bool hitTestClipContent(const FloatRect&, const FloatPoint&);
 
-    SVGUnitTypes::SVGUnitType clipPathUnits() const { return toSVGClipPathElement(element())->clipPathUnitsCurrentValue(); }
+    SVGUnitTypes::SVGUnitType clipPathUnits() const { return toSVGClipPathElement(element())->clipPathUnits()->currentValue()->enumValue(); }
 
     static const RenderSVGResourceType s_resourceType;
 private:
diff --git a/Source/core/rendering/svg/RenderSVGResourceContainer.cpp b/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
index 0f7ac9b..71e0f2c 100644
--- a/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceContainer.cpp
@@ -32,7 +32,7 @@
 
 namespace WebCore {
 
-static inline SVGDocumentExtensions* svgExtensionsFromElement(SVGElement* element)
+static inline SVGDocumentExtensions& svgExtensionsFromElement(SVGElement* element)
 {
     ASSERT(element);
     return element->document().accessSVGExtensions();
@@ -51,7 +51,7 @@
 RenderSVGResourceContainer::~RenderSVGResourceContainer()
 {
     if (m_registered)
-        svgExtensionsFromElement(element())->removeResource(m_id);
+        svgExtensionsFromElement(element()).removeResource(m_id);
 }
 
 void RenderSVGResourceContainer::layout()
@@ -92,8 +92,8 @@
     removeAllClientsFromCache();
 
     // Remove old id, that is guaranteed to be present in cache.
-    SVGDocumentExtensions* extensions = svgExtensionsFromElement(element());
-    extensions->removeResource(m_id);
+    SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
+    extensions.removeResource(m_id);
     m_id = element()->getIdAttribute();
 
     registerResource();
@@ -210,22 +210,22 @@
 
 void RenderSVGResourceContainer::registerResource()
 {
-    SVGDocumentExtensions* extensions = svgExtensionsFromElement(element());
-    if (!extensions->hasPendingResource(m_id)) {
-        extensions->addResource(m_id, this);
+    SVGDocumentExtensions& extensions = svgExtensionsFromElement(element());
+    if (!extensions.hasPendingResource(m_id)) {
+        extensions.addResource(m_id, this);
         return;
     }
 
-    OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions->removePendingResource(m_id));
+    OwnPtr<SVGDocumentExtensions::SVGPendingElements> clients(extensions.removePendingResource(m_id));
 
     // Cache us with the new id.
-    extensions->addResource(m_id, this);
+    extensions.addResource(m_id, this);
 
     // Update cached resources of pending clients.
     const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
     for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
         ASSERT((*it)->hasPendingResources());
-        extensions->clearHasPendingResourcesIfPossible(*it);
+        extensions.clearHasPendingResourcesIfPossible(*it);
         RenderObject* renderer = (*it)->renderer();
         if (!renderer)
             continue;
diff --git a/Source/core/rendering/svg/RenderSVGResourceContainer.h b/Source/core/rendering/svg/RenderSVGResourceContainer.h
index 5bd1d42..a65623f 100644
--- a/Source/core/rendering/svg/RenderSVGResourceContainer.h
+++ b/Source/core/rendering/svg/RenderSVGResourceContainer.h
@@ -91,7 +91,7 @@
     if (id.isEmpty())
         return 0;
 
-    if (RenderSVGResourceContainer* renderResource = document.accessSVGExtensions()->resourceById(id))
+    if (RenderSVGResourceContainer* renderResource = document.accessSVGExtensions().resourceById(id))
         return renderResource;
 
     return 0;
diff --git a/Source/core/rendering/svg/RenderSVGResourceFilter.cpp b/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
index 08bb896..f62c653 100644
--- a/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceFilter.cpp
@@ -83,11 +83,7 @@
 
     // Add effects to the builder
     RefPtr<SVGFilterBuilder> builder = SVGFilterBuilder::create(SourceGraphic::create(filter), SourceAlpha::create(filter));
-    for (Node* node = filterElement->firstChild(); node; node = node->nextSibling()) {
-        if (!node->isSVGElement())
-            continue;
-
-        SVGElement* element = toSVGElement(node);
+    for (SVGElement* element = Traversal<SVGElement>::firstChild(*filterElement); element; element = Traversal<SVGElement>::nextSibling(*element)) {
         if (!element->isFilterEffect() || !element->renderer())
             continue;
 
@@ -95,11 +91,11 @@
         RefPtr<FilterEffect> effect = effectElement->build(builder.get(), filter);
         if (!effect) {
             builder->clearEffects();
-            return 0;
+            return nullptr;
         }
         builder->appendEffectToEffectReferences(effect, effectElement->renderer());
         effectElement->setStandardAttributes(effect.get());
-        effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnitsCurrentValue(), targetBoundingBox));
+        effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnits()->currentValue()->enumValue(), targetBoundingBox));
         effect->setOperatingColorSpace(
             effectElement->renderer()->style()->svgStyle()->colorInterpolationFilters() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB);
         builder->add(AtomicString(effectElement->result()->currentValue()->value()), effect);
@@ -107,19 +103,18 @@
     return builder.release();
 }
 
-bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, FloatSize& scale)
+void RenderSVGResourceFilter::adjustScaleForMaximumImageSize(const FloatSize& size, FloatSize& filterScale)
 {
-    bool matchesFilterSize = true;
-    if (size.width() * scale.width() > kMaxFilterSize) {
-        scale.setWidth(kMaxFilterSize / size.width());
-        matchesFilterSize = false;
-    }
-    if (size.height() * scale.height() > kMaxFilterSize) {
-        scale.setHeight(kMaxFilterSize / size.height());
-        matchesFilterSize = false;
-    }
+    FloatSize scaledSize(size);
+    scaledSize.scale(filterScale.width(), filterScale.height());
+    float scaledArea = scaledSize.width() * scaledSize.height();
 
-    return matchesFilterSize;
+    if (scaledArea <= FilterEffect::maxFilterArea())
+        return;
+
+    // If area of scaled size is bigger than the upper limit, adjust the scale
+    // to fit.
+    filterScale.scale(sqrt(FilterEffect::maxFilterArea() / scaledArea));
 }
 
 static bool createImageBuffer(const Filter* filter, OwnPtr<ImageBuffer>& imageBuffer, bool accelerated)
@@ -170,7 +165,7 @@
     FloatRect targetBoundingBox = object->objectBoundingBox();
 
     SVGFilterElement* filterElement = toSVGFilterElement(element());
-    filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnitsCurrentValue(), targetBoundingBox);
+    filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits()->currentValue()->enumValue(), targetBoundingBox);
     if (filterData->boundaries.isEmpty())
         return false;
 
@@ -196,7 +191,7 @@
     }
     // The size of the scaled filter boundaries shouldn't be bigger than kMaxFilterSize.
     // Intermediate filters are limited by the filter boundaries so they can't be bigger than this.
-    fitsInMaximumImageSize(filterData->boundaries.size(), filterScale);
+    adjustScaleForMaximumImageSize(filterData->boundaries.size(), filterScale);
 
     filterData->drawingRegion = object->strokeBoundingBox();
     filterData->drawingRegion.intersect(filterData->boundaries);
@@ -207,7 +202,7 @@
     IntRect intDrawingRegion = enclosingIntRect(absoluteDrawingRegion);
 
     // Create the SVGFilter object.
-    bool primitiveBoundingBoxMode = filterElement->primitiveUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
+    bool primitiveBoundingBoxMode = filterElement->primitiveUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
     filterData->shearFreeAbsoluteTransform = AffineTransform();
     if (!deferredFiltersEnabled)
         filterData->shearFreeAbsoluteTransform.scale(filterScale.width(), filterScale.height());
@@ -226,12 +221,13 @@
 
     if (deferredFiltersEnabled) {
         SkiaImageFilterBuilder builder(context);
-        FloatRect oldBounds = context->getClipBounds();
-        m_objects.set(object, oldBounds);
+        m_objects.add(object);
         RefPtr<ImageFilter> imageFilter = builder.build(lastEffect, ColorSpaceDeviceRGB);
         FloatRect boundaries = enclosingIntRect(filterData->boundaries);
+        context->save();
+        // Clip drawing of filtered image to primitive boundaries.
+        context->clipRect(boundaries);
         if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
-            context->save();
             // Get boundaries in device coords.
             FloatSize size = context->getCTM().mapSize(boundaries.size());
             // Compute the scale amount required so that the resulting offscreen is exactly filterResX by filterResY pixels.
@@ -239,15 +235,9 @@
                 filterElement->filterResX()->currentValue()->value() / size.width(),
                 filterElement->filterResY()->currentValue()->value() / size.height());
             // Scale the CTM so the primitive is drawn to filterRes.
-            context->translate(boundaries.x(), boundaries.y());
             context->scale(filterResScale);
-            context->translate(-boundaries.x(), -boundaries.y());
             // Create a resize filter with the inverse scale.
             imageFilter = builder.buildResize(1 / filterResScale.width(), 1 / filterResScale.height(), imageFilter.get());
-            // Clip the context so that the offscreen created in beginLayer()
-            // is clipped to filterResX by filerResY. Use Replace mode since
-            // this clip may be larger than the parent device.
-            context->clipRectReplace(boundaries);
         }
         context->beginLayer(1, CompositeSourceOver, &boundaries, ColorFilterNone, imageFilter.get());
         return true;
@@ -295,18 +285,8 @@
     ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
 
     if (object->document().settings()->deferredFiltersEnabled()) {
-        SVGFilterElement* filterElement = toSVGFilterElement(element());
-        if (filterElement->hasAttribute(SVGNames::filterResAttr)) {
-            // Restore the clip bounds before endLayer(), so the filtered
-            // image draw is clipped to the original device bounds, not the
-            // clip we set before the beginLayer() above.
-            FloatRect oldBounds = m_objects.get(object);
-            context->clipRectReplace(oldBounds);
-            context->endLayer();
-            context->restore();
-        } else {
-            context->endLayer();
-        }
+        context->endLayer();
+        context->restore();
         m_objects.remove(object);
         return;
     }
@@ -371,7 +351,7 @@
 FloatRect RenderSVGResourceFilter::resourceBoundingBox(const RenderObject* object)
 {
     if (SVGFilterElement* element = toSVGFilterElement(this->element()))
-        return SVGLengthContext::resolveRectangle<SVGFilterElement>(element, element->filterUnitsCurrentValue(), object->objectBoundingBox());
+        return SVGLengthContext::resolveRectangle<SVGFilterElement>(element, element->filterUnits()->currentValue()->enumValue(), object->objectBoundingBox());
 
     return FloatRect();
 }
diff --git a/Source/core/rendering/svg/RenderSVGResourceFilter.h b/Source/core/rendering/svg/RenderSVGResourceFilter.h
index 20af2f2..c82cdaa 100644
--- a/Source/core/rendering/svg/RenderSVGResourceFilter.h
+++ b/Source/core/rendering/svg/RenderSVGResourceFilter.h
@@ -75,8 +75,8 @@
 
     PassRefPtr<SVGFilterBuilder> buildPrimitives(SVGFilter*);
 
-    SVGUnitTypes::SVGUnitType filterUnits() const { return toSVGFilterElement(element())->filterUnitsCurrentValue(); }
-    SVGUnitTypes::SVGUnitType primitiveUnits() const { return toSVGFilterElement(element())->primitiveUnitsCurrentValue(); }
+    SVGUnitTypes::SVGUnitType filterUnits() const { return toSVGFilterElement(element())->filterUnits()->currentValue()->enumValue(); }
+    SVGUnitTypes::SVGUnitType primitiveUnits() const { return toSVGFilterElement(element())->primitiveUnits()->currentValue()->enumValue(); }
 
     void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
 
@@ -85,14 +85,12 @@
 
     FloatRect drawingRegion(RenderObject*) const;
 private:
-    bool fitsInMaximumImageSize(const FloatSize&, FloatSize&);
+    void adjustScaleForMaximumImageSize(const FloatSize&, FloatSize&);
 
     typedef HashMap<RenderObject*, OwnPtr<FilterData> > FilterMap;
     FilterMap m_filter;
 
-    HashMap<RenderObject*, FloatRect> m_objects;
-
-    static bool s_deferredFilterRendering;
+    HashSet<RenderObject*> m_objects;
 };
 
 DEFINE_RENDER_OBJECT_TYPE_CASTS(RenderSVGResourceFilter, isSVGResourceFilter());
diff --git a/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
index e34449d..f7073ca 100644
--- a/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
@@ -44,12 +44,13 @@
         return;
 
     const SVGRenderStyle* newStyle = this->style()->svgStyle();
-    if (element()->hasTagName(SVGNames::feFloodTag)) {
+    ASSERT(element());
+    if (isSVGFEFloodElement(*element())) {
         if (newStyle->floodColor() != oldStyle->svgStyle()->floodColor())
             toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_colorAttr);
         if (newStyle->floodOpacity() != oldStyle->svgStyle()->floodOpacity())
             toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_opacityAttr);
-    } else if (element()->hasTagName(SVGNames::feDiffuseLightingTag) || element()->hasTagName(SVGNames::feSpecularLightingTag)) {
+    } else if (isSVGFEDiffuseLightingElement(*element()) || isSVGFESpecularLightingElement(*element())) {
         if (newStyle->lightingColor() != oldStyle->svgStyle()->lightingColor())
             toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::lighting_colorAttr);
     }
diff --git a/Source/core/rendering/svg/RenderSVGResourceGradient.cpp b/Source/core/rendering/svg/RenderSVGResourceGradient.cpp
index b26cdff..1c026e5 100644
--- a/Source/core/rendering/svg/RenderSVGResourceGradient.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceGradient.cpp
@@ -124,13 +124,13 @@
     ASSERT(svgStyle);
 
     if (resourceMode & ApplyToFillMode) {
-        context->setAlpha(svgStyle->fillOpacity());
+        context->setAlphaAsFloat(svgStyle->fillOpacity());
         context->setFillGradient(gradientData->gradient);
         context->setFillRule(svgStyle->fillRule());
     } else if (resourceMode & ApplyToStrokeMode) {
         if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
             gradientData->gradient->setGradientSpaceTransform(transformOnNonScalingStroke(object, gradientData->userspaceTransform));
-        context->setAlpha(svgStyle->strokeOpacity());
+        context->setAlphaAsFloat(svgStyle->strokeOpacity());
         context->setStrokeGradient(gradientData->gradient);
         SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
     }
diff --git a/Source/core/rendering/svg/RenderSVGResourceMarker.cpp b/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
index e8943ca..80f6ed5 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceMarker.cpp
@@ -110,8 +110,8 @@
     ASSERT(marker);
 
     float angle = -1;
-    if (marker->orientTypeCurrentValue() == SVGMarkerOrientAngle)
-        angle = marker->orientAngleCurrentValue().value();
+    if (marker->orientType()->currentValue()->enumValue() == SVGMarkerOrientAngle)
+        angle = marker->orientAngle()->currentValue()->value();
 
     return angle;
 }
@@ -122,7 +122,7 @@
     ASSERT(marker);
 
     float markerAngle = angle();
-    bool useStrokeWidth = marker->markerUnitsCurrentValue() == SVGMarkerUnitsStrokeWidth;
+    bool useStrokeWidth = marker->markerUnits()->currentValue()->enumValue() == SVGMarkerUnitsStrokeWidth;
 
     AffineTransform transform;
     transform.translate(origin.x(), origin.y());
diff --git a/Source/core/rendering/svg/RenderSVGResourceMarker.h b/Source/core/rendering/svg/RenderSVGResourceMarker.h
index 0305065..777ce00 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMarker.h
+++ b/Source/core/rendering/svg/RenderSVGResourceMarker.h
@@ -57,7 +57,7 @@
 
     FloatPoint referencePoint() const;
     float angle() const;
-    SVGMarkerUnitsType markerUnits() const { return toSVGMarkerElement(element())->markerUnitsCurrentValue(); }
+    SVGMarkerUnitsType markerUnits() const { return toSVGMarkerElement(element())->markerUnits()->currentValue()->enumValue(); }
 
     virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
     static const RenderSVGResourceType s_resourceType;
diff --git a/Source/core/rendering/svg/RenderSVGResourceMasker.cpp b/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
index 85a5775..6bcf50d 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceMasker.cpp
@@ -67,7 +67,7 @@
     clearInvalidationMask();
 
     FloatRect repaintRect = object->repaintRectInLocalCoordinates();
-    if (repaintRect.isEmpty() || !element()->hasChildNodes())
+    if (repaintRect.isEmpty() || !element()->hasChildren())
         return false;
 
     // Content layer start.
@@ -115,7 +115,7 @@
     ASSERT(context);
 
     AffineTransform contentTransformation;
-    SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskContentUnitsCurrentValue();
+    SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskContentUnits()->currentValue()->enumValue();
     if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y());
         contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height());
@@ -137,9 +137,9 @@
     // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and
     // userSpaceOnUse units (http://crbug.com/294900).
     context->beginRecording(strokeBoundingBox());
-    for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
-        RenderObject* renderer = childNode->renderer();
-        if (!childNode->isSVGElement() || !renderer)
+    for (Element* childElement = ElementTraversal::firstWithin(*element()); childElement; childElement = ElementTraversal::nextSibling(*childElement)) {
+        RenderObject* renderer = childElement->renderer();
+        if (!childElement->isSVGElement() || !renderer)
             continue;
         RenderStyle* style = renderer->style();
         if (!style || style->display() == NONE || style->visibility() != VISIBLE)
@@ -153,9 +153,9 @@
 
 void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
 {
-    for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) {
-        RenderObject* renderer = childNode->renderer();
-        if (!childNode->isSVGElement() || !renderer)
+    for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
+        RenderObject* renderer = childElement->renderer();
+        if (!renderer)
             continue;
         RenderStyle* style = renderer->style();
         if (!style || style->display() == NONE || style->visibility() != VISIBLE)
@@ -170,7 +170,7 @@
     ASSERT(maskElement);
 
     FloatRect objectBoundingBox = object->objectBoundingBox();
-    FloatRect maskBoundaries = SVGLengthContext::resolveRectangle<SVGMaskElement>(maskElement, maskElement->maskUnitsCurrentValue(), objectBoundingBox);
+    FloatRect maskBoundaries = SVGLengthContext::resolveRectangle<SVGMaskElement>(maskElement, maskElement->maskUnits()->currentValue()->enumValue(), objectBoundingBox);
 
     // Resource was not layouted yet. Give back clipping rect of the mask.
     if (selfNeedsLayout())
@@ -180,7 +180,7 @@
         calculateMaskContentRepaintRect();
 
     FloatRect maskRect = m_maskContentBoundaries;
-    if (maskElement->maskContentUnitsCurrentValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
+    if (maskElement->maskContentUnits()->currentValue()->value() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
         AffineTransform transform;
         transform.translate(objectBoundingBox.x(), objectBoundingBox.y());
         transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
diff --git a/Source/core/rendering/svg/RenderSVGResourceMasker.h b/Source/core/rendering/svg/RenderSVGResourceMasker.h
index d4476f8..5baaf2d 100644
--- a/Source/core/rendering/svg/RenderSVGResourceMasker.h
+++ b/Source/core/rendering/svg/RenderSVGResourceMasker.h
@@ -48,8 +48,8 @@
     virtual void postApplyResource(RenderObject*, GraphicsContext*&, unsigned short, const Path*, const RenderSVGShape*) OVERRIDE;
     FloatRect resourceBoundingBox(const RenderObject*);
 
-    SVGUnitTypes::SVGUnitType maskUnits() const { return toSVGMaskElement(element())->maskUnitsCurrentValue(); }
-    SVGUnitTypes::SVGUnitType maskContentUnits() const { return toSVGMaskElement(element())->maskContentUnitsCurrentValue(); }
+    SVGUnitTypes::SVGUnitType maskUnits() const { return toSVGMaskElement(element())->maskUnits()->currentValue()->enumValue(); }
+    SVGUnitTypes::SVGUnitType maskContentUnits() const { return toSVGMaskElement(element())->maskContentUnits()->currentValue()->enumValue(); }
 
     virtual RenderSVGResourceType resourceType() const OVERRIDE { return s_resourceType; }
     static const RenderSVGResourceType s_resourceType;
diff --git a/Source/core/rendering/svg/RenderSVGResourcePattern.cpp b/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
index 353e454..d6f93ef 100644
--- a/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourcePattern.cpp
@@ -158,13 +158,13 @@
     ASSERT(svgStyle);
 
     if (resourceMode & ApplyToFillMode) {
-        context->setAlpha(svgStyle->fillOpacity());
+        context->setAlphaAsFloat(svgStyle->fillOpacity());
         context->setFillPattern(patternData->pattern);
         context->setFillRule(svgStyle->fillRule());
     } else if (resourceMode & ApplyToStrokeMode) {
         if (svgStyle->vectorEffect() == VE_NON_SCALING_STROKE)
             patternData->pattern->setPatternSpaceTransform(transformOnNonScalingStroke(object, patternData->transform));
-        context->setAlpha(svgStyle->strokeOpacity());
+        context->setAlphaAsFloat(svgStyle->strokeOpacity());
         context->setStrokePattern(patternData->pattern);
         SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
     }
@@ -266,12 +266,12 @@
         contentTransformation = tileImageTransform;
 
     // Draw the content into the ImageBuffer.
-    for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
-        if (!node->isSVGElement() || !node->renderer())
+    for (Element* element = ElementTraversal::firstWithin(*attributes.patternContentElement()); element; element = ElementTraversal::nextSibling(*element)) {
+        if (!element->isSVGElement() || !element->renderer())
             continue;
-        if (node->renderer()->needsLayout())
+        if (element->renderer()->needsLayout())
             return nullptr;
-        SVGRenderingContext::renderSubtree(tileImage->context(), node->renderer(), contentTransformation);
+        SVGRenderingContext::renderSubtree(tileImage->context(), element->renderer(), contentTransformation);
     }
 
     return tileImage.release();
diff --git a/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp b/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp
index a79ad3a..fac2a84 100644
--- a/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp
+++ b/Source/core/rendering/svg/RenderSVGResourceSolidColor.cpp
@@ -21,8 +21,8 @@
 
 #include "core/rendering/svg/RenderSVGResourceSolidColor.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/style/RenderStyle.h"
 #include "core/rendering/svg/RenderSVGShape.h"
 #include "core/rendering/svg/SVGRenderSupport.h"
@@ -56,9 +56,9 @@
 
     if (resourceMode & ApplyToFillMode) {
         if (!isRenderingMask && svgStyle)
-            context->setAlpha(svgStyle->fillOpacity());
+            context->setAlphaAsFloat(svgStyle->fillOpacity());
         else
-            context->setAlpha(1);
+            context->setAlphaAsFloat(1);
         context->setFillColor(m_color);
         if (!isRenderingMask)
             context->setFillRule(svgStyle ? svgStyle->fillRule() : RULE_NONZERO);
@@ -68,7 +68,7 @@
     } else if (resourceMode & ApplyToStrokeMode) {
         // When rendering the mask for a RenderSVGResourceClipper, the stroke code path is never hit.
         ASSERT(!isRenderingMask);
-        context->setAlpha(svgStyle ? svgStyle->strokeOpacity() : 1);
+        context->setAlphaAsFloat(svgStyle ? svgStyle->strokeOpacity() : 1);
         context->setStrokeColor(m_color);
 
         if (style)
diff --git a/Source/core/rendering/svg/RenderSVGRoot.cpp b/Source/core/rendering/svg/RenderSVGRoot.cpp
index ecdad3d..4c81c67 100644
--- a/Source/core/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/core/rendering/svg/RenderSVGRoot.cpp
@@ -25,7 +25,7 @@
 
 #include "core/rendering/svg/RenderSVGRoot.h"
 
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/LayoutRectRecorder.h"
 #include "core/rendering/LayoutRepainter.h"
@@ -118,7 +118,7 @@
     if (!node())
         return false;
 
-    Frame* frame = node()->document().frame();
+    LocalFrame* frame = node()->document().frame();
     if (!frame)
         return false;
 
@@ -199,7 +199,7 @@
     LayoutRectRecorder recorder(*this);
 
     // Arbitrary affine transforms are incompatible with LayoutState.
-    LayoutStateDisabler layoutStateDisabler(view());
+    LayoutStateDisabler layoutStateDisabler(*this);
 
     bool needsLayout = selfNeedsLayout();
     LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout);
diff --git a/Source/core/rendering/svg/RenderSVGRoot.h b/Source/core/rendering/svg/RenderSVGRoot.h
index d549044..0d8c998 100644
--- a/Source/core/rendering/svg/RenderSVGRoot.h
+++ b/Source/core/rendering/svg/RenderSVGRoot.h
@@ -57,6 +57,7 @@
 
     virtual bool hasRelativeIntrinsicLogicalWidth() const OVERRIDE;
     virtual bool hasRelativeLogicalHeight() const OVERRIDE;
+    virtual bool visibleForTouchAction() const OVERRIDE { return true; }
 
     // localToBorderBoxTransform maps local SVG viewport coordinates to local CSS box coordinates.
     const AffineTransform& localToBorderBoxTransform() const { return m_localToBorderBoxTransform; }
diff --git a/Source/core/rendering/svg/RenderSVGShape.cpp b/Source/core/rendering/svg/RenderSVGShape.cpp
index 21655ff..b5c9528 100644
--- a/Source/core/rendering/svg/RenderSVGShape.cpp
+++ b/Source/core/rendering/svg/RenderSVGShape.cpp
@@ -63,7 +63,7 @@
 {
     m_path.clear();
     m_path = adoptPtr(new Path);
-    ASSERT(RenderSVGShape::isEmpty());
+    ASSERT(RenderSVGShape::isShapeEmpty());
 
     updatePathFromGraphicsElement(toSVGGraphicsElement(element()), path());
     processMarkerPositions();
@@ -72,11 +72,6 @@
     m_strokeBoundingBox = calculateStrokeBoundingBox();
 }
 
-bool RenderSVGShape::isEmpty() const
-{
-    return path().isEmpty();
-}
-
 void RenderSVGShape::fillShape(GraphicsContext* context) const
 {
     context->fillPath(path());
@@ -243,7 +238,7 @@
 {
     ANNOTATE_GRAPHICS_CONTEXT(paintInfo, this);
 
-    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || isEmpty())
+    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || isShapeEmpty())
         return;
     FloatRect boundingBox = repaintRectInLocalCoordinates();
     if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
diff --git a/Source/core/rendering/svg/RenderSVGShape.h b/Source/core/rendering/svg/RenderSVGShape.h
index ca41092..e603e15 100644
--- a/Source/core/rendering/svg/RenderSVGShape.h
+++ b/Source/core/rendering/svg/RenderSVGShape.h
@@ -65,7 +65,7 @@
 
 protected:
     virtual void updateShapeFromElement();
-    virtual bool isEmpty() const OVERRIDE;
+    virtual bool isShapeEmpty() const { return path().isEmpty(); }
     virtual bool shapeDependentStrokeContains(const FloatPoint&);
     virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
     float strokeWidth() const;
diff --git a/Source/core/rendering/svg/RenderSVGTSpan.cpp b/Source/core/rendering/svg/RenderSVGTSpan.cpp
index 9c71d54..b7bec1d 100644
--- a/Source/core/rendering/svg/RenderSVGTSpan.cpp
+++ b/Source/core/rendering/svg/RenderSVGTSpan.cpp
@@ -26,6 +26,7 @@
 
 #include "SVGNames.h"
 #include "core/rendering/svg/SVGRenderSupport.h"
+#include "core/svg/SVGAltGlyphElement.h"
 
 namespace WebCore {
 
@@ -42,7 +43,8 @@
 
 #if ENABLE(SVG_FONTS)
     // Only allow other types of  children if this is not an 'altGlyph'.
-    if (node()->hasTagName(SVGNames::altGlyphTag))
+    ASSERT(node());
+    if (isSVGAltGlyphElement(*node()))
         return false;
 #endif
 
diff --git a/Source/core/rendering/svg/RenderSVGText.cpp b/Source/core/rendering/svg/RenderSVGText.cpp
index 0a97525..9a2c607 100644
--- a/Source/core/rendering/svg/RenderSVGText.cpp
+++ b/Source/core/rendering/svg/RenderSVGText.cpp
@@ -266,9 +266,8 @@
         m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(affectedAttributes[i]->context());
 }
 
-void RenderSVGText::subtreeStyleDidChange(RenderSVGInlineText* text)
+void RenderSVGText::subtreeStyleDidChange()
 {
-    ASSERT(text);
     if (!shouldHandleSubtreeMutations() || documentBeingDestroyed())
         return;
 
@@ -277,7 +276,7 @@
     // Only update the metrics cache, but not the text positioning element cache
     // nor the layout attributes cached in the leaf #text renderers.
     FontCachePurgePreventer fontCachePurgePreventer;
-    for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) {
+    for (RenderObject* descendant = firstChild(); descendant; descendant = descendant->nextInPreOrder(this)) {
         if (descendant->isSVGInlineText())
             m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(toRenderSVGInlineText(descendant));
     }
@@ -322,6 +321,9 @@
 void RenderSVGText::layout()
 {
     ASSERT(needsLayout());
+
+    subtreeStyleDidChange();
+
     LayoutRectRecorder recorder(*this);
     LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this));
 
@@ -417,7 +419,7 @@
 
 RootInlineBox* RenderSVGText::createRootInlineBox()
 {
-    RootInlineBox* box = new SVGRootInlineBox(this);
+    RootInlineBox* box = new SVGRootInlineBox(*this);
     box->setHasVirtualLogicalHeight();
     return box;
 }
@@ -458,7 +460,7 @@
     if (!closestBox)
         return createPositionWithAffinity(0, DOWNSTREAM);
 
-    return closestBox->renderer()->positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
+    return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
 }
 
 void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
diff --git a/Source/core/rendering/svg/RenderSVGText.h b/Source/core/rendering/svg/RenderSVGText.h
index 76bc693..0787235 100644
--- a/Source/core/rendering/svg/RenderSVGText.h
+++ b/Source/core/rendering/svg/RenderSVGText.h
@@ -53,7 +53,7 @@
     void subtreeChildWasAdded(RenderObject*);
     void subtreeChildWillBeRemoved(RenderObject*, Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes);
     void subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes);
-    void subtreeStyleDidChange(RenderSVGInlineText*);
+    void subtreeStyleDidChange();
     void subtreeTextDidChange(RenderSVGInlineText*);
 
 private:
diff --git a/Source/core/rendering/svg/RenderSVGTextPath.cpp b/Source/core/rendering/svg/RenderSVGTextPath.cpp
index 26d2055..c1ff874 100644
--- a/Source/core/rendering/svg/RenderSVGTextPath.cpp
+++ b/Source/core/rendering/svg/RenderSVGTextPath.cpp
@@ -41,7 +41,8 @@
 
 #if ENABLE(SVG_FONTS)
     // 'altGlyph' is supported by the content model for 'textPath', but...
-    if (child->node()->hasTagName(SVGNames::altGlyphTag))
+    ASSERT(child->node());
+    if (isSVGAltGlyphElement(*child->node()))
         return false;
 #endif
 
@@ -52,20 +53,20 @@
 {
     SVGTextPathElement* textPathElement = toSVGTextPathElement(node());
     Element* targetElement = SVGURIReference::targetElementFromIRIString(textPathElement->href()->currentValue()->value(), textPathElement->document());
-    if (!targetElement || !targetElement->hasTagName(SVGNames::pathTag))
+    if (!isSVGPathElement(targetElement))
         return Path();
 
-    SVGPathElement* pathElement = toSVGPathElement(targetElement);
+    SVGPathElement& pathElement = toSVGPathElement(*targetElement);
 
     Path pathData;
-    updatePathFromGraphicsElement(pathElement, pathData);
+    updatePathFromGraphicsElement(&pathElement, pathData);
 
     // Spec:  The transform attribute on the referenced 'path' element represents a
     // supplemental transformation relative to the current user coordinate system for
     // the current 'text' element, including any adjustments to the current user coordinate
     // system due to a possible transform attribute on the current 'text' element.
     // http://www.w3.org/TR/SVG/text.html#TextPathElement
-    pathData.transform(pathElement->animatedLocalTransform());
+    pathData.transform(pathElement.animatedLocalTransform());
     return pathData;
 }
 
diff --git a/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp b/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp
index c55400c..f61bee4 100644
--- a/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp
+++ b/Source/core/rendering/svg/RenderSVGTransformableContainer.cpp
@@ -49,7 +49,8 @@
 
 bool RenderSVGTransformableContainer::isChildAllowed(RenderObject* child, RenderStyle* style) const
 {
-    if (element()->hasTagName(SVGNames::switchTag)) {
+    ASSERT(element());
+    if (isSVGSwitchElement(*element())) {
         Node* node = child->node();
         // Reject non-SVG/non-valid elements.
         if (!node->isSVGElement() || !toSVGElement(node)->isValid())
@@ -57,10 +58,10 @@
         // Reject this child if it isn't the first valid node.
         if (hasValidPredecessor(node))
             return false;
-    } else if (element()->hasTagName(SVGNames::aTag)) {
+    } else if (isSVGAElement(*element())) {
         // http://www.w3.org/2003/01/REC-SVG11-20030114-errata#linking-text-environment
         // The 'a' element may contain any element that its parent may contain, except itself.
-        if (child->node()->hasTagName(SVGNames::aTag))
+        if (isSVGAElement(*child->node()))
             return false;
         if (parent() && parent()->isSVG())
             return parent()->isChildAllowed(child, style);
@@ -71,16 +72,17 @@
 bool RenderSVGTransformableContainer::calculateLocalTransform()
 {
     SVGGraphicsElement* element = toSVGGraphicsElement(this->element());
+    ASSERT(element);
 
     // If we're either the renderer for a <use> element, or for any <g> element inside the shadow
     // tree, that was created during the use/symbol/svg expansion in SVGUseElement. These containers
     // need to respect the translations induced by their corresponding use elements x/y attributes.
     SVGUseElement* useElement = 0;
-    if (element->hasTagName(SVGNames::useTag))
+    if (isSVGUseElement(*element)) {
         useElement = toSVGUseElement(element);
-    else if (element->isInShadowTree() && element->hasTagName(SVGNames::gTag)) {
+    } else if (element->isInShadowTree() && isSVGGElement(*element)) {
         SVGElement* correspondingElement = element->correspondingElement();
-        if (correspondingElement && correspondingElement->hasTagName(SVGNames::useTag))
+        if (isSVGUseElement(correspondingElement))
             useElement = toSVGUseElement(correspondingElement);
     }
 
diff --git a/Source/core/rendering/svg/RenderSVGViewportContainer.cpp b/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
index 63fa495..0dae02c 100644
--- a/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/core/rendering/svg/RenderSVGViewportContainer.cpp
@@ -42,7 +42,8 @@
 
 void RenderSVGViewportContainer::determineIfLayoutSizeChanged()
 {
-    if (!element()->hasTagName(SVGNames::svgTag))
+    ASSERT(element());
+    if (!isSVGSVGElement(*element()))
         return;
 
     m_isLayoutSizeChanged = toSVGSVGElement(element())->hasRelativeLengths() && selfNeedsLayout();
@@ -57,7 +58,8 @@
 void RenderSVGViewportContainer::calcViewport()
 {
     SVGElement* element = this->element();
-    if (!element->hasTagName(SVGNames::svgTag))
+    ASSERT(element);
+    if (!isSVGSVGElement(*element))
         return;
     SVGSVGElement* svg = toSVGSVGElement(element);
     FloatRect oldViewport = m_viewport;
@@ -74,7 +76,7 @@
         const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
         for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
             const SVGElementInstance* instance = (*it);
-            ASSERT(instance->correspondingElement()->hasTagName(SVGNames::svgTag) || instance->correspondingElement()->hasTagName(SVGNames::symbolTag));
+            ASSERT(isSVGSVGElement(instance->correspondingElement()) || isSVGSymbolElement(instance->correspondingElement()));
             if (instance->shadowTreeElement() == svg) {
                 ASSERT(correspondingElement == instance->correspondingElement());
                 useElement = instance->directUseElement();
@@ -85,7 +87,7 @@
         }
 
         ASSERT(useElement);
-        bool isSymbolElement = correspondingElement->hasTagName(SVGNames::symbolTag);
+        bool isSymbolElement = isSVGSymbolElement(*correspondingElement);
 
         // Spec (<use> on <symbol>): This generated 'svg' will always have explicit values for attributes width and height.
         // If attributes width and/or height are provided on the 'use' element, then these attributes
@@ -132,7 +134,8 @@
 
 AffineTransform RenderSVGViewportContainer::viewportTransform() const
 {
-    if (element()->hasTagName(SVGNames::svgTag)) {
+    ASSERT(element());
+    if (isSVGSVGElement(*element())) {
         SVGSVGElement* svg = toSVGSVGElement(element());
         return svg->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
     }
@@ -151,11 +154,10 @@
 
 void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
 {
+    ASSERT(element());
     // An empty viewBox disables rendering.
-    if (element()->hasTagName(SVGNames::svgTag)) {
-        if (toSVGSVGElement(element())->hasEmptyViewBox())
-            return;
-    }
+    if (isSVGSVGElement(*element()) && toSVGSVGElement(*element()).hasEmptyViewBox())
+        return;
 
     RenderSVGContainer::paint(paintInfo, paintOffset);
 }
diff --git a/Source/core/rendering/svg/SVGInlineFlowBox.cpp b/Source/core/rendering/svg/SVGInlineFlowBox.cpp
index 1832911..d4a861c 100644
--- a/Source/core/rendering/svg/SVGInlineFlowBox.cpp
+++ b/Source/core/rendering/svg/SVGInlineFlowBox.cpp
@@ -50,10 +50,7 @@
     ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
     ASSERT(!paintInfo.context->paintingDisabled());
 
-    RenderObject* boxRenderer = renderer();
-    ASSERT(boxRenderer);
-
-    SVGRenderingContext renderingContext(boxRenderer, paintInfo, SVGRenderingContext::SaveGraphicsContext);
+    SVGRenderingContext renderingContext(&renderer(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
     if (renderingContext.isRenderingPrepared()) {
         for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
             child->paint(paintInfo, paintOffset, 0, 0);
diff --git a/Source/core/rendering/svg/SVGInlineFlowBox.h b/Source/core/rendering/svg/SVGInlineFlowBox.h
index b215b1f..339a204 100644
--- a/Source/core/rendering/svg/SVGInlineFlowBox.h
+++ b/Source/core/rendering/svg/SVGInlineFlowBox.h
@@ -29,7 +29,7 @@
 
 class SVGInlineFlowBox FINAL : public InlineFlowBox {
 public:
-    SVGInlineFlowBox(RenderObject* obj)
+    SVGInlineFlowBox(RenderObject& obj)
         : InlineFlowBox(obj)
         , m_logicalHeight(0)
     {
diff --git a/Source/core/rendering/svg/SVGInlineTextBox.cpp b/Source/core/rendering/svg/SVGInlineTextBox.cpp
index df21423..c7be22f 100644
--- a/Source/core/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/core/rendering/svg/SVGInlineTextBox.cpp
@@ -25,8 +25,8 @@
 #include "core/dom/DocumentMarkerController.h"
 #include "core/dom/RenderedDocumentMarker.h"
 #include "core/editing/Editor.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/HitTestResult.h"
 #include "core/rendering/InlineFlowBox.h"
 #include "core/rendering/PointerEventsHitRules.h"
@@ -39,7 +39,7 @@
 #include "core/rendering/svg/SVGTextRunRenderingContext.h"
 #include "platform/FloatConversion.h"
 #include "platform/fonts/FontCache.h"
-#include "platform/graphics/DrawLooper.h"
+#include "platform/graphics/DrawLooperBuilder.h"
 #include "platform/graphics/GraphicsContextStateSaver.h"
 
 using namespace std;
@@ -55,7 +55,7 @@
 
 COMPILE_ASSERT(sizeof(SVGInlineTextBox) == sizeof(ExpectedSVGInlineTextBoxSize), SVGInlineTextBox_is_not_of_expected_size);
 
-SVGInlineTextBox::SVGInlineTextBox(RenderObject* object)
+SVGInlineTextBox::SVGInlineTextBox(RenderObject& object)
     : InlineTextBox(object)
     , m_logicalHeight(0)
     , m_paintingResourceMode(ApplyToDefaultMode)
@@ -88,13 +88,12 @@
 
 int SVGInlineTextBox::offsetForPositionInFragment(const SVGTextFragment& fragment, float position, bool includePartialGlyphs) const
 {
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
 
-    float scalingFactor = textRenderer->scalingFactor();
+    float scalingFactor = textRenderer.scalingFactor();
     ASSERT(scalingFactor);
 
-    RenderStyle* style = textRenderer->style();
+    RenderStyle* style = textRenderer.style();
     ASSERT(style);
 
     TextRun textRun = constructTextRun(style, fragment);
@@ -106,7 +105,7 @@
     if (!fragmentTransform.isIdentity())
         textRun.setHorizontalGlyphStretch(narrowPrecisionToFloat(fragmentTransform.xScale()));
 
-    return fragment.characterOffset - start() + textRenderer->scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
+    return fragment.characterOffset - start() + textRenderer.scaledFont().offsetForPosition(textRun, position * scalingFactor, includePartialGlyphs);
 }
 
 float SVGInlineTextBox::positionForOffset(int) const
@@ -123,13 +122,12 @@
 
     FontCachePurgePreventer fontCachePurgePreventer;
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
 
-    float scalingFactor = textRenderer->scalingFactor();
+    float scalingFactor = textRenderer.scalingFactor();
     ASSERT(scalingFactor);
 
-    const Font& scaledFont = textRenderer->scaledFont();
+    const Font& scaledFont = textRenderer.scaledFont();
     const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
     FloatPoint textOrigin(fragment.x, fragment.y);
     if (scalingFactor != 1)
@@ -153,10 +151,7 @@
     if (startPosition >= endPosition)
         return LayoutRect();
 
-    RenderText* text = textRenderer();
-    ASSERT(text);
-
-    RenderStyle* style = text->style();
+    RenderStyle* style = textRenderer().style();
     ASSERT(style);
 
     AffineTransform fragmentTransform;
@@ -175,8 +170,7 @@
 
         FloatRect fragmentRect = selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
         fragment.buildFragmentTransform(fragmentTransform);
-        if (!fragmentTransform.isIdentity())
-            fragmentRect = fragmentTransform.mapRect(fragmentRect);
+        fragmentRect = fragmentTransform.mapRect(fragmentRect);
 
         selectionRect.unite(fragmentRect);
     }
@@ -184,25 +178,24 @@
     return enclosingIntRect(selectionRect);
 }
 
-static inline bool textShouldBePainted(RenderSVGInlineText* textRenderer)
+static inline bool textShouldBePainted(RenderSVGInlineText& textRenderer)
 {
     // Font::pixelSize(), returns FontDescription::computedPixelSize(), which returns "int(x + 0.5)".
     // If the absolute font size on screen is below x=0.5, don't render anything.
-    return textRenderer->scaledFont().fontDescription().computedPixelSize();
+    return textRenderer.scaledFont().fontDescription().computedPixelSize();
 }
 
 void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
 {
-    ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
+    ASSERT(paintInfo.shouldPaintWithinRoot(&renderer()));
     ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
     ASSERT(truncation() == cNoTruncation);
 
-    if (renderer()->style()->visibility() != VISIBLE)
+    if (renderer().style()->visibility() != VISIBLE)
         return;
 
-    RenderObject* parentRenderer = parent()->renderer();
-    ASSERT(parentRenderer);
-    ASSERT(!parentRenderer->document().printing());
+    RenderObject& parentRenderer = parent()->renderer();
+    ASSERT(!parentRenderer.document().printing());
 
     // Determine whether or not we're selected.
     bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
@@ -210,16 +203,15 @@
     if (!hasSelection || paintSelectedTextOnly)
         return;
 
-    Color backgroundColor = renderer()->selectionBackgroundColor();
+    Color backgroundColor = renderer().selectionBackgroundColor();
     if (!backgroundColor.alpha())
         return;
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
     if (!textShouldBePainted(textRenderer))
         return;
 
-    RenderStyle* style = parentRenderer->style();
+    RenderStyle* style = parentRenderer.style();
     ASSERT(style);
 
     int startPosition, endPosition;
@@ -254,33 +246,31 @@
 
 void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
 {
-    ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
+    ASSERT(paintInfo.shouldPaintWithinRoot(&renderer()));
     ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
     ASSERT(truncation() == cNoTruncation);
 
-    if (renderer()->style()->visibility() != VISIBLE)
+    if (renderer().style()->visibility() != VISIBLE)
         return;
 
     // Note: We're explicitely not supporting composition & custom underlines and custom highlighters - unlike InlineTextBox.
     // If we ever need that for SVG, it's very easy to refactor and reuse the code.
 
-    RenderObject* parentRenderer = parent()->renderer();
-    ASSERT(parentRenderer);
+    RenderObject& parentRenderer = parent()->renderer();
 
     bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
-    bool hasSelection = !parentRenderer->document().printing() && selectionState() != RenderObject::SelectionNone;
+    bool hasSelection = !parentRenderer.document().printing() && selectionState() != RenderObject::SelectionNone;
     if (!hasSelection && paintSelectedTextOnly)
         return;
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
     if (!textShouldBePainted(textRenderer))
         return;
 
-    RenderStyle* style = parentRenderer->style();
+    RenderStyle* style = parentRenderer.style();
     ASSERT(style);
 
-    paintDocumentMarkers(paintInfo.context, paintOffset, style, textRenderer->scaledFont(), true);
+    paintDocumentMarkers(paintInfo.context, paintOffset, style, textRenderer.scaledFont(), true);
 
     const SVGRenderStyle* svgStyle = style->svgStyle();
     ASSERT(svgStyle);
@@ -290,7 +280,7 @@
 
     RenderStyle* selectionStyle = style;
     if (hasSelection) {
-        selectionStyle = parentRenderer->getCachedPseudoStyle(SELECTION);
+        selectionStyle = parentRenderer.getCachedPseudoStyle(SELECTION);
         if (selectionStyle) {
             const SVGRenderStyle* svgSelectionStyle = selectionStyle->svgStyle();
             ASSERT(svgSelectionStyle);
@@ -303,7 +293,7 @@
             selectionStyle = style;
     }
 
-    if (textRenderer->frame() && textRenderer->frame()->view() && textRenderer->frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask) {
+    if (textRenderer.frame() && textRenderer.frame()->view() && textRenderer.frame()->view()->paintBehavior() & PaintBehaviorRenderingSVGMask) {
         hasFill = true;
         hasVisibleStroke = false;
     }
@@ -371,7 +361,7 @@
     ASSERT(style);
     ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
 
-    bool hasFallback;
+    bool hasFallback = false;
     if (m_paintingResourceMode & ApplyToFillMode)
         m_paintingResource = RenderSVGResource::fillPaintingResource(renderer, style, hasFallback);
     else if (m_paintingResourceMode & ApplyToStrokeMode)
@@ -401,16 +391,13 @@
 {
     ASSERT(m_paintingResource);
 
-    RenderObject* parentRenderer = parent()->renderer();
-    ASSERT(parentRenderer);
-
-    m_paintingResource->postApplyResource(parentRenderer, context, m_paintingResourceMode, path, /*RenderSVGShape*/ 0);
+    m_paintingResource->postApplyResource(&parent()->renderer(), context, m_paintingResourceMode, path, /*RenderSVGShape*/ 0);
     m_paintingResource = 0;
 }
 
 bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, float scalingFactor, TextRun& textRun, RenderStyle* style)
 {
-    bool acquiredResource = acquirePaintingResource(context, scalingFactor, parent()->renderer(), style);
+    bool acquiredResource = acquirePaintingResource(context, scalingFactor, &parent()->renderer(), style);
     if (!acquiredResource)
         return false;
 
@@ -438,10 +425,8 @@
 TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFragment& fragment) const
 {
     ASSERT(style);
-    ASSERT(textRenderer());
 
-    RenderText* text = textRenderer();
-    ASSERT(text);
+    RenderText* text = &textRenderer();
 
     // FIXME(crbug.com/264211): This should not be necessary but can occur if we
     //                          layout during layout. Remove this when 264211 is fixed.
@@ -530,7 +515,7 @@
     // Lookup first render object in parent hierarchy which has text-decoration set.
     RenderObject* renderer = 0;
     while (parentBox) {
-        renderer = parentBox->renderer();
+        renderer = &parentBox->renderer();
 
         if (renderer->style() && renderer->style()->textDecoration() != TextDecorationNone)
             break;
@@ -544,7 +529,7 @@
 
 void SVGInlineTextBox::paintDecoration(GraphicsContext* context, TextDecoration decoration, const SVGTextFragment& fragment)
 {
-    if (textRenderer()->style()->textDecorationsInEffect() == TextDecorationNone)
+    if (textRenderer().style()->textDecorationsInEffect() == TextDecorationNone)
         return;
 
     // Find out which render style defined the text-decoration, as its fill/stroke properties have to be used for drawing instead of ours.
@@ -616,13 +601,12 @@
 
 void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyle* style, TextRun& textRun, const SVGTextFragment& fragment, int startPosition, int endPosition)
 {
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
 
-    float scalingFactor = textRenderer->scalingFactor();
+    float scalingFactor = textRenderer.scalingFactor();
     ASSERT(scalingFactor);
 
-    const Font& scaledFont = textRenderer->scaledFont();
+    const Font& scaledFont = textRenderer.scaledFont();
     const ShadowList* shadowList = style->textShadow();
 
     // Text shadows are disabled when printing. http://crbug.com/258321
@@ -639,15 +623,15 @@
     }
 
     if (hasShadow) {
-        DrawLooper drawLooper;
+        OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create();
         for (size_t i = shadowList->shadows().size(); i--; ) {
             const ShadowData& shadow = shadowList->shadows()[i];
             FloatSize offset(shadow.x(), shadow.y());
-            drawLooper.addShadow(offset, shadow.blur(), shadow.color(),
-                DrawLooper::ShadowRespectsTransforms, DrawLooper::ShadowRespectsAlpha);
+            drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(),
+                DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowRespectsAlpha);
         }
-        drawLooper.addUnmodifiedContent();
-        context->setDrawLooper(drawLooper);
+        drawLooperBuilder->addUnmodifiedContent();
+        context->setDrawLooper(drawLooperBuilder.release());
     }
 
     if (prepareGraphicsContextForTextPainting(context, scalingFactor, textRun, style)) {
@@ -690,13 +674,13 @@
 
     // Draw text using selection style from the start to the end position of the selection
     if (style != selectionStyle)
-        SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, selectionStyle);
+        SVGResourcesCache::clientStyleChanged(&parent()->renderer(), StyleDifferenceRepaint, selectionStyle);
 
     TextRun selectionTextRun = constructTextRun(selectionStyle, fragment);
     paintTextWithShadows(context, selectionStyle, textRun, fragment, startPosition, endPosition);
 
     if (style != selectionStyle)
-        SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, style);
+        SVGResourcesCache::clientStyleChanged(&parent()->renderer(), StyleDifferenceRepaint, style);
 
     // Eventually draw text using regular style from the end position of the selection to the end of the current chunk part
     if (endPosition < static_cast<int>(fragment.length) && !paintSelectedTextOnly)
@@ -714,12 +698,11 @@
     if (marker->type() != DocumentMarker::TextMatch)
         return;
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
 
     FloatRect markerRect;
     AffineTransform fragmentTransform;
-    for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
+    for (InlineTextBox* box = textRenderer.firstTextBox(); box; box = box->nextTextBox()) {
         if (!box->isSVGInlineTextBox())
             continue;
 
@@ -743,40 +726,37 @@
 
             FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, style);
             fragment.buildFragmentTransform(fragmentTransform);
-            bool fragmentTransformIsIdentity = fragmentTransform.isIdentity();
 
             // Draw the marker highlight.
-            if (renderer()->frame()->editor().markedTextMatchesAreHighlighted()) {
+            if (renderer().frame()->editor().markedTextMatchesAreHighlighted()) {
                 Color color = marker->activeMatch() ?
                     RenderTheme::theme().platformActiveTextSearchHighlightColor() :
                     RenderTheme::theme().platformInactiveTextSearchHighlightColor();
                 GraphicsContextStateSaver stateSaver(*context);
-                if (!fragmentTransformIsIdentity)
+                if (!fragmentTransform.isIdentity())
                     context->concatCTM(fragmentTransform);
                 context->setFillColor(color);
                 context->fillRect(fragmentRect, color);
             }
 
-            if (!fragmentTransformIsIdentity)
-                fragmentRect = fragmentTransform.mapRect(fragmentRect);
+            fragmentRect = fragmentTransform.mapRect(fragmentRect);
             markerRect.unite(fragmentRect);
         }
     }
 
-    toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
+    toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer.localToAbsoluteQuad(markerRect).enclosingBoundingBox());
 }
 
 FloatRect SVGInlineTextBox::calculateBoundaries() const
 {
     FloatRect textRect;
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(this->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(this->textRenderer());
 
-    float scalingFactor = textRenderer->scalingFactor();
+    float scalingFactor = textRenderer.scalingFactor();
     ASSERT(scalingFactor);
 
-    float baseline = textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor;
+    float baseline = textRenderer.scaledFont().fontMetrics().floatAscent() / scalingFactor;
 
     AffineTransform fragmentTransform;
     unsigned textFragmentsSize = m_textFragments.size();
@@ -784,8 +764,7 @@
         const SVGTextFragment& fragment = m_textFragments.at(i);
         FloatRect fragmentRect(fragment.x, fragment.y - baseline, fragment.width, fragment.height);
         fragment.buildFragmentTransform(fragmentTransform);
-        if (!fragmentTransform.isIdentity())
-            fragmentRect = fragmentTransform.mapRect(fragmentRect);
+        fragmentRect = fragmentTransform.mapRect(fragmentRect);
 
         textRect.unite(fragmentRect);
     }
@@ -798,18 +777,18 @@
     // FIXME: integrate with InlineTextBox::nodeAtPoint better.
     ASSERT(!isLineBreak());
 
-    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, renderer()->style()->pointerEvents());
-    bool isVisible = renderer()->style()->visibility() == VISIBLE;
+    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, renderer().style()->pointerEvents());
+    bool isVisible = renderer().style()->visibility() == VISIBLE;
     if (isVisible || !hitRules.requireVisible) {
         if (hitRules.canHitBoundingBox
-            || (hitRules.canHitStroke && (renderer()->style()->svgStyle()->hasStroke() || !hitRules.requireStroke))
-            || (hitRules.canHitFill && (renderer()->style()->svgStyle()->hasFill() || !hitRules.requireFill))) {
+            || (hitRules.canHitStroke && (renderer().style()->svgStyle()->hasStroke() || !hitRules.requireStroke))
+            || (hitRules.canHitFill && (renderer().style()->svgStyle()->hasFill() || !hitRules.requireFill))) {
             FloatPoint boxOrigin(x(), y());
             boxOrigin.moveBy(accumulatedOffset);
             FloatRect rect(boxOrigin, size());
             if (locationInContainer.intersects(rect)) {
-                renderer()->updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
-                if (!result.addNodeToRectBasedTestResult(renderer()->node(), request, locationInContainer, rect))
+                renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(accumulatedOffset));
+                if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, rect))
                     return true;
              }
         }
diff --git a/Source/core/rendering/svg/SVGInlineTextBox.h b/Source/core/rendering/svg/SVGInlineTextBox.h
index 2dfc2a8..a146ad8 100644
--- a/Source/core/rendering/svg/SVGInlineTextBox.h
+++ b/Source/core/rendering/svg/SVGInlineTextBox.h
@@ -32,7 +32,7 @@
 
 class SVGInlineTextBox FINAL : public InlineTextBox {
 public:
-    SVGInlineTextBox(RenderObject*);
+    SVGInlineTextBox(RenderObject&);
 
     virtual bool isSVGInlineTextBox() const OVERRIDE { return true; }
 
diff --git a/Source/core/rendering/svg/SVGRenderSupport.cpp b/Source/core/rendering/svg/SVGRenderSupport.cpp
index a9676a0..34dc6e6 100644
--- a/Source/core/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/core/rendering/svg/SVGRenderSupport.cpp
@@ -67,8 +67,6 @@
 
 void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, const RenderLayerModelObject* repaintContainer, TransformState& transformState, bool* wasFixed)
 {
-    transformState.applyTransform(object->localToParentTransform());
-
     RenderObject* parent = object->parent();
 
     // At the SVG/HTML boundary (aka RenderSVGRoot), we apply the localToBorderBoxTransform
@@ -77,6 +75,8 @@
     if (parent->isSVGRoot())
         transformState.applyTransform(toRenderSVGRoot(parent)->localToBorderBoxTransform());
 
+    transformState.applyTransform(object->localToParentTransform());
+
     MapCoordinatesFlags mode = UseTransforms;
     parent->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
 }
@@ -140,13 +140,9 @@
             continue;
 
         const AffineTransform& transform = current->localToParentTransform();
-        if (transform.isIdentity()) {
-            updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox());
-            strokeBoundingBox.unite(current->repaintRectInLocalCoordinates());
-        } else {
-            updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, transform.mapRect(current->objectBoundingBox()));
-            strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
-        }
+        updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current,
+            transform.mapRect(current->objectBoundingBox()));
+        strokeBoundingBox.unite(transform.mapRect(current->repaintRectInLocalCoordinates()));
     }
 
     repaintBoundingBox = strokeBoundingBox;
@@ -154,9 +150,6 @@
 
 bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo)
 {
-    if (localTransform.isIdentity())
-        return localRepaintRect.intersects(paintInfo.rect);
-
     return localTransform.mapRect(localRepaintRect).intersects(paintInfo.rect);
 }
 
@@ -396,21 +389,13 @@
         return;
 
     DashArray dashArray;
-    size_t length = dashes->numberOfItems();
+    size_t length = dashes->length();
     for (size_t i = 0; i < length; ++i)
         dashArray.append(dashes->at(i)->value(lengthContext));
 
     strokeData->setLineDash(dashArray, svgStyle->strokeDashOffset()->value(lengthContext));
 }
 
-bool SVGRenderSupport::isEmptySVGInlineText(const RenderObject* object)
-{
-    // RenderSVGInlineText performs whitespace filtering in order to support xml:space
-    // (http://www.w3.org/TR/SVG/struct.html#LangSpaceAttrs), and can end up with an empty string
-    // even when its original constructor argument is non-empty.
-    return object->isSVGInlineText() && toRenderSVGInlineText(object)->hasEmptyText();
-}
-
 bool SVGRenderSupport::isRenderableTextNode(const RenderObject* object)
 {
     ASSERT(object->isText());
diff --git a/Source/core/rendering/svg/SVGRenderSupport.h b/Source/core/rendering/svg/SVGRenderSupport.h
index cf5a005..fc80a7c 100644
--- a/Source/core/rendering/svg/SVGRenderSupport.h
+++ b/Source/core/rendering/svg/SVGRenderSupport.h
@@ -40,59 +40,50 @@
 class RenderSVGRoot;
 class TransformState;
 
-// SVGRendererSupport is a helper class sharing code between all SVG renderers.
-class SVGRenderSupport {
-public:
-    // Shares child layouting code between RenderSVGRoot/RenderSVG(Hidden)Container
-    static void layoutChildren(RenderObject*, bool selfNeedsLayout);
+namespace SVGRenderSupport {
+// Shares child layouting code between RenderSVGRoot/RenderSVG(Hidden)Container
+void layoutChildren(RenderObject*, bool selfNeedsLayout);
 
-    // Layout resources used by this node.
-    static void layoutResourcesIfNeeded(const RenderObject*);
+// Layout resources used by this node.
+void layoutResourcesIfNeeded(const RenderObject*);
 
-    // Helper function determining wheter overflow is hidden
-    static bool isOverflowHidden(const RenderObject*);
+// Helper function determining wheter overflow is hidden
+bool isOverflowHidden(const RenderObject*);
 
-    // Calculates the repaintRect in combination with filter, clipper and masker in local coordinates.
-    static void intersectRepaintRectWithResources(const RenderObject*, FloatRect&);
+// Calculates the repaintRect in combination with filter, clipper and masker in local coordinates.
+void intersectRepaintRectWithResources(const RenderObject*, FloatRect&);
 
-    // Determines whether a container needs to be laid out because it's filtered and a child is being laid out.
-    static bool filtersForceContainerLayout(RenderObject*);
+// Determines whether a container needs to be laid out because it's filtered and a child is being laid out.
+bool filtersForceContainerLayout(RenderObject*);
 
-    // Determines whether the passed point lies in a clipping area
-    static bool pointInClippingArea(RenderObject*, const FloatPoint&);
+// Determines whether the passed point lies in a clipping area
+bool pointInClippingArea(RenderObject*, const FloatPoint&);
 
-    static void computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox);
-    static bool paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo&);
+void computeContainerBoundingBoxes(const RenderObject* container, FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, FloatRect& strokeBoundingBox, FloatRect& repaintBoundingBox);
+bool paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo&);
 
-    // Important functions used by nearly all SVG renderers centralizing coordinate transformations / repaint rect calculations
-    static LayoutRect clippedOverflowRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer);
-    static void computeFloatRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed);
-    static void mapLocalToContainer(const RenderObject*, const RenderLayerModelObject* repaintContainer, TransformState&, bool* wasFixed = 0);
-    static const RenderObject* pushMappingToContainer(const RenderObject*, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&);
-    static bool checkForSVGRepaintDuringLayout(RenderObject*);
+// Important functions used by nearly all SVG renderers centralizing coordinate transformations / repaint rect calculations
+LayoutRect clippedOverflowRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer);
+void computeFloatRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed);
+void mapLocalToContainer(const RenderObject*, const RenderLayerModelObject* repaintContainer, TransformState&, bool* wasFixed = 0);
+const RenderObject* pushMappingToContainer(const RenderObject*, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&);
+bool checkForSVGRepaintDuringLayout(RenderObject*);
 
-    // Shared between SVG renderers and resources.
-    static void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
-    static void applyStrokeStyleToStrokeData(StrokeData*, const RenderStyle*, const RenderObject*);
+// Shared between SVG renderers and resources.
+void applyStrokeStyleToContext(GraphicsContext*, const RenderStyle*, const RenderObject*);
+void applyStrokeStyleToStrokeData(StrokeData*, const RenderStyle*, const RenderObject*);
 
-    // Determines if any ancestor's transform has changed.
-    static bool transformToRootChanged(RenderObject*);
+// Determines if any ancestor's transform has changed.
+bool transformToRootChanged(RenderObject*);
 
-    // FIXME: These methods do not belong here.
-    static const RenderSVGRoot* findTreeRootObject(const RenderObject*);
+// FIXME: These methods do not belong here.
+const RenderSVGRoot* findTreeRootObject(const RenderObject*);
 
-    // Helper method for determining whether an RenderSVGInlineText object has zero length text.
-    static bool isEmptySVGInlineText(const RenderObject*);
+// Helper method for determining if a RenderObject marked as text (isText()== true)
+// can/will be rendered as part of a <text>.
+bool isRenderableTextNode(const RenderObject*);
 
-    // Helper method for determining if a RenderObject marked as text (isText()== true)
-    // can/will be rendered as part of a <text>.
-    static bool isRenderableTextNode(const RenderObject*);
-
-private:
-    // This class is not constructable.
-    SVGRenderSupport();
-    ~SVGRenderSupport();
-};
+} // namespace SVGRenderSupport
 
 } // namespace WebCore
 
diff --git a/Source/core/rendering/svg/SVGRenderTreeAsText.cpp b/Source/core/rendering/svg/SVGRenderTreeAsText.cpp
index 0057e85..bff3488 100644
--- a/Source/core/rendering/svg/SVGRenderTreeAsText.cpp
+++ b/Source/core/rendering/svg/SVGRenderTreeAsText.cpp
@@ -154,15 +154,35 @@
     return ts;
 }
 
+namespace {
+
+template<typename Enum>
+String SVGEnumerationToString(Enum value)
+{
+    const SVGEnumerationStringEntries& entries = getStaticStringEntries<Enum>();
+
+    SVGEnumerationStringEntries::const_iterator it = entries.begin();
+    SVGEnumerationStringEntries::const_iterator itEnd = entries.end();
+    for (; it != itEnd; ++it) {
+        if (value == it->first)
+            return it->second;
+    }
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+}
+
 static TextStream& operator<<(TextStream& ts, const SVGUnitTypes::SVGUnitType& unitType)
 {
-    ts << SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::toString(unitType);
+    ts << SVGEnumerationToString<SVGUnitTypes::SVGUnitType>(unitType);
     return ts;
 }
 
 static TextStream& operator<<(TextStream& ts, const SVGMarkerUnitsType& markerUnit)
 {
-    ts << SVGPropertyTraits<SVGMarkerUnitsType>::toString(markerUnit);
+    ts << SVGEnumerationToString<SVGMarkerUnitsType>(markerUnit);
     return ts;
 }
 
@@ -221,7 +241,7 @@
 
 static TextStream& operator<<(TextStream& ts, const SVGSpreadMethodType& type)
 {
-    ts << SVGPropertyTraits<SVGSpreadMethodType>::toString(type).upper();
+    ts << SVGEnumerationToString<SVGSpreadMethodType>(type).upper();
     return ts;
 }
 
@@ -318,37 +338,38 @@
     writePositionAndStyle(ts, shape);
 
     SVGElement* svgElement = shape.element();
+    ASSERT(svgElement);
     SVGLengthContext lengthContext(svgElement);
 
-    if (svgElement->hasTagName(SVGNames::rectTag)) {
-        SVGRectElement* element = toSVGRectElement(svgElement);
-        writeNameValuePair(ts, "x", element->x()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "y", element->y()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "width", element->width()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "height", element->height()->currentValue()->value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::lineTag)) {
-        SVGLineElement* element = toSVGLineElement(svgElement);
-        writeNameValuePair(ts, "x1", element->x1()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "y1", element->y1()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "x2", element->x2()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "y2", element->y2()->currentValue()->value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::ellipseTag)) {
-        SVGEllipseElement* element = toSVGEllipseElement(svgElement);
-        writeNameValuePair(ts, "cx", element->cx()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "cy", element->cy()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "rx", element->rx()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "ry", element->ry()->currentValue()->value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::circleTag)) {
-        SVGCircleElement* element = toSVGCircleElement(svgElement);
-        writeNameValuePair(ts, "cx", element->cx()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "cy", element->cy()->currentValue()->value(lengthContext));
-        writeNameValuePair(ts, "r", element->r()->currentValue()->value(lengthContext));
-    } else if (svgElement->hasTagName(SVGNames::polygonTag) || svgElement->hasTagName(SVGNames::polylineTag)) {
-        writeNameAndQuotedValue(ts, "points", toSVGPolyElement(svgElement)->points()->currentValue()->valueAsString());
-    } else if (svgElement->hasTagName(SVGNames::pathTag)) {
+    if (isSVGRectElement(*svgElement)) {
+        SVGRectElement& element = toSVGRectElement(*svgElement);
+        writeNameValuePair(ts, "x", element.x()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "y", element.y()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "width", element.width()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "height", element.height()->currentValue()->value(lengthContext));
+    } else if (isSVGLineElement(*svgElement)) {
+        SVGLineElement& element = toSVGLineElement(*svgElement);
+        writeNameValuePair(ts, "x1", element.x1()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "y1", element.y1()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "x2", element.x2()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "y2", element.y2()->currentValue()->value(lengthContext));
+    } else if (isSVGEllipseElement(*svgElement)) {
+        SVGEllipseElement& element = toSVGEllipseElement(*svgElement);
+        writeNameValuePair(ts, "cx", element.cx()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "cy", element.cy()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "rx", element.rx()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "ry", element.ry()->currentValue()->value(lengthContext));
+    } else if (isSVGCircleElement(*svgElement)) {
+        SVGCircleElement& element = toSVGCircleElement(*svgElement);
+        writeNameValuePair(ts, "cx", element.cx()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "cy", element.cy()->currentValue()->value(lengthContext));
+        writeNameValuePair(ts, "r", element.r()->currentValue()->value(lengthContext));
+    } else if (isSVGPolyElement(*svgElement)) {
+        writeNameAndQuotedValue(ts, "points", toSVGPolyElement(*svgElement).points()->currentValue()->valueAsString());
+    } else if (isSVGPathElement(*svgElement)) {
         String pathString;
         // FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests.
-        buildStringFromByteStream(toSVGPathElement(svgElement)->pathByteStream(), pathString, NormalizedParsing);
+        buildStringFromByteStream(toSVGPathElement(*svgElement).pathByteStream(), pathString, NormalizedParsing);
         writeNameAndQuotedValue(ts, "data", pathString);
     } else
         ASSERT_NOT_REACHED();
@@ -381,11 +402,10 @@
     if (fragments.isEmpty())
         return;
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(textBox->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(textBox->textRenderer());
 
-    const SVGRenderStyle* svgStyle = textRenderer->style()->svgStyle();
-    String text = textBox->textRenderer()->text();
+    const SVGRenderStyle* svgStyle = textRenderer.style()->svgStyle();
+    String text = textBox->textRenderer().text();
 
     unsigned fragmentsSize = fragments.size();
     for (unsigned i = 0; i < fragmentsSize; ++i) {
diff --git a/Source/core/rendering/svg/SVGRenderingContext.cpp b/Source/core/rendering/svg/SVGRenderingContext.cpp
index a699609..7928a7c 100644
--- a/Source/core/rendering/svg/SVGRenderingContext.cpp
+++ b/Source/core/rendering/svg/SVGRenderingContext.cpp
@@ -26,9 +26,9 @@
 
 #include "core/rendering/svg/SVGRenderingContext.h"
 
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "core/rendering/RenderLayer.h"
 #include "core/rendering/svg/RenderSVGImage.h"
diff --git a/Source/core/rendering/svg/SVGResources.cpp b/Source/core/rendering/svg/SVGResources.cpp
index 22059f2..f59ad85 100644
--- a/Source/core/rendering/svg/SVGResources.cpp
+++ b/Source/core/rendering/svg/SVGResources.cpp
@@ -137,19 +137,19 @@
     return s_tagList;
 }
 
-static inline AtomicString targetReferenceFromResource(SVGElement* element)
+static inline AtomicString targetReferenceFromResource(SVGElement& element)
 {
     String target;
-    if (element->hasTagName(SVGNames::patternTag))
-        target = toSVGPatternElement(element)->href()->currentValue()->value();
-    else if (element->hasTagName(SVGNames::linearGradientTag) || element->hasTagName(SVGNames::radialGradientTag))
-        target = toSVGGradientElement(element)->href()->currentValue()->value();
-    else if (element->hasTagName(SVGNames::filterTag))
-        target = toSVGFilterElement(element)->href()->currentValue()->value();
+    if (isSVGPatternElement(element))
+        target = toSVGPatternElement(element).href()->currentValue()->value();
+    else if (isSVGGradientElement(element))
+        target = toSVGGradientElement(element).href()->currentValue()->value();
+    else if (isSVGFilterElement(element))
+        target = toSVGFilterElement(element).href()->currentValue()->value();
     else
         ASSERT_NOT_REACHED();
 
-    return SVGURIReference::fragmentIdentifierFromIRIString(target, element->document());
+    return SVGURIReference::fragmentIdentifierFromIRIString(target, element.document());
 }
 
 static inline bool svgPaintTypeHasURL(SVGPaint::SVGPaintType paintType)
@@ -186,10 +186,10 @@
     return container;
 }
 
-static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, SVGElement* element)
+static inline void registerPendingResource(SVGDocumentExtensions& extensions, const AtomicString& id, SVGElement* element)
 {
     ASSERT(element);
-    extensions->addPendingResource(id, element);
+    extensions.addPendingResource(id, element);
 }
 
 bool SVGResources::hasResourceData() const
@@ -223,8 +223,7 @@
 
     Document& document = object->document();
 
-    SVGDocumentExtensions* extensions = document.accessSVGExtensions();
-    ASSERT(extensions);
+    SVGDocumentExtensions& extensions = document.accessSVGExtensions();
 
     const AtomicString& tagName = element->localName();
     if (tagName.isNull())
@@ -286,7 +285,7 @@
     }
 
     if (chainableResourceTags().contains(tagName)) {
-        AtomicString id = targetReferenceFromResource(element);
+        AtomicString id = targetReferenceFromResource(*element);
         if (!ensureResources(resources)->setLinkedResource(getRenderSVGResourceContainerById(document, id)))
             registerPendingResource(extensions, id, element);
     }
diff --git a/Source/core/rendering/svg/SVGResourcesCache.cpp b/Source/core/rendering/svg/SVGResourcesCache.cpp
index f0a3365..c5cc3dc 100644
--- a/Source/core/rendering/svg/SVGResourcesCache.cpp
+++ b/Source/core/rendering/svg/SVGResourcesCache.cpp
@@ -85,10 +85,8 @@
 {
     Document& document = renderer->document();
 
-    SVGDocumentExtensions* extensions = document.accessSVGExtensions();
-    ASSERT(extensions);
-
-    SVGResourcesCache* cache = extensions->resourcesCache();
+    SVGDocumentExtensions& extensions = document.accessSVGExtensions();
+    SVGResourcesCache* cache = extensions.resourcesCache();
     ASSERT(cache);
 
     return cache;
@@ -194,9 +192,9 @@
         // Mark users of destroyed resources as pending resolution based on the id of the old resource.
         Element* resourceElement = resource->element();
         Element* clientElement = toElement(it->key->node());
-        SVGDocumentExtensions* extensions = clientElement->document().accessSVGExtensions();
+        SVGDocumentExtensions& extensions = clientElement->document().accessSVGExtensions();
 
-        extensions->addPendingResource(resourceElement->fastGetAttribute(HTMLNames::idAttr), clientElement);
+        extensions.addPendingResource(resourceElement->fastGetAttribute(HTMLNames::idAttr), clientElement);
     }
 }
 
diff --git a/Source/core/rendering/svg/SVGRootInlineBox.cpp b/Source/core/rendering/svg/SVGRootInlineBox.cpp
index 04284b6..9b236b6 100644
--- a/Source/core/rendering/svg/SVGRootInlineBox.cpp
+++ b/Source/core/rendering/svg/SVGRootInlineBox.cpp
@@ -38,10 +38,7 @@
     ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
     ASSERT(!paintInfo.context->paintingDisabled());
 
-    RenderObject* boxRenderer = renderer();
-    ASSERT(boxRenderer);
-
-    bool isPrinting = renderer()->document().printing();
+    bool isPrinting = renderer().document().printing();
     bool hasSelection = !isPrinting && selectionState() != RenderObject::SelectionNone;
 
     PaintInfo childPaintInfo(paintInfo);
@@ -54,7 +51,7 @@
         }
     }
 
-    SVGRenderingContext renderingContext(boxRenderer, paintInfo, SVGRenderingContext::SaveGraphicsContext);
+    SVGRenderingContext renderingContext(&renderer(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
     if (renderingContext.isRenderingPrepared()) {
         for (InlineBox* child = firstChild(); child; child = child->nextOnLine())
             child->paint(paintInfo, paintOffset, 0, 0);
@@ -71,14 +68,13 @@
 
 void SVGRootInlineBox::computePerCharacterLayoutInformation()
 {
-    RenderSVGText* textRoot = toRenderSVGText(block());
-    ASSERT(textRoot);
+    RenderSVGText& textRoot = toRenderSVGText(block());
 
-    Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot->layoutAttributes();
+    Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot.layoutAttributes();
     if (layoutAttributes.isEmpty())
         return;
 
-    if (textRoot->needsReordering())
+    if (textRoot.needsReordering())
         reorderValueLists(layoutAttributes);
 
     // Perform SVG text layout phase two (see SVGTextLayoutEngine for details).
@@ -99,24 +95,23 @@
 {
     for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
         if (child->isSVGInlineTextBox()) {
-            ASSERT(child->renderer());
-            ASSERT(child->renderer()->isSVGInlineText());
+            ASSERT(child->renderer().isSVGInlineText());
             characterLayout.layoutInlineTextBox(toSVGInlineTextBox(child));
         } else {
             // Skip generated content.
-            Node* node = child->renderer()->node();
+            Node* node = child->renderer().node();
             if (!node)
                 continue;
 
             SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
-            bool isTextPath = node->hasTagName(SVGNames::textPathTag);
+            bool isTextPath = isSVGTextPathElement(*node);
             if (isTextPath) {
                 // Build text chunks for all <textPath> children, using the line layout algorithm.
                 // This is needeed as text-anchor is just an additional startOffset for text paths.
                 SVGTextLayoutEngine lineLayout(characterLayout.layoutAttributes());
                 layoutCharactersInTextBoxes(flowBox, lineLayout);
 
-                characterLayout.beginTextPathLayout(child->renderer(), lineLayout);
+                characterLayout.beginTextPathLayout(&child->renderer(), lineLayout);
             }
 
             layoutCharactersInTextBoxes(flowBox, characterLayout);
@@ -132,8 +127,7 @@
     for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
         FloatRect boxRect;
         if (child->isSVGInlineTextBox()) {
-            ASSERT(child->renderer());
-            ASSERT(child->renderer()->isSVGInlineText());
+            ASSERT(child->renderer().isSVGInlineText());
 
             SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
             boxRect = textBox->calculateBoundaries();
@@ -143,7 +137,7 @@
             textBox->setLogicalHeight(boxRect.height());
         } else {
             // Skip generated content.
-            if (!child->renderer()->node())
+            if (!child->renderer().node())
                 continue;
 
             SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
@@ -162,18 +156,17 @@
 
 void SVGRootInlineBox::layoutRootBox(const FloatRect& childRect)
 {
-    RenderBlockFlow* parentBlock = block();
-    ASSERT(parentBlock);
+    RenderBlockFlow& parentBlock = block();
 
     // Finally, assign the root block position, now that all content is laid out.
     LayoutRect boundingRect = enclosingLayoutRect(childRect);
-    parentBlock->setLocation(boundingRect.location());
-    parentBlock->setSize(boundingRect.size());
+    parentBlock.setLocation(boundingRect.location());
+    parentBlock.setSize(boundingRect.size());
 
     // Position all children relative to the parent block.
     for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
         // Skip generated content.
-        if (!child->renderer()->node())
+        if (!child->renderer().node())
             continue;
         child->adjustPosition(-childRect.x(), -childRect.y());
     }
@@ -217,21 +210,11 @@
     SVGCharacterDataMap::iterator itLast = lastAttributes->characterDataMap().find(lastPosition + 1);
     bool firstPresent = itFirst != firstAttributes->characterDataMap().end();
     bool lastPresent = itLast != lastAttributes->characterDataMap().end();
-    if (!firstPresent && !lastPresent)
+    // We only want to perform the swap if both inline boxes are absolutely
+    // positioned.
+    if (!firstPresent || !lastPresent)
         return;
-
-    if (firstPresent && lastPresent) {
-        std::swap(itFirst->value, itLast->value);
-        return;
-    }
-
-    if (firstPresent && !lastPresent) {
-        lastAttributes->characterDataMap().set(lastPosition + 1, itFirst->value);
-        return;
-    }
-
-    // !firstPresent && lastPresent
-    firstAttributes->characterDataMap().set(firstPosition + 1, itLast->value);
+    std::swap(itFirst->value, itLast->value);
 }
 
 static inline void findFirstAndLastAttributesInVector(Vector<SVGTextLayoutAttributes*>& attributes, RenderSVGInlineText* firstContext, RenderSVGInlineText* lastContext,
@@ -278,12 +261,12 @@
 
         // Reordering is only necessary for BiDi text that is _absolutely_ positioned.
         if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len()) {
-            RenderSVGInlineText* firstContext = toRenderSVGInlineText(firstTextBox->textRenderer());
-            RenderSVGInlineText* lastContext = toRenderSVGInlineText(lastTextBox->textRenderer());
+            RenderSVGInlineText& firstContext = toRenderSVGInlineText(firstTextBox->textRenderer());
+            RenderSVGInlineText& lastContext = toRenderSVGInlineText(lastTextBox->textRenderer());
 
             SVGTextLayoutAttributes* firstAttributes = 0;
             SVGTextLayoutAttributes* lastAttributes = 0;
-            findFirstAndLastAttributesInVector(attributes, firstContext, lastContext, firstAttributes, lastAttributes);
+            findFirstAndLastAttributesInVector(attributes, &firstContext, &lastContext, firstAttributes, lastAttributes);
             swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTextBox->start(), lastTextBox->start());
         }
 
diff --git a/Source/core/rendering/svg/SVGRootInlineBox.h b/Source/core/rendering/svg/SVGRootInlineBox.h
index 0193429..2f3ffba 100644
--- a/Source/core/rendering/svg/SVGRootInlineBox.h
+++ b/Source/core/rendering/svg/SVGRootInlineBox.h
@@ -33,7 +33,7 @@
 
 class SVGRootInlineBox FINAL : public RootInlineBox {
 public:
-    SVGRootInlineBox(RenderBlockFlow* block)
+    SVGRootInlineBox(RenderBlockFlow& block)
         : RootInlineBox(block)
         , m_logicalHeight(0)
     {
diff --git a/Source/core/rendering/svg/SVGTextChunkBuilder.cpp b/Source/core/rendering/svg/SVGTextChunkBuilder.cpp
index 3c64a64..488fbd4 100644
--- a/Source/core/rendering/svg/SVGTextChunkBuilder.cpp
+++ b/Source/core/rendering/svg/SVGTextChunkBuilder.cpp
@@ -91,10 +91,9 @@
     SVGInlineTextBox* textBox = lineLayoutBoxes[boxStart];
     ASSERT(textBox);
 
-    RenderSVGInlineText* textRenderer = toRenderSVGInlineText(textBox->textRenderer());
-    ASSERT(textRenderer);
+    RenderSVGInlineText& textRenderer = toRenderSVGInlineText(textBox->textRenderer());
 
-    const RenderStyle* style = textRenderer->style();
+    const RenderStyle* style = toRenderSVGInlineText(textBox->textRenderer()).style();
     ASSERT(style);
 
     const SVGRenderStyle* svgStyle = style->svgStyle();
@@ -125,14 +124,14 @@
 
     // Handle 'lengthAdjust' property.
     float desiredTextLength = 0;
-    if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textRenderer->parent())) {
+    if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textRenderer.parent())) {
         SVGLengthContext lengthContext(textContentElement);
         if (textContentElement->textLengthIsSpecifiedByUser())
             desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext);
         else
             desiredTextLength = 0;
 
-        switch (textContentElement->lengthAdjustCurrentValue()) {
+        switch (textContentElement->lengthAdjust()->currentValue()->enumValue()) {
         case SVGLengthAdjustUnknown:
             break;
         case SVGLengthAdjustSpacing:
diff --git a/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp b/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
index 778acbc..35811eb 100644
--- a/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
+++ b/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
@@ -23,6 +23,7 @@
 
 #include "core/rendering/svg/RenderSVGInlineText.h"
 #include "core/rendering/svg/RenderSVGText.h"
+#include "core/rendering/svg/SVGTextMetricsBuilder.h"
 #include "core/svg/SVGTextPositioningElement.h"
 
 namespace WebCore {
@@ -53,7 +54,7 @@
         buildCharacterDataMap(textRoot);
     }
 
-    m_metricsBuilder.buildMetricsAndLayoutAttributes(textRoot, text, m_characterDataMap);
+    SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(textRoot, text, m_characterDataMap);
 }
 
 bool SVGTextLayoutAttributesBuilder::buildLayoutAttributesForForSubtree(RenderSVGText* textRoot)
@@ -72,14 +73,14 @@
         return false;
 
     buildCharacterDataMap(textRoot);
-    m_metricsBuilder.buildMetricsAndLayoutAttributes(textRoot, 0, m_characterDataMap);
+    SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(textRoot, 0, m_characterDataMap);
     return true;
 }
 
 void SVGTextLayoutAttributesBuilder::rebuildMetricsForTextRenderer(RenderSVGInlineText* text)
 {
     ASSERT(text);
-    m_metricsBuilder.measureTextRenderer(text);
+    SVGTextMetricsBuilder::measureTextRenderer(text);
 }
 
 static inline void processRenderSVGInlineText(RenderSVGInlineText* text, unsigned& atCharacter, UChar& lastCharacter)
@@ -184,11 +185,11 @@
     RefPtr<SVGLengthList> dyList = position.element->dy()->currentValue();
     RefPtr<SVGNumberList> rotateList = position.element->rotate()->currentValue();
 
-    unsigned xListSize = xList->numberOfItems();
-    unsigned yListSize = yList->numberOfItems();
-    unsigned dxListSize = dxList->numberOfItems();
-    unsigned dyListSize = dyList->numberOfItems();
-    unsigned rotateListSize = rotateList->numberOfItems();
+    unsigned xListSize = xList->length();
+    unsigned yListSize = yList->length();
+    unsigned dxListSize = dxList->length();
+    unsigned dyListSize = dyList->length();
+    unsigned rotateListSize = rotateList->length();
     if (!xListSize && !yListSize && !dxListSize && !dyListSize && !rotateListSize)
         return;
 
@@ -218,7 +219,7 @@
     if (lastRotation == SVGTextLayoutAttributes::emptyValue())
         return;
 
-    for (unsigned i = rotateList->numberOfItems(); i < position.length; ++i) {
+    for (unsigned i = rotateList->length(); i < position.length; ++i) {
         SVGCharacterDataMap::iterator it = m_characterDataMap.find(position.start + i + 1);
         if (it == m_characterDataMap.end()) {
             SVGCharacterData data;
diff --git a/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h b/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h
index d92c125..82d2d06 100644
--- a/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h
+++ b/Source/core/rendering/svg/SVGTextLayoutAttributesBuilder.h
@@ -20,7 +20,7 @@
 #ifndef SVGTextLayoutAttributesBuilder_h
 #define SVGTextLayoutAttributesBuilder_h
 
-#include "core/rendering/svg/SVGTextMetricsBuilder.h"
+#include "core/rendering/svg/SVGTextLayoutAttributes.h"
 #include "wtf/Vector.h"
 
 namespace WebCore {
@@ -73,7 +73,6 @@
     unsigned m_textLength;
     Vector<TextPosition> m_textPositions;
     SVGCharacterDataMap m_characterDataMap;
-    SVGTextMetricsBuilder m_metricsBuilder;
 };
 
 } // namespace WebCore
diff --git a/Source/core/rendering/svg/SVGTextLayoutEngine.cpp b/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
index ba2e95f..f74577a 100644
--- a/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
+++ b/Source/core/rendering/svg/SVGTextLayoutEngine.cpp
@@ -149,7 +149,7 @@
     while (currentParent) {
         if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(currentParent)) {
             SVGLengthContext lengthContext(textContentElement);
-            if (textContentElement->lengthAdjustCurrentValue() == SVGLengthAdjustSpacing && textContentElement->textLengthIsSpecifiedByUser())
+            if (textContentElement->lengthAdjust()->currentValue()->enumValue() == SVGLengthAdjustSpacing && textContentElement->textLengthIsSpecifiedByUser())
                 return true;
         }
 
@@ -208,7 +208,7 @@
 
     if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textPath)) {
         SVGLengthContext lengthContext(textContentElement);
-        lengthAdjust = textContentElement->lengthAdjustCurrentValue();
+        lengthAdjust = textContentElement->lengthAdjust()->currentValue()->enumValue();
         if (textContentElement->textLengthIsSpecifiedByUser())
             desiredTextLength = textContentElement->textLength()->currentValue()->value(lengthContext);
         else
@@ -240,18 +240,17 @@
 {
     ASSERT(textBox);
 
-    RenderSVGInlineText* text = toRenderSVGInlineText(textBox->textRenderer());
-    ASSERT(text);
-    ASSERT(text->parent());
-    ASSERT(text->parent()->node());
-    ASSERT(text->parent()->node()->isSVGElement());
+    RenderSVGInlineText& text = toRenderSVGInlineText(textBox->textRenderer());
+    ASSERT(text.parent());
+    ASSERT(text.parent()->node());
+    ASSERT(text.parent()->node()->isSVGElement());
 
-    const RenderStyle* style = text->style();
+    const RenderStyle* style = text.style();
     ASSERT(style);
 
     textBox->clearTextFragments();
     m_isVerticalText = style->svgStyle()->isVerticalWritingMode();
-    layoutTextOnLineOrPath(textBox, text, style);
+    layoutTextOnLineOrPath(textBox, &text, style);
 
     if (m_inPathLayout) {
         m_pathLayoutBoxes.append(textBox);
diff --git a/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp b/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp
index 282d5bc..3968338 100644
--- a/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.cpp
@@ -37,15 +37,18 @@
 SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const Font& font)
     : m_font(font)
     , m_lastCharacter(0)
+#if ENABLE(SVG_FONTS)
+    , m_lastGlyph(0)
+#endif
 {
 }
 
-float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const SVGTextMetrics::Glyph& currentGlyph)
+float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, Glyph currentGlyph)
 {
 #if ENABLE(SVG_FONTS)
     const SimpleFontData* fontData = m_font.primaryFont();
     if (!fontData->isSVGFont()) {
-        m_lastGlyph.isValid = false;
+        m_lastGlyph = 0;
         return 0;
     }
 
@@ -59,24 +62,24 @@
 
     SVGFontElement* svgFont = svgFontFace->associatedFontElement();
     if (!svgFont) {
-        m_lastGlyph.isValid = false;
+        m_lastGlyph = 0;
         return 0;
     }
 
     float kerning = 0;
-    if (m_lastGlyph.isValid) {
+    if (m_lastGlyph) {
         if (isVerticalText)
-            kerning = svgFont->verticalKerningForPairOfStringsAndGlyphs(m_lastGlyph.unicodeString, m_lastGlyph.name, currentGlyph.unicodeString, currentGlyph.name);
+            kerning = svgFont->verticalKerningForPairOfGlyphs(m_lastGlyph, currentGlyph);
         else
-            kerning = svgFont->horizontalKerningForPairOfStringsAndGlyphs(m_lastGlyph.unicodeString, m_lastGlyph.name, currentGlyph.unicodeString, currentGlyph.name);
+            kerning = svgFont->horizontalKerningForPairOfGlyphs(m_lastGlyph, currentGlyph);
+
+        kerning *= m_font.fontDescription().computedSize() / m_font.fontMetrics().unitsPerEm();
     }
 
     m_lastGlyph = currentGlyph;
-    m_lastGlyph.isValid = true;
-    kerning *= m_font.fontDescription().computedSize() / m_font.fontMetrics().unitsPerEm();
     return kerning;
 #else
-    return false;
+    return 0;
 #endif
 }
 
diff --git a/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h b/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h
index 5cc8bec..3db5846 100644
--- a/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h
+++ b/Source/core/rendering/svg/SVGTextLayoutEngineSpacing.h
@@ -34,7 +34,7 @@
 public:
     SVGTextLayoutEngineSpacing(const Font&);
 
-    float calculateSVGKerning(bool isVerticalText, const SVGTextMetrics::Glyph& currentGlyph);
+    float calculateSVGKerning(bool isVerticalText, Glyph currentGlyph);
     float calculateCSSKerningAndSpacing(const SVGRenderStyle*, SVGElement* lengthContext, UChar currentCharacter);
 
 private:
@@ -42,7 +42,7 @@
     UChar m_lastCharacter;
 
 #if ENABLE(SVG_FONTS)
-    SVGTextMetrics::Glyph m_lastGlyph;
+    Glyph m_lastGlyph;
 #endif
 };
 
diff --git a/Source/core/rendering/svg/SVGTextMetrics.cpp b/Source/core/rendering/svg/SVGTextMetrics.cpp
index 26c82db..e9bacb4 100644
--- a/Source/core/rendering/svg/SVGTextMetrics.cpp
+++ b/Source/core/rendering/svg/SVGTextMetrics.cpp
@@ -30,6 +30,7 @@
     : m_width(0)
     , m_height(0)
     , m_length(0)
+    , m_glyph(0)
 {
 }
 
@@ -37,6 +38,7 @@
     : m_width(0)
     , m_height(0)
     , m_length(1)
+    , m_glyph(0)
 {
 }
 
@@ -51,12 +53,9 @@
     int length = 0;
 
     // Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
-    m_width = scaledFont.width(run, length, m_glyph.name) / scalingFactor;
+    m_width = scaledFont.width(run, length, m_glyph) / scalingFactor;
     m_height = scaledFont.fontMetrics().floatHeight() / scalingFactor;
 
-    m_glyph.unicodeString = run.is8Bit() ? String(run.characters8(), length) : String(run.characters16(), length);
-    m_glyph.isValid = true;
-
     ASSERT(length >= 0);
     m_length = static_cast<unsigned>(length);
 }
@@ -101,7 +100,7 @@
     return SVGTextMetrics(text, constructTextRun(text, position, length));
 }
 
-SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, unsigned length, float width, const String& glyphName)
+SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, unsigned length, float width, Glyph glyphNameGlyphId)
 {
     ASSERT(text);
 
@@ -111,11 +110,7 @@
 
     m_width = width / scalingFactor;
     m_height = text->scaledFont().fontMetrics().floatHeight() / scalingFactor;
-    if (needsContext) {
-        m_glyph.isValid = true;
-        m_glyph.unicodeString = text->substring(position, length);
-        m_glyph.name = glyphName;
-    }
+    m_glyph = needsContext ? glyphNameGlyphId : 0;
 
     m_length = length;
 }
diff --git a/Source/core/rendering/svg/SVGTextMetrics.h b/Source/core/rendering/svg/SVGTextMetrics.h
index 3629339..8c3bb26 100644
--- a/Source/core/rendering/svg/SVGTextMetrics.h
+++ b/Source/core/rendering/svg/SVGTextMetrics.h
@@ -20,6 +20,7 @@
 #ifndef SVGTextMetrics_h
 #define SVGTextMetrics_h
 
+#include "platform/fonts/Glyph.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
@@ -36,12 +37,12 @@
 
     SVGTextMetrics();
     SVGTextMetrics(MetricsType);
-    SVGTextMetrics(RenderSVGInlineText*, unsigned position, unsigned length, float width, const String& glyphName);
+    SVGTextMetrics(RenderSVGInlineText*, unsigned position, unsigned length, float width, Glyph glyphNameGlyphId);
 
     static SVGTextMetrics measureCharacterRange(RenderSVGInlineText*, unsigned position, unsigned length);
     static TextRun constructTextRun(RenderSVGInlineText*, unsigned position, unsigned length);
 
-    bool isEmpty() const { return !m_width && !m_height && !m_glyph.isValid && m_length == 1; }
+    bool isEmpty() const { return !m_width && !m_height && m_length <= 1; }
 
     float width() const { return m_width; }
     void setWidth(float width) { m_width = width; }
@@ -49,19 +50,8 @@
     float height() const { return m_height; }
     unsigned length() const { return m_length; }
 
-    struct Glyph {
-        Glyph()
-            : isValid(false)
-        {
-        }
-
-        bool isValid;
-        String name;
-        String unicodeString;
-    };
-
     // Only useful when measuring individual characters, to lookup ligatures.
-    const Glyph& glyph() const { return m_glyph; }
+    Glyph glyph() const { return m_glyph; }
 
 private:
     SVGTextMetrics(RenderSVGInlineText*, const TextRun&);
diff --git a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
index 55dc71f..5bac22f 100644
--- a/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
+++ b/Source/core/rendering/svg/SVGTextMetricsBuilder.cpp
@@ -23,187 +23,185 @@
 
 #include "core/rendering/svg/RenderSVGInlineText.h"
 #include "core/rendering/svg/RenderSVGText.h"
+#include "core/rendering/svg/SVGTextMetrics.h"
+#include "platform/fonts/WidthIterator.h"
 #include "platform/text/TextPath.h"
+#include "platform/text/TextRun.h"
+#include "wtf/Vector.h"
 
 namespace WebCore {
 
-SVGTextMetricsBuilder::SVGTextMetricsBuilder()
-    : m_text(0)
-    , m_run(static_cast<const UChar*>(0), 0)
-    , m_textPosition(0)
+class SVGTextMetricsCalculator {
+public:
+    SVGTextMetricsCalculator(RenderSVGInlineText*);
+
+    SVGTextMetrics computeMetricsForCharacter(unsigned textPosition);
+    unsigned textLength() const { return static_cast<unsigned>(m_run.charactersLength()); }
+
+    bool characterStartsSurrogatePair(unsigned textPosition) const
+    {
+        return U16_IS_LEAD(m_run[textPosition]) && textPosition + 1 < textLength() && U16_IS_TRAIL(m_run[textPosition + 1]);
+    }
+    bool characterIsWhiteSpace(unsigned textPosition) const
+    {
+        return m_run[textPosition] == ' ';
+    }
+
+private:
+    SVGTextMetrics computeMetricsForCharacterSimple(unsigned textPosition);
+    SVGTextMetrics computeMetricsForCharacterComplex(unsigned textPosition);
+
+    RenderSVGInlineText* m_text;
+    TextRun m_run;
+    bool m_isComplexText;
+    float m_totalWidth;
+
+    // Simple text only.
+    OwnPtr<WidthIterator> m_simpleWidthIterator;
+};
+
+SVGTextMetricsCalculator::SVGTextMetricsCalculator(RenderSVGInlineText* text)
+    : m_text(text)
+    , m_run(SVGTextMetrics::constructTextRun(text, 0, text->textLength()))
     , m_isComplexText(false)
     , m_totalWidth(0)
 {
-}
-
-inline bool SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair() const
-{
-    return U16_IS_LEAD(m_run[m_textPosition]) && int(m_textPosition + 1) < m_run.charactersLength() && U16_IS_TRAIL(m_run[m_textPosition + 1]);
-}
-
-bool SVGTextMetricsBuilder::advance()
-{
-    m_textPosition += m_currentMetrics.length();
-    if (int(m_textPosition) >= m_run.charactersLength())
-        return false;
-
-    if (m_isComplexText)
-        advanceComplexText();
-    else
-        advanceSimpleText();
-
-    return m_currentMetrics.length() > 0;
-}
-
-void SVGTextMetricsBuilder::advanceSimpleText()
-{
-    GlyphBuffer glyphBuffer;
-    unsigned metricsLength = m_simpleWidthIterator->advance(m_textPosition + 1, &glyphBuffer);
-    if (!metricsLength) {
-        m_currentMetrics = SVGTextMetrics();
-        return;
-    }
-
-    float currentWidth = m_simpleWidthIterator->runWidthSoFar() - m_totalWidth;
-    m_totalWidth = m_simpleWidthIterator->runWidthSoFar();
-
-#if ENABLE(SVG_FONTS)
-    m_currentMetrics = SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, m_simpleWidthIterator->lastGlyphName());
-#else
-    m_currentMetrics = SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, emptyString());
-#endif
-}
-
-void SVGTextMetricsBuilder::advanceComplexText()
-{
-    unsigned metricsLength = currentCharacterStartsSurrogatePair() ? 2 : 1;
-    m_currentMetrics = SVGTextMetrics::measureCharacterRange(m_text, m_textPosition, metricsLength);
-    m_complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, m_textPosition + metricsLength);
-    ASSERT(m_currentMetrics.length() == metricsLength);
-
-    // Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
-    // when rendering the glyph "in context" (with it's surrounding characters) it changes due to shaping.
-    // So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is
-    // not equal to the sum of the individual lengths of the glyphs, when measuring them isolated.
-    float currentWidth = m_complexStartToCurrentMetrics.width() - m_totalWidth;
-    if (currentWidth != m_currentMetrics.width())
-        m_currentMetrics.setWidth(currentWidth);
-
-    m_totalWidth = m_complexStartToCurrentMetrics.width();
-}
-
-void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlineText* text)
-{
-    m_text = text;
-    m_textPosition = 0;
-    m_currentMetrics = SVGTextMetrics();
-    m_complexStartToCurrentMetrics = SVGTextMetrics();
-    m_totalWidth = 0;
-
     const Font& scaledFont = text->scaledFont();
-    m_run = SVGTextMetrics::constructTextRun(text, 0, text->textLength());
     CodePath codePath = scaledFont.codePath(m_run);
     m_isComplexText = codePath == ComplexPath;
     m_run.setCharacterScanForCodePath(!m_isComplexText);
 
-    if (m_isComplexText)
-        m_simpleWidthIterator.clear();
-    else
+    if (!m_isComplexText)
         m_simpleWidthIterator = adoptPtr(new WidthIterator(&scaledFont, m_run));
 }
 
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterSimple(unsigned textPosition)
+{
+    GlyphBuffer glyphBuffer;
+    unsigned metricsLength = m_simpleWidthIterator->advance(textPosition + 1, &glyphBuffer);
+    if (!metricsLength)
+        return SVGTextMetrics();
+
+    float currentWidth = m_simpleWidthIterator->runWidthSoFar() - m_totalWidth;
+    m_totalWidth = m_simpleWidthIterator->runWidthSoFar();
+
+    Glyph glyphId = glyphBuffer.glyphAt(0);
+    return SVGTextMetrics(m_text, textPosition, metricsLength, currentWidth, glyphId);
+}
+
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacterComplex(unsigned textPosition)
+{
+    unsigned metricsLength = characterStartsSurrogatePair(textPosition) ? 2 : 1;
+    SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(m_text, textPosition, metricsLength);
+    ASSERT(metrics.length() == metricsLength);
+
+    SVGTextMetrics complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, textPosition + metricsLength);
+    // Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
+    // when rendering the glyph "in context" (with it's surrounding characters) it changes due to shaping.
+    // So whenever currentWidth != currentMetrics.width(), we are processing a text run whose length is
+    // not equal to the sum of the individual lengths of the glyphs, when measuring them isolated.
+    float currentWidth = complexStartToCurrentMetrics.width() - m_totalWidth;
+    if (currentWidth != metrics.width())
+        metrics.setWidth(currentWidth);
+
+    m_totalWidth = complexStartToCurrentMetrics.width();
+    return metrics;
+}
+
+SVGTextMetrics SVGTextMetricsCalculator::computeMetricsForCharacter(unsigned textPosition)
+{
+    if (m_isComplexText)
+        return computeMetricsForCharacterComplex(textPosition);
+
+    return computeMetricsForCharacterSimple(textPosition);
+}
+
 struct MeasureTextData {
     MeasureTextData(SVGCharacterDataMap* characterDataMap)
         : allCharactersMap(characterDataMap)
-        , hasLastCharacter(false)
-        , lastCharacter(0)
-        , processRenderer(false)
+        , lastCharacterWasWhiteSpace(true)
         , valueListPosition(0)
-        , skippedCharacters(0)
     {
     }
 
     SVGCharacterDataMap* allCharactersMap;
-    bool hasLastCharacter;
-    UChar lastCharacter;
-    bool processRenderer;
+    bool lastCharacterWasWhiteSpace;
     unsigned valueListPosition;
-    unsigned skippedCharacters;
 };
 
-void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data)
+static void measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data, bool processRenderer)
 {
     ASSERT(text);
 
     SVGTextLayoutAttributes* attributes = text->layoutAttributes();
     Vector<SVGTextMetrics>* textMetricsValues = &attributes->textMetricsValues();
-    if (data->processRenderer) {
+    if (processRenderer) {
         if (data->allCharactersMap)
             attributes->clear();
         else
             textMetricsValues->clear();
     }
 
-    initializeMeasurementWithTextRenderer(text);
+    SVGTextMetricsCalculator calculator(text);
     bool preserveWhiteSpace = text->style()->whiteSpace() == PRE;
-    int surrogatePairCharacters = 0;
+    unsigned surrogatePairCharacters = 0;
+    unsigned skippedCharacters = 0;
+    unsigned textPosition = 0;
+    unsigned textLength = calculator.textLength();
 
-    while (advance()) {
-        UChar currentCharacter = m_run[m_textPosition];
-        if (currentCharacter == ' ' && !preserveWhiteSpace && (!data->hasLastCharacter || data->lastCharacter == ' ')) {
-            if (data->processRenderer)
+    SVGTextMetrics currentMetrics;
+    for (; textPosition < textLength; textPosition += currentMetrics.length()) {
+        currentMetrics = calculator.computeMetricsForCharacter(textPosition);
+        if (!currentMetrics.length())
+            break;
+
+        bool characterIsWhiteSpace = calculator.characterIsWhiteSpace(textPosition);
+        if (characterIsWhiteSpace && !preserveWhiteSpace && data->lastCharacterWasWhiteSpace) {
+            if (processRenderer)
                 textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
             if (data->allCharactersMap)
-                data->skippedCharacters += m_currentMetrics.length();
+                skippedCharacters += currentMetrics.length();
             continue;
         }
 
-        if (data->processRenderer) {
+        if (processRenderer) {
             if (data->allCharactersMap) {
-                const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + m_textPosition - data->skippedCharacters - surrogatePairCharacters + 1);
+                const SVGCharacterDataMap::const_iterator it = data->allCharactersMap->find(data->valueListPosition + textPosition - skippedCharacters - surrogatePairCharacters + 1);
                 if (it != data->allCharactersMap->end())
-                    attributes->characterDataMap().set(m_textPosition + 1, it->value);
+                    attributes->characterDataMap().set(textPosition + 1, it->value);
             }
-            textMetricsValues->append(m_currentMetrics);
+            textMetricsValues->append(currentMetrics);
         }
 
-        if (data->allCharactersMap && currentCharacterStartsSurrogatePair())
+        if (data->allCharactersMap && calculator.characterStartsSurrogatePair(textPosition))
             surrogatePairCharacters++;
 
-        data->hasLastCharacter = true;
-        data->lastCharacter = currentCharacter;
+        data->lastCharacterWasWhiteSpace = characterIsWhiteSpace;
     }
 
     if (!data->allCharactersMap)
         return;
 
-    data->valueListPosition += m_textPosition - data->skippedCharacters;
-    data->skippedCharacters = 0;
+    data->valueListPosition += textPosition - skippedCharacters;
 }
 
-void SVGTextMetricsBuilder::walkTree(RenderObject* start, RenderSVGInlineText* stopAtLeaf, MeasureTextData* data)
+static void walkTree(RenderObject* start, RenderSVGInlineText* stopAtLeaf, MeasureTextData* data)
 {
-    for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+    RenderObject* child = start->firstChild();
+    while (child) {
         if (child->isSVGInlineText()) {
             RenderSVGInlineText* text = toRenderSVGInlineText(child);
-            if (stopAtLeaf && stopAtLeaf != text) {
-                data->processRenderer = false;
-                measureTextRenderer(text, data);
+            measureTextRenderer(text, data, !stopAtLeaf || stopAtLeaf == text);
+            if (stopAtLeaf && stopAtLeaf == text)
+                return;
+        } else if (child->isSVGInline()) {
+            // Visit children of text content elements.
+            if (RenderObject* inlineChild = child->firstChild()) {
+                child = inlineChild;
                 continue;
             }
-
-            data->processRenderer = true;
-            measureTextRenderer(text, data);
-            if (stopAtLeaf)
-                return;
-
-            continue;
         }
-
-        if (!child->isSVGInline())
-            continue;
-
-        walkTree(child, stopAtLeaf, data);
+        child = child->nextInPreOrderAfterChildren(start);
     }
 }
 
diff --git a/Source/core/rendering/svg/SVGTextMetricsBuilder.h b/Source/core/rendering/svg/SVGTextMetricsBuilder.h
index 076b052..bf0c5c7 100644
--- a/Source/core/rendering/svg/SVGTextMetricsBuilder.h
+++ b/Source/core/rendering/svg/SVGTextMetricsBuilder.h
@@ -21,48 +21,18 @@
 #define SVGTextMetricsBuilder_h
 
 #include "core/rendering/svg/SVGTextLayoutAttributes.h"
-#include "core/rendering/svg/SVGTextMetrics.h"
-#include "platform/fonts/WidthIterator.h"
-#include "platform/text/TextRun.h"
-#include "wtf/Vector.h"
 
 namespace WebCore {
 
-class RenderObject;
 class RenderSVGInlineText;
 class RenderSVGText;
-struct MeasureTextData;
 
-class SVGTextMetricsBuilder {
-    WTF_MAKE_NONCOPYABLE(SVGTextMetricsBuilder);
-public:
-    SVGTextMetricsBuilder();
-    void measureTextRenderer(RenderSVGInlineText*);
-    void buildMetricsAndLayoutAttributes(RenderSVGText*, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap);
+namespace SVGTextMetricsBuilder {
 
-private:
-    bool advance();
-    void advanceSimpleText();
-    void advanceComplexText();
-    bool currentCharacterStartsSurrogatePair() const;
+void measureTextRenderer(RenderSVGInlineText*);
+void buildMetricsAndLayoutAttributes(RenderSVGText*, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap);
 
-    void initializeMeasurementWithTextRenderer(RenderSVGInlineText*);
-    void walkTree(RenderObject*, RenderSVGInlineText* stopAtLeaf, MeasureTextData*);
-    void measureTextRenderer(RenderSVGInlineText*, MeasureTextData*);
-
-    RenderSVGInlineText* m_text;
-    TextRun m_run;
-    unsigned m_textPosition;
-    bool m_isComplexText;
-    SVGTextMetrics m_currentMetrics;
-    float m_totalWidth;
-
-    // Simple text only.
-    OwnPtr<WidthIterator> m_simpleWidthIterator;
-
-    // Complex text only.
-    SVGTextMetrics m_complexStartToCurrentMetrics;
-};
+} // namespace SVGTextMetricsBuilder
 
 } // namespace WebCore
 
diff --git a/Source/core/rendering/svg/SVGTextQuery.cpp b/Source/core/rendering/svg/SVGTextQuery.cpp
index d6cf4fd..d73c2d1 100644
--- a/Source/core/rendering/svg/SVGTextQuery.cpp
+++ b/Source/core/rendering/svg/SVGTextQuery.cpp
@@ -90,7 +90,7 @@
     for (InlineBox* child = flowBox->firstChild(); child; child = child->nextOnLine()) {
         if (child->isInlineFlowBox()) {
             // Skip generated content.
-            if (!child->renderer()->node())
+            if (!child->renderer().node())
                 continue;
 
             collectTextBoxesInFlowBox(toInlineFlowBox(child));
@@ -112,8 +112,7 @@
     // Loop over all text boxes
     for (unsigned textBoxPosition = 0; textBoxPosition < textBoxCount; ++textBoxPosition) {
         queryData->textBox = m_textBoxes.at(textBoxPosition);
-        queryData->textRenderer = toRenderSVGInlineText(queryData->textBox->textRenderer());
-        ASSERT(queryData->textRenderer);
+        queryData->textRenderer = &toRenderSVGInlineText(queryData->textBox->textRenderer());
         ASSERT(queryData->textRenderer->style());
         ASSERT(queryData->textRenderer->style()->svgStyle());
 
@@ -476,8 +475,6 @@
 
     AffineTransform fragmentTransform;
     fragment.buildFragmentTransform(fragmentTransform, SVGTextFragment::TransformIgnoringTextLength);
-    if (fragmentTransform.isIdentity())
-        return;
 
     extent = fragmentTransform.mapRect(extent);
 }
diff --git a/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp b/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp
index c48c91e..fe7685b 100644
--- a/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp
+++ b/Source/core/rendering/svg/SVGTextRunRenderingContext.cpp
@@ -73,12 +73,12 @@
     return 0;
 }
 
-float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, String& glyphName) const
+float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, Glyph& glyphId) const
 {
     WidthIterator it(&font, run);
     GlyphBuffer glyphBuffer;
     charsConsumed += it.advance(run.length(), &glyphBuffer);
-    glyphName = it.lastGlyphName();
+    glyphId = !glyphBuffer.isEmpty() ? glyphBuffer.glyphAt(0) : 0;
     return it.runWidthSoFar();
 }
 
@@ -126,7 +126,7 @@
         if (!glyph)
             continue;
 
-        float advance = glyphBuffer.advanceAt(from + i);
+        float advance = glyphBuffer.advanceAt(from + i).width();
         SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
         ASSERT(!svgGlyph.isPartOfLigature);
         ASSERT(svgGlyph.tableEntry == glyph);
@@ -198,7 +198,7 @@
             RenderObject* parentRenderObject = renderObject->isText() ? renderObject->parent() : renderObject;
             ASSERT(parentRenderObject);
             if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
-                if (parentRenderObjectElement->hasTagName(SVGNames::altGlyphTag))
+                if (isSVGAltGlyphElement(*parentRenderObjectElement))
                     glyphData.fontData = primaryFont;
             }
         }
diff --git a/Source/core/rendering/svg/SVGTextRunRenderingContext.h b/Source/core/rendering/svg/SVGTextRunRenderingContext.h
index e03f939..7615138 100644
--- a/Source/core/rendering/svg/SVGTextRunRenderingContext.h
+++ b/Source/core/rendering/svg/SVGTextRunRenderingContext.h
@@ -44,7 +44,7 @@
 
     virtual GlyphData glyphDataForCharacter(const Font&, const TextRun&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) OVERRIDE;
     virtual void drawSVGGlyphs(GraphicsContext*, const TextRun&, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const OVERRIDE;
-    virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const OVERRIDE;
+    virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, Glyph& glyphId) const OVERRIDE;
 #endif
 
 private:
diff --git a/Source/core/speech/SpeechInput.cpp b/Source/core/speech/SpeechInput.cpp
index 221e023..add5859 100644
--- a/Source/core/speech/SpeechInput.cpp
+++ b/Source/core/speech/SpeechInput.cpp
@@ -120,7 +120,7 @@
     return "SpeechInput";
 }
 
-void provideSpeechInputTo(Page* page, SpeechInputClient* client)
+void provideSpeechInputTo(Page& page, SpeechInputClient* client)
 {
     SpeechInput::provideTo(page, SpeechInput::supplementName(), SpeechInput::create(client));
 }
diff --git a/Source/core/speech/SpeechInputClient.h b/Source/core/speech/SpeechInputClient.h
index 4e8eb6f..832034a 100644
--- a/Source/core/speech/SpeechInputClient.h
+++ b/Source/core/speech/SpeechInputClient.h
@@ -67,7 +67,7 @@
     virtual ~SpeechInputClient() { }
 };
 
-void provideSpeechInputTo(Page*, SpeechInputClient*);
+void provideSpeechInputTo(Page&, SpeechInputClient*);
 
 } // namespace WebCore
 
diff --git a/Source/core/speech/SpeechInputEvent.cpp b/Source/core/speech/SpeechInputEvent.cpp
index f0222e9..8d88763 100644
--- a/Source/core/speech/SpeechInputEvent.cpp
+++ b/Source/core/speech/SpeechInputEvent.cpp
@@ -69,6 +69,12 @@
     return EventNames::SpeechInputEvent;
 }
 
+void SpeechInputEvent::trace(Visitor* visitor)
+{
+    visitor->trace(m_results);
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INPUT_SPEECH)
diff --git a/Source/core/speech/SpeechInputEvent.h b/Source/core/speech/SpeechInputEvent.h
index d9cd9be..b09cd94 100644
--- a/Source/core/speech/SpeechInputEvent.h
+++ b/Source/core/speech/SpeechInputEvent.h
@@ -30,7 +30,7 @@
 
 #include "core/events/Event.h"
 #include "core/speech/SpeechInputResultList.h"
-
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 
 namespace WebCore {
@@ -45,11 +45,13 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     SpeechInputEvent();
     SpeechInputEvent(const AtomicString& eventType, const SpeechInputResultArray& results);
 
-    RefPtr<SpeechInputResultList> m_results;
+    RefPtrWillBeMember<SpeechInputResultList> m_results;
 };
 
 } // namespace WebCore
diff --git a/Source/core/speech/SpeechInputResult.cpp b/Source/core/speech/SpeechInputResult.cpp
index 1673455..9476585 100644
--- a/Source/core/speech/SpeechInputResult.cpp
+++ b/Source/core/speech/SpeechInputResult.cpp
@@ -30,14 +30,14 @@
 
 namespace WebCore {
 
-PassRefPtr<SpeechInputResult> SpeechInputResult::create(const String& utterance, double confidence)
+PassRefPtrWillBeRawPtr<SpeechInputResult> SpeechInputResult::create(const String& utterance, double confidence)
 {
-    return adoptRef(new SpeechInputResult(utterance, confidence));
+    return adoptRefWillBeNoop(new SpeechInputResult(utterance, confidence));
 }
 
-PassRefPtr<SpeechInputResult> SpeechInputResult::create(const SpeechInputResult& source)
+PassRefPtrWillBeRawPtr<SpeechInputResult> SpeechInputResult::create(const SpeechInputResult& source)
 {
-    return adoptRef(new SpeechInputResult(source.m_utterance, source.m_confidence));
+    return adoptRefWillBeNoop(new SpeechInputResult(source.m_utterance, source.m_confidence));
 }
 
 SpeechInputResult::SpeechInputResult(const String& utterance, double confidence)
diff --git a/Source/core/speech/SpeechInputResult.h b/Source/core/speech/SpeechInputResult.h
index 5a5d44d..334dbe8 100644
--- a/Source/core/speech/SpeechInputResult.h
+++ b/Source/core/speech/SpeechInputResult.h
@@ -29,6 +29,7 @@
 #if ENABLE(INPUT_SPEECH)
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
@@ -37,14 +38,16 @@
 
 // This class holds one speech recognition result including the text and other related
 // fields, as received from the embedder.
-class SpeechInputResult : public RefCounted<SpeechInputResult>, public ScriptWrappable {
+class SpeechInputResult : public RefCountedWillBeGarbageCollectedFinalized<SpeechInputResult>, public ScriptWrappable {
 public:
-    static PassRefPtr<SpeechInputResult> create(const SpeechInputResult& source);
-    static PassRefPtr<SpeechInputResult> create(const String& utterance, double confidence);
+    static PassRefPtrWillBeRawPtr<SpeechInputResult> create(const SpeechInputResult& source);
+    static PassRefPtrWillBeRawPtr<SpeechInputResult> create(const String& utterance, double confidence);
 
     double confidence() const;
     const String& utterance() const;
 
+    void trace(Visitor *) { }
+
 private:
     SpeechInputResult(const String& utterance, double confidence);
 
@@ -52,7 +55,8 @@
     double m_confidence;
 };
 
-typedef Vector<RefPtr<SpeechInputResult> > SpeechInputResultArray;
+typedef WillBeHeapVector<RefPtrWillBeMember<SpeechInputResult> > SpeechInputResultArray;
+typedef WillBePersistentHeapVector<RefPtrWillBeMember<SpeechInputResult> > WillBePersistentSpeechInputResultArray;
 
 } // namespace WebCore
 
diff --git a/Source/core/speech/SpeechInputResult.idl b/Source/core/speech/SpeechInputResult.idl
index bc2d409..1b08612 100644
--- a/Source/core/speech/SpeechInputResult.idl
+++ b/Source/core/speech/SpeechInputResult.idl
@@ -24,6 +24,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,
     Conditional=INPUT_SPEECH
 ] interface SpeechInputResult {
diff --git a/Source/core/speech/SpeechInputResultList.cpp b/Source/core/speech/SpeechInputResultList.cpp
index 86f7fda..54e5fd5 100644
--- a/Source/core/speech/SpeechInputResultList.cpp
+++ b/Source/core/speech/SpeechInputResultList.cpp
@@ -35,9 +35,9 @@
 
 namespace WebCore {
 
-PassRefPtr<SpeechInputResultList> SpeechInputResultList::create(const SpeechInputResultArray& results)
+PassRefPtrWillBeRawPtr<SpeechInputResultList> SpeechInputResultList::create(const SpeechInputResultArray& results)
 {
-    return adoptRef(new SpeechInputResultList(results));
+    return adoptRefWillBeNoop(new SpeechInputResultList(results));
 }
 
 SpeechInputResult* SpeechInputResultList::item(unsigned index)
@@ -46,11 +46,16 @@
 }
 
 SpeechInputResultList::SpeechInputResultList(const SpeechInputResultArray& results)
-    : m_results(results) // Takes a copy of the array of RefPtrs.
+    : m_results(results) // Copies the incoming result array.
 {
     ScriptWrappable::init(this);
 }
 
+void SpeechInputResultList::trace(Visitor* visitor)
+{
+    visitor->trace(m_results);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INPUT_SPEECH)
diff --git a/Source/core/speech/SpeechInputResultList.h b/Source/core/speech/SpeechInputResultList.h
index 3edb9d5..85eb6a6 100644
--- a/Source/core/speech/SpeechInputResultList.h
+++ b/Source/core/speech/SpeechInputResultList.h
@@ -30,19 +30,22 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/speech/SpeechInputResult.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-class SpeechInputResultList : public RefCounted<SpeechInputResultList>, public ScriptWrappable {
+class SpeechInputResultList : public RefCountedWillBeGarbageCollectedFinalized<SpeechInputResultList>, public ScriptWrappable {
 public:
-    static PassRefPtr<SpeechInputResultList> create(const SpeechInputResultArray& results);
+    static PassRefPtrWillBeRawPtr<SpeechInputResultList> create(const SpeechInputResultArray& results);
 
     // Methods from the IDL.
     size_t length() { return m_results.size(); }
     SpeechInputResult* item(unsigned index);
 
+    void trace(Visitor *);
+
 private:
     explicit SpeechInputResultList(const SpeechInputResultArray& results);
 
diff --git a/Source/core/speech/SpeechInputResultList.idl b/Source/core/speech/SpeechInputResultList.idl
index 1983aed..878c5a6 100644
--- a/Source/core/speech/SpeechInputResultList.idl
+++ b/Source/core/speech/SpeechInputResultList.idl
@@ -24,6 +24,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,
     Conditional=INPUT_SPEECH
 ] interface SpeechInputResultList {
diff --git a/Source/core/storage/Storage.cpp b/Source/core/storage/Storage.cpp
index 3b7d77a..dbb7e8b 100644
--- a/Source/core/storage/Storage.cpp
+++ b/Source/core/storage/Storage.cpp
@@ -33,14 +33,12 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(Storage);
-
-PassRefPtrWillBeRawPtr<Storage> Storage::create(Frame* frame, PassOwnPtrWillBeRawPtr<StorageArea> storageArea)
+PassRefPtrWillBeRawPtr<Storage> Storage::create(LocalFrame* frame, PassOwnPtrWillBeRawPtr<StorageArea> storageArea)
 {
     return adoptRefWillBeNoop(new Storage(frame, storageArea));
 }
 
-Storage::Storage(Frame* frame, PassOwnPtrWillBeRawPtr<StorageArea> storageArea)
+Storage::Storage(LocalFrame* frame, PassOwnPtrWillBeRawPtr<StorageArea> storageArea)
     : DOMWindowProperty(frame)
     , m_storageArea(storageArea)
 {
diff --git a/Source/core/storage/Storage.h b/Source/core/storage/Storage.h
index 083ec83..179d54d 100644
--- a/Source/core/storage/Storage.h
+++ b/Source/core/storage/Storage.h
@@ -38,12 +38,11 @@
 namespace WebCore {
 
 class ExceptionState;
-class Frame;
+class LocalFrame;
 
 class Storage FINAL : public RefCountedWillBeGarbageCollectedFinalized<Storage>, public ScriptWrappable, public DOMWindowProperty {
-    DECLARE_GC_INFO;
 public:
-    static PassRefPtrWillBeRawPtr<Storage> create(Frame*, PassOwnPtrWillBeRawPtr<StorageArea>);
+    static PassRefPtrWillBeRawPtr<Storage> create(LocalFrame*, PassOwnPtrWillBeRawPtr<StorageArea>);
     virtual ~Storage();
 
     unsigned length(ExceptionState& ec) const { return m_storageArea->length(ec, m_frame); }
@@ -68,7 +67,7 @@
     void trace(Visitor*);
 
 private:
-    Storage(Frame*, PassOwnPtrWillBeRawPtr<StorageArea>);
+    Storage(LocalFrame*, PassOwnPtrWillBeRawPtr<StorageArea>);
 
     OwnPtrWillBeMember<StorageArea> m_storageArea;
 };
diff --git a/Source/core/storage/StorageArea.cpp b/Source/core/storage/StorageArea.cpp
index 0453f72..59f99e2 100644
--- a/Source/core/storage/StorageArea.cpp
+++ b/Source/core/storage/StorageArea.cpp
@@ -32,10 +32,9 @@
 #include "core/dom/ExceptionCode.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/page/Page.h"
-#include "core/page/PageGroup.h"
 #include "core/page/StorageClient.h"
 #include "core/storage/Storage.h"
 #include "core/storage/StorageEvent.h"
@@ -47,8 +46,6 @@
 
 namespace WebCore {
 
-DEFINE_GC_INFO(StorageArea);
-
 StorageArea::StorageArea(PassOwnPtr<blink::WebStorageArea> storageArea, StorageType storageType)
     : m_storageArea(storageArea)
     , m_storageType(storageType)
@@ -61,7 +58,7 @@
 {
 }
 
-unsigned StorageArea::length(ExceptionState& exceptionState, Frame* frame)
+unsigned StorageArea::length(ExceptionState& exceptionState, LocalFrame* frame)
 {
     if (!canAccessStorage(frame)) {
         exceptionState.throwSecurityError("access is denied for this document.");
@@ -70,7 +67,7 @@
     return m_storageArea->length();
 }
 
-String StorageArea::key(unsigned index, ExceptionState& exceptionState, Frame* frame)
+String StorageArea::key(unsigned index, ExceptionState& exceptionState, LocalFrame* frame)
 {
     if (!canAccessStorage(frame)) {
         exceptionState.throwSecurityError("access is denied for this document.");
@@ -79,7 +76,7 @@
     return m_storageArea->key(index);
 }
 
-String StorageArea::getItem(const String& key, ExceptionState& exceptionState, Frame* frame)
+String StorageArea::getItem(const String& key, ExceptionState& exceptionState, LocalFrame* frame)
 {
     if (!canAccessStorage(frame)) {
         exceptionState.throwSecurityError("access is denied for this document.");
@@ -88,7 +85,7 @@
     return m_storageArea->getItem(key);
 }
 
-void StorageArea::setItem(const String& key, const String& value, ExceptionState& exceptionState, Frame* frame)
+void StorageArea::setItem(const String& key, const String& value, ExceptionState& exceptionState, LocalFrame* frame)
 {
     if (!canAccessStorage(frame)) {
         exceptionState.throwSecurityError("access is denied for this document.");
@@ -100,7 +97,7 @@
         exceptionState.throwDOMException(QuotaExceededError, "Setting the value of '" + key + "' exceeded the quota.");
 }
 
-void StorageArea::removeItem(const String& key, ExceptionState& exceptionState, Frame* frame)
+void StorageArea::removeItem(const String& key, ExceptionState& exceptionState, LocalFrame* frame)
 {
     if (!canAccessStorage(frame)) {
         exceptionState.throwSecurityError("access is denied for this document.");
@@ -109,7 +106,7 @@
     m_storageArea->removeItem(key, frame->document()->url());
 }
 
-void StorageArea::clear(ExceptionState& exceptionState, Frame* frame)
+void StorageArea::clear(ExceptionState& exceptionState, LocalFrame* frame)
 {
     if (!canAccessStorage(frame)) {
         exceptionState.throwSecurityError("access is denied for this document.");
@@ -118,7 +115,7 @@
     m_storageArea->clear(frame->document()->url());
 }
 
-bool StorageArea::contains(const String& key, ExceptionState& exceptionState, Frame* frame)
+bool StorageArea::contains(const String& key, ExceptionState& exceptionState, LocalFrame* frame)
 {
     if (!canAccessStorage(frame)) {
         exceptionState.throwSecurityError("access is denied for this document.");
@@ -127,7 +124,7 @@
     return !getItem(key, exceptionState, frame).isNull();
 }
 
-bool StorageArea::canAccessStorage(Frame* frame)
+bool StorageArea::canAccessStorage(LocalFrame* frame)
 {
     if (!frame || !frame->page())
         return false;
@@ -147,9 +144,9 @@
 void StorageArea::dispatchLocalStorageEvent(const String& key, const String& oldValue, const String& newValue, SecurityOrigin* securityOrigin, const KURL& pageURL, blink::WebStorageArea* sourceAreaInstance, bool originatedInProcess)
 {
     // FIXME: This looks suspicious. Why doesn't this use allPages instead?
-    const HashSet<Page*>& pages = PageGroup::sharedGroup()->pages();
+    const HashSet<Page*>& pages = Page::ordinaryPages();
     for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); ++it) {
-        for (Frame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        for (LocalFrame* frame = (*it)->mainFrame(); frame; frame = frame->tree().traverseNext()) {
             Storage* storage = frame->domWindow()->optionalLocalStorage();
             if (storage && frame->document()->securityOrigin()->canAccess(securityOrigin) && !isEventSource(storage, sourceAreaInstance))
                 frame->domWindow()->enqueueWindowEvent(StorageEvent::create(EventTypeNames::storage, key, oldValue, newValue, pageURL, storage));
@@ -161,7 +158,7 @@
 static Page* findPageWithSessionStorageNamespace(const blink::WebStorageNamespace& sessionNamespace)
 {
     // FIXME: This looks suspicious. Why doesn't this use allPages instead?
-    const HashSet<Page*>& pages = PageGroup::sharedGroup()->pages();
+    const HashSet<Page*>& pages = Page::ordinaryPages();
     for (HashSet<Page*>::const_iterator it = pages.begin(); it != pages.end(); ++it) {
         const bool dontCreateIfMissing = false;
         StorageNamespace* storageNamespace = (*it)->sessionStorage(dontCreateIfMissing);
@@ -177,7 +174,7 @@
     if (!page)
         return;
 
-    for (Frame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
+    for (LocalFrame* frame = page->mainFrame(); frame; frame = frame->tree().traverseNext()) {
         Storage* storage = frame->domWindow()->optionalSessionStorage();
         if (storage && frame->document()->securityOrigin()->canAccess(securityOrigin) && !isEventSource(storage, sourceAreaInstance))
             frame->domWindow()->enqueueWindowEvent(StorageEvent::create(EventTypeNames::storage, key, oldValue, newValue, pageURL, storage));
diff --git a/Source/core/storage/StorageArea.h b/Source/core/storage/StorageArea.h
index c68f8e8..511a6e4 100644
--- a/Source/core/storage/StorageArea.h
+++ b/Source/core/storage/StorageArea.h
@@ -39,7 +39,7 @@
 namespace WebCore {
 
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class KURL;
 class Page;
 class SecurityOrigin;
@@ -51,21 +51,20 @@
 };
 
 class StorageArea : public NoBaseWillBeGarbageCollectedFinalized<StorageArea> {
-    DECLARE_GC_INFO;
 public:
     StorageArea(PassOwnPtr<blink::WebStorageArea>, StorageType);
     virtual ~StorageArea();
 
     // The HTML5 DOM Storage API
-    unsigned length(ExceptionState&, Frame* sourceFrame);
-    String key(unsigned index, ExceptionState&, Frame* sourceFrame);
-    String getItem(const String& key, ExceptionState&, Frame* sourceFrame);
-    void setItem(const String& key, const String& value, ExceptionState&, Frame* sourceFrame);
-    void removeItem(const String& key, ExceptionState&, Frame* sourceFrame);
-    void clear(ExceptionState&, Frame* sourceFrame);
-    bool contains(const String& key, ExceptionState&, Frame* sourceFrame);
+    unsigned length(ExceptionState&, LocalFrame* sourceFrame);
+    String key(unsigned index, ExceptionState&, LocalFrame* sourceFrame);
+    String getItem(const String& key, ExceptionState&, LocalFrame* sourceFrame);
+    void setItem(const String& key, const String& value, ExceptionState&, LocalFrame* sourceFrame);
+    void removeItem(const String& key, ExceptionState&, LocalFrame* sourceFrame);
+    void clear(ExceptionState&, LocalFrame* sourceFrame);
+    bool contains(const String& key, ExceptionState&, LocalFrame* sourceFrame);
 
-    bool canAccessStorage(Frame*);
+    bool canAccessStorage(LocalFrame*);
     size_t memoryBytesUsedByCache();
 
     static void dispatchLocalStorageEvent(const String& key, const String& oldValue, const String& newValue,
@@ -82,7 +81,7 @@
     OwnPtr<blink::WebStorageArea> m_storageArea;
     StorageType m_storageType;
     mutable bool m_canAccessStorageCachedResult;
-    mutable Frame* m_canAccessStorageCachedFrame;
+    mutable LocalFrame* m_canAccessStorageCachedFrame;
 };
 
 } // namespace WebCore
diff --git a/Source/core/storage/StorageEvent.cpp b/Source/core/storage/StorageEvent.cpp
index 1c434f3..398877c 100644
--- a/Source/core/storage/StorageEvent.cpp
+++ b/Source/core/storage/StorageEvent.cpp
@@ -100,4 +100,13 @@
     return EventNames::StorageEvent;
 }
 
+void StorageEvent::trace(Visitor* visitor)
+{
+    // FIXME: oilpan: this code is not called as of now since Event is not on
+    // the oilpan heap anymore. We are keeping this code to avoid having to
+    // rewrite it once Event is moved back onto the oilpan heap.
+    visitor->trace(m_storageArea);
+    Event::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/storage/StorageEvent.h b/Source/core/storage/StorageEvent.h
index eaf165d..1acea93 100644
--- a/Source/core/storage/StorageEvent.h
+++ b/Source/core/storage/StorageEvent.h
@@ -35,8 +35,7 @@
 class Storage;
 
 struct StorageEventInit : public EventInit {
-    // FIXME: oilpan: Replace this with STACK_ALLOCATED.
-    DISALLOW_ALLOCATION();
+    STACK_ALLOCATED();
 public:
     StorageEventInit();
 
@@ -44,7 +43,7 @@
     String oldValue;
     String newValue;
     String url;
-    RefPtrWillBeRawPtr<Storage> storageArea;
+    RefPtrWillBeMember<Storage> storageArea;
 };
 
 class StorageEvent FINAL : public Event {
@@ -68,6 +67,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     StorageEvent();
     StorageEvent(const AtomicString& type, const String& key, const String& oldValue, const String& newValue, const String& url, Storage* storageArea);
diff --git a/Source/core/svg/SVGAElement.cpp b/Source/core/svg/SVGAElement.cpp
index 2142ba4..db4f473 100644
--- a/Source/core/svg/SVGAElement.cpp
+++ b/Source/core/svg/SVGAElement.cpp
@@ -32,7 +32,7 @@
 #include "core/events/KeyboardEvent.h"
 #include "core/events/MouseEvent.h"
 #include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLAnchorElement.h"
 #include "core/html/HTMLFormElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
@@ -54,12 +54,6 @@
 
 using namespace HTMLNames;
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGAElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGAElement::SVGAElement(Document& document)
     : SVGGraphicsElement(SVGNames::aTag, document)
     , SVGURIReference(this)
@@ -67,7 +61,6 @@
 {
     ScriptWrappable::init(this);
     addToPropertyMap(m_svgTarget);
-    registerAnimatedPropertiesForSVGAElement();
 }
 
 PassRefPtr<SVGAElement> SVGAElement::create(Document& document)
@@ -163,7 +156,7 @@
                     return;
                 }
                 // Only allow navigation to internal <view> anchors.
-                if (targetElement && !targetElement->hasTagName(SVGNames::viewTag))
+                if (targetElement && !isSVGViewElement(*targetElement))
                     return;
             }
 
@@ -172,7 +165,7 @@
                 target = AtomicString("_blank", AtomicString::ConstructFromLiteral);
             event->setDefaultHandled();
 
-            Frame* frame = document().frame();
+            LocalFrame* frame = document().frame();
             if (!frame)
                 return;
             FrameLoadRequest frameRequest(&document(), ResourceRequest(document().completeURL(url)), target);
diff --git a/Source/core/svg/SVGAElement.h b/Source/core/svg/SVGAElement.h
index 64519d2..3f3239c 100644
--- a/Source/core/svg/SVGAElement.h
+++ b/Source/core/svg/SVGAElement.h
@@ -55,10 +55,6 @@
     virtual bool willRespondToMouseClickEvents() OVERRIDE;
 
     RefPtr<SVGAnimatedString> m_svgTarget;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAElement)
-        // This declaration used to define a non-virtual "String& target() const" method, that clashes with "virtual String Element::target() const".
-        // That's why it has been renamed to "svgTarget", the CodeGenerators take care of calling svgTargetAnimated() instead of targetAnimated(), see CodeGenerator.pm.
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGAltGlyphDefElement.cpp b/Source/core/svg/SVGAltGlyphDefElement.cpp
index 5142195..c72543f 100644
--- a/Source/core/svg/SVGAltGlyphDefElement.cpp
+++ b/Source/core/svg/SVGAltGlyphDefElement.cpp
@@ -23,6 +23,7 @@
 #include "core/svg/SVGAltGlyphDefElement.h"
 
 #include "SVGNames.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/svg/SVGAltGlyphItemElement.h"
 #include "core/svg/SVGGlyphRefElement.h"
 
@@ -88,8 +89,8 @@
     bool fountFirstGlyphRef = false;
     bool foundFirstAltGlyphItem = false;
 
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (!foundFirstAltGlyphItem && child->hasTagName(SVGNames::glyphRefTag)) {
+    for (SVGElement* child = Traversal<SVGElement>::firstChild(*this); child; child = Traversal<SVGElement>::nextSibling(*child)) {
+        if (!foundFirstAltGlyphItem && isSVGGlyphRefElement(*child)) {
             fountFirstGlyphRef = true;
             AtomicString referredGlyphName;
 
@@ -103,7 +104,7 @@
                 glyphNames.clear();
                 return false;
             }
-        } else if (!fountFirstGlyphRef && child->hasTagName(SVGNames::altGlyphItemTag)) {
+        } else if (!fountFirstGlyphRef && isSVGAltGlyphItemElement(*child)) {
             foundFirstAltGlyphItem = true;
             Vector<AtomicString> referredGlyphNames;
 
diff --git a/Source/core/svg/SVGAltGlyphDefElement.h b/Source/core/svg/SVGAltGlyphDefElement.h
index a23e725..0c8c168 100644
--- a/Source/core/svg/SVGAltGlyphDefElement.h
+++ b/Source/core/svg/SVGAltGlyphDefElement.h
@@ -39,8 +39,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGAltGlyphDefElement, hasTagName(SVGNames::altGlyphDefTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGAltGlyphElement.cpp b/Source/core/svg/SVGAltGlyphElement.cpp
index d4e56d1..7686d1d 100644
--- a/Source/core/svg/SVGAltGlyphElement.cpp
+++ b/Source/core/svg/SVGAltGlyphElement.cpp
@@ -35,18 +35,11 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGAltGlyphElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextPositioningElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGAltGlyphElement::SVGAltGlyphElement(Document& document)
     : SVGTextPositioningElement(SVGNames::altGlyphTag, document)
     , SVGURIReference(this)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGAltGlyphElement();
 }
 
 PassRefPtr<SVGAltGlyphElement> SVGAltGlyphElement::create(Document& document)
@@ -86,13 +79,12 @@
     if (!element)
         return false;
 
-    if (element->hasTagName(SVGNames::glyphTag)) {
+    if (isSVGGlyphElement(*element)) {
         glyphNames.append(target);
         return true;
     }
 
-    if (element->hasTagName(SVGNames::altGlyphDefTag)
-        && toSVGAltGlyphDefElement(element)->hasValidGlyphElements(glyphNames))
+    if (isSVGAltGlyphDefElement(*element) && toSVGAltGlyphDefElement(*element).hasValidGlyphElements(glyphNames))
         return true;
 
     return false;
diff --git a/Source/core/svg/SVGAltGlyphElement.h b/Source/core/svg/SVGAltGlyphElement.h
index ffa4bfb..666e19a 100644
--- a/Source/core/svg/SVGAltGlyphElement.h
+++ b/Source/core/svg/SVGAltGlyphElement.h
@@ -49,13 +49,8 @@
     explicit SVGAltGlyphElement(Document&);
 
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
-
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAltGlyphElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGAltGlyphElement, hasTagName(SVGNames::altGlyphTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGAltGlyphItemElement.cpp b/Source/core/svg/SVGAltGlyphItemElement.cpp
index abe9e8d..94c5faf 100644
--- a/Source/core/svg/SVGAltGlyphItemElement.cpp
+++ b/Source/core/svg/SVGAltGlyphItemElement.cpp
@@ -22,6 +22,7 @@
 #if ENABLE(SVG_FONTS)
 #include "core/svg/SVGAltGlyphItemElement.h"
 
+#include "core/dom/ElementTraversal.h"
 #include "core/svg/SVGGlyphRefElement.h"
 
 namespace WebCore {
@@ -47,15 +48,13 @@
     //
     // Here we fill glyphNames and return true only if all referenced glyphs are valid and
     // there is at least one glyph.
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(SVGNames::glyphRefTag)) {
-            AtomicString referredGlyphName;
-            if (toSVGGlyphRefElement(child)->hasValidGlyphElement(referredGlyphName))
-                glyphNames.append(referredGlyphName);
-            else {
-                glyphNames.clear();
-                return false;
-            }
+    for (SVGGlyphRefElement* glyph = Traversal<SVGGlyphRefElement>::firstChild(*this); glyph; glyph = Traversal<SVGGlyphRefElement>::nextSibling(*glyph)) {
+        AtomicString referredGlyphName;
+        if (glyph->hasValidGlyphElement(referredGlyphName)) {
+            glyphNames.append(referredGlyphName);
+        } else {
+            glyphNames.clear();
+            return false;
         }
     }
     return !glyphNames.isEmpty();
diff --git a/Source/core/svg/SVGAltGlyphItemElement.h b/Source/core/svg/SVGAltGlyphItemElement.h
index 400596d..811b1bc 100644
--- a/Source/core/svg/SVGAltGlyphItemElement.h
+++ b/Source/core/svg/SVGAltGlyphItemElement.h
@@ -39,8 +39,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGAltGlyphItemElement, hasTagName(SVGNames::altGlyphItemTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGAngle.cpp b/Source/core/svg/SVGAngle.cpp
index 65cc9be..7698f8f 100644
--- a/Source/core/svg/SVGAngle.cpp
+++ b/Source/core/svg/SVGAngle.cpp
@@ -23,17 +23,92 @@
 #include "core/svg/SVGAngle.h"
 
 #include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
 #include "core/svg/SVGParserUtilities.h"
 #include "wtf/MathExtras.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-SVGAngle::SVGAngle()
-    : m_unitType(SVG_ANGLETYPE_UNSPECIFIED)
-    , m_valueInSpecifiedUnits(0)
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerOrientType>()
 {
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVGMarkerOrientUnknown, emptyString()));
+        entries.append(std::make_pair(SVGMarkerOrientAuto, "auto"));
+        entries.append(std::make_pair(SVGMarkerOrientAngle, "angle"));
+    }
+    return entries;
+}
+
+SVGMarkerOrientEnumeration::SVGMarkerOrientEnumeration(SVGAngle* angle)
+    : SVGEnumeration<SVGMarkerOrientType>(SVGMarkerOrientAngle)
+    , m_angle(angle)
+{
+}
+
+SVGMarkerOrientEnumeration::~SVGMarkerOrientEnumeration()
+{
+}
+
+void SVGMarkerOrientEnumeration::notifyChange()
+{
+    ASSERT(m_angle);
+    m_angle->orientTypeChanged();
+}
+
+void SVGMarkerOrientEnumeration::add(PassRefPtr<NewSVGPropertyBase>, SVGElement*)
+{
+    // SVGMarkerOrientEnumeration is only animated via SVGAngle
+    ASSERT_NOT_REACHED();
+}
+
+void SVGMarkerOrientEnumeration::calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> from, PassRefPtr<NewSVGPropertyBase> to, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+    // SVGMarkerOrientEnumeration is only animated via SVGAngle
+    ASSERT_NOT_REACHED();
+}
+
+float SVGMarkerOrientEnumeration::calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement* contextElement)
+{
+    // SVGMarkerOrientEnumeration is only animated via SVGAngle
+    ASSERT_NOT_REACHED();
+    return -1.0;
+}
+
+SVGAngle::SVGAngle()
+    : NewSVGPropertyBase(classType())
+    , m_unitType(SVG_ANGLETYPE_UNSPECIFIED)
+    , m_valueInSpecifiedUnits(0)
+    , m_orientType(SVGMarkerOrientEnumeration::create(this))
+{
+}
+
+SVGAngle::SVGAngle(SVGAngleType unitType, float valueInSpecifiedUnits, SVGMarkerOrientType orientType)
+    : NewSVGPropertyBase(classType())
+    , m_unitType(unitType)
+    , m_valueInSpecifiedUnits(valueInSpecifiedUnits)
+    , m_orientType(SVGMarkerOrientEnumeration::create(this))
+{
+    m_orientType->setEnumValue(orientType);
+}
+
+SVGAngle::~SVGAngle()
+{
+}
+
+PassRefPtr<SVGAngle> SVGAngle::clone() const
+{
+    return adoptRef(new SVGAngle(m_unitType, m_valueInSpecifiedUnits, m_orientType->enumValue()));
+}
+
+PassRefPtr<NewSVGPropertyBase> SVGAngle::cloneForAnimation(const String& value) const
+{
+    RefPtr<SVGAngle> point = create();
+    point->setValueAsString(value, IGNORE_EXCEPTION);
+    return point.release();
 }
 
 float SVGAngle::value() const
@@ -68,6 +143,7 @@
         m_valueInSpecifiedUnits = value;
         break;
     }
+    m_orientType->setEnumValue(SVGMarkerOrientAngle);
 }
 
 template<typename CharType>
@@ -153,7 +229,13 @@
 void SVGAngle::setValueAsString(const String& value, ExceptionState& exceptionState)
 {
     if (value.isEmpty()) {
-        m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
+        newValueSpecifiedUnits(SVG_ANGLETYPE_UNSPECIFIED, 0);
+        return;
+    }
+
+    if (value == "auto") {
+        newValueSpecifiedUnits(SVG_ANGLETYPE_UNSPECIFIED, 0);
+        m_orientType->setEnumValue(SVGMarkerOrientAuto);
         return;
     }
 
@@ -167,29 +249,20 @@
         return;
     }
 
+    m_orientType->setEnumValue(SVGMarkerOrientAngle);
     m_unitType = unitType;
     m_valueInSpecifiedUnits = valueInSpecifiedUnits;
 }
 
-void SVGAngle::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState& exceptionState)
+void SVGAngle::newValueSpecifiedUnits(SVGAngleType unitType, float valueInSpecifiedUnits)
 {
-    if (unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) {
-        exceptionState.throwDOMException(NotSupportedError, "Cannot set value with unknown or invalid units (" + String::number(unitType) + ").");
-        return;
-    }
-
-    if (unitType != m_unitType)
-        m_unitType = static_cast<SVGAngleType>(unitType);
-
+    m_orientType->setEnumValue(SVGMarkerOrientAngle);
+    m_unitType = unitType;
     m_valueInSpecifiedUnits = valueInSpecifiedUnits;
 }
 
-void SVGAngle::convertToSpecifiedUnits(unsigned short unitType, ExceptionState& exceptionState)
+void SVGAngle::convertToSpecifiedUnits(SVGAngleType unitType, ExceptionState& exceptionState)
 {
-    if (unitType == SVG_ANGLETYPE_UNKNOWN || unitType > SVG_ANGLETYPE_GRAD) {
-        exceptionState.throwDOMException(NotSupportedError, "Cannot convert to unknown or invalid units (" + String::number(unitType) + ").");
-        return;
-    }
     if (m_unitType == SVG_ANGLETYPE_UNKNOWN) {
         exceptionState.throwDOMException(NotSupportedError, "Cannot convert from unknown or invalid units.");
         return;
@@ -252,7 +325,83 @@
         break;
     }
 
-    m_unitType = static_cast<SVGAngleType>(unitType);
+    m_unitType = unitType;
+    m_orientType->setEnumValue(SVGMarkerOrientAngle);
+}
+
+void SVGAngle::add(PassRefPtr<NewSVGPropertyBase> other, SVGElement*)
+{
+    RefPtr<SVGAngle> otherAngle = toSVGAngle(other);
+
+    // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
+    if (orientType()->enumValue() != SVGMarkerOrientAngle || otherAngle->orientType()->enumValue() != SVGMarkerOrientAngle)
+        return;
+
+    setValue(value() + otherAngle->value());
+}
+
+void SVGAngle::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> from, PassRefPtr<NewSVGPropertyBase> to, PassRefPtr<NewSVGPropertyBase> toAtEndOfDuration, SVGElement*)
+{
+    ASSERT(animationElement);
+    bool isToAnimation = animationElement->animationMode() == ToAnimation;
+
+    RefPtr<SVGAngle> fromAngle = isToAnimation ? this : toSVGAngle(from);
+    RefPtr<SVGAngle> toAngle = toSVGAngle(to);
+    RefPtr<SVGAngle> toAtEndOfDurationAngle = toSVGAngle(toAtEndOfDuration);
+
+    SVGMarkerOrientType fromOrientType = fromAngle->orientType()->enumValue();
+    SVGMarkerOrientType toOrientType = toAngle->orientType()->enumValue();
+
+    if (fromOrientType != toOrientType) {
+        // Animating from eg. auto to 90deg, or auto to 90deg.
+        if (fromOrientType == SVGMarkerOrientAngle) {
+            // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword..
+            if (toOrientType == SVGMarkerOrientAuto) {
+                if (percentage < 0.5f) {
+                    newValueSpecifiedUnits(fromAngle->unitType(), fromAngle->valueInSpecifiedUnits());
+                    return;
+                }
+                orientType()->setEnumValue(SVGMarkerOrientAuto);
+                return;
+            }
+            m_valueInSpecifiedUnits = 0;
+            orientType()->setEnumValue(SVGMarkerOrientUnknown);
+            return;
+        }
+    }
+
+    // From 'auto' to 'auto'.
+    if (fromOrientType == SVGMarkerOrientAuto) {
+        m_valueInSpecifiedUnits = 0;
+        orientType()->setEnumValue(SVGMarkerOrientAuto);
+        return;
+    }
+
+    // If the enumeration value is not angle or auto, its unknown.
+    if (fromOrientType != SVGMarkerOrientAngle) {
+        m_valueInSpecifiedUnits = 0;
+        orientType()->setEnumValue(SVGMarkerOrientUnknown);
+        return;
+    }
+
+    // Regular from angle to angle animation, with all features like additive etc.
+    float animatedValue = value();
+    animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngle->value(), toAngle->value(), toAtEndOfDurationAngle->value(), animatedValue);
+    orientType()->setEnumValue(SVGMarkerOrientAngle);
+    setValue(animatedValue);
+}
+
+float SVGAngle::calculateDistance(PassRefPtr<NewSVGPropertyBase> other, SVGElement*)
+{
+    return fabsf(value() - toSVGAngle(other)->value());
+}
+
+void SVGAngle::orientTypeChanged()
+{
+    if (orientType()->enumValue() == SVGMarkerOrientAuto) {
+        m_unitType = SVG_ANGLETYPE_UNSPECIFIED;
+        m_valueInSpecifiedUnits = 0;
+    }
 }
 
 }
diff --git a/Source/core/svg/SVGAngle.h b/Source/core/svg/SVGAngle.h
index 860d3f0..37b1108 100644
--- a/Source/core/svg/SVGAngle.h
+++ b/Source/core/svg/SVGAngle.h
@@ -22,16 +22,45 @@
 #ifndef SVGAngle_h
 #define SVGAngle_h
 
-#include "core/svg/properties/SVGPropertyTraits.h"
+#include "core/svg/SVGEnumeration.h"
 
 namespace WebCore {
 
-class ExceptionState;
+class SVGAngle;
+class SVGAngleTearOff;
 
-class SVGAngle {
-    WTF_MAKE_FAST_ALLOCATED;
+enum SVGMarkerOrientType {
+    SVGMarkerOrientUnknown = 0,
+    SVGMarkerOrientAuto,
+    SVGMarkerOrientAngle
+};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerOrientType>();
+
+class SVGMarkerOrientEnumeration : public SVGEnumeration<SVGMarkerOrientType> {
 public:
-    SVGAngle();
+    static PassRefPtr<SVGMarkerOrientEnumeration> create(SVGAngle* angle)
+    {
+        return adoptRef(new SVGMarkerOrientEnumeration(angle));
+    }
+
+    virtual ~SVGMarkerOrientEnumeration();
+
+    virtual void add(PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+    virtual void calculateAnimatedValue(SVGAnimationElement*, float, unsigned, PassRefPtr<NewSVGPropertyBase>, PassRefPtr<NewSVGPropertyBase>, PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+    virtual float calculateDistance(PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+
+private:
+    SVGMarkerOrientEnumeration(SVGAngle*);
+
+    virtual void notifyChange() OVERRIDE;
+
+    // FIXME: oilpan: This is kept as raw-ptr to avoid reference cycles. Should be Member in oilpan.
+    SVGAngle* m_angle;
+};
+
+class SVGAngle : public NewSVGPropertyBase {
+public:
+    typedef SVGAngleTearOff TearOffType;
 
     enum SVGAngleType {
         SVG_ANGLETYPE_UNKNOWN = 0,
@@ -41,6 +70,13 @@
         SVG_ANGLETYPE_GRAD = 4
     };
 
+    static PassRefPtr<SVGAngle> create()
+    {
+        return adoptRef(new SVGAngle());
+    }
+
+    virtual ~SVGAngle();
+
     SVGAngleType unitType() const { return m_unitType; }
 
     void setValue(float);
@@ -49,22 +85,41 @@
     void setValueInSpecifiedUnits(float valueInSpecifiedUnits) { m_valueInSpecifiedUnits = valueInSpecifiedUnits; }
     float valueInSpecifiedUnits() const { return m_valueInSpecifiedUnits; }
 
-    void setValueAsString(const String&, ExceptionState&);
-    String valueAsString() const;
+    void newValueSpecifiedUnits(SVGAngleType unitType, float valueInSpecifiedUnits);
+    void convertToSpecifiedUnits(SVGAngleType unitType, ExceptionState&);
 
-    void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState&);
-    void convertToSpecifiedUnits(unsigned short unitType, ExceptionState&);
+    SVGEnumeration<SVGMarkerOrientType>* orientType() { return m_orientType.get(); }
+    void orientTypeChanged();
+
+    // NewSVGPropertyBase:
+
+    PassRefPtr<SVGAngle> clone() const;
+    virtual PassRefPtr<NewSVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+    virtual String valueAsString() const OVERRIDE;
+    void setValueAsString(const String&, ExceptionState&);
+
+    virtual void add(PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+    virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> from, PassRefPtr<NewSVGPropertyBase> to, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+    virtual float calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+    static AnimatedPropertyType classType() { return AnimatedAngle; }
 
 private:
+    SVGAngle();
+    SVGAngle(SVGAngleType, float, SVGMarkerOrientType);
+
     SVGAngleType m_unitType;
     float m_valueInSpecifiedUnits;
+    RefPtr<SVGMarkerOrientEnumeration> m_orientType;
 };
 
-template<>
-struct SVGPropertyTraits<SVGAngle> {
-    static SVGAngle initialValue() { return SVGAngle(); }
-    static String toString(const SVGAngle& type) { return type.valueAsString(); }
-};
+inline PassRefPtr<SVGAngle> toSVGAngle(PassRefPtr<NewSVGPropertyBase> passBase)
+{
+    RefPtr<NewSVGPropertyBase> base = passBase;
+    ASSERT(base->type() == SVGAngle::classType());
+    return static_pointer_cast<SVGAngle>(base.release());
+}
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGAngle.idl b/Source/core/svg/SVGAngle.idl
index 423a6db..79ab480 100644
--- a/Source/core/svg/SVGAngle.idl
+++ b/Source/core/svg/SVGAngle.idl
@@ -21,6 +21,8 @@
  */
 
 [
+    ImplementedAs=SVGAngleTearOff,
+    SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGAngle {
     // Angle Unit Types
@@ -31,8 +33,8 @@
     const unsigned short SVG_ANGLETYPE_GRAD = 4;
 
     readonly attribute unsigned short unitType;
-    attribute float value;
-    attribute float valueInSpecifiedUnits;
+    [RaisesException=Setter] attribute float value;
+    [RaisesException=Setter] attribute float valueInSpecifiedUnits;
 
     [TreatNullAs=NullString, RaisesException=Setter] attribute DOMString valueAsString;
 
diff --git a/Source/core/svg/SVGAngleTearOff.cpp b/Source/core/svg/SVGAngleTearOff.cpp
new file mode 100644
index 0000000..c1408ea
--- /dev/null
+++ b/Source/core/svg/SVGAngleTearOff.cpp
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGAngleTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+SVGAngleTearOff::SVGAngleTearOff(PassRefPtr<SVGAngle> targetProperty, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+    : NewSVGPropertyTearOff<SVGAngle>(targetProperty, contextElement, propertyIsAnimVal, attributeName)
+{
+    ScriptWrappable::init(this);
+}
+
+SVGAngleTearOff::~SVGAngleTearOff()
+{
+}
+
+void SVGAngleTearOff::setValue(float value, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setValue(value);
+    commitChange();
+}
+
+void SVGAngleTearOff::setValueInSpecifiedUnits(float value, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setValueInSpecifiedUnits(value);
+    commitChange();
+}
+
+void SVGAngleTearOff::newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    if (unitType == SVGAngle::SVG_ANGLETYPE_UNKNOWN || unitType > SVGAngle::SVG_ANGLETYPE_GRAD) {
+        exceptionState.throwDOMException(NotSupportedError, "Cannot set value with unknown or invalid units (" + String::number(unitType) + ").");
+        return;
+    }
+
+    target()->newValueSpecifiedUnits(static_cast<SVGAngle::SVGAngleType>(unitType), valueInSpecifiedUnits);
+    commitChange();
+}
+
+void SVGAngleTearOff::convertToSpecifiedUnits(unsigned short unitType, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    if (unitType == SVGAngle::SVG_ANGLETYPE_UNKNOWN || unitType > SVGAngle::SVG_ANGLETYPE_GRAD) {
+        exceptionState.throwDOMException(NotSupportedError, "Cannot convert to unknown or invalid units (" + String::number(unitType) + ").");
+        return;
+    }
+
+    target()->convertToSpecifiedUnits(static_cast<SVGAngle::SVGAngleType>(unitType), exceptionState);
+    if (!exceptionState.hadException())
+        commitChange();
+}
+
+void SVGAngleTearOff::setValueAsString(const String& value, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setValueAsString(value, exceptionState);
+    commitChange();
+}
+
+}
diff --git a/Source/core/svg/SVGAngleTearOff.h b/Source/core/svg/SVGAngleTearOff.h
new file mode 100644
index 0000000..eec763b
--- /dev/null
+++ b/Source/core/svg/SVGAngleTearOff.h
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGAngleTearOff_h
+#define SVGAngleTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGAngle.h"
+#include "core/svg/properties/NewSVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGAngleTearOff FINAL : public NewSVGPropertyTearOff<SVGAngle>, public ScriptWrappable {
+public:
+    static PassRefPtr<SVGAngleTearOff> create(PassRefPtr<SVGAngle> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = nullQName())
+    {
+        return adoptRef(new SVGAngleTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+    }
+
+    enum {
+        SVG_ANGLETYPE_UNKNOWN = SVGAngle::SVG_ANGLETYPE_UNKNOWN,
+        SVG_ANGLETYPE_UNSPECIFIED = SVGAngle::SVG_ANGLETYPE_UNSPECIFIED,
+        SVG_ANGLETYPE_DEG = SVGAngle::SVG_ANGLETYPE_DEG,
+        SVG_ANGLETYPE_RAD = SVGAngle::SVG_ANGLETYPE_RAD,
+        SVG_ANGLETYPE_GRAD = SVGAngle::SVG_ANGLETYPE_GRAD
+    };
+
+    virtual ~SVGAngleTearOff();
+
+    unsigned short unitType() { return target()->unitType(); }
+
+    void setValue(float, ExceptionState&);
+    float value() { return target()->value(); }
+
+    void setValueInSpecifiedUnits(float, ExceptionState&);
+    float valueInSpecifiedUnits() { return target()->valueInSpecifiedUnits(); }
+
+    void newValueSpecifiedUnits(unsigned short unitType, float valueInSpecifiedUnits, ExceptionState&);
+    void convertToSpecifiedUnits(unsigned short unitType, ExceptionState&);
+
+    String valueAsString() { return target()->valueAsString(); }
+    void setValueAsString(const String&, ExceptionState&);
+
+private:
+    SVGAngleTearOff(PassRefPtr<SVGAngle>, SVGElement*, PropertyIsAnimValType, const QualifiedName&);
+};
+
+} // namespace WebCore
+
+#endif // SVGAngleTearOff_h_
diff --git a/Source/core/svg/SVGAnimateElement.cpp b/Source/core/svg/SVGAnimateElement.cpp
index a7993c0..4a4138e 100644
--- a/Source/core/svg/SVGAnimateElement.cpp
+++ b/Source/core/svg/SVGAnimateElement.cpp
@@ -28,10 +28,9 @@
 #include "core/css/parser/BisonCSSParser.h"
 #include "core/css/StylePropertySet.h"
 #include "core/dom/QualifiedName.h"
-#include "core/svg/SVGAnimatedType.h"
 #include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/SVGAnimatorFactory.h"
 #include "core/svg/SVGDocumentExtensions.h"
+#include "core/svg/SVGElementInstance.h"
 
 namespace WebCore {
 
@@ -39,7 +38,7 @@
     : SVGAnimationElement(tagName, document)
     , m_animatedPropertyType(AnimatedString)
 {
-    ASSERT(hasTagName(SVGNames::animateTag) || hasTagName(SVGNames::setTag) || hasTagName(SVGNames::animateTransformTag));
+    ASSERT(isSVGAnimateElement(*this));
     ScriptWrappable::init(this);
 }
 
@@ -63,36 +62,6 @@
     return m_animatedPropertyType != AnimatedUnknown && !hasInvalidCSSAttributeType();
 }
 
-AnimatedPropertyType SVGAnimateElement::determineAnimatedPropertyType(SVGElement* targetElement) const
-{
-    ASSERT(targetElement);
-
-    Vector<AnimatedPropertyType> propertyTypes;
-    targetElement->animatedPropertyTypeForAttribute(attributeName(), propertyTypes);
-    if (propertyTypes.isEmpty())
-        return AnimatedUnknown;
-
-    ASSERT(propertyTypes.size() <= 2);
-    AnimatedPropertyType type = propertyTypes[0];
-
-    // Animations of transform lists are not allowed for <animate> or <set>
-    // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
-    if (type == AnimatedTransformList && !hasTagName(SVGNames::animateTransformTag))
-        return AnimatedUnknown;
-
-    // Fortunately there's just one special case needed here: SVGMarkerElements orientAttr, which
-    // corresponds to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType. We have to
-    // figure out whose value to change here.
-    if (targetElement->hasTagName(SVGNames::markerTag) && type == AnimatedAngle) {
-        ASSERT(propertyTypes.size() == 2);
-        ASSERT(propertyTypes[0] == AnimatedAngle);
-        ASSERT(propertyTypes[1] == AnimatedEnumeration);
-    } else if (propertyTypes.size() == 2)
-        ASSERT(propertyTypes[0] == propertyTypes[1]);
-
-    return type;
-}
-
 void SVGAnimateElement::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGSMILElement* resultElement)
 {
     ASSERT(resultElement);
@@ -100,22 +69,22 @@
     if (!targetElement || !isSVGAnimateElement(*resultElement))
         return;
 
-    ASSERT(m_animatedPropertyType == determineAnimatedPropertyType(targetElement));
+    ASSERT(m_animatedPropertyType == determineAnimatedPropertyType());
 
     ASSERT(percentage >= 0 && percentage <= 1);
-    ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag));
+    ASSERT(m_animatedPropertyType != AnimatedTransformList || isSVGAnimateTransformElement(*this));
     ASSERT(m_animatedPropertyType != AnimatedUnknown);
     ASSERT(m_animator);
     ASSERT(m_animator->type() == m_animatedPropertyType);
-    ASSERT(m_fromType);
-    ASSERT(m_fromType->type() == m_animatedPropertyType);
-    ASSERT(m_toType);
+    ASSERT(m_fromProperty);
+    ASSERT(m_fromProperty->type() == m_animatedPropertyType);
+    ASSERT(m_toProperty);
 
     SVGAnimateElement* resultAnimationElement = toSVGAnimateElement(resultElement);
-    ASSERT(resultAnimationElement->m_animatedType);
+    ASSERT(resultAnimationElement->m_animatedProperty);
     ASSERT(resultAnimationElement->m_animatedPropertyType == m_animatedPropertyType);
 
-    if (hasTagName(SVGNames::setTag))
+    if (isSVGSetElement(*this))
         percentage = 1;
 
     if (calcMode() == CalcModeDiscrete)
@@ -124,23 +93,16 @@
     // Target element might have changed.
     m_animator->setContextElement(targetElement);
 
-    // Be sure to detach list wrappers before we modfiy their underlying value. If we'd do
-    // if after calculateAnimatedValue() ran the cached pointers in the list propery tear
-    // offs would point nowhere, and we couldn't create copies of those values anymore,
-    // while detaching. This is covered by assertions, moving this down would fire them.
-    if (!m_animatedProperties.isEmpty())
-        m_animator->animValWillChange(m_animatedProperties);
-
     // Values-animation accumulates using the last values entry corresponding to the end of duration time.
-    SVGAnimatedType* toAtEndOfDurationType = m_toAtEndOfDurationType ? m_toAtEndOfDurationType.get() : m_toType.get();
-    m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromType.get(), m_toType.get(), toAtEndOfDurationType, resultAnimationElement->m_animatedType.get());
+    NewSVGPropertyBase* toAtEndOfDurationProperty = m_toAtEndOfDurationProperty ? m_toAtEndOfDurationProperty.get() : m_toProperty.get();
+    m_animator->calculateAnimatedValue(percentage, repeatCount, m_fromProperty.get(), m_toProperty.get(), toAtEndOfDurationProperty, resultAnimationElement->m_animatedProperty.get());
 }
 
 bool SVGAnimateElement::calculateToAtEndOfDurationValue(const String& toAtEndOfDurationString)
 {
     if (toAtEndOfDurationString.isEmpty())
         return false;
-    m_toAtEndOfDurationType = ensureAnimator()->constructFromString(toAtEndOfDurationString);
+    m_toAtEndOfDurationProperty = ensureAnimator()->constructFromString(toAtEndOfDurationString);
     return true;
 }
 
@@ -151,7 +113,7 @@
         return false;
 
     determinePropertyValueTypes(fromString, toString);
-    ensureAnimator()->calculateFromAndToValues(m_fromType, m_toType, fromString, toString);
+    ensureAnimator()->calculateFromAndToValues(m_fromProperty, m_toProperty, fromString, toString);
     ASSERT(m_animatedPropertyType == m_animator->type());
     return true;
 }
@@ -169,32 +131,34 @@
     if (animationMode() == FromByAnimation && !animatedPropertyTypeSupportsAddition())
         return false;
 
-    ASSERT(!hasTagName(SVGNames::setTag));
+    ASSERT(!isSVGSetElement(*this));
 
     determinePropertyValueTypes(fromString, byString);
-    ensureAnimator()->calculateFromAndByValues(m_fromType, m_toType, fromString, byString);
+    ensureAnimator()->calculateFromAndByValues(m_fromProperty, m_toProperty, fromString, byString);
     ASSERT(m_animatedPropertyType == m_animator->type());
     return true;
 }
 
-#ifndef NDEBUG
-static inline bool propertyTypesAreConsistent(AnimatedPropertyType expectedPropertyType, const SVGElementAnimatedPropertyList& animatedTypes)
+namespace {
+
+Vector<SVGElement*> findElementInstances(SVGElement* targetElement)
 {
-    SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
-    for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) {
-        for (size_t i = 0; i < it->properties.size(); ++i) {
-            if (expectedPropertyType != it->properties[i]->animatedPropertyType()) {
-                // This is the only allowed inconsistency. SVGAnimatedAngleAnimator handles both SVGAnimatedAngle & SVGAnimatedEnumeration for markers orient attribute.
-                if (expectedPropertyType == AnimatedAngle && it->properties[i]->animatedPropertyType() == AnimatedEnumeration)
-                    return true;
-                return false;
-            }
-        }
+    ASSERT(targetElement);
+    Vector<SVGElement*> animatedElements;
+
+    animatedElements.append(targetElement);
+
+    const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
+    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
+    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+        if (SVGElement* shadowTreeElement = (*it)->shadowTreeElement())
+            animatedElements.append(shadowTreeElement);
     }
 
-    return true;
+    return animatedElements;
 }
-#endif
+
+}
 
 void SVGAnimateElement::resetAnimatedType()
 {
@@ -210,25 +174,23 @@
 
     if (shouldApply == ApplyXMLAnimation) {
         // SVG DOM animVal animation code-path.
-        m_animatedProperties = animator->findAnimatedPropertiesForAttributeName(targetElement, attributeName);
-        SVGElementAnimatedPropertyList::const_iterator end = m_animatedProperties.end();
-        for (SVGElementAnimatedPropertyList::const_iterator it = m_animatedProperties.begin(); it != end; ++it)
-            document().accessSVGExtensions()->addElementReferencingTarget(this, it->element);
+        m_animatedElements = findElementInstances(targetElement);
+        ASSERT(!m_animatedElements.isEmpty());
 
-        ASSERT(!m_animatedProperties.isEmpty());
+        Vector<SVGElement*>::const_iterator end = m_animatedElements.end();
+        for (Vector<SVGElement*>::const_iterator it = m_animatedElements.begin(); it != end; ++it)
+            document().accessSVGExtensions().addElementReferencingTarget(this, *it);
 
-        ASSERT(propertyTypesAreConsistent(m_animatedPropertyType, m_animatedProperties));
-        if (!m_animatedType)
-            m_animatedType = animator->startAnimValAnimation(m_animatedProperties);
-        else {
-            animator->resetAnimValToBaseVal(m_animatedProperties, m_animatedType.get());
-            animator->animValDidChange(m_animatedProperties);
-        }
+        if (!m_animatedProperty)
+            m_animatedProperty = animator->startAnimValAnimation(m_animatedElements);
+        else
+            m_animatedProperty = animator->resetAnimValToBaseVal(m_animatedElements);
+
         return;
     }
 
     // CSS properties animation code-path.
-    ASSERT(m_animatedProperties.isEmpty());
+    ASSERT(m_animatedElements.isEmpty());
     String baseValue;
 
     if (shouldApply == ApplyCSSAnimation) {
@@ -236,8 +198,7 @@
         computeCSSPropertyValue(targetElement, cssPropertyID(attributeName.localName()), baseValue);
     }
 
-    if (!m_animatedType || !m_animatedType->setValueAsString(attributeName, baseValue))
-        m_animatedType = animator->constructFromString(baseValue);
+    m_animatedProperty = animator->constructFromString(baseValue);
 }
 
 static inline void applyCSSPropertyToTarget(SVGElement* targetElement, CSSPropertyID id, const String& value)
@@ -301,6 +262,7 @@
 static inline void notifyTargetAboutAnimValChange(SVGElement* targetElement, const QualifiedName& attributeName)
 {
     ASSERT_WITH_SECURITY_IMPLICATION(!targetElement->m_deletionHasBegun);
+    targetElement->invalidateSVGAttributes();
     targetElement->svgAttributeChanged(attributeName);
 }
 
@@ -324,52 +286,51 @@
 
 void SVGAnimateElement::clearAnimatedType(SVGElement* targetElement)
 {
-    if (!m_animatedType)
+    if (!m_animatedProperty)
         return;
 
     if (!targetElement) {
-        m_animatedType.clear();
+        m_animatedProperty.clear();
         return;
     }
 
-    if (m_animatedProperties.isEmpty()) {
+    if (m_animatedElements.isEmpty()) {
         // CSS properties animation code-path.
         removeCSSPropertyFromTargetAndInstances(targetElement, attributeName());
-        m_animatedType.clear();
+        m_animatedProperty.clear();
         return;
     }
 
     // SVG DOM animVal animation code-path.
     if (m_animator) {
-        m_animator->stopAnimValAnimation(m_animatedProperties);
+        m_animator->stopAnimValAnimation(m_animatedElements);
         notifyTargetAndInstancesAboutAnimValChange(targetElement, attributeName());
     }
 
-    m_animatedProperties.clear();
-    m_animatedType.clear();
+    m_animatedElements.clear();
+    m_animatedProperty.clear();
 }
 
 void SVGAnimateElement::applyResultsToTarget()
 {
-    ASSERT(m_animatedPropertyType != AnimatedTransformList || hasTagName(SVGNames::animateTransformTag));
+    ASSERT(m_animatedPropertyType != AnimatedTransformList || isSVGAnimateTransformElement(*this));
     ASSERT(m_animatedPropertyType != AnimatedUnknown);
     ASSERT(m_animator);
 
     // Early exit if our animated type got destructed by a previous endedActiveInterval().
-    if (!m_animatedType)
+    if (!m_animatedProperty)
         return;
 
-    if (m_animatedProperties.isEmpty()) {
+    if (m_animatedElements.isEmpty()) {
         // CSS properties animation code-path.
         // Convert the result of the animation to a String and apply it as CSS property on the target & all instances.
-        applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedType->valueAsString());
+        applyCSSPropertyToTargetAndInstances(targetElement(), attributeName(), m_animatedProperty->valueAsString());
         return;
     }
 
     // SVG DOM animVal animation code-path.
     // At this point the SVG DOM values are already changed, unlike for CSS.
     // We only have to trigger update notifications here.
-    m_animator->animValDidChange(m_animatedProperties);
     notifyTargetAndInstancesAboutAnimValChange(targetElement(), attributeName());
 }
 
@@ -421,18 +382,18 @@
 
 void SVGAnimateElement::resetAnimatedPropertyType()
 {
-    ASSERT(!m_animatedType);
-    m_fromType.clear();
-    m_toType.clear();
-    m_toAtEndOfDurationType.clear();
+    ASSERT(!m_animatedProperty);
+    m_fromProperty.clear();
+    m_toProperty.clear();
+    m_toAtEndOfDurationProperty.clear();
     m_animator.clear();
-    m_animatedPropertyType = targetElement() ? determineAnimatedPropertyType(targetElement()) : AnimatedString;
+    m_animatedPropertyType = determineAnimatedPropertyType();
 }
 
 SVGAnimatedTypeAnimator* SVGAnimateElement::ensureAnimator()
 {
     if (!m_animator)
-        m_animator = SVGAnimatorFactory::create(this, targetElement(), m_animatedPropertyType);
+        m_animator = SVGAnimatedTypeAnimator::create(m_animatedPropertyType, this, targetElement());
     ASSERT(m_animatedPropertyType == m_animator->type());
     return m_animator.get();
 }
diff --git a/Source/core/svg/SVGAnimateElement.h b/Source/core/svg/SVGAnimateElement.h
index 04660ca..bb79d71 100644
--- a/Source/core/svg/SVGAnimateElement.h
+++ b/Source/core/svg/SVGAnimateElement.h
@@ -30,8 +30,6 @@
 
 namespace WebCore {
 
-class SVGAnimatedProperty;
-class SVGAnimatedType;
 class SVGAnimatedTypeAnimator;
 
 class SVGAnimateElement : public SVGAnimationElement {
@@ -39,8 +37,6 @@
     static PassRefPtr<SVGAnimateElement> create(Document&);
     virtual ~SVGAnimateElement();
 
-    AnimatedPropertyType determineAnimatedPropertyType(SVGElement*) const;
-
 protected:
     SVGAnimateElement(const QualifiedName&, Document&);
 
@@ -67,12 +63,12 @@
 
     virtual bool hasValidAttributeType() OVERRIDE;
 
-    OwnPtr<SVGAnimatedType> m_fromType;
-    OwnPtr<SVGAnimatedType> m_toType;
-    OwnPtr<SVGAnimatedType> m_toAtEndOfDurationType;
-    OwnPtr<SVGAnimatedType> m_animatedType;
+    RefPtr<NewSVGPropertyBase> m_fromProperty;
+    RefPtr<NewSVGPropertyBase> m_toProperty;
+    RefPtr<NewSVGPropertyBase> m_toAtEndOfDurationProperty;
+    RefPtr<NewSVGPropertyBase> m_animatedProperty;
 
-    SVGElementAnimatedPropertyList m_animatedProperties;
+    Vector<SVGElement*> m_animatedElements;
     OwnPtr<SVGAnimatedTypeAnimator> m_animator;
 };
 
@@ -83,7 +79,7 @@
         || node.hasTagName(SVGNames::setTag);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGAnimateElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGAnimateElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGAnimateMotionElement.cpp b/Source/core/svg/SVGAnimateMotionElement.cpp
index fd90123..1ade309 100644
--- a/Source/core/svg/SVGAnimateMotionElement.cpp
+++ b/Source/core/svg/SVGAnimateMotionElement.cpp
@@ -70,26 +70,24 @@
         return false;
     // Spec: SVG 1.1 section 19.2.15
     // FIXME: svgTag is missing. Needs to be checked, if transforming <svg> could cause problems.
-    if (targetElement->hasTagName(gTag)
-        || targetElement->hasTagName(defsTag)
-        || targetElement->hasTagName(useTag)
-        || targetElement->hasTagName(SVGNames::imageTag)
-        || targetElement->hasTagName(switchTag)
-        || targetElement->hasTagName(pathTag)
-        || targetElement->hasTagName(rectTag)
-        || targetElement->hasTagName(circleTag)
-        || targetElement->hasTagName(ellipseTag)
-        || targetElement->hasTagName(lineTag)
-        || targetElement->hasTagName(polylineTag)
-        || targetElement->hasTagName(polygonTag)
-        || targetElement->hasTagName(textTag)
-        || targetElement->hasTagName(clipPathTag)
-        || targetElement->hasTagName(maskTag)
-        || targetElement->hasTagName(SVGNames::aTag)
-        || targetElement->hasTagName(foreignObjectTag)
-        )
-        return true;
-    return false;
+    return (isSVGGElement(*targetElement)
+        || isSVGDefsElement(*targetElement)
+        || isSVGUseElement(*targetElement)
+        || isSVGImageElement(*targetElement)
+        || isSVGSwitchElement(*targetElement)
+        || isSVGPathElement(*targetElement)
+        || isSVGRectElement(*targetElement)
+        || isSVGCircleElement(*targetElement)
+        || isSVGEllipseElement(*targetElement)
+        || isSVGLineElement(*targetElement)
+        || isSVGPolylineElement(*targetElement)
+        || isSVGPolygonElement(*targetElement)
+        || isSVGTextElement(*targetElement)
+        || isSVGClipPathElement(*targetElement)
+        || isSVGMaskElement(*targetElement)
+        || isSVGAElement(*targetElement)
+        || isSVGForeignObjectElement(*targetElement)
+        );
 }
 
 bool SVGAnimateMotionElement::hasValidAttributeName()
@@ -140,15 +138,11 @@
     m_animationPath = Path();
     bool foundMPath = false;
 
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(SVGNames::mpathTag)) {
-            SVGMPathElement* mPath = toSVGMPathElement(child);
-            SVGPathElement* pathElement = mPath->pathElement();
-            if (pathElement) {
-                updatePathFromGraphicsElement(pathElement, m_animationPath);
-                foundMPath = true;
-                break;
-            }
+    for (SVGMPathElement* mpath = Traversal<SVGMPathElement>::firstChild(*this); mpath; mpath = Traversal<SVGMPathElement>::nextSibling(*mpath)) {
+        if (SVGPathElement* pathElement = mpath->pathElement()) {
+            updatePathFromGraphicsElement(pathElement, m_animationPath);
+            foundMPath = true;
+            break;
         }
     }
 
diff --git a/Source/core/svg/SVGAnimateMotionElement.h b/Source/core/svg/SVGAnimateMotionElement.h
index 3dce19c..d438042 100644
--- a/Source/core/svg/SVGAnimateMotionElement.h
+++ b/Source/core/svg/SVGAnimateMotionElement.h
@@ -73,8 +73,6 @@
     Path m_animationPath;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGAnimateMotionElement, hasTagName(SVGNames::animateMotionTag));
-
 } // namespace WebCore
 
 #endif // SVGAnimateMotionElement_h
diff --git a/Source/core/svg/SVGAnimateTransformElement.cpp b/Source/core/svg/SVGAnimateTransformElement.cpp
index 6774a38..70dc573 100644
--- a/Source/core/svg/SVGAnimateTransformElement.cpp
+++ b/Source/core/svg/SVGAnimateTransformElement.cpp
@@ -31,7 +31,7 @@
 
 inline SVGAnimateTransformElement::SVGAnimateTransformElement(Document& document)
     : SVGAnimateElement(SVGNames::animateTransformTag, document)
-    , m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
+    , m_type(SVG_TRANSFORM_UNKNOWN)
 {
     ScriptWrappable::init(this);
 }
@@ -70,8 +70,8 @@
 
     if (name == SVGNames::typeAttr) {
         m_type = parseTransformType(value);
-        if (m_type == SVGTransform::SVG_TRANSFORM_MATRIX)
-            m_type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
+        if (m_type == SVG_TRANSFORM_MATRIX)
+            m_type = SVG_TRANSFORM_UNKNOWN;
         return;
     }
 
diff --git a/Source/core/svg/SVGAnimateTransformElement.h b/Source/core/svg/SVGAnimateTransformElement.h
index 16b4637..3ede192 100644
--- a/Source/core/svg/SVGAnimateTransformElement.h
+++ b/Source/core/svg/SVGAnimateTransformElement.h
@@ -34,7 +34,7 @@
 public:
     static PassRefPtr<SVGAnimateTransformElement> create(Document&);
 
-    SVGTransform::SVGTransformType transformType() const { return m_type; }
+    SVGTransformType transformType() const { return m_type; }
 
 private:
     explicit SVGAnimateTransformElement(Document&);
@@ -44,11 +44,9 @@
     bool isSupportedAttribute(const QualifiedName&);
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
 
-    SVGTransform::SVGTransformType m_type;
+    SVGTransformType m_type;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGAnimateTransformElement, hasTagName(SVGNames::animateTransformTag));
-
 } // namespace WebCore
 
 #endif // SVGAnimateTransformElement_h
diff --git a/Source/core/svg/SVGAnimatedAngle.cpp b/Source/core/svg/SVGAnimatedAngle.cpp
index a6265e5..ad42628 100644
--- a/Source/core/svg/SVGAnimatedAngle.cpp
+++ b/Source/core/svg/SVGAnimatedAngle.cpp
@@ -1,152 +1,81 @@
 /*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
 #include "core/svg/SVGAnimatedAngle.h"
 
-#include "bindings/v8/ExceptionStatePlaceholder.h"
-#include "core/svg/SVGAnimateElement.h"
+#include "SVGNames.h"
+#include "core/svg/SVGAngleTearOff.h"
 #include "core/svg/SVGMarkerElement.h"
 
 namespace WebCore {
 
-SVGAnimatedAngleAnimator::SVGAnimatedAngleAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedAngle, animationElement, contextElement)
+SVGAnimatedAngle::SVGAnimatedAngle(SVGMarkerElement* contextElement)
+    : NewSVGAnimatedProperty<SVGAngle>(contextElement, SVGNames::orientAttr, SVGAngle::create())
+    , m_orientType(SVGAnimatedEnumeration<SVGMarkerOrientType>::create(contextElement, SVGNames::orientAttr, baseValue()->orientType()))
 {
 }
 
-PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::constructFromString(const String& string)
+SVGAnimatedAngle::~SVGAnimatedAngle()
 {
-    OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createAngleAndEnumeration(new pair<SVGAngle, unsigned>);
-    pair<SVGAngle, unsigned>& animatedPair = animatedType->angleAndEnumeration();
-
-    SVGAngle angle;
-    SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(string,  angle);
-    if (orientType > 0)
-        animatedPair.second = orientType;
-    if (orientType == SVGMarkerOrientAngle)
-        animatedPair.first = angle;
-
-    return animatedType.release();
 }
 
-PassOwnPtr<SVGAnimatedType> SVGAnimatedAngleAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
+void SVGAnimatedAngle::synchronizeAttribute()
 {
-    return SVGAnimatedType::createAngleAndEnumeration(constructFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes));
+    ASSERT(needsSynchronizeAttribute());
+
+    AtomicString value;
+    if (m_orientType->currentValue()->enumValue() == SVGMarkerOrientAuto)
+        value = "auto";
+    else
+        value = AtomicString(currentValue()->valueAsString());
+
+    contextElement()->setSynchronizedLazyAttribute(attributeName(), value);
 }
 
-void SVGAnimatedAngleAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
+void SVGAnimatedAngle::animationStarted()
 {
-    stopAnimValAnimationForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
+    NewSVGAnimatedProperty<SVGAngle>::animationStarted();
+    m_orientType->animationStarted();
 }
 
-void SVGAnimatedAngleAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
+void SVGAnimatedAngle::setAnimatedValue(PassRefPtr<NewSVGPropertyBase> value)
 {
-    resetFromBaseValues<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::angleAndEnumeration);
+    NewSVGAnimatedProperty<SVGAngle>::setAnimatedValue(value);
+    m_orientType->setAnimatedValue(currentValue()->orientType());
 }
 
-void SVGAnimatedAngleAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
+void SVGAnimatedAngle::animationEnded()
 {
-    animValWillChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedAngleAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForTypes<SVGAnimatedAngle, SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedAngleAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    ASSERT(from->type() == AnimatedAngle);
-    ASSERT(from->type() == to->type());
-
-    const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = from->angleAndEnumeration();
-    pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
-    // Only respect by animations, if from and by are both specified in angles (and not eg. 'auto').
-    if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second || fromAngleAndEnumeration.second != SVGMarkerOrientAngle)
-        return;
-    const SVGAngle& fromAngle = fromAngleAndEnumeration.first;
-    SVGAngle& toAngle = toAngleAndEnumeration.first;
-    toAngle.setValue(toAngle.value() + fromAngle.value());
-}
-
-void SVGAnimatedAngleAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    const pair<SVGAngle, unsigned>& fromAngleAndEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->angleAndEnumeration() : from->angleAndEnumeration();
-    const pair<SVGAngle, unsigned>& toAngleAndEnumeration = to->angleAndEnumeration();
-    const pair<SVGAngle, unsigned>& toAtEndOfDurationAngleAndEnumeration = toAtEndOfDuration->angleAndEnumeration();
-    pair<SVGAngle, unsigned>& animatedAngleAndEnumeration = animated->angleAndEnumeration();
-
-    if (fromAngleAndEnumeration.second != toAngleAndEnumeration.second) {
-        // Animating from eg. auto to 90deg, or auto to 90deg.
-        if (fromAngleAndEnumeration.second == SVGMarkerOrientAngle) {
-            // Animating from an angle value to eg. 'auto' - this disabled additive as 'auto' is a keyword..
-            if (toAngleAndEnumeration.second == SVGMarkerOrientAuto) {
-                if (percentage < 0.5f) {
-                    animatedAngleAndEnumeration.first = fromAngleAndEnumeration.first;
-                    animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
-                    return;
-                }
-                animatedAngleAndEnumeration.first.setValue(0);
-                animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
-                return;
-            }
-            animatedAngleAndEnumeration.first.setValue(0);
-            animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
-            return;
-        }
-    }
-
-    // From 'auto' to 'auto'.
-    if (fromAngleAndEnumeration.second == SVGMarkerOrientAuto) {
-        animatedAngleAndEnumeration.first.setValue(0);
-        animatedAngleAndEnumeration.second = SVGMarkerOrientAuto;
-        return;
-    }
-
-    // If the enumeration value is not angle or auto, its unknown.
-    if (fromAngleAndEnumeration.second != SVGMarkerOrientAngle) {
-        animatedAngleAndEnumeration.first.setValue(0);
-        animatedAngleAndEnumeration.second = SVGMarkerOrientUnknown;
-        return;
-    }
-
-    // Regular from angle to angle animation, with all features like additive etc.
-    animatedAngleAndEnumeration.second = SVGMarkerOrientAngle;
-
-    SVGAngle& animatedSVGAngle = animatedAngleAndEnumeration.first;
-    const SVGAngle& toAtEndOfDurationSVGAngle = toAtEndOfDurationAngleAndEnumeration.first;
-    float animatedAngle = animatedSVGAngle.value();
-    m_animationElement->animateAdditiveNumber(percentage, repeatCount, fromAngleAndEnumeration.first.value(), toAngleAndEnumeration.first.value(), toAtEndOfDurationSVGAngle.value(), animatedAngle);
-    animatedSVGAngle.setValue(animatedAngle);
-}
-
-float SVGAnimatedAngleAnimator::calculateDistance(const String& fromString, const String& toString)
-{
-    SVGAngle from = SVGAngle();
-    from.setValueAsString(fromString, ASSERT_NO_EXCEPTION);
-    SVGAngle to = SVGAngle();
-    to.setValueAsString(toString, ASSERT_NO_EXCEPTION);
-    return fabsf(to.value() - from.value());
+    NewSVGAnimatedProperty<SVGAngle>::animationEnded();
+    m_orientType->animationEnded();
 }
 
 }
diff --git a/Source/core/svg/SVGAnimatedAngle.h b/Source/core/svg/SVGAnimatedAngle.h
index 2adbf19..72e4c3c 100644
--- a/Source/core/svg/SVGAnimatedAngle.h
+++ b/Source/core/svg/SVGAnimatedAngle.h
@@ -1,60 +1,69 @@
 /*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef SVGAnimatedAngle_h
 #define SVGAnimatedAngle_h
 
-#include "core/svg/SVGAngle.h"
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedPropertyTearOff.h"
+#include "core/svg/SVGAngleTearOff.h"
+#include "core/svg/SVGAnimatedEnumeration.h"
 
 namespace WebCore {
 
-typedef SVGAnimatedPropertyTearOff<SVGAngle> SVGAnimatedAngle;
+class SVGMarkerElement;
 
-// Helper macros to declare/define a SVGAnimatedAngle object. SVGAnimatedAngle is only used in the SVG DOM for SVGMarkerElement.
-#define DECLARE_ANIMATED_ANGLE(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedAngle, SVGAngle, UpperProperty, LowerProperty)
-
-// Only used for SVGMarkerElements orientAttr, which maps to SVGAnimatedAngle orientAngle and SVGAnimatedEnumeration orientType.
-#define DEFINE_ANIMATED_ANGLE_AND_ENUMERATION(OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedAngle, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, SVGAnimatedAngle, SVGAngle)
-
-class SVGAnimationElement;
-
-class SVGAnimatedAngleAnimator FINAL : public SVGAnimatedTypeAnimator {
+class SVGAnimatedAngle FINAL : public NewSVGAnimatedProperty<SVGAngle> {
 public:
-    SVGAnimatedAngleAnimator(SVGAnimationElement*, SVGElement*);
-    virtual ~SVGAnimatedAngleAnimator() { }
+    static PassRefPtr<SVGAnimatedAngle> create(SVGMarkerElement* contextElement)
+    {
+        return adoptRef(new SVGAnimatedAngle(contextElement));
+    }
 
-    virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) OVERRIDE;
-    virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) OVERRIDE;
-    virtual void animValWillChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void animValDidChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
+    virtual ~SVGAnimatedAngle();
 
-    virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual float calculateDistance(const String& fromString, const String& toString) OVERRIDE;
+    SVGAnimatedEnumeration<SVGMarkerOrientType>* orientType() { return m_orientType.get(); }
+
+    // NewSVGAnimatedPropertyBase:
+
+    virtual void synchronizeAttribute() OVERRIDE;
+
+    virtual void animationStarted() OVERRIDE;
+    virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) OVERRIDE;
+    virtual void animationEnded() OVERRIDE;
+
+protected:
+    SVGAnimatedAngle(SVGMarkerElement* contextElement);
+
+private:
+    RefPtr<SVGAnimatedEnumeration<SVGMarkerOrientType> > m_orientType;
 };
 
 } // namespace WebCore
 
-#endif
+#endif // SVGAnimatedAngle_h
diff --git a/Source/core/svg/SVGAnimatedAngle.idl b/Source/core/svg/SVGAnimatedAngle.idl
index 9a51845..7fe115c 100644
--- a/Source/core/svg/SVGAnimatedAngle.idl
+++ b/Source/core/svg/SVGAnimatedAngle.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedAngle {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedAngle {
     readonly attribute SVGAngle baseVal;
     readonly attribute SVGAngle animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedBoolean.idl b/Source/core/svg/SVGAnimatedBoolean.idl
index b78954a..9b0703c 100644
--- a/Source/core/svg/SVGAnimatedBoolean.idl
+++ b/Source/core/svg/SVGAnimatedBoolean.idl
@@ -24,9 +24,9 @@
  */
 
 [
+    SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGAnimatedBoolean {
     [RaisesException=Setter] attribute boolean baseVal;
     readonly attribute boolean animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedColor.cpp b/Source/core/svg/SVGAnimatedColor.cpp
index 42ec7ea..969f28b 100644
--- a/Source/core/svg/SVGAnimatedColor.cpp
+++ b/Source/core/svg/SVGAnimatedColor.cpp
@@ -24,7 +24,6 @@
 #include "core/rendering/RenderObject.h"
 #include "core/svg/ColorDistance.h"
 #include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGColor.h"
 
 namespace WebCore {
 
@@ -37,7 +36,7 @@
 {
     // SVGAnimatedColor is deprecated. So No SVG DOM animation.
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 static inline Color fallbackColorForCurrentColor(SVGElement* targetElement)
diff --git a/Source/core/svg/SVGAnimatedEnumeration.cpp b/Source/core/svg/SVGAnimatedEnumeration.cpp
deleted file mode 100644
index d23f38e..0000000
--- a/Source/core/svg/SVGAnimatedEnumeration.cpp
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedEnumeration.h"
-
-#include "SVGNames.h"
-#include "core/svg/SVGAnimationElement.h"
-#include "core/svg/SVGComponentTransferFunctionElement.h"
-#include "core/svg/SVGFEBlendElement.h"
-#include "core/svg/SVGFEColorMatrixElement.h"
-#include "core/svg/SVGFECompositeElement.h"
-#include "core/svg/SVGFEConvolveMatrixElement.h"
-#include "core/svg/SVGFEDisplacementMapElement.h"
-#include "core/svg/SVGFEMorphologyElement.h"
-#include "core/svg/SVGFETurbulenceElement.h"
-#include "core/svg/SVGGradientElement.h"
-#include "core/svg/SVGMarkerElement.h"
-#include "core/svg/SVGTextContentElement.h"
-#include "core/svg/SVGTextPathElement.h"
-#include "core/svg/SVGUnitTypes.h"
-
-namespace WebCore {
-
-static inline unsigned enumerationValueForTargetAttribute(SVGElement* targetElement, const QualifiedName& attrName, const String& value)
-{
-    ASSERT(targetElement);
-    if (attrName == SVGNames::clipPathUnitsAttr
-        || attrName == SVGNames::filterUnitsAttr
-        || attrName == SVGNames::gradientUnitsAttr
-        || attrName == SVGNames::maskContentUnitsAttr
-        || attrName == SVGNames::maskUnitsAttr
-        || attrName == SVGNames::patternContentUnitsAttr
-        || attrName == SVGNames::patternUnitsAttr
-        || attrName == SVGNames::primitiveUnitsAttr)
-        return SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-
-    if (attrName == SVGNames::lengthAdjustAttr)
-        return SVGPropertyTraits<SVGLengthAdjustType>::fromString(value);
-    if (attrName == SVGNames::markerUnitsAttr)
-        return SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value);
-    if (attrName == SVGNames::methodAttr)
-        return SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
-    if (attrName == SVGNames::spacingAttr)
-        return SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
-    if (attrName == SVGNames::spreadMethodAttr)
-        return SVGPropertyTraits<SVGSpreadMethodType>::fromString(value);
-
-    if (attrName == SVGNames::edgeModeAttr)
-        return SVGPropertyTraits<EdgeModeType>::fromString(value);
-
-    if (attrName == SVGNames::operatorAttr) {
-        if (targetElement->hasTagName(SVGNames::feCompositeTag))
-            return SVGPropertyTraits<CompositeOperationType>::fromString(value);
-        ASSERT(targetElement->hasTagName(SVGNames::feMorphologyTag));
-        return SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
-    }
-
-    if (attrName == SVGNames::typeAttr) {
-        if (targetElement->hasTagName(SVGNames::feColorMatrixTag))
-            return SVGPropertyTraits<ColorMatrixType>::fromString(value);
-        if (targetElement->hasTagName(SVGNames::feTurbulenceTag))
-            return SVGPropertyTraits<TurbulenceType>::fromString(value);
-
-        ASSERT(targetElement->hasTagName(SVGNames::feFuncATag)
-               || targetElement->hasTagName(SVGNames::feFuncBTag)
-               || targetElement->hasTagName(SVGNames::feFuncGTag)
-               || targetElement->hasTagName(SVGNames::feFuncRTag));
-        return SVGPropertyTraits<ComponentTransferType>::fromString(value);
-    }
-
-    if (attrName == SVGNames::modeAttr)
-        return SVGPropertyTraits<BlendModeType>::fromString(value);
-    if (attrName == SVGNames::stitchTilesAttr)
-        return SVGPropertyTraits<SVGStitchOptions>::fromString(value);
-    if (attrName == SVGNames::xChannelSelectorAttr)
-        return SVGPropertyTraits<ChannelSelectorType>::fromString(value);
-    if (attrName == SVGNames::yChannelSelectorAttr)
-        return SVGPropertyTraits<ChannelSelectorType>::fromString(value);
-
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-SVGAnimatedEnumerationAnimator::SVGAnimatedEnumerationAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedEnumeration, animationElement, contextElement)
-{
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedEnumerationAnimator::constructFromString(const String& string)
-{
-    ASSERT(m_animationElement);
-    OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createEnumeration(new unsigned);
-    animatedType->enumeration() = enumerationValueForTargetAttribute(m_animationElement->targetElement(), m_animationElement->attributeName(), string);
-    return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedEnumerationAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    return SVGAnimatedType::createEnumeration(constructFromBaseValue<SVGAnimatedEnumeration>(animatedTypes));
-}
-
-void SVGAnimatedEnumerationAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    stopAnimValAnimationForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
-    resetFromBaseValue<SVGAnimatedEnumeration>(animatedTypes, type, &SVGAnimatedType::enumeration);
-}
-
-void SVGAnimatedEnumerationAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValWillChangeForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForType<SVGAnimatedEnumeration>(animatedTypes);
-}
-
-void SVGAnimatedEnumerationAnimator::addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*)
-{
-    ASSERT_NOT_REACHED();
-}
-
-void SVGAnimatedEnumerationAnimator::calculateAnimatedValue(float percentage, unsigned, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType*, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    unsigned fromEnumeration = m_animationElement->animationMode() == ToAnimation ? animated->enumeration() : from->enumeration();
-    unsigned toEnumeration = to->enumeration();
-    unsigned& animatedEnumeration = animated->enumeration();
-
-    m_animationElement->animateDiscreteType<unsigned>(percentage, fromEnumeration, toEnumeration, animatedEnumeration);
-}
-
-float SVGAnimatedEnumerationAnimator::calculateDistance(const String&, const String&)
-{
-    // No paced animations for enumerations.
-    return -1;
-}
-
-}
diff --git a/Source/core/svg/SVGAnimatedEnumeration.h b/Source/core/svg/SVGAnimatedEnumeration.h
index 939eaec..98b2f7d 100644
--- a/Source/core/svg/SVGAnimatedEnumeration.h
+++ b/Source/core/svg/SVGAnimatedEnumeration.h
@@ -1,57 +1,75 @@
 /*
- * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef SVGAnimatedEnumeration_h
 #define SVGAnimatedEnumeration_h
 
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
+#include "core/svg/SVGAnimatedEnumerationBase.h"
 
 namespace WebCore {
 
-typedef SVGAnimatedStaticPropertyTearOff<unsigned> SVGAnimatedEnumeration;
-
-// Helper macros to declare/define a SVGAnimatedEnumeration object
-#define DECLARE_ANIMATED_ENUMERATION(UpperProperty, LowerProperty, EnumType) \
-DECLARE_ANIMATED_PROPERTY(SVGAnimatedEnumerationPropertyTearOff<EnumType>, EnumType, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_ENUMERATION(OwnerType, DOMAttribute, UpperProperty, LowerProperty, EnumType) \
-DEFINE_ANIMATED_PROPERTY(AnimatedEnumeration, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedEnumerationPropertyTearOff<EnumType>, EnumType)
-
-class SVGAnimatedEnumerationAnimator FINAL : public SVGAnimatedTypeAnimator {
+template<typename Enum>
+class SVGAnimatedEnumeration : public SVGAnimatedEnumerationBase {
 public:
-    SVGAnimatedEnumerationAnimator(SVGAnimationElement*, SVGElement*);
-    virtual ~SVGAnimatedEnumerationAnimator() { }
+    static PassRefPtr<SVGAnimatedEnumeration<Enum> > create(SVGElement* contextElement, const QualifiedName& attributeName, Enum initialValue)
+    {
+        return adoptRef(new SVGAnimatedEnumeration(contextElement, attributeName, SVGEnumeration<Enum>::create(initialValue)));
+    }
 
-    virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) OVERRIDE;
-    virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) OVERRIDE;
-    virtual void animValWillChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void animValDidChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
+    static PassRefPtr<SVGAnimatedEnumeration<Enum> > create(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGEnumeration<Enum> > initialValue)
+    {
+        return adoptRef(new SVGAnimatedEnumeration(contextElement, attributeName, initialValue));
+    }
 
-    virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual float calculateDistance(const String& fromString, const String& toString) OVERRIDE;
+    SVGEnumeration<Enum>* baseValue()
+    {
+        return static_cast<SVGEnumeration<Enum>*>(SVGAnimatedEnumerationBase::baseValue());
+    }
+
+    SVGEnumeration<Enum>* currentValue()
+    {
+        return static_cast<SVGEnumeration<Enum>*>(SVGAnimatedEnumerationBase::currentValue());
+    }
+
+    const SVGEnumeration<Enum>* currentValue() const
+    {
+        return static_cast<const SVGEnumeration<Enum>*>(SVGAnimatedEnumerationBase::currentValue());
+    }
+
+protected:
+    SVGAnimatedEnumeration(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGEnumeration<Enum> > initialValue)
+        : SVGAnimatedEnumerationBase(contextElement, attributeName, initialValue)
+    {
+    }
 };
 
 } // namespace WebCore
 
-#endif
+#endif // SVGAnimatedEnumeration_h
diff --git a/Source/core/svg/SVGAnimatedEnumeration.idl b/Source/core/svg/SVGAnimatedEnumeration.idl
index 7ed1d19..868519c 100644
--- a/Source/core/svg/SVGAnimatedEnumeration.idl
+++ b/Source/core/svg/SVGAnimatedEnumeration.idl
@@ -24,6 +24,8 @@
  */
 
 [
+    ImplementedAs=SVGAnimatedEnumerationBase,
+    SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGAnimatedEnumeration {
     [RaisesException=Setter] attribute unsigned short baseVal;
diff --git a/Source/core/html/HTMLImportStateResolver.h b/Source/core/svg/SVGAnimatedEnumerationBase.cpp
similarity index 66%
copy from Source/core/html/HTMLImportStateResolver.h
copy to Source/core/svg/SVGAnimatedEnumerationBase.cpp
index 417680c..8c42b4c 100644
--- a/Source/core/html/HTMLImportStateResolver.h
+++ b/Source/core/svg/SVGAnimatedEnumerationBase.cpp
@@ -28,34 +28,36 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef HTMLImportStateResolver_h
-#define HTMLImportStateResolver_h
+#include "config.h"
 
-#include "core/html/HTMLImportState.h"
+#include "core/svg/SVGAnimatedEnumerationBase.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGElement.h"
 
 namespace WebCore {
 
-class HTMLImport;
-
-class HTMLImportStateResolver {
-public:
-    explicit HTMLImportStateResolver(HTMLImport* import)
-        : m_import(import)
-    { }
-
-    HTMLImportState resolve() const;
-
-private:
-    static bool isBlockingFollowers(HTMLImport*);
-
-    bool shouldBlockDocumentCreation() const;
-    bool shouldBlockScriptExecution() const;
-    bool isActive() const;
-
-    HTMLImport* m_import;
-};
-
+SVGAnimatedEnumerationBase::~SVGAnimatedEnumerationBase()
+{
 }
 
-#endif // HTMLImportStateResolver_h
+void SVGAnimatedEnumerationBase::setBaseVal(unsigned short value, ExceptionState& exceptionState)
+{
+    if (this->isReadOnly()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
 
+    baseValue()->setValue(value, exceptionState);
+    if (exceptionState.hadException())
+        return;
+
+    m_baseValueUpdated = true;
+
+    ASSERT(this->attributeName() != nullQName());
+    contextElement()->invalidateSVGAttributes();
+    contextElement()->svgAttributeChanged(this->attributeName());
+}
+
+}
diff --git a/Source/core/html/HTMLImportStateResolver.h b/Source/core/svg/SVGAnimatedEnumerationBase.h
similarity index 70%
copy from Source/core/html/HTMLImportStateResolver.h
copy to Source/core/svg/SVGAnimatedEnumerationBase.h
index 417680c..16a8bd1 100644
--- a/Source/core/html/HTMLImportStateResolver.h
+++ b/Source/core/svg/SVGAnimatedEnumerationBase.h
@@ -28,34 +28,27 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef HTMLImportStateResolver_h
-#define HTMLImportStateResolver_h
+#ifndef SVGAnimatedEnumerationBase_h
+#define SVGAnimatedEnumerationBase_h
 
-#include "core/html/HTMLImportState.h"
+#include "core/svg/SVGEnumeration.h"
+#include "core/svg/properties/NewSVGAnimatedProperty.h"
 
 namespace WebCore {
 
-class HTMLImport;
-
-class HTMLImportStateResolver {
+class SVGAnimatedEnumerationBase : public NewSVGAnimatedProperty<SVGEnumerationBase> {
 public:
-    explicit HTMLImportStateResolver(HTMLImport* import)
-        : m_import(import)
-    { }
+    virtual ~SVGAnimatedEnumerationBase();
 
-    HTMLImportState resolve() const;
+    void setBaseVal(unsigned short, ExceptionState&);
 
-private:
-    static bool isBlockingFollowers(HTMLImport*);
-
-    bool shouldBlockDocumentCreation() const;
-    bool shouldBlockScriptExecution() const;
-    bool isActive() const;
-
-    HTMLImport* m_import;
+protected:
+    SVGAnimatedEnumerationBase(SVGElement* contextElement, const QualifiedName& attributeName, PassRefPtr<SVGEnumerationBase> initialValue)
+        : NewSVGAnimatedProperty<SVGEnumerationBase>(contextElement, attributeName, initialValue)
+    {
+    }
 };
 
 }
 
-#endif // HTMLImportStateResolver_h
-
+#endif // SVGAnimatedEnumerationBase_h
diff --git a/Source/core/svg/SVGAnimatedInteger.idl b/Source/core/svg/SVGAnimatedInteger.idl
index 14287a3..78ad65a 100644
--- a/Source/core/svg/SVGAnimatedInteger.idl
+++ b/Source/core/svg/SVGAnimatedInteger.idl
@@ -24,6 +24,7 @@
  */
 
 [
+    SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGAnimatedInteger {
     [RaisesException=Setter] attribute long baseVal;
diff --git a/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp b/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp
index b87e561..bf4fc44 100644
--- a/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp
+++ b/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp
@@ -65,20 +65,6 @@
     m_secondInteger->animationEnded();
 }
 
-void SVGAnimatedIntegerOptionalInteger::animValWillChange()
-{
-    NewSVGAnimatedPropertyCommon<SVGIntegerOptionalInteger>::animValWillChange();
-    m_firstInteger->animValWillChange();
-    m_secondInteger->animValWillChange();
-}
-
-void SVGAnimatedIntegerOptionalInteger::animValDidChange()
-{
-    NewSVGAnimatedPropertyCommon<SVGIntegerOptionalInteger>::animValDidChange();
-    m_firstInteger->animValDidChange();
-    m_secondInteger->animValDidChange();
-}
-
 bool SVGAnimatedIntegerOptionalInteger::needsSynchronizeAttribute()
 {
     return m_firstInteger->needsSynchronizeAttribute()
diff --git a/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h b/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h
index 0c1a272..a0e3352 100644
--- a/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h
+++ b/Source/core/svg/SVGAnimatedIntegerOptionalInteger.h
@@ -52,8 +52,6 @@
     virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) OVERRIDE;
     virtual bool needsSynchronizeAttribute() OVERRIDE;
     virtual void animationEnded() OVERRIDE;
-    virtual void animValWillChange() OVERRIDE;
-    virtual void animValDidChange() OVERRIDE;
 
     SVGAnimatedInteger* firstInteger() { return m_firstInteger.get(); }
     SVGAnimatedInteger* secondInteger() { return m_secondInteger.get(); }
diff --git a/Source/core/svg/SVGAnimatedLength.idl b/Source/core/svg/SVGAnimatedLength.idl
index d300347..c741a20 100644
--- a/Source/core/svg/SVGAnimatedLength.idl
+++ b/Source/core/svg/SVGAnimatedLength.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedLength {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedLength {
     readonly attribute SVGLength baseVal;
     readonly attribute SVGLength animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedLengthList.idl b/Source/core/svg/SVGAnimatedLengthList.idl
index f193b7c..ec507a3 100644
--- a/Source/core/svg/SVGAnimatedLengthList.idl
+++ b/Source/core/svg/SVGAnimatedLengthList.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedLengthList {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedLengthList {
     readonly attribute SVGLengthList baseVal;
     readonly attribute SVGLengthList animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp b/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp
deleted file mode 100644
index 328f822..0000000
--- a/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "core/svg/SVGAnimatedNewPropertyAnimator.h"
-
-#include "core/svg/SVGAnimatedColor.h"
-#include "core/svg/SVGAnimationElement.h"
-#include "core/svg/SVGElementInstance.h"
-#include "core/svg/SVGLength.h"
-#include "core/svg/SVGLengthList.h"
-#include "core/svg/SVGNumber.h"
-#include "core/svg/SVGPointList.h"
-#include "core/svg/SVGString.h"
-
-namespace WebCore {
-
-SVGAnimatedNewPropertyAnimator::SVGAnimatedNewPropertyAnimator(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(type, animationElement, contextElement)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    const QualifiedName& attributeName = m_animationElement->attributeName();
-    m_animatedProperty = m_contextElement->propertyFromAttribute(attributeName);
-    if (m_animatedProperty)
-        ASSERT(m_animatedProperty->type() == m_type);
-}
-
-SVGAnimatedNewPropertyAnimator::~SVGAnimatedNewPropertyAnimator()
-{
-}
-
-PassRefPtr<NewSVGPropertyBase> SVGAnimatedNewPropertyAnimator::createPropertyForAnimation(const String& value)
-{
-    if (isAnimatingSVGDom()) {
-        ASSERT(m_animatedProperty);
-
-        // SVG DOM animVal animation code-path.
-        return m_animatedProperty->currentValueBase()->cloneForAnimation(value);
-    }
-
-    ASSERT(isAnimatingCSSProperty());
-
-    // CSS properties animation code-path.
-    // Create a basic instance of the corresponding SVG property.
-    // The instance will not have full context info. (e.g. SVGLengthMode)
-
-    switch (m_type) {
-    case AnimatedColor:
-        return SVGColorProperty::create(value.isEmpty() ? StyleColor::currentColor() : SVGColor::colorFromRGBColorString(value));
-    case AnimatedNumber: {
-        RefPtr<SVGNumber> property = SVGNumber::create();
-        property->setValueAsString(value, IGNORE_EXCEPTION);
-        return property.release();
-    }
-    case AnimatedLength: {
-        RefPtr<SVGLength> property = SVGLength::create(LengthModeOther);
-        property->setValueAsString(value, IGNORE_EXCEPTION);
-        return property.release();
-    }
-    case AnimatedLengthList: {
-        RefPtr<SVGLengthList> property = SVGLengthList::create(LengthModeOther);
-        property->setValueAsString(value, IGNORE_EXCEPTION);
-        return property.release();
-    }
-    case AnimatedString: {
-        RefPtr<SVGString> property = SVGString::create();
-        property->setValueAsString(value, IGNORE_EXCEPTION);
-        return property.release();
-    }
-
-    // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need support.
-    case AnimatedBoolean:
-    case AnimatedNumberList:
-    case AnimatedNumberOptionalNumber:
-    case AnimatedPoint:
-    case AnimatedPoints:
-    case AnimatedRect:
-        ASSERT_NOT_REACHED();
-
-    // These properties are not yet migrated to NewProperty implementation. see http://crbug.com/308818
-    case AnimatedAngle:
-    case AnimatedEnumeration:
-    case AnimatedInteger:
-    case AnimatedIntegerOptionalInteger:
-    case AnimatedPath:
-    case AnimatedPreserveAspectRatio:
-    case AnimatedStringList:
-    case AnimatedTransformList:
-        ASSERT_NOT_REACHED();
-
-    case AnimatedUnknown:
-        ASSERT_NOT_REACHED();
-    };
-
-    ASSERT_NOT_REACHED();
-    return 0;
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNewPropertyAnimator::constructFromString(const String& value)
-{
-    return SVGAnimatedType::createNewProperty(createPropertyForAnimation(value));
-}
-
-namespace {
-
-typedef void (NewSVGAnimatedPropertyBase::*NewSVGAnimatedPropertyMethod)();
-
-void invokeMethodOnAllTargetProperties(const SVGElementAnimatedPropertyList& list, const QualifiedName& attributeName, NewSVGAnimatedPropertyMethod method)
-{
-    SVGElementAnimatedPropertyList::const_iterator it = list.begin();
-    SVGElementAnimatedPropertyList::const_iterator itEnd = list.end();
-    for (; it != itEnd; ++it) {
-        RefPtr<NewSVGAnimatedPropertyBase> animatedProperty = it->element->propertyFromAttribute(attributeName);
-        if (animatedProperty)
-            (animatedProperty.get()->*method)();
-    }
-}
-
-void setAnimatedValueOnAllTargetProperties(const SVGElementAnimatedPropertyList& list, const QualifiedName& attributeName, PassRefPtr<NewSVGPropertyBase> passValue)
-{
-    RefPtr<NewSVGPropertyBase> value = passValue;
-
-    SVGElementAnimatedPropertyList::const_iterator it = list.begin();
-    SVGElementAnimatedPropertyList::const_iterator itEnd = list.end();
-    for (; it != itEnd; ++it) {
-        RefPtr<NewSVGAnimatedPropertyBase> animatedProperty = it->element->propertyFromAttribute(attributeName);
-        if (animatedProperty)
-            animatedProperty->setAnimatedValue(value);
-    }
-}
-
-}
-
-PassRefPtr<NewSVGPropertyBase> SVGAnimatedNewPropertyAnimator::resetAnimation(const SVGElementAnimatedPropertyList& list)
-{
-    ASSERT(isAnimatingSVGDom());
-    RefPtr<NewSVGPropertyBase> animatedValue = m_animatedProperty->createAnimatedValue();
-    ASSERT(animatedValue->type() == m_type);
-    setAnimatedValueOnAllTargetProperties(list, m_animatedProperty->attributeName(), animatedValue);
-
-    return animatedValue.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedNewPropertyAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& list)
-{
-    ASSERT(isAnimatingSVGDom());
-    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
-
-    invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animationStarted);
-
-    return SVGAnimatedType::createNewProperty(resetAnimation(list));
-}
-
-void SVGAnimatedNewPropertyAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& list)
-{
-    ASSERT(isAnimatingSVGDom());
-    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
-
-    invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animationEnded);
-}
-
-void SVGAnimatedNewPropertyAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& list, SVGAnimatedType* animated)
-{
-    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
-
-    animated->newProperty() = resetAnimation(list);
-}
-
-void SVGAnimatedNewPropertyAnimator::animValWillChange(const SVGElementAnimatedPropertyList& list)
-{
-    ASSERT(isAnimatingSVGDom());
-    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
-
-    invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animValWillChange);
-}
-
-void SVGAnimatedNewPropertyAnimator::animValDidChange(const SVGElementAnimatedPropertyList& list)
-{
-    ASSERT(isAnimatingSVGDom());
-    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
-
-    invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animValDidChange);
-}
-
-void SVGAnimatedNewPropertyAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    to->newProperty()->add(from->newProperty(), m_contextElement);
-}
-
-class ParsePropertyFromString {
-public:
-    explicit ParsePropertyFromString(SVGAnimatedNewPropertyAnimator* animator)
-        : m_animator(animator)
-    {
-    }
-
-    PassRefPtr<NewSVGPropertyBase> operator()(SVGAnimationElement*, const String& value)
-    {
-        return m_animator->createPropertyForAnimation(value);
-    }
-
-private:
-    SVGAnimatedNewPropertyAnimator* m_animator;
-};
-
-void SVGAnimatedNewPropertyAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    RefPtr<NewSVGPropertyBase> fromValue = m_animationElement->animationMode() == ToAnimation ? animated->newProperty() : from->newProperty();
-    RefPtr<NewSVGPropertyBase> toValue = to->newProperty();
-    RefPtr<NewSVGPropertyBase> toAtEndOfDurationValue = toAtEndOfDuration->newProperty();
-    RefPtr<NewSVGPropertyBase> animatedValue = animated->newProperty();
-
-    // Apply CSS inheritance rules.
-    ParsePropertyFromString parsePropertyFromString(this);
-    m_animationElement->adjustForInheritance<RefPtr<NewSVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->fromPropertyValueType(), fromValue, m_contextElement);
-    m_animationElement->adjustForInheritance<RefPtr<NewSVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->toPropertyValueType(), toValue, m_contextElement);
-
-    animatedValue->calculateAnimatedValue(m_animationElement, percentage, repeatCount, fromValue, toValue, toAtEndOfDurationValue, m_contextElement);
-}
-
-float SVGAnimatedNewPropertyAnimator::calculateDistance(const String& fromString, const String& toString)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-    RefPtr<NewSVGPropertyBase> fromValue = createPropertyForAnimation(fromString);
-    RefPtr<NewSVGPropertyBase> toValue = createPropertyForAnimation(toString);
-    return fromValue->calculateDistance(toValue, m_contextElement);
-}
-
-} // namespace WebCore
diff --git a/Source/core/svg/SVGAnimatedNewPropertyAnimator.h b/Source/core/svg/SVGAnimatedNewPropertyAnimator.h
deleted file mode 100644
index 4057e31..0000000
--- a/Source/core/svg/SVGAnimatedNewPropertyAnimator.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef SVGAnimatedNewPropertyAnimator_h
-#define SVGAnimatedNewPropertyAnimator_h
-
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-
-namespace WebCore {
-
-class NewSVGAnimatedPropertyBase;
-
-// Bridges new SVGProperty impl. to existing SVG animation impl.
-class SVGAnimatedNewPropertyAnimator FINAL : public SVGAnimatedTypeAnimator {
-public:
-    SVGAnimatedNewPropertyAnimator(AnimatedPropertyType, SVGAnimationElement*, SVGElement*);
-    virtual ~SVGAnimatedNewPropertyAnimator();
-
-    PassRefPtr<NewSVGPropertyBase> createPropertyForAnimation(const String&);
-
-    // SVGAnimatedTypeAnimator:
-    virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) OVERRIDE;
-
-    virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) OVERRIDE;
-    virtual void animValWillChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void animValDidChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-
-    virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual float calculateDistance(const String& fromString, const String& toString) OVERRIDE;
-
-private:
-    PassRefPtr<NewSVGPropertyBase> resetAnimation(const SVGElementAnimatedPropertyList&);
-
-    bool isAnimatingSVGDom() const { return m_animatedProperty; }
-    bool isAnimatingCSSProperty() const { return !m_animatedProperty; }
-
-    RefPtr<NewSVGAnimatedPropertyBase> m_animatedProperty;
-};
-
-} // namespace WebCore
-
-#endif // SVGAnimatedNewPropertyAnimator_h
diff --git a/Source/core/svg/SVGAnimatedNumber.idl b/Source/core/svg/SVGAnimatedNumber.idl
index 7890bef..dc92eb7 100644
--- a/Source/core/svg/SVGAnimatedNumber.idl
+++ b/Source/core/svg/SVGAnimatedNumber.idl
@@ -25,6 +25,7 @@
  */
 
 [
+    SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGAnimatedNumber {
     [RaisesException=Setter] attribute float baseVal;
diff --git a/Source/core/svg/SVGAnimatedNumberList.idl b/Source/core/svg/SVGAnimatedNumberList.idl
index 43845d3..355e490 100644
--- a/Source/core/svg/SVGAnimatedNumberList.idl
+++ b/Source/core/svg/SVGAnimatedNumberList.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedNumberList {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedNumberList {
     readonly attribute SVGNumberList baseVal;
     readonly attribute SVGNumberList animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp b/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp
index 1073b73..dc0247e 100644
--- a/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp
+++ b/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp
@@ -54,20 +54,6 @@
     m_secondNumber->animationEnded();
 }
 
-void SVGAnimatedNumberOptionalNumber::animValWillChange()
-{
-    NewSVGAnimatedPropertyCommon<SVGNumberOptionalNumber>::animValWillChange();
-    m_firstNumber->animValWillChange();
-    m_secondNumber->animValWillChange();
-}
-
-void SVGAnimatedNumberOptionalNumber::animValDidChange()
-{
-    NewSVGAnimatedPropertyCommon<SVGNumberOptionalNumber>::animValDidChange();
-    m_firstNumber->animValDidChange();
-    m_secondNumber->animValDidChange();
-}
-
 bool SVGAnimatedNumberOptionalNumber::needsSynchronizeAttribute()
 {
     return m_firstNumber->needsSynchronizeAttribute()
diff --git a/Source/core/svg/SVGAnimatedNumberOptionalNumber.h b/Source/core/svg/SVGAnimatedNumberOptionalNumber.h
index b9ff601..427295e 100644
--- a/Source/core/svg/SVGAnimatedNumberOptionalNumber.h
+++ b/Source/core/svg/SVGAnimatedNumberOptionalNumber.h
@@ -52,8 +52,6 @@
     virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) OVERRIDE;
     virtual bool needsSynchronizeAttribute() OVERRIDE;
     virtual void animationEnded() OVERRIDE;
-    virtual void animValWillChange() OVERRIDE;
-    virtual void animValDidChange() OVERRIDE;
 
     SVGAnimatedNumber* firstNumber() { return m_firstNumber.get(); }
     SVGAnimatedNumber* secondNumber() { return m_secondNumber.get(); }
diff --git a/Source/core/svg/SVGAnimatedPath.cpp b/Source/core/svg/SVGAnimatedPath.cpp
index 57e33dc..b487c41 100644
--- a/Source/core/svg/SVGAnimatedPath.cpp
+++ b/Source/core/svg/SVGAnimatedPath.cpp
@@ -1,147 +1,47 @@
 /*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include "config.h"
-
 #include "core/svg/SVGAnimatedPath.h"
 
-#include "core/svg/SVGAnimateElement.h"
-#include "core/svg/SVGPathUtilities.h"
-#include "core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h"
+#include "core/svg/SVGPathElement.h"
 
 namespace WebCore {
 
-SVGAnimatedPathAnimator::SVGAnimatedPathAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedPath, animationElement, contextElement)
+SVGAnimatedPath::SVGAnimatedPath(SVGPathElement* contextElement, const QualifiedName& attributeName)
+    : NewSVGAnimatedProperty<SVGPathSegList>(contextElement, attributeName, SVGPathSegList::create(contextElement, PathSegUnalteredRole))
 {
 }
 
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPathAnimator::constructFromString(const String& string)
+SVGAnimatedPath::~SVGAnimatedPath()
 {
-    OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create();
-    buildSVGPathByteStreamFromString(string, byteStream.get(), UnalteredParsing);
-    return SVGAnimatedType::createPath(byteStream.release());
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedPathAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    ASSERT(animatedTypes.size() >= 1);
-    SVGAnimatedPathSegListPropertyTearOff* property = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get());
-    const SVGPathSegList& baseValue = property->currentBaseValue();
-
-    // Build initial path byte stream.
-    OwnPtr<SVGPathByteStream> byteStream = SVGPathByteStream::create();
-    buildSVGPathByteStreamFromSVGPathSegList(baseValue, byteStream.get(), UnalteredParsing);
-
-    Vector<RefPtr<SVGAnimatedPathSegListPropertyTearOff> > result;
-
-    SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
-    for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it)
-        result.append(castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(it->properties[0].get()));
-
-    SVGElementInstance::InstanceUpdateBlocker blocker(property->contextElement());
-
-    size_t resultSize = result.size();
-    for (size_t i = 0; i < resultSize; ++i)
-        result[i]->animationStarted(byteStream.get(), &baseValue);
-
-    return SVGAnimatedType::createPath(byteStream.release());
-}
-
-void SVGAnimatedPathAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    stopAnimValAnimationForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes);
-}
-
-void SVGAnimatedPathAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
-    ASSERT(animatedTypes.size() >= 1);
-    ASSERT(type);
-    ASSERT(type->type() == m_type);
-    const SVGPathSegList& baseValue = castAnimatedPropertyToActualType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes[0].properties[0].get())->currentBaseValue();
-    buildSVGPathByteStreamFromSVGPathSegList(baseValue, type->path(), UnalteredParsing);
-}
-
-void SVGAnimatedPathAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValWillChangeForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes);
-}
-
-void SVGAnimatedPathAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForType<SVGAnimatedPathSegListPropertyTearOff>(animatedTypes);
-}
-
-void SVGAnimatedPathAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    ASSERT(from->type() == AnimatedPath);
-    ASSERT(from->type() == to->type());
-
-    SVGPathByteStream* fromPath = from->path();
-    SVGPathByteStream* toPath = to->path();
-    unsigned fromPathSize = fromPath->size();
-    if (!fromPathSize || fromPathSize != toPath->size())
-        return;
-    addToSVGPathByteStream(toPath, fromPath);
-}
-
-void SVGAnimatedPathAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-    ASSERT(m_contextElement);
-
-    SVGPathByteStream* fromPath = from->path();
-    SVGPathByteStream* toPath = to->path();
-    SVGPathByteStream* toAtEndOfDurationPath = toAtEndOfDuration->path();
-    SVGPathByteStream* animatedPath = animated->path();
-
-    OwnPtr<SVGPathByteStream> underlyingPath;
-    bool isToAnimation = m_animationElement->animationMode() == ToAnimation;
-    if (isToAnimation) {
-        underlyingPath = animatedPath->copy();
-        fromPath = underlyingPath.get();
-    }
-
-    // Cache the current animated value before the buildAnimatedSVGPathByteStream() clears animatedPath.
-    OwnPtr<SVGPathByteStream> lastAnimatedPath;
-    if (!fromPath->size() || (m_animationElement->isAdditive() && !isToAnimation))
-        lastAnimatedPath = animatedPath->copy();
-
-    // Pass false to 'resizeAnimatedListIfNeeded' here, as the path animation is not a regular Vector<SVGXXX> type, but a SVGPathByteStream, that works differently.
-    if (!m_animationElement->adjustFromToListValues<SVGPathByteStream>(*fromPath, *toPath, *animatedPath, percentage, false))
-        return;
-
-    buildAnimatedSVGPathByteStream(fromPath, toPath, animatedPath, percentage);
-
-    // Handle additive='sum'.
-    if (lastAnimatedPath)
-        addToSVGPathByteStream(animatedPath, lastAnimatedPath.get());
-
-    // Handle accumulate='sum'.
-    if (m_animationElement->isAccumulated() && repeatCount)
-        addToSVGPathByteStream(animatedPath, toAtEndOfDurationPath, repeatCount);
-}
-
-float SVGAnimatedPathAnimator::calculateDistance(const String&, const String&)
-{
-    // FIXME: Support paced animations.
-    return -1;
 }
 
 }
diff --git a/Source/core/svg/SVGAnimatedPath.h b/Source/core/svg/SVGAnimatedPath.h
index d7534b2..6e03c58 100644
--- a/Source/core/svg/SVGAnimatedPath.h
+++ b/Source/core/svg/SVGAnimatedPath.h
@@ -1,48 +1,56 @@
 /*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef SVGAnimatedPath_h
 #define SVGAnimatedPath_h
 
-#include "core/svg/SVGAnimatedTypeAnimator.h"
+#include "core/svg/SVGPathSegListTearOff.h"
+#include "core/svg/properties/NewSVGAnimatedProperty.h"
 
 namespace WebCore {
 
-class SVGAnimationElement;
+class SVGPathElement;
 
-class SVGAnimatedPathAnimator FINAL : public SVGAnimatedTypeAnimator {
+class SVGAnimatedPath : public NewSVGAnimatedProperty<SVGPathSegList> {
 public:
-    SVGAnimatedPathAnimator(SVGAnimationElement*, SVGElement*);
-    virtual ~SVGAnimatedPathAnimator() { }
+    virtual ~SVGAnimatedPath();
 
-    virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) OVERRIDE;
-    virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) OVERRIDE;
-    virtual void animValWillChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void animValDidChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
+    static PassRefPtr<SVGAnimatedPath> create(SVGPathElement* contextElement, const QualifiedName& attributeName)
+    {
+        return adoptRef(new SVGAnimatedPath(contextElement, attributeName));
+    }
 
-    virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual float calculateDistance(const String& fromString, const String& toString) OVERRIDE;
+protected:
+    SVGAnimatedPath(SVGPathElement*, const QualifiedName&);
 };
 
 } // namespace WebCore
 
-#endif
+#endif // SVGAnimatedPath_h
diff --git a/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl b/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl
index b2e6c7f..dbcb42d 100644
--- a/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl
+++ b/Source/core/svg/SVGAnimatedPreserveAspectRatio.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedPreserveAspectRatio {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedPreserveAspectRatio {
     readonly attribute SVGPreserveAspectRatio baseVal;
     readonly attribute SVGPreserveAspectRatio animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedRect.idl b/Source/core/svg/SVGAnimatedRect.idl
index 6bce556..33a7123 100644
--- a/Source/core/svg/SVGAnimatedRect.idl
+++ b/Source/core/svg/SVGAnimatedRect.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedRect {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedRect {
     readonly attribute SVGRect baseVal;
     readonly attribute SVGRect animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedString.idl b/Source/core/svg/SVGAnimatedString.idl
index d1fbf52..dec2f05 100644
--- a/Source/core/svg/SVGAnimatedString.idl
+++ b/Source/core/svg/SVGAnimatedString.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedString {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedString {
     [RaisesException=Setter] attribute DOMString baseVal;
     readonly attribute DOMString animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedTransformList.cpp b/Source/core/svg/SVGAnimatedTransformList.cpp
deleted file mode 100644
index 9a3971b..0000000
--- a/Source/core/svg/SVGAnimatedTransformList.cpp
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2008 Apple Inc. All rights reserved.
- * Copyright (C) Research In Motion Limited 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/SVGAnimatedTransformList.h"
-
-#include "SVGNames.h"
-#include "core/svg/SVGAnimateTransformElement.h"
-#include "core/svg/SVGAnimatedNumber.h"
-#include "core/svg/SVGTransformDistance.h"
-
-namespace WebCore {
-
-SVGAnimatedTransformListAnimator::SVGAnimatedTransformListAnimator(SVGAnimationElement* animationElement, SVGElement* contextElement)
-    : SVGAnimatedTypeAnimator(AnimatedTransformList, animationElement, contextElement)
-    , m_transformTypeString(SVGTransform::transformTypePrefixForParsing(toSVGAnimateTransformElement(animationElement)->transformType()))
-{
-    // Only <animateTransform> uses this animator, as <animate> doesn't allow to animate transform lists directly.
-    ASSERT(animationElement->hasTagName(SVGNames::animateTransformTag));
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedTransformListAnimator::constructFromString(const String& string)
-{
-    OwnPtr<SVGAnimatedType> animatedType = SVGAnimatedType::createTransformList(new SVGTransformList);
-    animatedType->transformList().parse(m_transformTypeString + string + ')');
-    ASSERT(animatedType->transformList().size() <= 1);
-    return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedTransformListAnimator::startAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    return SVGAnimatedType::createTransformList(constructFromBaseValue<SVGAnimatedTransformList>(animatedTypes));
-}
-
-void SVGAnimatedTransformListAnimator::stopAnimValAnimation(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    stopAnimValAnimationForType<SVGAnimatedTransformList>(animatedTypes);
-}
-
-void SVGAnimatedTransformListAnimator::resetAnimValToBaseVal(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type)
-{
-    resetFromBaseValue<SVGAnimatedTransformList>(animatedTypes, type, &SVGAnimatedType::transformList);
-}
-
-void SVGAnimatedTransformListAnimator::animValWillChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValWillChangeForType<SVGAnimatedTransformList>(animatedTypes);
-}
-
-void SVGAnimatedTransformListAnimator::animValDidChange(const SVGElementAnimatedPropertyList& animatedTypes)
-{
-    animValDidChangeForType<SVGAnimatedTransformList>(animatedTypes);
-}
-
-void SVGAnimatedTransformListAnimator::addAnimatedTypes(SVGAnimatedType* from, SVGAnimatedType* to)
-{
-    ASSERT(from->type() == AnimatedTransformList);
-    ASSERT(from->type() == to->type());
-
-    const SVGTransformList& fromTransformList = from->transformList();
-    SVGTransformList& toTransformList = to->transformList();
-    unsigned fromTransformListSize = fromTransformList.size();
-    if (!fromTransformListSize || fromTransformListSize != toTransformList.size())
-        return;
-
-    ASSERT(fromTransformListSize == 1);
-    const SVGTransform& fromTransform = fromTransformList[0];
-    SVGTransform& toTransform = toTransformList[0];
-
-    ASSERT(fromTransform.type() == toTransform.type());
-    toTransform = SVGTransformDistance::addSVGTransforms(fromTransform, toTransform);
-}
-
-void SVGAnimatedTransformListAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType* from, SVGAnimatedType* to, SVGAnimatedType* toAtEndOfDuration, SVGAnimatedType* animated)
-{
-    ASSERT(m_animationElement);
-
-    // Spec: To animations provide specific functionality to get a smooth change from the underlying value to the
-    // ‘to’ attribute value, which conflicts mathematically with the requirement for additive transform animations
-    // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations for ‘animateTransform’ is undefined.
-    // FIXME: This is not taken into account yet.
-    const SVGTransformList& fromTransformList = m_animationElement->animationMode() == ToAnimation ? animated->transformList() : from->transformList();
-    const SVGTransformList& toTransformList = to->transformList();
-    const SVGTransformList& toAtEndOfDurationTransformList = toAtEndOfDuration->transformList();
-    SVGTransformList& animatedTransformList = animated->transformList();
-
-    // Pass false to 'resizeAnimatedListIfNeeded' here, as the special post-multiplication behavior of <animateTransform> needs to be respected below.
-    if (!m_animationElement->adjustFromToListValues<SVGTransformList>(fromTransformList, toTransformList, animatedTransformList, percentage, false))
-        return;
-
-    // Never resize the animatedTransformList to the toTransformList size, instead either clear the list or append to it.
-    if (!animatedTransformList.isEmpty() && !m_animationElement->isAdditive())
-        animatedTransformList.clear();
-
-    unsigned fromTransformListSize = fromTransformList.size();
-    const SVGTransform& toTransform = toTransformList[0];
-    const SVGTransform effectiveFrom = fromTransformListSize ? fromTransformList[0] : SVGTransform(toTransform.type(), SVGTransform::ConstructZeroTransform);
-    SVGTransform currentTransform = SVGTransformDistance(effectiveFrom, toTransform).scaledDistance(percentage).addToSVGTransform(effectiveFrom);
-    if (m_animationElement->isAccumulated() && repeatCount) {
-        const SVGTransform effectiveToAtEnd = toAtEndOfDurationTransformList.size() ? toAtEndOfDurationTransformList[0] : SVGTransform(toTransform.type(), SVGTransform::ConstructZeroTransform);
-        animatedTransformList.append(SVGTransformDistance::addSVGTransforms(currentTransform, effectiveToAtEnd, repeatCount));
-    } else
-        animatedTransformList.append(currentTransform);
-}
-
-float SVGAnimatedTransformListAnimator::calculateDistance(const String& fromString, const String& toString)
-{
-    ASSERT(m_animationElement);
-
-    // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example)
-    // is paced separately. To implement this we need to treat each component as individual animation everywhere.
-    OwnPtr<SVGAnimatedType> from = constructFromString(fromString);
-    OwnPtr<SVGAnimatedType> to = constructFromString(toString);
-
-    SVGTransformList& fromTransformList = from->transformList();
-    SVGTransformList& toTransformList = to->transformList();
-    unsigned itemsCount = fromTransformList.size();
-    if (!itemsCount || itemsCount != toTransformList.size())
-        return -1;
-
-    ASSERT(itemsCount == 1);
-    if (fromTransformList[0].type() != toTransformList[0].type())
-        return -1;
-
-    // Spec: http://www.w3.org/TR/SVG/animate.html#complexDistances
-    // Paced animations assume a notion of distance between the various animation values defined by the ‘to’, ‘from’, ‘by’ and ‘values’ attributes.
-    // Distance is defined only for scalar types (such as <length>), colors and the subset of transformation types that are supported by ‘animateTransform’.
-    return SVGTransformDistance(fromTransformList[0], toTransformList[0]).distance();
-}
-
-}
diff --git a/Source/core/svg/SVGAnimatedTransformList.h b/Source/core/svg/SVGAnimatedTransformList.h
index 01ee83a..69de67f 100644
--- a/Source/core/svg/SVGAnimatedTransformList.h
+++ b/Source/core/svg/SVGAnimatedTransformList.h
@@ -1,60 +1,42 @@
 /*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef SVGAnimatedTransformList_h
 #define SVGAnimatedTransformList_h
 
-#include "core/svg/SVGAnimatedTypeAnimator.h"
-#include "core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h"
+#include "core/svg/SVGTransformListTearOff.h"
+#include "core/svg/properties/NewSVGAnimatedProperty.h"
 
 namespace WebCore {
 
-typedef SVGAnimatedTransformListPropertyTearOff SVGAnimatedTransformList;
-
-// Helper macros to declare/define a SVGAnimatedTransformList object
-#define DECLARE_ANIMATED_TRANSFORM_LIST(UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_LIST_PROPERTY(SVGAnimatedTransformList, SVGTransformList, UpperProperty, LowerProperty)
-
-#define DEFINE_ANIMATED_TRANSFORM_LIST(OwnerType, DOMAttribute, UpperProperty, LowerProperty) \
-DEFINE_ANIMATED_PROPERTY(AnimatedTransformList, OwnerType, DOMAttribute, DOMAttribute.localName(), UpperProperty, LowerProperty, SVGAnimatedTransformList, SVGTransformList)
-
-class SVGAnimationElement;
-
-class SVGAnimatedTransformListAnimator FINAL : public SVGAnimatedTypeAnimator {
-public:
-    SVGAnimatedTransformListAnimator(SVGAnimationElement*, SVGElement*);
-    virtual ~SVGAnimatedTransformListAnimator() { }
-
-    virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) OVERRIDE;
-    virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) OVERRIDE;
-    virtual void animValWillChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
-    virtual void animValDidChange(const SVGElementAnimatedPropertyList&) OVERRIDE;
-
-    virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) OVERRIDE;
-    virtual float calculateDistance(const String& fromString, const String& toString) OVERRIDE;
-
-private:
-    const String& m_transformTypeString;
-};
+typedef NewSVGAnimatedProperty<SVGTransformList> SVGAnimatedTransformList;
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGAnimatedTransformList.idl b/Source/core/svg/SVGAnimatedTransformList.idl
index 718a2a6..7a56c32 100644
--- a/Source/core/svg/SVGAnimatedTransformList.idl
+++ b/Source/core/svg/SVGAnimatedTransformList.idl
@@ -23,8 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGAnimatedTransformList {
+[
+    SetWrapperReferenceTo(SVGElement contextElement),
+] interface SVGAnimatedTransformList {
     readonly attribute SVGTransformList baseVal;
     readonly attribute SVGTransformList animVal;
 };
-
diff --git a/Source/core/svg/SVGAnimatedType.cpp b/Source/core/svg/SVGAnimatedType.cpp
deleted file mode 100644
index 2912116..0000000
--- a/Source/core/svg/SVGAnimatedType.cpp
+++ /dev/null
@@ -1,194 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/SVGAnimatedType.h"
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/svg/SVGParserUtilities.h"
-#include "core/svg/SVGPathByteStream.h"
-
-namespace WebCore {
-
-SVGAnimatedType::SVGAnimatedType(AnimatedPropertyType type)
-    : m_type(type)
-{
-}
-
-SVGAnimatedType::~SVGAnimatedType()
-{
-    switch (m_type) {
-    case AnimatedAngle:
-        delete m_data.angleAndEnumeration;
-        break;
-    case AnimatedEnumeration:
-        delete m_data.enumeration;
-        break;
-    case AnimatedPath:
-        delete m_data.path;
-        break;
-    case AnimatedTransformList:
-        delete m_data.transformList;
-        break;
-    // Below properties are migrated to new property implementation.
-    case AnimatedBoolean:
-    case AnimatedColor:
-    case AnimatedInteger:
-    case AnimatedIntegerOptionalInteger:
-    case AnimatedNumber:
-    case AnimatedNumberList:
-    case AnimatedNumberOptionalNumber:
-    case AnimatedLength:
-    case AnimatedLengthList:
-    case AnimatedPoints:
-    case AnimatedPreserveAspectRatio:
-    case AnimatedRect:
-    case AnimatedString:
-    case AnimatedStringList:
-        // handled by RefPtr
-        break;
-
-    // There is no SVGAnimatedPoint
-    case AnimatedPoint:
-        ASSERT_NOT_REACHED();
-        break;
-
-    case AnimatedUnknown:
-        ASSERT_NOT_REACHED();
-        break;
-    }
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createAngleAndEnumeration(std::pair<SVGAngle, unsigned>* angleAndEnumeration)
-{
-    ASSERT(angleAndEnumeration);
-    OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedAngle));
-    animatedType->m_data.angleAndEnumeration = angleAndEnumeration;
-    return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createEnumeration(unsigned* enumeration)
-{
-    ASSERT(enumeration);
-    OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedEnumeration));
-    animatedType->m_data.enumeration = enumeration;
-    return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createPath(PassOwnPtr<SVGPathByteStream> path)
-{
-    ASSERT(path);
-    OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedPath));
-    animatedType->m_data.path = path.leakPtr();
-    return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createTransformList(SVGTransformList* transformList)
-{
-    ASSERT(transformList);
-    OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(AnimatedTransformList));
-    animatedType->m_data.transformList = transformList;
-    return animatedType.release();
-}
-
-PassOwnPtr<SVGAnimatedType> SVGAnimatedType::createNewProperty(PassRefPtr<NewSVGPropertyBase> newProperty)
-{
-    ASSERT(newProperty);
-    OwnPtr<SVGAnimatedType> animatedType = adoptPtr(new SVGAnimatedType(newProperty->type()));
-    animatedType->m_newProperty = newProperty;
-    return animatedType.release();
-}
-
-String SVGAnimatedType::valueAsString()
-{
-    switch (m_type) {
-    // Below properties have migrated to new property implementation.
-    case AnimatedColor:
-    case AnimatedNumber:
-    case AnimatedNumberList:
-    case AnimatedNumberOptionalNumber:
-    case AnimatedLength:
-    case AnimatedLengthList:
-    case AnimatedPoints:
-    case AnimatedPreserveAspectRatio:
-    case AnimatedRect:
-    case AnimatedString:
-    case AnimatedStringList:
-        return m_newProperty->valueAsString();
-
-    // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need valueAsString() support.
-    case AnimatedAngle:
-    case AnimatedBoolean:
-    case AnimatedEnumeration:
-    case AnimatedInteger:
-    case AnimatedIntegerOptionalInteger:
-    case AnimatedPath:
-    case AnimatedPoint:
-    case AnimatedTransformList:
-    case AnimatedUnknown:
-        // Only SVG DOM animations use these property types - that means valueAsString() is never used for those.
-        ASSERT_NOT_REACHED();
-        break;
-    }
-    ASSERT_NOT_REACHED();
-    return String();
-}
-
-bool SVGAnimatedType::setValueAsString(const QualifiedName& attrName, const String& value)
-{
-    switch (m_type) {
-    // Below properties have migrated to new property implementation.
-    case AnimatedColor:
-    case AnimatedNumber:
-    case AnimatedNumberList:
-    case AnimatedNumberOptionalNumber:
-    case AnimatedLength:
-    case AnimatedLengthList:
-    case AnimatedPoints:
-    case AnimatedPreserveAspectRatio:
-    case AnimatedRect:
-    case AnimatedString:
-    case AnimatedStringList:
-        // Always use createForAnimation call path for these implementations.
-        return false;
-
-    // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need setValueAsString() support.
-    case AnimatedAngle:
-    case AnimatedBoolean:
-    case AnimatedEnumeration:
-    case AnimatedInteger:
-    case AnimatedIntegerOptionalInteger:
-    case AnimatedPath:
-    case AnimatedPoint:
-    case AnimatedTransformList:
-    case AnimatedUnknown:
-        // Only SVG DOM animations use these property types - that means setValueAsString() is never used for those.
-        ASSERT_NOT_REACHED();
-        break;
-    }
-    return true;
-}
-
-bool SVGAnimatedType::supportsAnimVal(AnimatedPropertyType type)
-{
-    // AnimatedColor is only used for CSS property animations.
-    return type != AnimatedUnknown && type != AnimatedColor;
-}
-
-} // namespace WebCore
diff --git a/Source/core/svg/SVGAnimatedType.h b/Source/core/svg/SVGAnimatedType.h
deleted file mode 100644
index 7e7a2c7..0000000
--- a/Source/core/svg/SVGAnimatedType.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedType_h
-#define SVGAnimatedType_h
-
-#include "core/css/StyleColor.h"
-#include "core/svg/SVGAngle.h"
-#include "core/svg/SVGColor.h"
-#include "core/svg/SVGTransformList.h"
-#include "core/svg/properties/NewSVGAnimatedProperty.h"
-#include "core/svg/properties/SVGPropertyInfo.h"
-
-namespace WebCore {
-
-class SVGPathByteStream;
-
-class SVGAnimatedType FINAL {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    ~SVGAnimatedType();
-
-    static PassOwnPtr<SVGAnimatedType> createAngleAndEnumeration(std::pair<SVGAngle, unsigned>*);
-    static PassOwnPtr<SVGAnimatedType> createColor(StyleColor*);
-    static PassOwnPtr<SVGAnimatedType> createEnumeration(unsigned*);
-    static PassOwnPtr<SVGAnimatedType> createPath(PassOwnPtr<SVGPathByteStream>);
-    static PassOwnPtr<SVGAnimatedType> createTransformList(SVGTransformList*);
-    // Temporary compatibility layer. This shouldn't be needed after all properties are switched to NewSVGAnimatedProperty impl.
-    static PassOwnPtr<SVGAnimatedType> createNewProperty(PassRefPtr<NewSVGPropertyBase>);
-    static bool supportsAnimVal(AnimatedPropertyType);
-
-    AnimatedPropertyType type() const { return m_type; }
-
-    std::pair<SVGAngle, unsigned>& angleAndEnumeration()
-    {
-        ASSERT(m_type == AnimatedAngle);
-        return *m_data.angleAndEnumeration;
-    }
-
-    StyleColor& color()
-    {
-        ASSERT(m_type == AnimatedColor);
-        return *m_data.color;
-    }
-
-    unsigned& enumeration()
-    {
-        ASSERT(m_type == AnimatedEnumeration);
-        return *m_data.enumeration;
-    }
-
-    SVGPathByteStream* path()
-    {
-        ASSERT(m_type == AnimatedPath);
-        return m_data.path;
-    }
-
-    SVGTransformList& transformList()
-    {
-        ASSERT(m_type == AnimatedTransformList);
-        return *m_data.transformList;
-    }
-
-    RefPtr<NewSVGPropertyBase>& newProperty()
-    {
-        ASSERT(m_newProperty);
-        return m_newProperty;
-    }
-
-    String valueAsString();
-    bool setValueAsString(const QualifiedName&, const String&);
-
-private:
-    SVGAnimatedType(AnimatedPropertyType);
-
-    AnimatedPropertyType m_type;
-
-    union DataUnion {
-        DataUnion()
-        {
-        }
-
-        std::pair<SVGAngle, unsigned>* angleAndEnumeration;
-        StyleColor* color;
-        unsigned* enumeration;
-        SVGPathByteStream* path;
-        SVGTransformList* transformList;
-    } m_data;
-    RefPtr<NewSVGPropertyBase> m_newProperty;
-};
-
-} // namespace WebCore
-
-#endif // SVGAnimatedType_h
diff --git a/Source/core/svg/SVGAnimatedTypeAnimator.cpp b/Source/core/svg/SVGAnimatedTypeAnimator.cpp
index 6e833fd..a4ad0bb 100644
--- a/Source/core/svg/SVGAnimatedTypeAnimator.cpp
+++ b/Source/core/svg/SVGAnimatedTypeAnimator.cpp
@@ -21,20 +21,21 @@
 #include "config.h"
 #include "core/svg/SVGAnimatedTypeAnimator.h"
 
+#include "core/svg/SVGAnimateTransformElement.h"
+#include "core/svg/SVGAnimatedColor.h"
+#include "core/svg/SVGAnimationElement.h"
 #include "core/svg/SVGElement.h"
-#include "core/svg/properties/SVGAttributeToPropertyMap.h"
+#include "core/svg/SVGElementInstance.h"
+#include "core/svg/SVGLength.h"
+#include "core/svg/SVGLengthList.h"
+#include "core/svg/SVGNumber.h"
+#include "core/svg/SVGPaint.h"
+#include "core/svg/SVGPointList.h"
+#include "core/svg/SVGString.h"
+#include "core/svg/SVGTransformList.h"
 
 namespace WebCore {
 
-SVGElementAnimatedProperties::SVGElementAnimatedProperties()
-    : element(0)
-{ }
-
-SVGElementAnimatedProperties::SVGElementAnimatedProperties(SVGElement* element, Vector<RefPtr<SVGAnimatedProperty> >& properties)
-    : element(element)
-    , properties(properties)
-{ }
-
 SVGAnimatedTypeAnimator::SVGAnimatedTypeAnimator(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* contextElement)
     : m_type(type)
     , m_animationElement(animationElement)
@@ -42,69 +43,222 @@
 {
     ASSERT(m_animationElement);
     ASSERT(m_contextElement);
+    ASSERT(m_type != AnimatedPoint
+        && m_type != AnimatedStringList
+        && m_type != AnimatedTransform
+        && m_type != AnimatedUnknown);
+
+    const QualifiedName& attributeName = m_animationElement->attributeName();
+    m_animatedProperty = m_contextElement->propertyFromAttribute(attributeName);
+    if (m_animatedProperty)
+        ASSERT(m_animatedProperty->type() == m_type);
 }
 
 SVGAnimatedTypeAnimator::~SVGAnimatedTypeAnimator()
 {
 }
 
-void SVGAnimatedTypeAnimator::calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString)
+PassRefPtr<NewSVGPropertyBase> SVGAnimatedTypeAnimator::createPropertyForAnimation(const String& value)
+{
+    if (isAnimatingSVGDom()) {
+        // SVG DOM animVal animation code-path.
+
+        if (m_type == AnimatedTransformList) {
+            // TransformList must be animated via <animateTransform>,
+            // and its {from,by,to} attribute values needs to be parsed w.r.t. its "type" attribute.
+            // Spec: http://www.w3.org/TR/SVG/single-page.html#animate-AnimateTransformElement
+            ASSERT(m_animationElement);
+            SVGTransformType transformType = toSVGAnimateTransformElement(m_animationElement)->transformType();
+            return SVGTransformList::create(transformType, value);
+        }
+
+        ASSERT(m_animatedProperty);
+        return m_animatedProperty->currentValueBase()->cloneForAnimation(value);
+    }
+
+    ASSERT(isAnimatingCSSProperty());
+
+    // CSS properties animation code-path.
+    // Create a basic instance of the corresponding SVG property.
+    // The instance will not have full context info. (e.g. SVGLengthMode)
+
+    switch (m_type) {
+    case AnimatedColor:
+        return SVGColorProperty::create(value.isEmpty() ? StyleColor::currentColor() : SVGPaint::colorFromRGBColorString(value));
+    case AnimatedNumber: {
+        RefPtr<SVGNumber> property = SVGNumber::create();
+        property->setValueAsString(value, IGNORE_EXCEPTION);
+        return property.release();
+    }
+    case AnimatedLength: {
+        RefPtr<SVGLength> property = SVGLength::create(LengthModeOther);
+        property->setValueAsString(value, IGNORE_EXCEPTION);
+        return property.release();
+    }
+    case AnimatedLengthList: {
+        RefPtr<SVGLengthList> property = SVGLengthList::create(LengthModeOther);
+        property->setValueAsString(value, IGNORE_EXCEPTION);
+        return property.release();
+    }
+    case AnimatedString: {
+        RefPtr<SVGString> property = SVGString::create();
+        property->setValueAsString(value, IGNORE_EXCEPTION);
+        return property.release();
+    }
+
+    // These types don't appear in the table in SVGElement::cssPropertyToTypeMap() and thus don't need support.
+    case AnimatedBoolean:
+    case AnimatedNumberList:
+    case AnimatedNumberOptionalNumber:
+    case AnimatedPoint:
+    case AnimatedPoints:
+    case AnimatedRect:
+    case AnimatedTransform:
+    case AnimatedTransformList:
+        ASSERT_NOT_REACHED();
+
+    // These properties are not yet migrated to NewProperty implementation. see http://crbug.com/308818
+    case AnimatedAngle:
+    case AnimatedEnumeration:
+    case AnimatedInteger:
+    case AnimatedIntegerOptionalInteger:
+    case AnimatedPath:
+    case AnimatedPreserveAspectRatio:
+    case AnimatedStringList:
+        ASSERT_NOT_REACHED();
+
+    case AnimatedUnknown:
+        ASSERT_NOT_REACHED();
+    };
+
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+PassRefPtr<NewSVGPropertyBase> SVGAnimatedTypeAnimator::constructFromString(const String& value)
+{
+    return createPropertyForAnimation(value);
+}
+
+void SVGAnimatedTypeAnimator::calculateFromAndToValues(RefPtr<NewSVGPropertyBase>& from, RefPtr<NewSVGPropertyBase>& to, const String& fromString, const String& toString)
 {
     from = constructFromString(fromString);
     to = constructFromString(toString);
 }
 
-void SVGAnimatedTypeAnimator::calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString)
+void SVGAnimatedTypeAnimator::calculateFromAndByValues(RefPtr<NewSVGPropertyBase>& from, RefPtr<NewSVGPropertyBase>& to, const String& fromString, const String& byString)
 {
     from = constructFromString(fromString);
     to = constructFromString(byString);
-    addAnimatedTypes(from.get(), to.get());
+    to->add(from, m_contextElement);
 }
 
-SVGElementAnimatedPropertyList SVGAnimatedTypeAnimator::findAnimatedPropertiesForAttributeName(SVGElement* targetElement, const QualifiedName& attributeName)
+namespace {
+
+typedef void (NewSVGAnimatedPropertyBase::*NewSVGAnimatedPropertyMethod)();
+
+void invokeMethodOnAllTargetProperties(const Vector<SVGElement*>& list, const QualifiedName& attributeName, NewSVGAnimatedPropertyMethod method)
 {
-    ASSERT(targetElement);
+    Vector<SVGElement*>::const_iterator it = list.begin();
+    Vector<SVGElement*>::const_iterator itEnd = list.end();
+    for (; it != itEnd; ++it) {
+        RefPtr<NewSVGAnimatedPropertyBase> animatedProperty = (*it)->propertyFromAttribute(attributeName);
+        if (animatedProperty)
+            (animatedProperty.get()->*method)();
+    }
+}
 
-    SVGElementAnimatedPropertyList propertiesByInstance;
+void setAnimatedValueOnAllTargetProperties(const Vector<SVGElement*>& list, const QualifiedName& attributeName, PassRefPtr<NewSVGPropertyBase> passValue)
+{
+    RefPtr<NewSVGPropertyBase> value = passValue;
 
-    Vector<RefPtr<SVGAnimatedProperty> > targetProperties;
-    targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(targetElement, attributeName, targetProperties);
+    Vector<SVGElement*>::const_iterator it = list.begin();
+    Vector<SVGElement*>::const_iterator itEnd = list.end();
+    for (; it != itEnd; ++it) {
+        RefPtr<NewSVGAnimatedPropertyBase> animatedProperty = (*it)->propertyFromAttribute(attributeName);
+        if (animatedProperty)
+            animatedProperty->setAnimatedValue(value);
+    }
+}
 
-    if (!SVGAnimatedType::supportsAnimVal(m_type))
-        return SVGElementAnimatedPropertyList();
+}
 
-    SVGElementAnimatedProperties propertiesPair(targetElement, targetProperties);
-    propertiesByInstance.append(propertiesPair);
+PassRefPtr<NewSVGPropertyBase> SVGAnimatedTypeAnimator::resetAnimation(const Vector<SVGElement*>& list)
+{
+    ASSERT(isAnimatingSVGDom());
+    RefPtr<NewSVGPropertyBase> animatedValue = m_animatedProperty->createAnimatedValue();
+    ASSERT(animatedValue->type() == m_type);
+    setAnimatedValueOnAllTargetProperties(list, m_animatedProperty->attributeName(), animatedValue);
 
-    const HashSet<SVGElementInstance*>& instances = targetElement->instancesForElement();
-    const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
-    for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
-        SVGElement* shadowTreeElement = (*it)->shadowTreeElement();
-        if (!shadowTreeElement)
-            continue;
+    return animatedValue.release();
+}
 
-        Vector<RefPtr<SVGAnimatedProperty> > instanceProperties;
-        targetElement->localAttributeToPropertyMap().animatedPropertiesForAttribute(shadowTreeElement, attributeName, instanceProperties);
+PassRefPtr<NewSVGPropertyBase> SVGAnimatedTypeAnimator::startAnimValAnimation(const Vector<SVGElement*>& list)
+{
+    ASSERT(isAnimatingSVGDom());
+    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
 
-        SVGElementAnimatedProperties instancePropertiesPair(shadowTreeElement, instanceProperties);
-        propertiesByInstance.append(instancePropertiesPair);
+    invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animationStarted);
+
+    return resetAnimation(list);
+}
+
+void SVGAnimatedTypeAnimator::stopAnimValAnimation(const Vector<SVGElement*>& list)
+{
+    ASSERT(isAnimatingSVGDom());
+    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
+
+    invokeMethodOnAllTargetProperties(list, m_animatedProperty->attributeName(), &NewSVGAnimatedPropertyBase::animationEnded);
+}
+
+PassRefPtr<NewSVGPropertyBase> SVGAnimatedTypeAnimator::resetAnimValToBaseVal(const Vector<SVGElement*>& list)
+{
+    SVGElementInstance::InstanceUpdateBlocker blocker(m_contextElement);
+
+    return resetAnimation(list);
+}
+
+class ParsePropertyFromString {
+public:
+    explicit ParsePropertyFromString(SVGAnimatedTypeAnimator* animator)
+        : m_animator(animator)
+    {
     }
 
-#if !ASSERT_DISABLED
-    SVGElementAnimatedPropertyList::const_iterator propertiesEnd = propertiesByInstance.end();
-    for (SVGElementAnimatedPropertyList::const_iterator it = propertiesByInstance.begin(); it != propertiesEnd; ++it) {
-        size_t propertiesSize = it->properties.size();
-        for (size_t i = 0; i < propertiesSize; ++i) {
-            RefPtr<SVGAnimatedProperty> property = it->properties[i];
-            if (property->animatedPropertyType() != m_type) {
-                ASSERT(m_type == AnimatedAngle);
-                ASSERT(property->animatedPropertyType() == AnimatedEnumeration);
-            }
-        }
+    PassRefPtr<NewSVGPropertyBase> operator()(SVGAnimationElement*, const String& value)
+    {
+        return m_animator->createPropertyForAnimation(value);
     }
-#endif
 
-    return propertiesByInstance;
+private:
+    SVGAnimatedTypeAnimator* m_animator;
+};
+
+void SVGAnimatedTypeAnimator::calculateAnimatedValue(float percentage, unsigned repeatCount, NewSVGPropertyBase* from, NewSVGPropertyBase* to, NewSVGPropertyBase* toAtEndOfDuration, NewSVGPropertyBase* animated)
+{
+    ASSERT(m_animationElement);
+    ASSERT(m_contextElement);
+
+    RefPtr<NewSVGPropertyBase> fromValue = m_animationElement->animationMode() == ToAnimation ? animated : from;
+    RefPtr<NewSVGPropertyBase> toValue = to;
+    RefPtr<NewSVGPropertyBase> toAtEndOfDurationValue = toAtEndOfDuration;
+    RefPtr<NewSVGPropertyBase> animatedValue = animated;
+
+    // Apply CSS inheritance rules.
+    ParsePropertyFromString parsePropertyFromString(this);
+    m_animationElement->adjustForInheritance<RefPtr<NewSVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->fromPropertyValueType(), fromValue, m_contextElement);
+    m_animationElement->adjustForInheritance<RefPtr<NewSVGPropertyBase>, ParsePropertyFromString>(parsePropertyFromString, m_animationElement->toPropertyValueType(), toValue, m_contextElement);
+
+    animatedValue->calculateAnimatedValue(m_animationElement, percentage, repeatCount, fromValue, toValue, toAtEndOfDurationValue, m_contextElement);
+}
+
+float SVGAnimatedTypeAnimator::calculateDistance(const String& fromString, const String& toString)
+{
+    ASSERT(m_animationElement);
+    ASSERT(m_contextElement);
+    RefPtr<NewSVGPropertyBase> fromValue = createPropertyForAnimation(fromString);
+    RefPtr<NewSVGPropertyBase> toValue = createPropertyForAnimation(toString);
+    return fromValue->calculateDistance(toValue, m_contextElement);
 }
 
 }
diff --git a/Source/core/svg/SVGAnimatedTypeAnimator.h b/Source/core/svg/SVGAnimatedTypeAnimator.h
index fd6c4e3..b1fc001 100644
--- a/Source/core/svg/SVGAnimatedTypeAnimator.h
+++ b/Source/core/svg/SVGAnimatedTypeAnimator.h
@@ -21,206 +21,57 @@
 #ifndef SVGAnimatedTypeAnimator_h
 #define SVGAnimatedTypeAnimator_h
 
-#include "core/svg/SVGAnimatedType.h"
-#include "core/svg/SVGElementInstance.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
+#include "core/svg/properties/SVGPropertyInfo.h"
 #include "wtf/PassOwnPtr.h"
+#include "wtf/RefPtr.h"
+#include "wtf/Vector.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-struct SVGElementAnimatedProperties {
-    SVGElementAnimatedProperties();
-
-    SVGElementAnimatedProperties(SVGElement*, Vector<RefPtr<SVGAnimatedProperty> >&);
-
-    SVGElement* element;
-    Vector<RefPtr<SVGAnimatedProperty> > properties;
-};
-typedef Vector<SVGElementAnimatedProperties> SVGElementAnimatedPropertyList;
-
+class NewSVGAnimatedPropertyBase;
+class NewSVGPropertyBase;
+class SVGElement;
 class SVGAnimationElement;
 
-class SVGAnimatedTypeAnimator {
+class SVGAnimatedTypeAnimator FINAL {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    virtual ~SVGAnimatedTypeAnimator();
-    virtual PassOwnPtr<SVGAnimatedType> constructFromString(const String&) = 0;
+    static PassOwnPtr<SVGAnimatedTypeAnimator> create(AnimatedPropertyType type, SVGAnimationElement* animationElement, SVGElement* targetElement)
+    {
+        return adoptPtr(new SVGAnimatedTypeAnimator(type, animationElement, targetElement));
+    }
+    ~SVGAnimatedTypeAnimator();
 
-    virtual PassOwnPtr<SVGAnimatedType> startAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0;
-    virtual void stopAnimValAnimation(const SVGElementAnimatedPropertyList&) = 0;
-    virtual void resetAnimValToBaseVal(const SVGElementAnimatedPropertyList&, SVGAnimatedType*) = 0;
-    virtual void animValWillChange(const SVGElementAnimatedPropertyList&) = 0;
-    virtual void animValDidChange(const SVGElementAnimatedPropertyList&) = 0;
-    virtual void addAnimatedTypes(SVGAnimatedType*, SVGAnimatedType*) = 0;
+    PassRefPtr<NewSVGPropertyBase> constructFromString(const String&);
 
-    virtual void calculateAnimatedValue(float percentage, unsigned repeatCount, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*, SVGAnimatedType*) = 0;
-    virtual float calculateDistance(const String& fromString, const String& toString) = 0;
+    PassRefPtr<NewSVGPropertyBase> startAnimValAnimation(const Vector<SVGElement*>&);
+    void stopAnimValAnimation(const Vector<SVGElement*>&);
+    PassRefPtr<NewSVGPropertyBase> resetAnimValToBaseVal(const Vector<SVGElement*>&);
 
-    void calculateFromAndToValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& toString);
-    void calculateFromAndByValues(OwnPtr<SVGAnimatedType>& from, OwnPtr<SVGAnimatedType>& to, const String& fromString, const String& byString);
+    void calculateAnimatedValue(float percentage, unsigned repeatCount, NewSVGPropertyBase*, NewSVGPropertyBase*, NewSVGPropertyBase*, NewSVGPropertyBase*);
+    float calculateDistance(const String& fromString, const String& toString);
+
+    void calculateFromAndToValues(RefPtr<NewSVGPropertyBase>& from, RefPtr<NewSVGPropertyBase>& to, const String& fromString, const String& toString);
+    void calculateFromAndByValues(RefPtr<NewSVGPropertyBase>& from, RefPtr<NewSVGPropertyBase>& to, const String& fromString, const String& byString);
 
     void setContextElement(SVGElement* contextElement) { m_contextElement = contextElement; }
     AnimatedPropertyType type() const { return m_type; }
 
-    SVGElementAnimatedPropertyList findAnimatedPropertiesForAttributeName(SVGElement*, const QualifiedName&);
-
-protected:
+private:
     SVGAnimatedTypeAnimator(AnimatedPropertyType, SVGAnimationElement*, SVGElement*);
 
-    // Helpers for animators that operate on single types, eg. just one SVGAnimatedInteger.
-    template<typename AnimValType>
-    typename AnimValType::ContentType* constructFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 1);
-        const typename AnimValType::ContentType& animatedType = castAnimatedPropertyToActualType<AnimValType>(animatedTypes[0].properties[0].get())->currentBaseValue();
+    friend class ParsePropertyFromString;
+    PassRefPtr<NewSVGPropertyBase> createPropertyForAnimation(const String&);
+    PassRefPtr<NewSVGPropertyBase> resetAnimation(const Vector<SVGElement*>&);
 
-        typename AnimValType::ContentType* copy = new typename AnimValType::ContentType(animatedType);
-        executeAction<AnimValType>(StartAnimationAction, animatedTypes, 0, copy);
-        return copy;
-    }
-
-    template<typename AnimValType>
-    void resetFromBaseValue(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, typename AnimValType::ContentType& (SVGAnimatedType::*getter)())
-    {
-        ASSERT(animatedTypes[0].properties.size() == 1);
-        ASSERT(type);
-        ASSERT(type->type() == m_type);
-        typename AnimValType::ContentType& animatedTypeValue = (type->*getter)();
-        animatedTypeValue = castAnimatedPropertyToActualType<AnimValType>(animatedTypes[0].properties[0].get())->currentBaseValue();
-
-        executeAction<AnimValType>(StartAnimationAction, animatedTypes, 0, &animatedTypeValue);
-    }
-
-    template<typename AnimValType>
-    void stopAnimValAnimationForType(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 1);
-        executeAction<AnimValType>(StopAnimationAction, animatedTypes, 0);
-    }
-
-    template<typename AnimValType>
-    void animValDidChangeForType(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 1);
-        executeAction<AnimValType>(AnimValDidChangeAction, animatedTypes, 0);
-    }
-
-    template<typename AnimValType>
-    void animValWillChangeForType(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 1);
-        executeAction<AnimValType>(AnimValWillChangeAction, animatedTypes, 0);
-    }
-
-    // Helpers for animators that operate on pair types, eg. a pair of SVGAnimatedIntegers.
-    template<typename AnimValType1, typename AnimValType2>
-    pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>* constructFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 2);
-        const typename AnimValType1::ContentType& firstType = castAnimatedPropertyToActualType<AnimValType1>(animatedTypes[0].properties[0].get())->currentBaseValue();
-        const typename AnimValType2::ContentType& secondType = castAnimatedPropertyToActualType<AnimValType2>(animatedTypes[0].properties[1].get())->currentBaseValue();
-
-        pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>* copy = new pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>(firstType, secondType);
-        executeAction<AnimValType1>(StartAnimationAction, animatedTypes, 0, &copy->first);
-        executeAction<AnimValType2>(StartAnimationAction, animatedTypes, 1, &copy->second);
-        return copy;
-    }
-
-    template<typename AnimValType1, typename AnimValType2>
-    void resetFromBaseValues(const SVGElementAnimatedPropertyList& animatedTypes, SVGAnimatedType* type, pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& (SVGAnimatedType::*getter)())
-    {
-        ASSERT(animatedTypes[0].properties.size() == 2);
-        ASSERT(type);
-        ASSERT(type->type() == m_type);
-
-        pair<typename AnimValType1::ContentType, typename AnimValType2::ContentType>& animatedTypeValue = (type->*getter)();
-        animatedTypeValue.first = castAnimatedPropertyToActualType<AnimValType1>(animatedTypes[0].properties[0].get())->currentBaseValue();
-        animatedTypeValue.second = castAnimatedPropertyToActualType<AnimValType2>(animatedTypes[0].properties[1].get())->currentBaseValue();
-
-        executeAction<AnimValType1>(StartAnimationAction, animatedTypes, 0, &animatedTypeValue.first);
-        executeAction<AnimValType2>(StartAnimationAction, animatedTypes, 1, &animatedTypeValue.second);
-    }
-
-    template<typename AnimValType1, typename AnimValType2>
-    void stopAnimValAnimationForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 2);
-        executeAction<AnimValType1>(StopAnimationAction, animatedTypes, 0);
-        executeAction<AnimValType2>(StopAnimationAction, animatedTypes, 1);
-    }
-
-    template<typename AnimValType1, typename AnimValType2>
-    void animValDidChangeForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 2);
-        executeAction<AnimValType1>(AnimValDidChangeAction, animatedTypes, 0);
-        executeAction<AnimValType2>(AnimValDidChangeAction, animatedTypes, 1);
-    }
-
-    template<typename AnimValType1, typename AnimValType2>
-    void animValWillChangeForTypes(const SVGElementAnimatedPropertyList& animatedTypes)
-    {
-        ASSERT(animatedTypes[0].properties.size() == 2);
-        executeAction<AnimValType1>(AnimValWillChangeAction, animatedTypes, 0);
-        executeAction<AnimValType2>(AnimValWillChangeAction, animatedTypes, 1);
-    }
-
-    template<typename AnimValType>
-    AnimValType* castAnimatedPropertyToActualType(SVGAnimatedProperty* property)
-    {
-        ASSERT(property);
-        ASSERT(property->contextElement());
-        // We can't assert property->animatedPropertyType() == m_type, as there's an exception for SVGMarkerElements orient attribute.
-        if (property->animatedPropertyType() != m_type) {
-            ASSERT(m_type == AnimatedAngle);
-            ASSERT(property->animatedPropertyType() == AnimatedEnumeration);
-        }
-        return static_cast<AnimValType*>(property);
-    }
+    bool isAnimatingSVGDom() const { return m_animatedProperty; }
+    bool isAnimatingCSSProperty() const { return !m_animatedProperty; }
 
     AnimatedPropertyType m_type;
     SVGAnimationElement* m_animationElement;
     SVGElement* m_contextElement;
-
-private:
-    enum AnimationAction {
-        StartAnimationAction,
-        StopAnimationAction,
-        AnimValWillChangeAction,
-        AnimValDidChangeAction
-    };
-
-    template<typename AnimValType>
-    void executeAction(AnimationAction action, const SVGElementAnimatedPropertyList& animatedTypes, unsigned whichProperty, typename AnimValType::ContentType* type = 0)
-    {
-        SVGElementInstance::InstanceUpdateBlocker blocker(animatedTypes[0].element);
-
-        SVGElementAnimatedPropertyList::const_iterator end = animatedTypes.end();
-        for (SVGElementAnimatedPropertyList::const_iterator it = animatedTypes.begin(); it != end; ++it) {
-            ASSERT_WITH_SECURITY_IMPLICATION(whichProperty < it->properties.size());
-            AnimValType* property = castAnimatedPropertyToActualType<AnimValType>(it->properties[whichProperty].get());
-
-            switch (action) {
-            case StartAnimationAction:
-                ASSERT(type);
-                if (!property->isAnimating())
-                    property->animationStarted(type);
-                break;
-            case StopAnimationAction:
-                ASSERT(!type);
-                property->animationEnded();
-                break;
-            case AnimValWillChangeAction:
-                ASSERT(!type);
-                property->animValWillChange();
-                break;
-            case AnimValDidChangeAction:
-                ASSERT(!type);
-                property->animValDidChange();
-                break;
-            }
-        }
-    }
+    RefPtr<NewSVGAnimatedPropertyBase> m_animatedProperty;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGAnimationElement.cpp b/Source/core/svg/SVGAnimationElement.cpp
index 718ca21..e06ef95 100644
--- a/Source/core/svg/SVGAnimationElement.cpp
+++ b/Source/core/svg/SVGAnimationElement.cpp
@@ -39,11 +39,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGAnimationElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 SVGAnimationElement::SVGAnimationElement(const QualifiedName& tagName, Document& document)
     : SVGSMILElement(tagName, document)
     , SVGTests(this)
@@ -56,7 +51,6 @@
     , m_animationMode(NoAnimation)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGAnimationElement();
 
     UseCounter::count(document, UseCounter::SVGAnimationElement);
 }
@@ -189,7 +183,7 @@
     }
 
     if (name == SVGNames::keyPointsAttr) {
-        if (hasTagName(SVGNames::animateMotionTag)) {
+        if (isSVGAnimateMotionElement(*this)) {
             // This is specified to be an animateMotion attribute only but it is simpler to put it here
             // where the other timing calculatations are.
             parseKeyTimes(value, m_keyPoints, false);
@@ -311,7 +305,7 @@
     else if (calcMode == spline)
         setCalcMode(CalcModeSpline);
     else
-        setCalcMode(hasTagName(SVGNames::animateMotionTag) ? CalcModePaced : CalcModeLinear);
+        setCalcMode(isSVGAnimateMotionElement(*this) ? CalcModePaced : CalcModeLinear);
 }
 
 void SVGAnimationElement::setAttributeType(const AtomicString& attributeType)
@@ -421,10 +415,12 @@
 {
     unsigned index;
     unsigned keyTimesCount = m_keyTimes.size();
-    // Compare index + 1 to keyTimesCount because the last keyTimes entry is
-    // required to be 1, and percent can never exceed 1; i.e., the second last
-    // keyTimes entry defines the beginning of the final interval
-    for (index = 1; index + 1 < keyTimesCount; ++index) {
+    // For linear and spline animations, the last value must be '1'. In those
+    // cases we don't need to consider the last value, since |percent| is never
+    // greater than one.
+    if (keyTimesCount && calcMode() != CalcModeDiscrete)
+        keyTimesCount--;
+    for (index = 1; index < keyTimesCount; ++index) {
         if (m_keyTimes[index] > percent)
             break;
     }
@@ -453,14 +449,15 @@
         return m_keyPoints[m_keyPoints.size() - 1];
 
     unsigned index = calculateKeyTimesIndex(percent);
-    float fromPercent = m_keyTimes[index];
-    float toPercent = m_keyTimes[index + 1];
     float fromKeyPoint = m_keyPoints[index];
-    float toKeyPoint = m_keyPoints[index + 1];
 
     if (calcMode() == CalcModeDiscrete)
         return fromKeyPoint;
 
+    ASSERT(index + 1 < m_keyTimes.size());
+    float fromPercent = m_keyTimes[index];
+    float toPercent = m_keyTimes[index + 1];
+    float toKeyPoint = m_keyPoints[index + 1];
     float keyPointPercent = (percent - fromPercent) / (toPercent - fromPercent);
 
     if (calcMode() == CalcModeSpline) {
@@ -489,6 +486,26 @@
     to = m_values[index + 1];
 }
 
+AnimatedPropertyType SVGAnimationElement::determineAnimatedPropertyType() const
+{
+    if (!targetElement())
+        return AnimatedString;
+
+    RefPtr<NewSVGAnimatedPropertyBase> property = targetElement()->propertyFromAttribute(attributeName());
+    if (property) {
+        AnimatedPropertyType propertyType = property->type();
+
+        // Only <animatedTransform> is allowed to animate AnimatedTransformList.
+        // http://www.w3.org/TR/SVG/animate.html#AnimationAttributesAndProperties
+        if (propertyType == AnimatedTransformList && !isSVGAnimateTransformElement(*this))
+            return AnimatedUnknown;
+
+        return propertyType;
+    }
+
+    return SVGElement::animatedPropertyTypeForCSSAttribute(attributeName());
+}
+
 void SVGAnimationElement::currentValuesForValuesAnimation(float percent, float& effectivePercent, String& from, String& to)
 {
     unsigned valuesCount = m_values.size();
@@ -504,7 +521,7 @@
 
     CalcMode calcMode = this->calcMode();
     if (hasTagName(SVGNames::animateTag)) {
-        AnimatedPropertyType attributeType = toSVGAnimateElement(this)->determineAnimatedPropertyType(targetElement());
+        AnimatedPropertyType attributeType = determineAnimatedPropertyType();
         // Fall back to discrete animations for Strings.
         if (attributeType == AnimatedBoolean
             || attributeType == AnimatedEnumeration
diff --git a/Source/core/svg/SVGAnimationElement.h b/Source/core/svg/SVGAnimationElement.h
index bec165a..2749778 100644
--- a/Source/core/svg/SVGAnimationElement.h
+++ b/Source/core/svg/SVGAnimationElement.h
@@ -196,6 +196,8 @@
 
     virtual void setTargetElement(SVGElement*) OVERRIDE;
     virtual void setAttributeName(const QualifiedName&) OVERRIDE;
+    AnimatedPropertyType determineAnimatedPropertyType() const;
+
     bool hasInvalidCSSAttributeType() const { return m_hasInvalidCSSAttributeType; }
 
     virtual void updateAnimationMode();
@@ -224,9 +226,6 @@
 
     void adjustForInheritance(SVGElement* targetElement, const QualifiedName& attributeName, String&);
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGAnimationElement)
-    END_DECLARE_ANIMATED_PROPERTIES
-
     void setCalcMode(const AtomicString&);
 
     bool m_animationValid;
diff --git a/Source/core/svg/SVGAnimatorFactory.h b/Source/core/svg/SVGAnimatorFactory.h
deleted file mode 100644
index eb13b84..0000000
--- a/Source/core/svg/SVGAnimatorFactory.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011, 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatorFactory_h
-#define SVGAnimatorFactory_h
-
-#include "core/svg/SVGAnimatedAngle.h"
-#include "core/svg/SVGAnimatedColor.h"
-#include "core/svg/SVGAnimatedEnumeration.h"
-#include "core/svg/SVGAnimatedNewPropertyAnimator.h"
-#include "core/svg/SVGAnimatedPath.h"
-#include "core/svg/SVGAnimatedPreserveAspectRatio.h"
-#include "core/svg/SVGAnimatedRect.h"
-#include "core/svg/SVGAnimatedString.h"
-#include "core/svg/SVGAnimatedTransformList.h"
-
-namespace WebCore {
-
-class SVGAnimationElement;
-
-class SVGAnimatorFactory {
-public:
-    static PassOwnPtr<SVGAnimatedTypeAnimator> create(SVGAnimationElement* animationElement, SVGElement* contextElement, AnimatedPropertyType attributeType)
-    {
-        ASSERT(animationElement);
-        ASSERT(contextElement);
-
-        switch (attributeType) {
-        case AnimatedAngle:
-            return adoptPtr(new SVGAnimatedAngleAnimator(animationElement, contextElement));
-        case AnimatedEnumeration:
-            return adoptPtr(new SVGAnimatedEnumerationAnimator(animationElement, contextElement));
-        case AnimatedPath:
-            return adoptPtr(new SVGAnimatedPathAnimator(animationElement, contextElement));
-        case AnimatedTransformList:
-            return adoptPtr(new SVGAnimatedTransformListAnimator(animationElement, contextElement));
-        // Below properties have migrated to new property implementation.
-        case AnimatedBoolean:
-        case AnimatedColor:
-        case AnimatedInteger:
-        case AnimatedIntegerOptionalInteger:
-        case AnimatedNumber:
-        case AnimatedNumberList:
-        case AnimatedNumberOptionalNumber:
-        case AnimatedLength:
-        case AnimatedLengthList:
-        case AnimatedPoints:
-        case AnimatedPreserveAspectRatio:
-        case AnimatedRect:
-        case AnimatedString:
-            return adoptPtr(new SVGAnimatedNewPropertyAnimator(attributeType, animationElement, contextElement));
-
-        // SVGAnimatedPoint/SVGAnimatedStringList does not exist.
-        case AnimatedPoint:
-        case AnimatedStringList:
-            ASSERT_NOT_REACHED();
-
-        case AnimatedUnknown:
-            break;
-        }
-
-        ASSERT_NOT_REACHED();
-        return nullptr;
-    }
-
-private:
-    SVGAnimatorFactory() { }
-
-};
-
-} // namespace WebCore
-
-#endif // SVGAnimatorFactory_h
diff --git a/Source/core/svg/SVGCircleElement.cpp b/Source/core/svg/SVGCircleElement.cpp
index 10bb166..7e8719a 100644
--- a/Source/core/svg/SVGCircleElement.cpp
+++ b/Source/core/svg/SVGCircleElement.cpp
@@ -29,11 +29,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGCircleElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGCircleElement::SVGCircleElement(Document& document)
     : SVGGeometryElement(SVGNames::circleTag, document)
     , m_cx(SVGAnimatedLength::create(this, SVGNames::cxAttr, SVGLength::create(LengthModeWidth)))
@@ -45,7 +40,6 @@
     addToPropertyMap(m_cx);
     addToPropertyMap(m_cy);
     addToPropertyMap(m_r);
-    registerAnimatedPropertiesForSVGCircleElement();
 }
 
 PassRefPtr<SVGCircleElement> SVGCircleElement::create(Document& document)
diff --git a/Source/core/svg/SVGCircleElement.h b/Source/core/svg/SVGCircleElement.h
index b634318..72166c1 100644
--- a/Source/core/svg/SVGCircleElement.h
+++ b/Source/core/svg/SVGCircleElement.h
@@ -52,12 +52,8 @@
     RefPtr<SVGAnimatedLength> m_cx;
     RefPtr<SVGAnimatedLength> m_cy;
     RefPtr<SVGAnimatedLength> m_r;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGCircleElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGCircleElement, hasTagName(SVGNames::circleTag));
-
 } // namespace WebCore
 
 #endif // SVGCircleElement_h
diff --git a/Source/core/svg/SVGClipPathElement.cpp b/Source/core/svg/SVGClipPathElement.cpp
index f067830..7573966 100644
--- a/Source/core/svg/SVGClipPathElement.cpp
+++ b/Source/core/svg/SVGClipPathElement.cpp
@@ -28,20 +28,12 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGClipPathElement, SVGNames::clipPathUnitsAttr, ClipPathUnits, clipPathUnits, SVGUnitTypes::SVGUnitType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGClipPathElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(clipPathUnits)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGClipPathElement::SVGClipPathElement(Document& document)
     : SVGGraphicsElement(SVGNames::clipPathTag, document)
-    , m_clipPathUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
+    , m_clipPathUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::clipPathUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGClipPathElement();
+    addToPropertyMap(m_clipPathUnits);
 }
 
 PassRefPtr<SVGClipPathElement> SVGClipPathElement::create(Document& document)
@@ -65,14 +57,14 @@
         return;
     }
 
-    if (name == SVGNames::clipPathUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setClipPathUnitsBaseValue(propertyValue);
-        return;
-    }
+    SVGParsingError parseError = NoError;
 
-    ASSERT_NOT_REACHED();
+    if (name == SVGNames::clipPathUnitsAttr)
+        m_clipPathUnits->setBaseValueAsString(value, parseError);
+    else
+        ASSERT_NOT_REACHED();
+
+    reportAttributeParsingError(parseError, name, value);
 }
 
 void SVGClipPathElement::svgAttributeChanged(const QualifiedName& attrName)
diff --git a/Source/core/svg/SVGClipPathElement.h b/Source/core/svg/SVGClipPathElement.h
index 62a8fb8..6bc2bbc 100644
--- a/Source/core/svg/SVGClipPathElement.h
+++ b/Source/core/svg/SVGClipPathElement.h
@@ -34,6 +34,7 @@
 class SVGClipPathElement FINAL : public SVGGraphicsElement {
 public:
     static PassRefPtr<SVGClipPathElement> create(Document&);
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* clipPathUnits() { return m_clipPathUnits.get(); }
 
 private:
     explicit SVGClipPathElement(Document&);
@@ -47,13 +48,9 @@
 
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGClipPathElement)
-        DECLARE_ANIMATED_ENUMERATION(ClipPathUnits, clipPathUnits, SVGUnitTypes::SVGUnitType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_clipPathUnits;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGClipPathElement, hasTagName(SVGNames::clipPathTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGColor.cpp b/Source/core/svg/SVGColor.cpp
deleted file mode 100644
index ba50d81..0000000
--- a/Source/core/svg/SVGColor.cpp
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/SVGColor.h"
-
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "core/css/parser/BisonCSSParser.h"
-#include "core/css/RGBColor.h"
-
-namespace WebCore {
-
-SVGColor::SVGColor(const SVGColorType& colorType)
-    : CSSValue(SVGColorClass)
-    , m_colorType(colorType)
-{
-}
-
-SVGColor::SVGColor(ClassType classType, const SVGColorType& colorType)
-    : CSSValue(classType)
-    , m_colorType(colorType)
-{
-}
-
-PassRefPtr<RGBColor> SVGColor::rgbColor() const
-{
-    return RGBColor::create(m_color.rgb());
-}
-
-StyleColor SVGColor::colorFromRGBColorString(const String& colorString)
-{
-    // FIXME: Rework css parser so it is more SVG aware.
-    RGBA32 color;
-    if (BisonCSSParser::parseColor(color, colorString.stripWhiteSpace()))
-        return StyleColor(color);
-    // FIXME: This branch catches the string currentColor, but we should error if we have an illegal color value.
-    return StyleColor::currentColor();
-}
-
-void SVGColor::setRGBColor(const String&, ExceptionState& exceptionState)
-{
-    // The whole SVGColor interface is deprecated in SVG 1.1 (2nd edition).
-    // The setters are the most problematic part so we remove the support for those first.
-    exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
-}
-
-void SVGColor::setRGBColorICCColor(const String&, const String&, ExceptionState& exceptionState)
-{
-    exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
-}
-
-void SVGColor::setColor(unsigned short, const String&, const String&, ExceptionState& exceptionState)
-{
-    exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
-}
-
-String SVGColor::customCSSText() const
-{
-    switch (m_colorType) {
-    case SVG_COLORTYPE_UNKNOWN:
-        return String();
-    case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR:
-    case SVG_COLORTYPE_RGBCOLOR:
-        // FIXME: No ICC color support.
-        return m_color.serializedAsCSSComponentValue();
-    case SVG_COLORTYPE_CURRENTCOLOR:
-        return "currentColor";
-    }
-
-    ASSERT_NOT_REACHED();
-    return String();
-}
-
-SVGColor::SVGColor(ClassType classType, const SVGColor& cloneFrom)
-    : CSSValue(classType, /*isCSSOMSafe*/ true)
-    , m_color(cloneFrom.m_color)
-    , m_colorType(cloneFrom.m_colorType)
-{
-}
-
-PassRefPtrWillBeRawPtr<SVGColor> SVGColor::cloneForCSSOM() const
-{
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new SVGColor(SVGColorClass, *this));
-}
-
-bool SVGColor::equals(const SVGColor& other) const
-{
-    return m_colorType == other.m_colorType && m_color == other.m_color;
-}
-
-}
diff --git a/Source/core/svg/SVGColor.h b/Source/core/svg/SVGColor.h
deleted file mode 100644
index ea5bd57..0000000
--- a/Source/core/svg/SVGColor.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGColor_h
-#define SVGColor_h
-
-#include "core/css/CSSValue.h"
-#include "core/css/StyleColor.h"
-#include "platform/graphics/Color.h"
-#include "wtf/PassRefPtr.h"
-
-namespace WebCore {
-
-class ExceptionState;
-class RGBColor;
-
-class SVGColor : public CSSValue {
-public:
-    enum SVGColorType {
-        SVG_COLORTYPE_UNKNOWN = 0,
-        SVG_COLORTYPE_RGBCOLOR = 1,
-        SVG_COLORTYPE_RGBCOLOR_ICCCOLOR = 2,
-        SVG_COLORTYPE_CURRENTCOLOR = 3
-    };
-
-    static PassRefPtrWillBeRawPtr<SVGColor> createFromString(const String& rgbColor)
-    {
-        RefPtrWillBeRawPtr<SVGColor> color = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGColor(SVG_COLORTYPE_RGBCOLOR));
-        StyleColor styleColor = colorFromRGBColorString(rgbColor);
-        ASSERT(!styleColor.isCurrentColor());
-        color->setColor(styleColor.color());
-        return color.release();
-    }
-
-    static PassRefPtrWillBeRawPtr<SVGColor> createFromColor(const Color& rgbColor)
-    {
-        RefPtrWillBeRawPtr<SVGColor> color = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGColor(SVG_COLORTYPE_RGBCOLOR));
-        color->setColor(rgbColor);
-        return color.release();
-    }
-
-    static PassRefPtrWillBeRawPtr<SVGColor> createCurrentColor()
-    {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new SVGColor(SVG_COLORTYPE_CURRENTCOLOR));
-    }
-
-    const Color& color() const { return m_color; }
-    const SVGColorType& colorType() const { return m_colorType; }
-    PassRefPtr<RGBColor> rgbColor() const;
-
-    static StyleColor colorFromRGBColorString(const String&);
-
-    void setRGBColor(const String& rgbColor, ExceptionState&);
-    void setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionState&);
-    void setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionState&);
-
-    String customCSSText() const;
-
-    ~SVGColor() { }
-
-    PassRefPtrWillBeRawPtr<SVGColor> cloneForCSSOM() const;
-
-    bool equals(const SVGColor&) const;
-
-    void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
-
-protected:
-    friend class CSSComputedStyleDeclaration;
-
-    SVGColor(ClassType, const SVGColorType&);
-    SVGColor(ClassType, const SVGColor& cloneFrom);
-
-    void setColor(const Color& color)
-    {
-        m_color = color;
-        setColorType(SVG_COLORTYPE_RGBCOLOR);
-    }
-    void setColorType(const SVGColorType& type) { m_colorType = type; }
-
-private:
-    SVGColor(const SVGColorType&);
-
-    Color m_color;
-    SVGColorType m_colorType;
-};
-
-DEFINE_CSS_VALUE_TYPE_CASTS(SVGColor, isSVGColor());
-
-} // namespace WebCore
-
-#endif // SVGColor_h
diff --git a/Source/core/svg/SVGComponentTransferFunctionElement.cpp b/Source/core/svg/SVGComponentTransferFunctionElement.cpp
index e4a1b50..3367fa5 100644
--- a/Source/core/svg/SVGComponentTransferFunctionElement.cpp
+++ b/Source/core/svg/SVGComponentTransferFunctionElement.cpp
@@ -30,12 +30,19 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGComponentTransferFunctionElement, SVGNames::typeAttr, Type, type, ComponentTransferType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGComponentTransferFunctionElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(type)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ComponentTransferType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_IDENTITY, "identity"));
+        entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_TABLE, "table"));
+        entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_DISCRETE, "discrete"));
+        entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_LINEAR, "linear"));
+        entries.append(std::make_pair(FECOMPONENTTRANSFER_TYPE_GAMMA, "gamma"));
+    }
+    return entries;
+}
 
 SVGComponentTransferFunctionElement::SVGComponentTransferFunctionElement(const QualifiedName& tagName, Document& document)
     : SVGElement(tagName, document)
@@ -45,7 +52,7 @@
     , m_amplitude(SVGAnimatedNumber::create(this, SVGNames::amplitudeAttr, SVGNumber::create(1)))
     , m_exponent(SVGAnimatedNumber::create(this, SVGNames::exponentAttr, SVGNumber::create(1)))
     , m_offset(SVGAnimatedNumber::create(this, SVGNames::offsetAttr, SVGNumber::create()))
-    , m_type(FECOMPONENTTRANSFER_TYPE_IDENTITY)
+    , m_type(SVGAnimatedEnumeration<ComponentTransferType>::create(this, SVGNames::typeAttr, FECOMPONENTTRANSFER_TYPE_IDENTITY))
 {
     ScriptWrappable::init(this);
 
@@ -55,7 +62,7 @@
     addToPropertyMap(m_amplitude);
     addToPropertyMap(m_exponent);
     addToPropertyMap(m_offset);
-    registerAnimatedPropertiesForSVGComponentTransferFunctionElement();
+    addToPropertyMap(m_type);
 }
 
 bool SVGComponentTransferFunctionElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -80,17 +87,12 @@
         return;
     }
 
-    if (name == SVGNames::typeAttr) {
-        ComponentTransferType propertyValue = SVGPropertyTraits<ComponentTransferType>::fromString(value);
-        if (propertyValue > 0)
-            setTypeBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::tableValuesAttr)
         m_tableValues->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::typeAttr)
+        m_type->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::slopeAttr)
         m_slope->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::interceptAttr)
@@ -120,7 +122,7 @@
 ComponentTransferFunction SVGComponentTransferFunctionElement::transferFunction() const
 {
     ComponentTransferFunction func;
-    func.type = typeCurrentValue();
+    func.type = m_type->currentValue()->enumValue();
     func.slope = m_slope->currentValue()->value();
     func.intercept = m_intercept->currentValue()->value();
     func.amplitude = m_amplitude->currentValue()->value();
diff --git a/Source/core/svg/SVGComponentTransferFunctionElement.h b/Source/core/svg/SVGComponentTransferFunctionElement.h
index 7dfdcd8..da9a956 100644
--- a/Source/core/svg/SVGComponentTransferFunctionElement.h
+++ b/Source/core/svg/SVGComponentTransferFunctionElement.h
@@ -29,46 +29,7 @@
 
 namespace WebCore {
 
-template<>
-struct SVGPropertyTraits<ComponentTransferType> {
-    static unsigned highestEnumValue() { return FECOMPONENTTRANSFER_TYPE_GAMMA; }
-
-    static String toString(ComponentTransferType type)
-    {
-        switch (type) {
-        case FECOMPONENTTRANSFER_TYPE_UNKNOWN:
-            return emptyString();
-        case FECOMPONENTTRANSFER_TYPE_IDENTITY:
-            return "identity";
-        case FECOMPONENTTRANSFER_TYPE_TABLE:
-            return "table";
-        case FECOMPONENTTRANSFER_TYPE_DISCRETE:
-            return "discrete";
-        case FECOMPONENTTRANSFER_TYPE_LINEAR:
-            return "linear";
-        case FECOMPONENTTRANSFER_TYPE_GAMMA:
-            return "gamma";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static ComponentTransferType fromString(const String& value)
-    {
-        if (value == "identity")
-            return FECOMPONENTTRANSFER_TYPE_IDENTITY;
-        if (value == "table")
-            return FECOMPONENTTRANSFER_TYPE_TABLE;
-        if (value == "discrete")
-            return FECOMPONENTTRANSFER_TYPE_DISCRETE;
-        if (value == "linear")
-            return FECOMPONENTTRANSFER_TYPE_LINEAR;
-        if (value == "gamma")
-            return FECOMPONENTTRANSFER_TYPE_GAMMA;
-        return FECOMPONENTTRANSFER_TYPE_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ComponentTransferType>();
 
 class SVGComponentTransferFunctionElement : public SVGElement {
 public:
@@ -80,6 +41,7 @@
     SVGAnimatedNumber* amplitude() { return m_amplitude.get(); }
     SVGAnimatedNumber* exponent() { return m_exponent.get(); }
     SVGAnimatedNumber* offset() { return m_offset.get(); }
+    SVGAnimatedEnumeration<ComponentTransferType>* type() { return m_type.get(); }
 
 protected:
     SVGComponentTransferFunctionElement(const QualifiedName&, Document&);
@@ -97,10 +59,7 @@
     RefPtr<SVGAnimatedNumber> m_amplitude;
     RefPtr<SVGAnimatedNumber> m_exponent;
     RefPtr<SVGAnimatedNumber> m_offset;
-
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGComponentTransferFunctionElement)
-        DECLARE_ANIMATED_ENUMERATION(Type, type, ComponentTransferType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<ComponentTransferType> > m_type;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGCursorElement.cpp b/Source/core/svg/SVGCursorElement.cpp
index c1bb5d7..a2a7d6c 100644
--- a/Source/core/svg/SVGCursorElement.cpp
+++ b/Source/core/svg/SVGCursorElement.cpp
@@ -29,11 +29,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGCursorElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGCursorElement::SVGCursorElement(Document& document)
     : SVGElement(SVGNames::cursorTag, document)
     , SVGTests(this)
@@ -45,7 +40,6 @@
 
     addToPropertyMap(m_x);
     addToPropertyMap(m_y);
-    registerAnimatedPropertiesForSVGCursorElement();
 }
 
 PassRefPtr<SVGCursorElement> SVGCursorElement::create(Document& document)
diff --git a/Source/core/svg/SVGCursorElement.h b/Source/core/svg/SVGCursorElement.h
index 56c02f2..024e0bb 100644
--- a/Source/core/svg/SVGCursorElement.h
+++ b/Source/core/svg/SVGCursorElement.h
@@ -58,14 +58,10 @@
 
     RefPtr<SVGAnimatedLength> m_x;
     RefPtr<SVGAnimatedLength> m_y;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGCursorElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     HashSet<SVGElement*> m_clients;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGCursorElement, hasTagName(SVGNames::cursorTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGDefsElement.cpp b/Source/core/svg/SVGDefsElement.cpp
index 188eb57..93d28f5 100644
--- a/Source/core/svg/SVGDefsElement.cpp
+++ b/Source/core/svg/SVGDefsElement.cpp
@@ -27,17 +27,10 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGDefsElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGDefsElement::SVGDefsElement(Document& document)
     : SVGGraphicsElement(SVGNames::defsTag, document)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGDefsElement();
 }
 
 PassRefPtr<SVGDefsElement> SVGDefsElement::create(Document& document)
diff --git a/Source/core/svg/SVGDefsElement.h b/Source/core/svg/SVGDefsElement.h
index 86faeb7..8a60824 100644
--- a/Source/core/svg/SVGDefsElement.h
+++ b/Source/core/svg/SVGDefsElement.h
@@ -35,8 +35,6 @@
 
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGDefsElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGDocument.cpp b/Source/core/svg/SVGDocument.cpp
index 5e3a9bb..ebefdee 100644
--- a/Source/core/svg/SVGDocument.cpp
+++ b/Source/core/svg/SVGDocument.cpp
@@ -39,18 +39,15 @@
 {
 }
 
-SVGSVGElement* SVGDocument::rootElement(const Document* document)
+SVGSVGElement* SVGDocument::rootElement(const Document& document)
 {
-    Element* elem = document->documentElement();
-    if (elem && elem->hasTagName(SVGNames::svgTag))
-        return toSVGSVGElement(elem);
-
-    return 0;
+    Element* elem = document.documentElement();
+    return isSVGSVGElement(elem) ? toSVGSVGElement(elem) : 0;
 }
 
 SVGSVGElement* SVGDocument::rootElement() const
 {
-    return rootElement(this);
+    return rootElement(*this);
 }
 
 void SVGDocument::dispatchZoomEvent(float prevScale, float newScale)
diff --git a/Source/core/svg/SVGDocument.h b/Source/core/svg/SVGDocument.h
index 78b3c7e..771f2b1 100644
--- a/Source/core/svg/SVGDocument.h
+++ b/Source/core/svg/SVGDocument.h
@@ -35,7 +35,7 @@
         return adoptRef(new SVGDocument(initializer));
     }
 
-    static SVGSVGElement* rootElement(const Document*);
+    static SVGSVGElement* rootElement(const Document&);
     SVGSVGElement* rootElement() const;
 
     void dispatchZoomEvent(float prevScale, float newScale);
diff --git a/Source/core/svg/SVGDocumentExtensions.cpp b/Source/core/svg/SVGDocumentExtensions.cpp
index c4a5a8f..8d0acd1 100644
--- a/Source/core/svg/SVGDocumentExtensions.cpp
+++ b/Source/core/svg/SVGDocumentExtensions.cpp
@@ -83,6 +83,22 @@
     return m_resources.get(id);
 }
 
+void SVGDocumentExtensions::serviceOnAnimationFrame(Document& document, double monotonicAnimationStartTime)
+{
+    if (!document.svgExtensions())
+        return;
+    document.accessSVGExtensions().serviceAnimations(monotonicAnimationStartTime);
+}
+
+void SVGDocumentExtensions::serviceAnimations(double monotonicAnimationStartTime)
+{
+    Vector<RefPtr<SVGSVGElement> > timeContainers;
+    timeContainers.appendRange(m_timeContainers.begin(), m_timeContainers.end());
+    Vector<RefPtr<SVGSVGElement> >::iterator end = timeContainers.end();
+    for (Vector<RefPtr<SVGSVGElement> >::iterator itr = timeContainers.begin(); itr != end; ++itr)
+        (*itr)->timeContainer()->serviceAnimations(monotonicAnimationStartTime);
+}
+
 void SVGDocumentExtensions::startAnimations()
 {
     // FIXME: Eventually every "Time Container" will need a way to latch on to some global timer
diff --git a/Source/core/svg/SVGDocumentExtensions.h b/Source/core/svg/SVGDocumentExtensions.h
index abf4a68..ba09942 100644
--- a/Source/core/svg/SVGDocumentExtensions.h
+++ b/Source/core/svg/SVGDocumentExtensions.h
@@ -54,6 +54,8 @@
     void removeResource(const AtomicString& id);
     RenderSVGResourceContainer* resourceById(const AtomicString& id) const;
 
+    static void serviceOnAnimationFrame(Document&, double monotonicAnimationStartTime);
+
     void startAnimations();
     void pauseAnimations();
     void unpauseAnimations();
@@ -109,6 +111,8 @@
     void removeElementFromPendingResources(Element*);
     PassOwnPtr<SVGPendingElements> removePendingResource(const AtomicString& id);
 
+    void serviceAnimations(double monotonicAnimationStartTime);
+
     // The following two functions are used for scheduling a pending resource to be removed.
     void markPendingResourcesForRemoval(const AtomicString&);
     Element* removeElementFromPendingResourcesForRemoval(const AtomicString&);
diff --git a/Source/core/svg/SVGElement.cpp b/Source/core/svg/SVGElement.cpp
index 5e5638a..ca015d3 100644
--- a/Source/core/svg/SVGElement.cpp
+++ b/Source/core/svg/SVGElement.cpp
@@ -45,17 +45,13 @@
 #include "core/svg/SVGElementRareData.h"
 #include "core/svg/SVGGraphicsElement.h"
 #include "core/svg/SVGSVGElement.h"
+#include "core/svg/SVGTitleElement.h"
 #include "core/svg/SVGUseElement.h"
 
 #include "wtf/TemporaryChange.h"
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 using namespace HTMLNames;
 using namespace SVGNames;
 
@@ -74,7 +70,6 @@
 #if !ASSERT_DISABLED
     , m_inRelativeLengthClientsInvalidation(false)
 #endif
-    , m_animatedPropertiesDestructed(false)
     // |m_isContextElement| must be initialized before |m_className|, as SVGAnimatedString tear-off c-tor currently set this to true.
     , m_isContextElement(false)
     , m_hasSVGRareData(false)
@@ -82,21 +77,12 @@
 {
     ScriptWrappable::init(this);
     addToPropertyMap(m_className);
-    registerAnimatedPropertiesForSVGElement();
     setHasCustomStyleCallbacks();
 }
 
 SVGElement::~SVGElement()
 {
     ASSERT(inDocument() || !hasRelativeLengths());
-}
-
-void
-SVGElement::cleanupAnimatedProperties()
-{
-    if (m_animatedPropertiesDestructed)
-        return;
-    m_animatedPropertiesDestructed = true;
 
     if (!hasSVGRareData())
         ASSERT(!SVGElementRareData::rareDataMap().contains(this));
@@ -123,9 +109,8 @@
         // removeAllElementReferencesForTarget() below.
         clearHasSVGRareData();
     }
-    document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
-    document().accessSVGExtensions()->removeAllElementReferencesForTarget(this);
-    SVGAnimatedProperty::detachAnimatedPropertiesForElement(this);
+    document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
+    document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
 }
 
 void SVGElement::willRecalcStyle(StyleRecalcChange change)
@@ -148,20 +133,20 @@
     if (!needsPendingResourceHandling() || !inDocument() || isInShadowTree())
         return;
 
-    SVGDocumentExtensions* extensions = document.accessSVGExtensions();
+    SVGDocumentExtensions& extensions = document.accessSVGExtensions();
     AtomicString resourceId = getIdAttribute();
-    if (!extensions->hasPendingResource(resourceId))
+    if (!extensions.hasPendingResource(resourceId))
         return;
 
     // Mark pending resources as pending for removal.
-    extensions->markPendingResourcesForRemoval(resourceId);
+    extensions.markPendingResourcesForRemoval(resourceId);
 
     // Rebuild pending resources for each client of a pending resource that is being removed.
-    while (Element* clientElement = extensions->removeElementFromPendingResourcesForRemoval(resourceId)) {
+    while (Element* clientElement = extensions.removeElementFromPendingResourcesForRemoval(resourceId)) {
         ASSERT(clientElement->hasPendingResources());
         if (clientElement->hasPendingResources()) {
             clientElement->buildPendingResource();
-            extensions->clearHasPendingResourcesIfPossible(clientElement);
+            extensions.clearHasPendingResourcesIfPossible(clientElement);
         }
     }
 }
@@ -199,7 +184,7 @@
 
 bool SVGElement::isOutermostSVGSVGElement() const
 {
-    if (!hasTagName(SVGNames::svgTag))
+    if (!isSVGSVGElement(*this))
         return false;
 
     // Element may not be in the document, pretend we're outermost for viewport(), getCTM(), etc.
@@ -207,7 +192,7 @@
         return true;
 
     // We act like an outermost SVG element, if we're a direct child of a <foreignObject> element.
-    if (parentNode()->hasTagName(SVGNames::foreignObjectTag))
+    if (isSVGForeignObjectElement(*parentNode()))
         return true;
 
     // If we're living in a shadow tree, we're a <svg> element that got created as replacement
@@ -226,15 +211,15 @@
         return;
 
     String errorString = "<" + tagName() + "> attribute " + name.toString() + "=\"" + value + "\"";
-    SVGDocumentExtensions* extensions = document().accessSVGExtensions();
+    SVGDocumentExtensions& extensions = document().accessSVGExtensions();
 
     if (error == NegativeValueForbiddenError) {
-        extensions->reportError("Invalid negative value for " + errorString);
+        extensions.reportError("Invalid negative value for " + errorString);
         return;
     }
 
     if (error == ParsingAttributeFailedError) {
-        extensions->reportError("Invalid value for " + errorString);
+        extensions.reportError("Invalid value for " + errorString);
         return;
     }
 
@@ -254,12 +239,12 @@
         // At this time, SVG nodes are not allowed in non-<use> shadow trees, so any shadow root we do
         // have should be a use. The assert and following test is here to catch future shadow DOM changes
         // that do enable SVG in a shadow tree.
-        ASSERT(!shadowHostElement || shadowHostElement->hasTagName(SVGNames::useTag));
-        if (shadowHostElement && shadowHostElement->hasTagName(SVGNames::useTag)) {
-            SVGUseElement* useElement = toSVGUseElement(shadowHostElement);
+        ASSERT(!shadowHostElement || isSVGUseElement(*shadowHostElement));
+        if (isSVGUseElement(shadowHostElement)) {
+            SVGUseElement& useElement = toSVGUseElement(*shadowHostElement);
 
             // If the <use> title is not empty we found the title to use.
-            String useTitle(useElement->title());
+            String useTitle(useElement.title());
             if (!useTitle.isEmpty())
                 return useTitle;
         }
@@ -267,35 +252,29 @@
 
     // If we aren't an instance in a <use> or the <use> title was not found, then find the first
     // <title> child of this element.
-    Element* titleElement = ElementTraversal::firstWithin(*this);
-    for (; titleElement; titleElement = ElementTraversal::nextSkippingChildren(*titleElement, this)) {
-        if (titleElement->hasTagName(SVGNames::titleTag) && titleElement->isSVGElement())
-            break;
-    }
-
     // If a title child was found, return the text contents.
-    if (titleElement)
+    if (Element* titleElement = Traversal<SVGTitleElement>::firstChild(*this))
         return titleElement->innerText();
 
     // Otherwise return a null/empty string.
     return String();
 }
 
-PassRefPtr<CSSValue> SVGElement::getPresentationAttribute(const AtomicString& name)
+PassRefPtrWillBeRawPtr<CSSValue> SVGElement::getPresentationAttribute(const AtomicString& name)
 {
     if (!hasAttributesWithoutUpdate())
-        return 0;
+        return nullptr;
 
     QualifiedName attributeName(nullAtom, name, nullAtom);
     const Attribute* attr = getAttributeItem(attributeName);
     if (!attr)
-        return 0;
+        return nullptr;
 
     RefPtr<MutableStylePropertySet> style = MutableStylePropertySet::create(SVGAttributeMode);
     CSSPropertyID propertyID = SVGElement::cssPropertyIdForSVGAttributeName(attr->name());
     style->setProperty(propertyID, attr->value());
-    RefPtr<CSSValue> cssValue = style->getPropertyCSSValue(propertyID);
-    return cssValue ? cssValue->cloneForCSSOM() : 0;
+    RefPtrWillBeRawPtr<CSSValue> cssValue = style->getPropertyCSSValue(propertyID);
+    return cssValue ? cssValue->cloneForCSSOM() : nullptr;
 }
 
 
@@ -375,8 +354,8 @@
     Element::removedFrom(rootParent);
 
     if (wasInDocument) {
-        document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
-        document().accessSVGExtensions()->removeAllElementReferencesForTarget(this);
+        document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
+        document().accessSVGExtensions().removeAllElementReferencesForTarget(this);
     }
 
     SVGElementInstance::invalidateAllInstancesOfElement(this);
@@ -498,12 +477,12 @@
     }
 
     // Register root SVG elements for top level viewport change notifications.
-    if (clientElement->isSVGSVGElement()) {
-        SVGDocumentExtensions* svgExtensions = accessDocumentSVGExtensions();
+    if (isSVGSVGElement(*clientElement)) {
+        SVGDocumentExtensions& svgExtensions = accessDocumentSVGExtensions();
         if (clientElement->hasRelativeLengths())
-            svgExtensions->addSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
+            svgExtensions.addSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
         else
-            svgExtensions->removeSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
+            svgExtensions.removeSVGRootWithRelativeLengthDescendents(toSVGSVGElement(clientElement));
     }
 }
 
@@ -536,7 +515,7 @@
 {
     ContainerNode* n = parentOrShadowHostNode();
     while (n) {
-        if (n->hasTagName(SVGNames::svgTag))
+        if (isSVGSVGElement(*n))
             return toSVGSVGElement(n);
 
         n = n->parentOrShadowHostNode();
@@ -551,7 +530,7 @@
     // to determine the "overflow" property. <use> on <symbol> wouldn't work otherwhise.
     ContainerNode* n = parentOrShadowHostNode();
     while (n) {
-        if (n->hasTagName(SVGNames::svgTag) || n->hasTagName(SVGNames::imageTag) || n->hasTagName(SVGNames::symbolTag))
+        if (isSVGSVGElement(*n) || isSVGImageElement(*n) || isSVGSymbolElement(*n))
             return toSVGElement(n);
 
         n = n->parentOrShadowHostNode();
@@ -560,7 +539,7 @@
     return 0;
 }
 
-SVGDocumentExtensions* SVGElement::accessDocumentSVGExtensions()
+SVGDocumentExtensions& SVGElement::accessDocumentSVGExtensions()
 {
     // This function is provided for use by SVGAnimatedProperty to avoid
     // global inclusion of core/dom/Document.h in SVG code.
@@ -673,86 +652,74 @@
 }
 
 typedef HashMap<QualifiedName, AnimatedPropertyType> AttributeToPropertyTypeMap;
-static inline AttributeToPropertyTypeMap& cssPropertyToTypeMap()
+AnimatedPropertyType SVGElement::animatedPropertyTypeForCSSAttribute(const QualifiedName& attributeName)
 {
-    DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, s_cssPropertyMap, ());
+    DEFINE_STATIC_LOCAL(AttributeToPropertyTypeMap, cssPropertyMap, ());
 
-    if (!s_cssPropertyMap.isEmpty())
-        return s_cssPropertyMap;
+    if (cssPropertyMap.isEmpty()) {
+        // Fill the map for the first use.
+        cssPropertyMap.set(alignment_baselineAttr, AnimatedString);
+        cssPropertyMap.set(baseline_shiftAttr, AnimatedString);
+        cssPropertyMap.set(buffered_renderingAttr, AnimatedString);
+        cssPropertyMap.set(clipAttr, AnimatedRect);
+        cssPropertyMap.set(clip_pathAttr, AnimatedString);
+        cssPropertyMap.set(clip_ruleAttr, AnimatedString);
+        cssPropertyMap.set(SVGNames::colorAttr, AnimatedColor);
+        cssPropertyMap.set(color_interpolationAttr, AnimatedString);
+        cssPropertyMap.set(color_interpolation_filtersAttr, AnimatedString);
+        cssPropertyMap.set(color_profileAttr, AnimatedString);
+        cssPropertyMap.set(color_renderingAttr, AnimatedString);
+        cssPropertyMap.set(cursorAttr, AnimatedString);
+        cssPropertyMap.set(displayAttr, AnimatedString);
+        cssPropertyMap.set(dominant_baselineAttr, AnimatedString);
+        cssPropertyMap.set(fillAttr, AnimatedColor);
+        cssPropertyMap.set(fill_opacityAttr, AnimatedNumber);
+        cssPropertyMap.set(fill_ruleAttr, AnimatedString);
+        cssPropertyMap.set(filterAttr, AnimatedString);
+        cssPropertyMap.set(flood_colorAttr, AnimatedColor);
+        cssPropertyMap.set(flood_opacityAttr, AnimatedNumber);
+        cssPropertyMap.set(font_familyAttr, AnimatedString);
+        cssPropertyMap.set(font_sizeAttr, AnimatedLength);
+        cssPropertyMap.set(font_stretchAttr, AnimatedString);
+        cssPropertyMap.set(font_styleAttr, AnimatedString);
+        cssPropertyMap.set(font_variantAttr, AnimatedString);
+        cssPropertyMap.set(font_weightAttr, AnimatedString);
+        cssPropertyMap.set(image_renderingAttr, AnimatedString);
+        cssPropertyMap.set(kerningAttr, AnimatedLength);
+        cssPropertyMap.set(letter_spacingAttr, AnimatedLength);
+        cssPropertyMap.set(lighting_colorAttr, AnimatedColor);
+        cssPropertyMap.set(marker_endAttr, AnimatedString);
+        cssPropertyMap.set(marker_midAttr, AnimatedString);
+        cssPropertyMap.set(marker_startAttr, AnimatedString);
+        cssPropertyMap.set(maskAttr, AnimatedString);
+        cssPropertyMap.set(mask_typeAttr, AnimatedString);
+        cssPropertyMap.set(opacityAttr, AnimatedNumber);
+        cssPropertyMap.set(overflowAttr, AnimatedString);
+        cssPropertyMap.set(paint_orderAttr, AnimatedString);
+        cssPropertyMap.set(pointer_eventsAttr, AnimatedString);
+        cssPropertyMap.set(shape_renderingAttr, AnimatedString);
+        cssPropertyMap.set(stop_colorAttr, AnimatedColor);
+        cssPropertyMap.set(stop_opacityAttr, AnimatedNumber);
+        cssPropertyMap.set(strokeAttr, AnimatedColor);
+        cssPropertyMap.set(stroke_dasharrayAttr, AnimatedLengthList);
+        cssPropertyMap.set(stroke_dashoffsetAttr, AnimatedLength);
+        cssPropertyMap.set(stroke_linecapAttr, AnimatedString);
+        cssPropertyMap.set(stroke_linejoinAttr, AnimatedString);
+        cssPropertyMap.set(stroke_miterlimitAttr, AnimatedNumber);
+        cssPropertyMap.set(stroke_opacityAttr, AnimatedNumber);
+        cssPropertyMap.set(stroke_widthAttr, AnimatedLength);
+        cssPropertyMap.set(text_anchorAttr, AnimatedString);
+        cssPropertyMap.set(text_decorationAttr, AnimatedString);
+        cssPropertyMap.set(text_renderingAttr, AnimatedString);
+        cssPropertyMap.set(vector_effectAttr, AnimatedString);
+        cssPropertyMap.set(visibilityAttr, AnimatedString);
+        cssPropertyMap.set(word_spacingAttr, AnimatedLength);
+    }
 
-    // Fill the map for the first use.
-    s_cssPropertyMap.set(alignment_baselineAttr, AnimatedString);
-    s_cssPropertyMap.set(baseline_shiftAttr, AnimatedString);
-    s_cssPropertyMap.set(buffered_renderingAttr, AnimatedString);
-    s_cssPropertyMap.set(clipAttr, AnimatedRect);
-    s_cssPropertyMap.set(clip_pathAttr, AnimatedString);
-    s_cssPropertyMap.set(clip_ruleAttr, AnimatedString);
-    s_cssPropertyMap.set(SVGNames::colorAttr, AnimatedColor);
-    s_cssPropertyMap.set(color_interpolationAttr, AnimatedString);
-    s_cssPropertyMap.set(color_interpolation_filtersAttr, AnimatedString);
-    s_cssPropertyMap.set(color_profileAttr, AnimatedString);
-    s_cssPropertyMap.set(color_renderingAttr, AnimatedString);
-    s_cssPropertyMap.set(cursorAttr, AnimatedString);
-    s_cssPropertyMap.set(displayAttr, AnimatedString);
-    s_cssPropertyMap.set(dominant_baselineAttr, AnimatedString);
-    s_cssPropertyMap.set(fillAttr, AnimatedColor);
-    s_cssPropertyMap.set(fill_opacityAttr, AnimatedNumber);
-    s_cssPropertyMap.set(fill_ruleAttr, AnimatedString);
-    s_cssPropertyMap.set(filterAttr, AnimatedString);
-    s_cssPropertyMap.set(flood_colorAttr, AnimatedColor);
-    s_cssPropertyMap.set(flood_opacityAttr, AnimatedNumber);
-    s_cssPropertyMap.set(font_familyAttr, AnimatedString);
-    s_cssPropertyMap.set(font_sizeAttr, AnimatedLength);
-    s_cssPropertyMap.set(font_stretchAttr, AnimatedString);
-    s_cssPropertyMap.set(font_styleAttr, AnimatedString);
-    s_cssPropertyMap.set(font_variantAttr, AnimatedString);
-    s_cssPropertyMap.set(font_weightAttr, AnimatedString);
-    s_cssPropertyMap.set(image_renderingAttr, AnimatedString);
-    s_cssPropertyMap.set(kerningAttr, AnimatedLength);
-    s_cssPropertyMap.set(letter_spacingAttr, AnimatedLength);
-    s_cssPropertyMap.set(lighting_colorAttr, AnimatedColor);
-    s_cssPropertyMap.set(marker_endAttr, AnimatedString);
-    s_cssPropertyMap.set(marker_midAttr, AnimatedString);
-    s_cssPropertyMap.set(marker_startAttr, AnimatedString);
-    s_cssPropertyMap.set(maskAttr, AnimatedString);
-    s_cssPropertyMap.set(mask_typeAttr, AnimatedString);
-    s_cssPropertyMap.set(opacityAttr, AnimatedNumber);
-    s_cssPropertyMap.set(overflowAttr, AnimatedString);
-    s_cssPropertyMap.set(paint_orderAttr, AnimatedString);
-    s_cssPropertyMap.set(pointer_eventsAttr, AnimatedString);
-    s_cssPropertyMap.set(shape_renderingAttr, AnimatedString);
-    s_cssPropertyMap.set(stop_colorAttr, AnimatedColor);
-    s_cssPropertyMap.set(stop_opacityAttr, AnimatedNumber);
-    s_cssPropertyMap.set(strokeAttr, AnimatedColor);
-    s_cssPropertyMap.set(stroke_dasharrayAttr, AnimatedLengthList);
-    s_cssPropertyMap.set(stroke_dashoffsetAttr, AnimatedLength);
-    s_cssPropertyMap.set(stroke_linecapAttr, AnimatedString);
-    s_cssPropertyMap.set(stroke_linejoinAttr, AnimatedString);
-    s_cssPropertyMap.set(stroke_miterlimitAttr, AnimatedNumber);
-    s_cssPropertyMap.set(stroke_opacityAttr, AnimatedNumber);
-    s_cssPropertyMap.set(stroke_widthAttr, AnimatedLength);
-    s_cssPropertyMap.set(text_anchorAttr, AnimatedString);
-    s_cssPropertyMap.set(text_decorationAttr, AnimatedString);
-    s_cssPropertyMap.set(text_renderingAttr, AnimatedString);
-    s_cssPropertyMap.set(vector_effectAttr, AnimatedString);
-    s_cssPropertyMap.set(visibilityAttr, AnimatedString);
-    s_cssPropertyMap.set(word_spacingAttr, AnimatedLength);
-    return s_cssPropertyMap;
-}
+    if (cssPropertyMap.contains(attributeName))
+        return cssPropertyMap.get(attributeName);
 
-void SVGElement::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes)
-{
-    localAttributeToPropertyMap().animatedPropertyTypeForAttribute(attributeName, propertyTypes);
-    if (!propertyTypes.isEmpty())
-        return;
-
-    RefPtr<NewSVGAnimatedPropertyBase> animatedProperty = m_newAttributeToPropertyMap.get(attributeName);
-    if (animatedProperty)
-        propertyTypes.append(animatedProperty->type());
-
-    AttributeToPropertyTypeMap& cssPropertyTypeMap = cssPropertyToTypeMap();
-    if (cssPropertyTypeMap.contains(attributeName))
-        propertyTypes.append(cssPropertyTypeMap.get(attributeName));
+    return AnimatedUnknown;
 }
 
 void SVGElement::addToPropertyMap(PassRefPtr<NewSVGAnimatedPropertyBase> passProperty)
@@ -769,7 +736,7 @@
 
 bool SVGElement::isAnimatableCSSProperty(const QualifiedName& attrName)
 {
-    return cssPropertyToTypeMap().contains(attrName);
+    return animatedPropertyTypeForCSSAttribute(attrName) != AnimatedUnknown;
 }
 
 bool SVGElement::isPresentationAttribute(const QualifiedName& name) const
@@ -900,7 +867,7 @@
         if (sendParentLoadEvents)
             parent = currentTarget->parentOrShadowHostElement(); // save the next parent to dispatch too incase dispatching the event changes the tree
         if (hasLoadListener(currentTarget.get())
-            && (currentTarget->isStructurallyExternal() || currentTarget->isSVGSVGElement()))
+            && (currentTarget->isStructurallyExternal() || isSVGSVGElement(*currentTarget)))
             currentTarget->dispatchEvent(Event::create(EventTypeNames::load));
         currentTarget = (parent && parent->isSVGElement()) ? static_pointer_cast<SVGElement>(parent) : RefPtr<SVGElement>();
         SVGElement* element = currentTarget.get();
@@ -922,7 +889,7 @@
 
 void SVGElement::sendSVGLoadEventIfPossibleAsynchronously()
 {
-    svgLoadEventTimer()->startOneShot(0);
+    svgLoadEventTimer()->startOneShot(0, FROM_HERE);
 }
 
 void SVGElement::svgLoadEventTimerFired(Timer<SVGElement>*)
@@ -946,7 +913,7 @@
 
     // finishParsingChildren() is called when the close tag is reached for an element (e.g. </svg>)
     // we send SVGLoad events here if we can, otherwise they'll be sent when any required loads finish
-    if (isSVGSVGElement())
+    if (isSVGSVGElement(*this))
         sendSVGLoadEventIfPossible();
 }
 
@@ -955,7 +922,7 @@
     Element::attributeChanged(name, newValue);
 
     if (isIdAttributeName(name))
-        document().accessSVGExtensions()->rebuildAllElementReferencesForTarget(this);
+        document().accessSVGExtensions().rebuildAllElementReferencesForTarget(this);
 
     // Changes to the style attribute are processed lazily (see Element::getAttribute() and related methods),
     // so we don't want changes to the style attribute to result in extra work here.
@@ -994,10 +961,7 @@
     if (!elementData() || !elementData()->m_animatedSVGAttributesAreDirty)
         return;
 
-    SVGElement* nonConstThis = const_cast<SVGElement*>(this);
     if (name == anyQName()) {
-        nonConstThis->localAttributeToPropertyMap().synchronizeProperties(nonConstThis);
-
         AttributeToPropertyMap::const_iterator::Values it = m_newAttributeToPropertyMap.values().begin();
         AttributeToPropertyMap::const_iterator::Values end = m_newAttributeToPropertyMap.values().end();
         for (; it != end; ++it) {
@@ -1007,32 +971,12 @@
 
         elementData()->m_animatedSVGAttributesAreDirty = false;
     } else {
-        nonConstThis->localAttributeToPropertyMap().synchronizeProperty(nonConstThis, name);
-
         RefPtr<NewSVGAnimatedPropertyBase> property = m_newAttributeToPropertyMap.get(name);
         if (property && property->needsSynchronizeAttribute())
             property->synchronizeAttribute();
     }
 }
 
-void SVGElement::synchronizeRequiredFeatures(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    contextElement->synchronizeRequiredFeatures();
-}
-
-void SVGElement::synchronizeRequiredExtensions(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    contextElement->synchronizeRequiredExtensions();
-}
-
-void SVGElement::synchronizeSystemLanguage(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    contextElement->synchronizeSystemLanguage();
-}
-
 PassRefPtr<RenderStyle> SVGElement::customStyleForRenderer()
 {
     if (!correspondingElement())
diff --git a/Source/core/svg/SVGElement.h b/Source/core/svg/SVGElement.h
index 2bac4f0..020e091 100644
--- a/Source/core/svg/SVGElement.h
+++ b/Source/core/svg/SVGElement.h
@@ -22,10 +22,10 @@
 #ifndef SVGElement_h
 #define SVGElement_h
 
+#include "SVGElementTypeHelpers.h"
 #include "core/dom/Element.h"
 #include "core/svg/SVGAnimatedString.h"
 #include "core/svg/SVGParsingError.h"
-#include "core/svg/properties/SVGAnimatedPropertyMacros.h"
 #include "core/svg/properties/SVGPropertyInfo.h"
 #include "platform/Timer.h"
 #include "wtf/HashMap.h"
@@ -38,7 +38,6 @@
 class Document;
 class NewSVGAnimatedPropertyBase;
 class SubtreeLayoutScope;
-class SVGAttributeToPropertyMap;
 class SVGCursorElement;
 class SVGDocumentExtensions;
 class SVGElementInstance;
@@ -57,11 +56,12 @@
     virtual String title() const OVERRIDE;
     bool hasRelativeLengths() const { return !m_elementsWithRelativeLengths.isEmpty(); }
     virtual bool supportsMarkers() const { return false; }
-    PassRefPtr<CSSValue> getPresentationAttribute(const AtomicString& name);
+    PassRefPtrWillBeRawPtr<CSSValue> getPresentationAttribute(const AtomicString& name);
     static bool isAnimatableCSSProperty(const QualifiedName&);
     enum CTMScope {
         NearestViewportScope, // Used by SVGGraphicsElement::getCTM()
-        ScreenScope // Used by SVGGraphicsElement::getScreenCTM()
+        ScreenScope, // Used by SVGGraphicsElement::getScreenCTM()
+        AncestorScope // Used by SVGSVGElement::get{Enclosure|Intersection}List()
     };
     virtual AffineTransform localCoordinateSpaceTransform(CTMScope) const;
     virtual bool needsPendingResourceHandling() const { return true; }
@@ -81,12 +81,10 @@
     SVGSVGElement* ownerSVGElement() const;
     SVGElement* viewportElement() const;
 
-    SVGDocumentExtensions* accessDocumentSVGExtensions();
+    SVGDocumentExtensions& accessDocumentSVGExtensions();
 
     virtual bool isSVGGraphicsElement() const { return false; }
-    virtual bool isSVGSVGElement() const { return false; }
     virtual bool isFilterEffect() const { return false; }
-    virtual bool isGradientStop() const { return false; }
     virtual bool isTextContent() const { return false; }
     virtual bool isTextPositioning() const { return false; }
     virtual bool isStructurallyExternal() const { return false; }
@@ -96,8 +94,8 @@
 
     virtual void svgAttributeChanged(const QualifiedName&);
 
-    void animatedPropertyTypeForAttribute(const QualifiedName&, Vector<AnimatedPropertyType>&);
     PassRefPtr<NewSVGAnimatedPropertyBase> propertyFromAttribute(const QualifiedName& attributeName);
+    static AnimatedPropertyType animatedPropertyTypeForCSSAttribute(const QualifiedName& attributeName);
 
     void sendSVGLoadEventIfPossible(bool sendParentLoadEvents = false);
     void sendSVGLoadEventIfPossibleAsynchronously();
@@ -106,7 +104,7 @@
 
     virtual AffineTransform* supplementalTransform() { return 0; }
 
-    void invalidateSVGAttributes() { ensureUniqueElementData()->m_animatedSVGAttributesAreDirty = true; }
+    void invalidateSVGAttributes() { ensureUniqueElementData().m_animatedSVGAttributesAreDirty = true; }
 
     const HashSet<SVGElementInstance*>& instancesForElement() const;
 
@@ -124,10 +122,6 @@
 
     virtual PassRefPtr<RenderStyle> customStyleForRenderer() OVERRIDE FINAL;
 
-    static void synchronizeRequiredFeatures(SVGElement* contextElement);
-    static void synchronizeRequiredExtensions(SVGElement* contextElement);
-    static void synchronizeSystemLanguage(SVGElement* contextElement);
-
     virtual void synchronizeRequiredFeatures() { }
     virtual void synchronizeRequiredExtensions() { }
     virtual void synchronizeSystemLanguage() { }
@@ -188,25 +182,6 @@
     void reportAttributeParsingError(SVGParsingError, const QualifiedName&, const AtomicString&);
     bool hasFocusEventListeners() const;
 
-    class CleanUpAnimatedPropertiesCaller {
-    public:
-        CleanUpAnimatedPropertiesCaller()
-        :   m_owner(0)
-        {
-        }
-
-        ~CleanUpAnimatedPropertiesCaller()
-        {
-            ASSERT(m_owner);
-            m_owner->cleanupAnimatedProperties();
-        }
-
-        void setOwner(SVGElement* owner) { m_owner = owner; }
-
-    private:
-        SVGElement* m_owner;
-    };
-
 private:
     friend class SVGElementInstance;
 
@@ -235,13 +210,10 @@
 #if !ASSERT_DISABLED
     bool m_inRelativeLengthClientsInvalidation;
 #endif
-    unsigned m_animatedPropertiesDestructed : 1;
     unsigned m_isContextElement : 1;
     unsigned m_hasSVGRareData : 1;
 
     RefPtr<SVGAnimatedString> m_className;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 struct SVGAttributeHashTranslator {
@@ -256,7 +228,7 @@
     static bool equal(const QualifiedName& a, const QualifiedName& b) { return a.matches(b); }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGElement, isSVGElement());
+DEFINE_ELEMENT_TYPE_CASTS(SVGElement, isSVGElement());
 
 }
 
diff --git a/Source/core/svg/SVGElement.idl b/Source/core/svg/SVGElement.idl
index feffa7c..1608f33 100644
--- a/Source/core/svg/SVGElement.idl
+++ b/Source/core/svg/SVGElement.idl
@@ -30,7 +30,7 @@
     attribute DOMString xmllang;
     attribute DOMString xmlspace;
 
-    readonly attribute SVGAnimatedString className;
+    [MeasureAs=SVGClassName] readonly attribute SVGAnimatedString className;
     readonly attribute CSSStyleDeclaration style;
 
     // CSSValue was deprecated in 2003:
diff --git a/Source/core/svg/SVGElementInstance.cpp b/Source/core/svg/SVGElementInstance.cpp
index 3e835c1..2d40ecc 100644
--- a/Source/core/svg/SVGElementInstance.cpp
+++ b/Source/core/svg/SVGElementInstance.cpp
@@ -118,7 +118,7 @@
     instanceCounter.decrement();
 #endif
 
-    m_element = 0;
+    m_element = nullptr;
 }
 
 // It's important not to inline removedLastRef, because we don't want to inline the code to
@@ -144,7 +144,7 @@
         m_element->removeInstanceMapping(this);
     // DO NOT clear ref to m_element because JavaScriptCore uses it for garbage collection
 
-    m_shadowTreeElement = 0;
+    m_shadowTreeElement = nullptr;
 
     m_directUseElement = 0;
     m_correspondingUseElement = 0;
diff --git a/Source/core/svg/SVGElementInstance.h b/Source/core/svg/SVGElementInstance.h
index 8ae0bfa..5161d15 100644
--- a/Source/core/svg/SVGElementInstance.h
+++ b/Source/core/svg/SVGElementInstance.h
@@ -164,7 +164,7 @@
     template<class GenericNode, class GenericNodeContainer>
     friend void Private::addChildNodesToDeletionQueue(GenericNode*& head, GenericNode*& tail, GenericNodeContainer&);
 
-    bool hasChildNodes() const { return m_firstChild; }
+    bool hasChildren() const { return m_firstChild; }
 
     void setFirstChild(SVGElementInstance* child) { m_firstChild = child; }
     void setLastChild(SVGElementInstance* child) { m_lastChild = child; }
diff --git a/Source/core/svg/SVGElementInstance.idl b/Source/core/svg/SVGElementInstance.idl
index 8f6a1d8..66b666c 100644
--- a/Source/core/svg/SVGElementInstance.idl
+++ b/Source/core/svg/SVGElementInstance.idl
@@ -24,7 +24,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGElementInstance : EventTarget
+[
+    DependentLifetime,
+] interface SVGElementInstance : EventTarget
 {
     readonly attribute SVGElement correspondingElement;
     readonly attribute SVGUseElement correspondingUseElement;
diff --git a/Source/core/svg/SVGElementInstanceList.idl b/Source/core/svg/SVGElementInstanceList.idl
index 91534bb..d2bf4b3 100644
--- a/Source/core/svg/SVGElementInstanceList.idl
+++ b/Source/core/svg/SVGElementInstanceList.idl
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGElementInstanceList {
+[
+    DependentLifetime,
+] interface SVGElementInstanceList {
     readonly attribute unsigned long length;
 
     SVGElementInstance item([Default=Undefined] optional unsigned long index);
diff --git a/Source/core/svg/SVGEllipseElement.cpp b/Source/core/svg/SVGEllipseElement.cpp
index 5da4774..5de44f8 100644
--- a/Source/core/svg/SVGEllipseElement.cpp
+++ b/Source/core/svg/SVGEllipseElement.cpp
@@ -29,11 +29,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGEllipseElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGEllipseElement::SVGEllipseElement(Document& document)
     : SVGGeometryElement(SVGNames::ellipseTag, document)
     , m_cx(SVGAnimatedLength::create(this, SVGNames::cxAttr, SVGLength::create(LengthModeWidth)))
@@ -47,7 +42,6 @@
     addToPropertyMap(m_cy);
     addToPropertyMap(m_rx);
     addToPropertyMap(m_ry);
-    registerAnimatedPropertiesForSVGEllipseElement();
 }
 
 PassRefPtr<SVGEllipseElement> SVGEllipseElement::create(Document& document)
diff --git a/Source/core/svg/SVGEllipseElement.h b/Source/core/svg/SVGEllipseElement.h
index 372c57d..379ce35 100644
--- a/Source/core/svg/SVGEllipseElement.h
+++ b/Source/core/svg/SVGEllipseElement.h
@@ -54,12 +54,8 @@
     RefPtr<SVGAnimatedLength> m_cy;
     RefPtr<SVGAnimatedLength> m_rx;
     RefPtr<SVGAnimatedLength> m_ry;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGEllipseElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGEllipseElement, hasTagName(SVGNames::ellipseTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGEnumeration.cpp b/Source/core/svg/SVGEnumeration.cpp
new file mode 100644
index 0000000..de404c6
--- /dev/null
+++ b/Source/core/svg/SVGEnumeration.cpp
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#include "core/svg/SVGEnumeration.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGAnimationElement.h"
+
+namespace WebCore {
+
+inline PassRefPtr<SVGEnumerationBase> toSVGEnumerationBase(PassRefPtr<NewSVGPropertyBase> passBase)
+{
+    RefPtr<NewSVGPropertyBase> base = passBase;
+    ASSERT(base->type() == SVGEnumerationBase::classType());
+    return static_pointer_cast<SVGEnumerationBase>(base.release());
+}
+
+SVGEnumerationBase::~SVGEnumerationBase()
+{
+}
+
+PassRefPtr<NewSVGPropertyBase> SVGEnumerationBase::cloneForAnimation(const String& value) const
+{
+    RefPtr<SVGEnumerationBase> svgEnumeration = clone();
+    svgEnumeration->setValueAsString(value, IGNORE_EXCEPTION);
+    return svgEnumeration.release();
+}
+
+String SVGEnumerationBase::valueAsString() const
+{
+    StringEntries::const_iterator it = m_entries.begin();
+    StringEntries::const_iterator itEnd = m_entries.end();
+    for (; it != itEnd; ++it) {
+        if (m_value == it->first)
+            return it->second;
+    }
+
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+void SVGEnumerationBase::setValue(unsigned short value, ExceptionState& exceptionState)
+{
+    if (!value) {
+        exceptionState.throwTypeError("The enumeration value provided is 0, which is not settable.");
+        return;
+    }
+
+    if (value > maxEnumValue()) {
+        exceptionState.throwTypeError("The enumeration value provided (" + String::number(value) + ") is larger than the largest allowed value (" + String::number(maxEnumValue()) + ").");
+        return;
+    }
+
+    m_value = value;
+    notifyChange();
+}
+
+void SVGEnumerationBase::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+    StringEntries::const_iterator it = m_entries.begin();
+    StringEntries::const_iterator itEnd = m_entries.end();
+    for (; it != itEnd; ++it) {
+        if (string == it->second) {
+            m_value = it->first;
+            notifyChange();
+            return;
+        }
+    }
+
+    exceptionState.throwDOMException(SyntaxError, "The value provided ('" + string + "') is invalid.");
+    notifyChange();
+}
+
+void SVGEnumerationBase::add(PassRefPtr<NewSVGPropertyBase>, SVGElement*)
+{
+    ASSERT_NOT_REACHED();
+}
+
+void SVGEnumerationBase::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> from, PassRefPtr<NewSVGPropertyBase> to, PassRefPtr<NewSVGPropertyBase>, SVGElement*)
+{
+    ASSERT(animationElement);
+    unsigned short fromEnumeration = animationElement->animationMode() == ToAnimation ? m_value : toSVGEnumerationBase(from)->value();
+    unsigned short toEnumeration = toSVGEnumerationBase(to)->value();
+
+    animationElement->animateDiscreteType<unsigned short>(percentage, fromEnumeration, toEnumeration, m_value);
+}
+
+float SVGEnumerationBase::calculateDistance(PassRefPtr<NewSVGPropertyBase>, SVGElement*)
+{
+    // No paced animations for boolean.
+    return -1;
+}
+
+}
diff --git a/Source/core/svg/SVGEnumeration.h b/Source/core/svg/SVGEnumeration.h
new file mode 100644
index 0000000..eef4a8c
--- /dev/null
+++ b/Source/core/svg/SVGEnumeration.h
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGEnumeration_h
+#define SVGEnumeration_h
+
+#include "core/svg/properties/NewSVGProperty.h"
+
+namespace WebCore {
+
+class SVGEnumerationBase : public NewSVGPropertyBase {
+public:
+    typedef std::pair<unsigned short, String> StringEntry;
+    typedef Vector<StringEntry> StringEntries;
+
+    // SVGEnumeration does not have a tear-off type.
+    typedef void TearOffType;
+    typedef unsigned short PrimitiveType;
+
+    virtual ~SVGEnumerationBase();
+
+    unsigned short value() const { return m_value; }
+    void setValue(unsigned short, ExceptionState&);
+
+    // This assumes that |m_entries| are sorted.
+    unsigned short maxEnumValue() const { return m_entries.last().first; }
+
+    // NewSVGPropertyBase:
+    virtual PassRefPtr<SVGEnumerationBase> clone() const = 0;
+    virtual PassRefPtr<NewSVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+    virtual String valueAsString() const OVERRIDE;
+    void setValueAsString(const String&, ExceptionState&);
+
+    virtual void add(PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+    virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> from, PassRefPtr<NewSVGPropertyBase> to, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+    virtual float calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+    static AnimatedPropertyType classType() { return AnimatedEnumeration; }
+
+    // Ensure that |SVGAnimatedEnumerationBase::setBaseVal| is used instead of |NewSVGAnimatedProperty<SVGEnumerationBase>::setBaseVal|.
+    void setValue(unsigned short) { ASSERT_NOT_REACHED(); }
+
+protected:
+    SVGEnumerationBase(unsigned short value, const StringEntries& entries)
+        : NewSVGPropertyBase(classType())
+        , m_value(value)
+        , m_entries(entries)
+    {
+    }
+
+    // Used by SVGMarkerOrientEnumeration.
+    virtual void notifyChange() { }
+
+    unsigned short m_value;
+    const StringEntries& m_entries;
+};
+typedef SVGEnumerationBase::StringEntries SVGEnumerationStringEntries;
+
+template<typename Enum> const SVGEnumerationStringEntries& getStaticStringEntries();
+
+template<typename Enum>
+class SVGEnumeration : public SVGEnumerationBase {
+public:
+    static PassRefPtr<SVGEnumeration<Enum> > create(Enum newValue)
+    {
+        return adoptRef(new SVGEnumeration<Enum>(newValue));
+    }
+
+    virtual ~SVGEnumeration()
+    {
+    }
+
+    virtual PassRefPtr<SVGEnumerationBase> clone() const OVERRIDE
+    {
+        return create(enumValue());
+    }
+
+    Enum enumValue() const
+    {
+        ASSERT(m_value <= maxEnumValue());
+        return static_cast<Enum>(m_value);
+    }
+
+    void setEnumValue(Enum value)
+    {
+        m_value = value;
+        notifyChange();
+    }
+
+protected:
+    explicit SVGEnumeration(Enum newValue)
+        : SVGEnumerationBase(newValue, getStaticStringEntries<Enum>())
+    {
+    }
+};
+
+} // namespace WebCore
+
+#endif // SVGEnumeration_h
diff --git a/Source/core/svg/SVGFEBlendElement.cpp b/Source/core/svg/SVGFEBlendElement.cpp
index 53556fd..e939b88 100644
--- a/Source/core/svg/SVGFEBlendElement.cpp
+++ b/Source/core/svg/SVGFEBlendElement.cpp
@@ -29,24 +29,30 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFEBlendElement, SVGNames::modeAttr, Mode, mode, BlendModeType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEBlendElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(mode)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<BlendModeType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(FEBLEND_MODE_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(FEBLEND_MODE_NORMAL, "normal"));
+        entries.append(std::make_pair(FEBLEND_MODE_MULTIPLY, "multiply"));
+        entries.append(std::make_pair(FEBLEND_MODE_SCREEN, "screen"));
+        entries.append(std::make_pair(FEBLEND_MODE_DARKEN, "darken"));
+        entries.append(std::make_pair(FEBLEND_MODE_LIGHTEN, "lighten"));
+    }
+    return entries;
+}
 
 inline SVGFEBlendElement::SVGFEBlendElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feBlendTag, document)
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
     , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
-    , m_mode(FEBLEND_MODE_NORMAL)
+    , m_mode(SVGAnimatedEnumeration<BlendModeType>::create(this, SVGNames::modeAttr, FEBLEND_MODE_NORMAL))
 {
     ScriptWrappable::init(this);
     addToPropertyMap(m_in1);
     addToPropertyMap(m_in2);
-    registerAnimatedPropertiesForSVGFEBlendElement();
+    addToPropertyMap(m_mode);
 }
 
 PassRefPtr<SVGFEBlendElement> SVGFEBlendElement::create(Document& document)
@@ -72,19 +78,14 @@
         return;
     }
 
-    if (name == SVGNames::modeAttr) {
-        BlendModeType propertyValue = SVGPropertyTraits<BlendModeType>::fromString(value);
-        if (propertyValue > 0)
-            setModeBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::inAttr)
         m_in1->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::in2Attr)
         m_in2->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::modeAttr)
+        m_mode->setBaseValueAsString(value, parseError);
     else
         ASSERT_NOT_REACHED();
 
@@ -95,7 +96,7 @@
 {
     FEBlend* blend = static_cast<FEBlend*>(effect);
     if (attrName == SVGNames::modeAttr)
-        return blend->setBlendMode(modeCurrentValue());
+        return blend->setBlendMode(m_mode->currentValue()->enumValue());
 
     ASSERT_NOT_REACHED();
     return false;
@@ -129,9 +130,9 @@
     FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
 
     if (!input1 || !input2)
-        return 0;
+        return nullptr;
 
-    RefPtr<FilterEffect> effect = FEBlend::create(filter, modeCurrentValue());
+    RefPtr<FilterEffect> effect = FEBlend::create(filter, m_mode->currentValue()->enumValue());
     FilterEffectVector& inputEffects = effect->inputEffects();
     inputEffects.reserveCapacity(2);
     inputEffects.append(input1);
diff --git a/Source/core/svg/SVGFEBlendElement.h b/Source/core/svg/SVGFEBlendElement.h
index ae91fba..cf44ed4 100644
--- a/Source/core/svg/SVGFEBlendElement.h
+++ b/Source/core/svg/SVGFEBlendElement.h
@@ -27,52 +27,14 @@
 
 namespace WebCore {
 
-template<>
-struct SVGPropertyTraits<BlendModeType> {
-    static unsigned highestEnumValue() { return FEBLEND_MODE_LIGHTEN; }
-
-    static String toString(BlendModeType type)
-    {
-        switch (type) {
-        case FEBLEND_MODE_UNKNOWN:
-            return emptyString();
-        case FEBLEND_MODE_NORMAL:
-            return "normal";
-        case FEBLEND_MODE_MULTIPLY:
-            return "multiply";
-        case FEBLEND_MODE_SCREEN:
-            return "screen";
-        case FEBLEND_MODE_DARKEN:
-            return "darken";
-        case FEBLEND_MODE_LIGHTEN:
-            return "lighten";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static BlendModeType fromString(const String& value)
-    {
-        if (value == "normal")
-            return FEBLEND_MODE_NORMAL;
-        if (value == "multiply")
-            return FEBLEND_MODE_MULTIPLY;
-        if (value == "screen")
-            return FEBLEND_MODE_SCREEN;
-        if (value == "darken")
-            return FEBLEND_MODE_DARKEN;
-        if (value == "lighten")
-            return FEBLEND_MODE_LIGHTEN;
-        return FEBLEND_MODE_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<BlendModeType>();
 
 class SVGFEBlendElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
     static PassRefPtr<SVGFEBlendElement> create(Document&);
     SVGAnimatedString* in1() { return m_in1.get(); }
     SVGAnimatedString* in2() { return m_in2.get(); }
+    SVGAnimatedEnumeration<BlendModeType>* mode() { return m_mode.get(); }
 
 private:
     explicit SVGFEBlendElement(Document&);
@@ -85,9 +47,7 @@
 
     RefPtr<SVGAnimatedString> m_in1;
     RefPtr<SVGAnimatedString> m_in2;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEBlendElement)
-        DECLARE_ANIMATED_ENUMERATION(Mode, mode, BlendModeType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<BlendModeType> > m_mode;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEColorMatrixElement.cpp b/Source/core/svg/SVGFEColorMatrixElement.cpp
index 56b9044..6c396e8 100644
--- a/Source/core/svg/SVGFEColorMatrixElement.cpp
+++ b/Source/core/svg/SVGFEColorMatrixElement.cpp
@@ -29,25 +29,30 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFEColorMatrixElement, SVGNames::typeAttr, Type, type, ColorMatrixType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEColorMatrixElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(type)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ColorMatrixType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(FECOLORMATRIX_TYPE_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(FECOLORMATRIX_TYPE_MATRIX, "matrix"));
+        entries.append(std::make_pair(FECOLORMATRIX_TYPE_SATURATE, "saturate"));
+        entries.append(std::make_pair(FECOLORMATRIX_TYPE_HUEROTATE, "hueRotate"));
+        entries.append(std::make_pair(FECOLORMATRIX_TYPE_LUMINANCETOALPHA, "luminanceToAlpha"));
+    }
+    return entries;
+}
 
 inline SVGFEColorMatrixElement::SVGFEColorMatrixElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feColorMatrixTag, document)
     , m_values(SVGAnimatedNumberList::create(this, SVGNames::valuesAttr, SVGNumberList::create()))
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
-    , m_type(FECOLORMATRIX_TYPE_MATRIX)
+    , m_type(SVGAnimatedEnumeration<ColorMatrixType>::create(this, SVGNames::typeAttr, FECOLORMATRIX_TYPE_MATRIX))
 {
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_values);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEColorMatrixElement();
+    addToPropertyMap(m_type);
 }
 
 PassRefPtr<SVGFEColorMatrixElement> SVGFEColorMatrixElement::create(Document& document)
@@ -73,19 +78,14 @@
         return;
     }
 
-    if (name == SVGNames::typeAttr) {
-        ColorMatrixType propertyValue = SVGPropertyTraits<ColorMatrixType>::fromString(value);
-        if (propertyValue > 0)
-            setTypeBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::inAttr)
         m_in1->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::valuesAttr)
         m_values->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::typeAttr)
+        m_type->setBaseValueAsString(value, parseError);
     else
         ASSERT_NOT_REACHED();
 
@@ -96,7 +96,7 @@
 {
     FEColorMatrix* colorMatrix = static_cast<FEColorMatrix*>(effect);
     if (attrName == SVGNames::typeAttr)
-        return colorMatrix->setType(typeCurrentValue());
+        return colorMatrix->setType(m_type->currentValue()->enumValue());
     if (attrName == SVGNames::valuesAttr)
         return colorMatrix->setValues(m_values->currentValue()->toFloatVector());
 
@@ -131,10 +131,10 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
     Vector<float> filterValues;
-    ColorMatrixType filterType = typeCurrentValue();
+    ColorMatrixType filterType = m_type->currentValue()->enumValue();
 
     // Use defaults if values is empty (SVG 1.1 15.10).
     if (!hasAttribute(SVGNames::valuesAttr)) {
@@ -154,12 +154,12 @@
         }
     } else {
         RefPtr<SVGNumberList> values = m_values->currentValue();
-        size_t size = values->numberOfItems();
+        size_t size = values->length();
 
         if ((filterType == FECOLORMATRIX_TYPE_MATRIX && size != 20)
             || (filterType == FECOLORMATRIX_TYPE_HUEROTATE && size != 1)
             || (filterType == FECOLORMATRIX_TYPE_SATURATE && size != 1))
-            return 0;
+            return nullptr;
 
         filterValues = values->toFloatVector();
     }
diff --git a/Source/core/svg/SVGFEColorMatrixElement.h b/Source/core/svg/SVGFEColorMatrixElement.h
index 9796c07..5f7b29a 100644
--- a/Source/core/svg/SVGFEColorMatrixElement.h
+++ b/Source/core/svg/SVGFEColorMatrixElement.h
@@ -28,42 +28,7 @@
 
 namespace WebCore {
 
-template<>
-struct SVGPropertyTraits<ColorMatrixType> {
-    static unsigned highestEnumValue() { return FECOLORMATRIX_TYPE_LUMINANCETOALPHA; }
-
-    static String toString(ColorMatrixType type)
-    {
-        switch (type) {
-        case FECOLORMATRIX_TYPE_UNKNOWN:
-            return emptyString();
-        case FECOLORMATRIX_TYPE_MATRIX:
-            return "matrix";
-        case FECOLORMATRIX_TYPE_SATURATE:
-            return "saturate";
-        case FECOLORMATRIX_TYPE_HUEROTATE:
-            return "hueRotate";
-        case FECOLORMATRIX_TYPE_LUMINANCETOALPHA:
-            return "luminanceToAlpha";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static ColorMatrixType fromString(const String& value)
-    {
-        if (value == "matrix")
-            return FECOLORMATRIX_TYPE_MATRIX;
-        if (value == "saturate")
-            return FECOLORMATRIX_TYPE_SATURATE;
-        if (value == "hueRotate")
-            return FECOLORMATRIX_TYPE_HUEROTATE;
-        if (value == "luminanceToAlpha")
-            return FECOLORMATRIX_TYPE_LUMINANCETOALPHA;
-        return FECOLORMATRIX_TYPE_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ColorMatrixType>();
 
 class SVGFEColorMatrixElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
@@ -71,6 +36,7 @@
 
     SVGAnimatedNumberList* values() { return m_values.get(); }
     SVGAnimatedString* in1() { return m_in1.get(); }
+    SVGAnimatedEnumeration<ColorMatrixType>* type() { return m_type.get(); }
 
 private:
     explicit SVGFEColorMatrixElement(Document&);
@@ -83,9 +49,7 @@
 
     RefPtr<SVGAnimatedNumberList> m_values;
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEColorMatrixElement)
-        DECLARE_ANIMATED_ENUMERATION(Type, type, ColorMatrixType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<ColorMatrixType> > m_type;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEComponentTransferElement.cpp b/Source/core/svg/SVGFEComponentTransferElement.cpp
index 89cc6ea..75eeac1 100644
--- a/Source/core/svg/SVGFEComponentTransferElement.cpp
+++ b/Source/core/svg/SVGFEComponentTransferElement.cpp
@@ -23,28 +23,22 @@
 #include "core/svg/SVGFEComponentTransferElement.h"
 
 #include "SVGNames.h"
-#include "platform/graphics/filters/FilterEffect.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/svg/SVGFEFuncAElement.h"
 #include "core/svg/SVGFEFuncBElement.h"
 #include "core/svg/SVGFEFuncGElement.h"
 #include "core/svg/SVGFEFuncRElement.h"
 #include "core/svg/graphics/filters/SVGFilterBuilder.h"
+#include "platform/graphics/filters/FilterEffect.h"
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEComponentTransferElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFEComponentTransferElement::SVGFEComponentTransferElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feComponentTransferTag, document)
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
 {
     ScriptWrappable::init(this);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEComponentTransferElement();
 }
 
 PassRefPtr<SVGFEComponentTransferElement> SVGFEComponentTransferElement::create(Document& document)
@@ -82,22 +76,22 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
     ComponentTransferFunction red;
     ComponentTransferFunction green;
     ComponentTransferFunction blue;
     ComponentTransferFunction alpha;
 
-    for (Node* node = firstChild(); node; node = node->nextSibling()) {
-        if (node->hasTagName(SVGNames::feFuncRTag))
-            red = toSVGFEFuncRElement(node)->transferFunction();
-        else if (node->hasTagName(SVGNames::feFuncGTag))
-            green = toSVGFEFuncGElement(node)->transferFunction();
-        else if (node->hasTagName(SVGNames::feFuncBTag))
-            blue = toSVGFEFuncBElement(node)->transferFunction();
-        else if (node->hasTagName(SVGNames::feFuncATag))
-            alpha = toSVGFEFuncAElement(node)->transferFunction();
+    for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
+        if (isSVGFEFuncRElement(*element))
+            red = toSVGFEFuncRElement(*element).transferFunction();
+        else if (isSVGFEFuncGElement(*element))
+            green = toSVGFEFuncGElement(*element).transferFunction();
+        else if (isSVGFEFuncBElement(*element))
+            blue = toSVGFEFuncBElement(*element).transferFunction();
+        else if (isSVGFEFuncAElement(*element))
+            alpha = toSVGFEFuncAElement(*element).transferFunction();
     }
 
     RefPtr<FilterEffect> effect = FEComponentTransfer::create(filter, red, green, blue, alpha);
diff --git a/Source/core/svg/SVGFEComponentTransferElement.h b/Source/core/svg/SVGFEComponentTransferElement.h
index 460ddf5..e97abf3 100644
--- a/Source/core/svg/SVGFEComponentTransferElement.h
+++ b/Source/core/svg/SVGFEComponentTransferElement.h
@@ -40,8 +40,6 @@
     virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
 
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEComponentTransferElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFECompositeElement.cpp b/Source/core/svg/SVGFECompositeElement.cpp
index 62faa23..0ac532c 100644
--- a/Source/core/svg/SVGFECompositeElement.cpp
+++ b/Source/core/svg/SVGFECompositeElement.cpp
@@ -29,13 +29,20 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFECompositeElement, SVGNames::operatorAttr, SVGOperator, svgOperator, CompositeOperationType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFECompositeElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(svgOperator)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<CompositeOperationType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(FECOMPOSITE_OPERATOR_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(FECOMPOSITE_OPERATOR_OVER, "over"));
+        entries.append(std::make_pair(FECOMPOSITE_OPERATOR_IN, "in"));
+        entries.append(std::make_pair(FECOMPOSITE_OPERATOR_OUT, "out"));
+        entries.append(std::make_pair(FECOMPOSITE_OPERATOR_ATOP, "atop"));
+        entries.append(std::make_pair(FECOMPOSITE_OPERATOR_XOR, "xor"));
+        entries.append(std::make_pair(FECOMPOSITE_OPERATOR_ARITHMETIC, "arithmetic"));
+    }
+    return entries;
+}
 
 inline SVGFECompositeElement::SVGFECompositeElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feCompositeTag, document)
@@ -45,7 +52,7 @@
     , m_k4(SVGAnimatedNumber::create(this, SVGNames::k4Attr, SVGNumber::create()))
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
     , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
-    , m_svgOperator(FECOMPOSITE_OPERATOR_OVER)
+    , m_svgOperator(SVGAnimatedEnumeration<CompositeOperationType>::create(this, SVGNames::operatorAttr, FECOMPOSITE_OPERATOR_OVER))
 {
     ScriptWrappable::init(this);
 
@@ -55,7 +62,7 @@
     addToPropertyMap(m_k4);
     addToPropertyMap(m_in1);
     addToPropertyMap(m_in2);
-    registerAnimatedPropertiesForSVGFECompositeElement();
+    addToPropertyMap(m_svgOperator);
 }
 
 PassRefPtr<SVGFECompositeElement> SVGFECompositeElement::create(Document& document)
@@ -85,13 +92,6 @@
         return;
     }
 
-    if (name == SVGNames::operatorAttr) {
-        CompositeOperationType propertyValue = SVGPropertyTraits<CompositeOperationType>::fromString(value);
-        if (propertyValue > 0)
-            setSVGOperatorBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::inAttr)
@@ -106,6 +106,8 @@
         m_k3->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::k4Attr)
         m_k4->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::operatorAttr)
+        m_svgOperator->setBaseValueAsString(value, parseError);
     else
         ASSERT_NOT_REACHED();
 
@@ -116,7 +118,7 @@
 {
     FEComposite* composite = static_cast<FEComposite*>(effect);
     if (attrName == SVGNames::operatorAttr)
-        return composite->setOperation(svgOperatorCurrentValue());
+        return composite->setOperation(m_svgOperator->currentValue()->enumValue());
     if (attrName == SVGNames::k1Attr)
         return composite->setK1(m_k1->currentValue()->value());
     if (attrName == SVGNames::k2Attr)
@@ -163,9 +165,9 @@
     FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
 
     if (!input1 || !input2)
-        return 0;
+        return nullptr;
 
-    RefPtr<FilterEffect> effect = FEComposite::create(filter, svgOperatorCurrentValue(), m_k1->currentValue()->value(), m_k2->currentValue()->value(), m_k3->currentValue()->value(), m_k4->currentValue()->value());
+    RefPtr<FilterEffect> effect = FEComposite::create(filter, m_svgOperator->currentValue()->enumValue(), m_k1->currentValue()->value(), m_k2->currentValue()->value(), m_k3->currentValue()->value(), m_k4->currentValue()->value());
     FilterEffectVector& inputEffects = effect->inputEffects();
     inputEffects.reserveCapacity(2);
     inputEffects.append(input1);
diff --git a/Source/core/svg/SVGFECompositeElement.h b/Source/core/svg/SVGFECompositeElement.h
index dae7b64..09842d9 100644
--- a/Source/core/svg/SVGFECompositeElement.h
+++ b/Source/core/svg/SVGFECompositeElement.h
@@ -28,50 +28,7 @@
 
 namespace WebCore {
 
-template<>
-struct SVGPropertyTraits<CompositeOperationType> {
-    static unsigned highestEnumValue() { return FECOMPOSITE_OPERATOR_ARITHMETIC; }
-
-    static String toString(CompositeOperationType type)
-    {
-        switch (type) {
-        case FECOMPOSITE_OPERATOR_UNKNOWN:
-            return emptyString();
-        case FECOMPOSITE_OPERATOR_OVER:
-            return "over";
-        case FECOMPOSITE_OPERATOR_IN:
-            return "in";
-        case FECOMPOSITE_OPERATOR_OUT:
-            return "out";
-        case FECOMPOSITE_OPERATOR_ATOP:
-            return "atop";
-        case FECOMPOSITE_OPERATOR_XOR:
-            return "xor";
-        case FECOMPOSITE_OPERATOR_ARITHMETIC:
-            return "arithmetic";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static CompositeOperationType fromString(const String& value)
-    {
-        if (value == "over")
-            return FECOMPOSITE_OPERATOR_OVER;
-        if (value == "in")
-            return FECOMPOSITE_OPERATOR_IN;
-        if (value == "out")
-            return FECOMPOSITE_OPERATOR_OUT;
-        if (value == "atop")
-            return FECOMPOSITE_OPERATOR_ATOP;
-        if (value == "xor")
-            return FECOMPOSITE_OPERATOR_XOR;
-        if (value == "arithmetic")
-            return FECOMPOSITE_OPERATOR_ARITHMETIC;
-        return FECOMPOSITE_OPERATOR_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<CompositeOperationType>();
 
 class SVGFECompositeElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
@@ -83,6 +40,7 @@
     SVGAnimatedNumber* k4() { return m_k4.get(); }
     SVGAnimatedString* in1() { return m_in1.get(); }
     SVGAnimatedString* in2() { return m_in2.get(); }
+    SVGAnimatedEnumeration<CompositeOperationType>* svgOperator() { return m_svgOperator.get(); }
 
 private:
     explicit SVGFECompositeElement(Document&);
@@ -99,9 +57,7 @@
     RefPtr<SVGAnimatedNumber> m_k4;
     RefPtr<SVGAnimatedString> m_in1;
     RefPtr<SVGAnimatedString> m_in2;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFECompositeElement)
-        DECLARE_ANIMATED_ENUMERATION(SVGOperator, svgOperator, CompositeOperationType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<CompositeOperationType> > m_svgOperator;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEConvolveMatrixElement.cpp b/Source/core/svg/SVGFEConvolveMatrixElement.cpp
index 6565c2f..ff626f2 100644
--- a/Source/core/svg/SVGFEConvolveMatrixElement.cpp
+++ b/Source/core/svg/SVGFEConvolveMatrixElement.cpp
@@ -32,26 +32,30 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFEConvolveMatrixElement, SVGNames::edgeModeAttr, EdgeMode, edgeMode, EdgeModeType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEConvolveMatrixElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(edgeMode)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<EdgeModeType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(EDGEMODE_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(EDGEMODE_DUPLICATE, "duplicate"));
+        entries.append(std::make_pair(EDGEMODE_WRAP, "wrap"));
+        entries.append(std::make_pair(EDGEMODE_NONE, "none"));
+    }
+    return entries;
+}
 
 inline SVGFEConvolveMatrixElement::SVGFEConvolveMatrixElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feConvolveMatrixTag, document)
     , m_bias(SVGAnimatedNumber::create(this, SVGNames::biasAttr, SVGNumber::create()))
     , m_divisor(SVGAnimatedNumber::create(this, SVGNames::divisorAttr, SVGNumber::create()))
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
+    , m_edgeMode(SVGAnimatedEnumeration<EdgeModeType>::create(this, SVGNames::edgeModeAttr, EDGEMODE_DUPLICATE))
     , m_kernelMatrix(SVGAnimatedNumberList::create(this, SVGNames::kernelMatrixAttr, SVGNumberList::create()))
     , m_kernelUnitLength(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::kernelUnitLengthAttr))
     , m_order(SVGAnimatedIntegerOptionalInteger::create(this, SVGNames::orderAttr))
     , m_preserveAlpha(SVGAnimatedBoolean::create(this, SVGNames::preserveAlphaAttr, SVGBoolean::create()))
     , m_targetX(SVGAnimatedInteger::create(this, SVGNames::targetXAttr, SVGInteger::create()))
     , m_targetY(SVGAnimatedInteger::create(this, SVGNames::targetYAttr, SVGInteger::create()))
-    , m_edgeMode(EDGEMODE_DUPLICATE)
 {
     ScriptWrappable::init(this);
 
@@ -61,10 +65,10 @@
     addToPropertyMap(m_kernelUnitLength);
     addToPropertyMap(m_kernelMatrix);
     addToPropertyMap(m_in1);
+    addToPropertyMap(m_edgeMode);
     addToPropertyMap(m_order);
     addToPropertyMap(m_targetX);
     addToPropertyMap(m_targetY);
-    registerAnimatedPropertiesForSVGFEConvolveMatrixElement();
 }
 
 PassRefPtr<SVGFEConvolveMatrixElement> SVGFEConvolveMatrixElement::create(Document& document)
@@ -97,17 +101,6 @@
         return;
     }
 
-    if (name == SVGNames::edgeModeAttr) {
-        EdgeModeType propertyValue = SVGPropertyTraits<EdgeModeType>::fromString(value);
-        if (propertyValue > 0)
-            setEdgeModeBaseValue(propertyValue);
-        else
-            document().accessSVGExtensions()->reportWarning(
-                "feConvolveMatrix: problem parsing edgeMode=\"" + value
-                + "\". Filtered element will not be displayed.");
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::inAttr)
@@ -122,6 +115,8 @@
         m_kernelMatrix->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::preserveAlphaAttr)
         m_preserveAlpha->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::edgeModeAttr)
+        m_edgeMode->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::targetXAttr)
         m_targetX->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::targetYAttr)
@@ -129,7 +124,7 @@
     else if (name == SVGNames::orderAttr) {
         m_order->setBaseValueAsString(value, parseError);
         if (parseError == NoError && (orderX()->baseValue()->value() < 1 || orderY()->baseValue()->value() < 1)) {
-            document().accessSVGExtensions()->reportWarning(
+            document().accessSVGExtensions().reportWarning(
                 "feConvolveMatrix: problem parsing order=\"" + value
                 + "\". Filtered element will not be displayed.");
         }
@@ -143,7 +138,7 @@
 {
     FEConvolveMatrix* convolveMatrix = static_cast<FEConvolveMatrix*>(effect);
     if (attrName == SVGNames::edgeModeAttr)
-        return convolveMatrix->setEdgeMode(edgeModeCurrentValue());
+        return convolveMatrix->setEdgeMode(m_edgeMode->currentValue()->enumValue());
     if (attrName == SVGNames::divisorAttr)
         return convolveMatrix->setDivisor(m_divisor->currentValue()->value());
     if (attrName == SVGNames::biasAttr)
@@ -196,7 +191,7 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
     int orderXValue = orderX()->currentValue()->value();
     int orderYValue = orderY()->currentValue()->value();
@@ -206,22 +201,22 @@
     }
     // Spec says order must be > 0. Bail if it is not.
     if (orderXValue < 1 || orderYValue < 1)
-        return 0;
+        return nullptr;
     RefPtr<SVGNumberList> kernelMatrix = this->m_kernelMatrix->currentValue();
-    size_t kernelMatrixSize = kernelMatrix->numberOfItems();
+    size_t kernelMatrixSize = kernelMatrix->length();
     // The spec says this is a requirement, and should bail out if fails
     if (orderXValue * orderYValue != static_cast<int>(kernelMatrixSize))
-        return 0;
+        return nullptr;
 
     int targetXValue = m_targetX->currentValue()->value();
     int targetYValue = m_targetY->currentValue()->value();
     if (hasAttribute(SVGNames::targetXAttr) && (targetXValue < 0 || targetXValue >= orderXValue))
-        return 0;
+        return nullptr;
     // The spec says the default value is: targetX = floor ( orderX / 2 ))
     if (!hasAttribute(SVGNames::targetXAttr))
         targetXValue = static_cast<int>(floorf(orderXValue / 2));
     if (hasAttribute(SVGNames::targetYAttr) && (targetYValue < 0 || targetYValue >= orderYValue))
-        return 0;
+        return nullptr;
     // The spec says the default value is: targetY = floor ( orderY / 2 ))
     if (!hasAttribute(SVGNames::targetYAttr))
         targetYValue = static_cast<int>(floorf(orderYValue / 2));
@@ -235,11 +230,11 @@
         kernelUnitLengthYValue = 1;
     }
     if (kernelUnitLengthXValue <= 0 || kernelUnitLengthYValue <= 0)
-        return 0;
+        return nullptr;
 
     float divisorValue = m_divisor->currentValue()->value();
     if (hasAttribute(SVGNames::divisorAttr) && !divisorValue)
-        return 0;
+        return nullptr;
     if (!hasAttribute(SVGNames::divisorAttr)) {
         for (size_t i = 0; i < kernelMatrixSize; ++i)
             divisorValue += kernelMatrix->at(i)->value();
@@ -249,7 +244,7 @@
 
     RefPtr<FilterEffect> effect = FEConvolveMatrix::create(filter,
                     IntSize(orderXValue, orderYValue), divisorValue,
-                    m_bias->currentValue()->value(), IntPoint(targetXValue, targetYValue), edgeModeCurrentValue(),
+                    m_bias->currentValue()->value(), IntPoint(targetXValue, targetYValue), m_edgeMode->currentValue()->enumValue(),
                     FloatPoint(kernelUnitLengthXValue, kernelUnitLengthYValue), m_preserveAlpha->currentValue()->value(), m_kernelMatrix->currentValue()->toFloatVector());
     effect->inputEffects().append(input1);
     return effect.release();
diff --git a/Source/core/svg/SVGFEConvolveMatrixElement.h b/Source/core/svg/SVGFEConvolveMatrixElement.h
index fab9faf..7a4a39f 100644
--- a/Source/core/svg/SVGFEConvolveMatrixElement.h
+++ b/Source/core/svg/SVGFEConvolveMatrixElement.h
@@ -32,38 +32,7 @@
 
 namespace WebCore {
 
-template<>
-struct SVGPropertyTraits<EdgeModeType> {
-    static unsigned highestEnumValue() { return EDGEMODE_NONE; }
-
-    static String toString(EdgeModeType type)
-    {
-        switch (type) {
-        case EDGEMODE_UNKNOWN:
-            return emptyString();
-        case EDGEMODE_DUPLICATE:
-            return "duplicate";
-        case EDGEMODE_WRAP:
-            return "wrap";
-        case EDGEMODE_NONE:
-            return "none";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static EdgeModeType fromString(const String& value)
-    {
-        if (value == "duplicate")
-            return EDGEMODE_DUPLICATE;
-        if (value == "wrap")
-            return EDGEMODE_WRAP;
-        if (value == "none")
-            return EDGEMODE_NONE;
-        return EDGEMODE_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<EdgeModeType>();
 
 class SVGFEConvolveMatrixElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
@@ -76,6 +45,7 @@
     SVGAnimatedNumber* kernelUnitLengthY() { return m_kernelUnitLength->secondNumber(); }
     SVGAnimatedNumberList* kernelMatrix() { return m_kernelMatrix.get(); }
     SVGAnimatedString* in1() { return m_in1.get(); }
+    SVGAnimatedEnumeration<EdgeModeType>* edgeMode() { return m_edgeMode.get(); }
     SVGAnimatedInteger* orderX() { return m_order->firstInteger(); }
     SVGAnimatedInteger* orderY() { return m_order->secondInteger(); }
     SVGAnimatedInteger* targetX() { return m_targetX.get(); }
@@ -93,15 +63,13 @@
     RefPtr<SVGAnimatedNumber> m_bias;
     RefPtr<SVGAnimatedNumber> m_divisor;
     RefPtr<SVGAnimatedString> m_in1;
+    RefPtr<SVGAnimatedEnumeration<EdgeModeType> > m_edgeMode;
     RefPtr<SVGAnimatedNumberList> m_kernelMatrix;
     RefPtr<SVGAnimatedNumberOptionalNumber> m_kernelUnitLength;
     RefPtr<SVGAnimatedIntegerOptionalInteger> m_order;
     RefPtr<SVGAnimatedBoolean> m_preserveAlpha;
     RefPtr<SVGAnimatedInteger> m_targetX;
     RefPtr<SVGAnimatedInteger> m_targetY;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEConvolveMatrixElement)
-        DECLARE_ANIMATED_ENUMERATION(EdgeMode, edgeMode, EdgeModeType)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEDiffuseLightingElement.cpp b/Source/core/svg/SVGFEDiffuseLightingElement.cpp
index 328ad94..c31990a 100644
--- a/Source/core/svg/SVGFEDiffuseLightingElement.cpp
+++ b/Source/core/svg/SVGFEDiffuseLightingElement.cpp
@@ -30,12 +30,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEDiffuseLightingElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFEDiffuseLightingElement::SVGFEDiffuseLightingElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feDiffuseLightingTag, document)
     , m_diffuseConstant(SVGAnimatedNumber::create(this, SVGNames::diffuseConstantAttr, SVGNumber::create(1)))
@@ -49,7 +43,6 @@
     addToPropertyMap(m_surfaceScale);
     addToPropertyMap(m_kernelUnitLength);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEDiffuseLightingElement();
 }
 
 PassRefPtr<SVGFEDiffuseLightingElement> SVGFEDiffuseLightingElement::create(Document& document)
@@ -109,7 +102,7 @@
         return diffuseLighting->setDiffuseConstant(m_diffuseConstant->currentValue()->value());
 
     LightSource* lightSource = const_cast<LightSource*>(diffuseLighting->lightSource());
-    const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
+    const SVGFELightElement* lightElement = SVGFELightElement::findLightElement(*this);
     ASSERT(lightSource);
     ASSERT(lightElement);
 
@@ -165,7 +158,7 @@
 
 void SVGFEDiffuseLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
 {
-    if (SVGFELightElement::findLightElement(this) != lightElement)
+    if (SVGFELightElement::findLightElement(*this) != lightElement)
         return;
 
     // The light element has different attribute names.
@@ -177,15 +170,15 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
-    RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this);
+    RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(*this);
     if (!lightSource)
-        return 0;
+        return nullptr;
 
     RenderObject* renderer = this->renderer();
     if (!renderer)
-        return 0;
+        return nullptr;
 
     ASSERT(renderer->style());
     Color color = renderer->style()->svgStyle()->lightingColor();
diff --git a/Source/core/svg/SVGFEDiffuseLightingElement.h b/Source/core/svg/SVGFEDiffuseLightingElement.h
index 8820206..3ca8cd2 100644
--- a/Source/core/svg/SVGFEDiffuseLightingElement.h
+++ b/Source/core/svg/SVGFEDiffuseLightingElement.h
@@ -30,7 +30,6 @@
 namespace WebCore {
 
 class FEDiffuseLighting;
-class SVGColor;
 
 class SVGFEDiffuseLightingElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
@@ -56,12 +55,8 @@
     RefPtr<SVGAnimatedNumber> m_surfaceScale;
     RefPtr<SVGAnimatedNumberOptionalNumber> m_kernelUnitLength;
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEDiffuseLightingElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFEDiffuseLightingElement, hasTagName(SVGNames::feDiffuseLightingTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFEDisplacementMapElement.cpp b/Source/core/svg/SVGFEDisplacementMapElement.cpp
index f01722d..4bffd5d 100644
--- a/Source/core/svg/SVGFEDisplacementMapElement.cpp
+++ b/Source/core/svg/SVGFEDisplacementMapElement.cpp
@@ -28,30 +28,34 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::xChannelSelectorAttr, XChannelSelector, xChannelSelector, ChannelSelectorType)
-DEFINE_ANIMATED_ENUMERATION(SVGFEDisplacementMapElement, SVGNames::yChannelSelectorAttr, YChannelSelector, yChannelSelector, ChannelSelectorType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEDisplacementMapElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(xChannelSelector)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(yChannelSelector)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ChannelSelectorType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(CHANNEL_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(CHANNEL_R, "R"));
+        entries.append(std::make_pair(CHANNEL_G, "G"));
+        entries.append(std::make_pair(CHANNEL_B, "B"));
+        entries.append(std::make_pair(CHANNEL_A, "A"));
+    }
+    return entries;
+}
 
 inline SVGFEDisplacementMapElement::SVGFEDisplacementMapElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feDisplacementMapTag, document)
     , m_scale(SVGAnimatedNumber::create(this, SVGNames::scaleAttr, SVGNumber::create(0)))
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
     , m_in2(SVGAnimatedString::create(this, SVGNames::in2Attr, SVGString::create()))
-    , m_xChannelSelector(CHANNEL_A)
-    , m_yChannelSelector(CHANNEL_A)
+    , m_xChannelSelector(SVGAnimatedEnumeration<ChannelSelectorType>::create(this, SVGNames::xChannelSelectorAttr, CHANNEL_A))
+    , m_yChannelSelector(SVGAnimatedEnumeration<ChannelSelectorType>::create(this, SVGNames::yChannelSelectorAttr, CHANNEL_A))
 {
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_scale);
     addToPropertyMap(m_in1);
     addToPropertyMap(m_in2);
-    registerAnimatedPropertiesForSVGFEDisplacementMapElement();
+    addToPropertyMap(m_xChannelSelector);
+    addToPropertyMap(m_yChannelSelector);
 }
 
 PassRefPtr<SVGFEDisplacementMapElement> SVGFEDisplacementMapElement::create(Document& document)
@@ -79,20 +83,6 @@
         return;
     }
 
-    if (name == SVGNames::xChannelSelectorAttr) {
-        ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
-        if (propertyValue > 0)
-            setXChannelSelectorBaseValue(propertyValue);
-        return;
-    }
-
-    if (name == SVGNames::yChannelSelectorAttr) {
-        ChannelSelectorType propertyValue = SVGPropertyTraits<ChannelSelectorType>::fromString(value);
-        if (propertyValue > 0)
-            setYChannelSelectorBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::inAttr)
@@ -101,6 +91,10 @@
         m_in2->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::scaleAttr)
         m_scale->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::xChannelSelectorAttr)
+        m_xChannelSelector->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::yChannelSelectorAttr)
+        m_yChannelSelector->setBaseValueAsString(value, parseError);
     else
         ASSERT_NOT_REACHED();
 
@@ -111,9 +105,9 @@
 {
     FEDisplacementMap* displacementMap = static_cast<FEDisplacementMap*>(effect);
     if (attrName == SVGNames::xChannelSelectorAttr)
-        return displacementMap->setXChannelSelector(xChannelSelectorCurrentValue());
+        return displacementMap->setXChannelSelector(m_xChannelSelector->currentValue()->enumValue());
     if (attrName == SVGNames::yChannelSelectorAttr)
-        return displacementMap->setYChannelSelector(yChannelSelectorCurrentValue());
+        return displacementMap->setYChannelSelector(m_yChannelSelector->currentValue()->enumValue());
     if (attrName == SVGNames::scaleAttr)
         return displacementMap->setScale(m_scale->currentValue()->value());
 
@@ -149,9 +143,9 @@
     FilterEffect* input2 = filterBuilder->getEffectById(AtomicString(m_in2->currentValue()->value()));
 
     if (!input1 || !input2)
-        return 0;
+        return nullptr;
 
-    RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, xChannelSelectorCurrentValue(), yChannelSelectorCurrentValue(), m_scale->currentValue()->value());
+    RefPtr<FilterEffect> effect = FEDisplacementMap::create(filter, m_xChannelSelector->currentValue()->enumValue(), m_yChannelSelector->currentValue()->enumValue(), m_scale->currentValue()->value());
     FilterEffectVector& inputEffects = effect->inputEffects();
     inputEffects.reserveCapacity(2);
     inputEffects.append(input1);
diff --git a/Source/core/svg/SVGFEDisplacementMapElement.h b/Source/core/svg/SVGFEDisplacementMapElement.h
index 79ff363..d1ba474 100644
--- a/Source/core/svg/SVGFEDisplacementMapElement.h
+++ b/Source/core/svg/SVGFEDisplacementMapElement.h
@@ -27,42 +27,7 @@
 
 namespace WebCore {
 
-template<>
-struct SVGPropertyTraits<ChannelSelectorType> {
-    static unsigned highestEnumValue() { return CHANNEL_A; }
-
-    static String toString(ChannelSelectorType type)
-    {
-        switch (type) {
-        case CHANNEL_UNKNOWN:
-            return emptyString();
-        case CHANNEL_R:
-            return "R";
-        case CHANNEL_G:
-            return "G";
-        case CHANNEL_B:
-            return "B";
-        case CHANNEL_A:
-            return "A";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static ChannelSelectorType fromString(const String& value)
-    {
-        if (value == "R")
-            return CHANNEL_R;
-        if (value == "G")
-            return CHANNEL_G;
-        if (value == "B")
-            return CHANNEL_B;
-        if (value == "A")
-            return CHANNEL_A;
-        return CHANNEL_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<ChannelSelectorType>();
 
 class SVGFEDisplacementMapElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
@@ -73,6 +38,8 @@
     SVGAnimatedNumber* scale() { return m_scale.get(); }
     SVGAnimatedString* in1() { return m_in1.get(); }
     SVGAnimatedString* in2() { return m_in2.get(); }
+    SVGAnimatedEnumeration<ChannelSelectorType>* xChannelSelector() { return m_xChannelSelector.get(); }
+    SVGAnimatedEnumeration<ChannelSelectorType>* yChannelSelector() { return m_yChannelSelector.get(); }
 
 private:
     SVGFEDisplacementMapElement(Document&);
@@ -86,10 +53,8 @@
     RefPtr<SVGAnimatedNumber> m_scale;
     RefPtr<SVGAnimatedString> m_in1;
     RefPtr<SVGAnimatedString> m_in2;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEDisplacementMapElement)
-        DECLARE_ANIMATED_ENUMERATION(XChannelSelector, xChannelSelector, ChannelSelectorType)
-        DECLARE_ANIMATED_ENUMERATION(YChannelSelector, yChannelSelector, ChannelSelectorType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<ChannelSelectorType> > m_xChannelSelector;
+    RefPtr<SVGAnimatedEnumeration<ChannelSelectorType> > m_yChannelSelector;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEDropShadowElement.cpp b/Source/core/svg/SVGFEDropShadowElement.cpp
index 5d219c5..910e47e 100644
--- a/Source/core/svg/SVGFEDropShadowElement.cpp
+++ b/Source/core/svg/SVGFEDropShadowElement.cpp
@@ -30,12 +30,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEDropShadowElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFEDropShadowElement::SVGFEDropShadowElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feDropShadowTag, document)
     , m_dx(SVGAnimatedNumber::create(this, SVGNames::dxAttr, SVGNumber::create(2)))
@@ -49,7 +43,6 @@
     addToPropertyMap(m_dy);
     addToPropertyMap(m_stdDeviation);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEDropShadowElement();
 }
 
 PassRefPtr<SVGFEDropShadowElement> SVGFEDropShadowElement::create(Document& document)
@@ -123,10 +116,10 @@
 {
     RenderObject* renderer = this->renderer();
     if (!renderer)
-        return 0;
+        return nullptr;
 
     if (stdDeviationX()->currentValue()->value() < 0 || stdDeviationY()->currentValue()->value() < 0)
-        return 0;
+        return nullptr;
 
     ASSERT(renderer->style());
     const SVGRenderStyle* svgStyle = renderer->style()->svgStyle();
@@ -136,7 +129,7 @@
 
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
     if (!input1)
-        return 0;
+        return nullptr;
 
     RefPtr<FilterEffect> effect = FEDropShadow::create(filter, stdDeviationX()->currentValue()->value(), stdDeviationY()->currentValue()->value(), m_dx->currentValue()->value(), m_dy->currentValue()->value(), color, opacity);
     effect->inputEffects().append(input1);
diff --git a/Source/core/svg/SVGFEDropShadowElement.h b/Source/core/svg/SVGFEDropShadowElement.h
index c3f9d0e..a0ae9d1 100644
--- a/Source/core/svg/SVGFEDropShadowElement.h
+++ b/Source/core/svg/SVGFEDropShadowElement.h
@@ -54,8 +54,6 @@
     RefPtr<SVGAnimatedNumber> m_dy;
     RefPtr<SVGAnimatedNumberOptionalNumber> m_stdDeviation;
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEDropShadowElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEFloodElement.cpp b/Source/core/svg/SVGFEFloodElement.cpp
index baee77b..f53b325 100644
--- a/Source/core/svg/SVGFEFloodElement.cpp
+++ b/Source/core/svg/SVGFEFloodElement.cpp
@@ -61,7 +61,7 @@
 {
     RenderObject* renderer = this->renderer();
     if (!renderer)
-        return 0;
+        return nullptr;
 
     ASSERT(renderer->style());
     const SVGRenderStyle* svgStyle = renderer->style()->svgStyle();
diff --git a/Source/core/svg/SVGFEFuncAElement.h b/Source/core/svg/SVGFEFuncAElement.h
index 01a473a..bcda64e 100644
--- a/Source/core/svg/SVGFEFuncAElement.h
+++ b/Source/core/svg/SVGFEFuncAElement.h
@@ -34,8 +34,6 @@
     explicit SVGFEFuncAElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncAElement, hasTagName(SVGNames::feFuncATag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFEFuncBElement.h b/Source/core/svg/SVGFEFuncBElement.h
index 24560e3..1f2d191 100644
--- a/Source/core/svg/SVGFEFuncBElement.h
+++ b/Source/core/svg/SVGFEFuncBElement.h
@@ -34,8 +34,6 @@
     explicit SVGFEFuncBElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncBElement, hasTagName(SVGNames::feFuncBTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFEFuncGElement.h b/Source/core/svg/SVGFEFuncGElement.h
index 3d6ccb8..836ebf2 100644
--- a/Source/core/svg/SVGFEFuncGElement.h
+++ b/Source/core/svg/SVGFEFuncGElement.h
@@ -34,8 +34,6 @@
     explicit SVGFEFuncGElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncGElement, hasTagName(SVGNames::feFuncGTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFEFuncRElement.h b/Source/core/svg/SVGFEFuncRElement.h
index 49bff72..4c0598b 100644
--- a/Source/core/svg/SVGFEFuncRElement.h
+++ b/Source/core/svg/SVGFEFuncRElement.h
@@ -34,8 +34,6 @@
     explicit SVGFEFuncRElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFEFuncRElement, hasTagName(SVGNames::feFuncRTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFEGaussianBlurElement.cpp b/Source/core/svg/SVGFEGaussianBlurElement.cpp
index 35b3892..7fb2af7 100644
--- a/Source/core/svg/SVGFEGaussianBlurElement.cpp
+++ b/Source/core/svg/SVGFEGaussianBlurElement.cpp
@@ -30,12 +30,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEGaussianBlurElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFEGaussianBlurElement::SVGFEGaussianBlurElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feGaussianBlurTag, document)
     , m_stdDeviation(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::stdDeviationAttr, 0, 0))
@@ -45,7 +39,6 @@
 
     addToPropertyMap(m_stdDeviation);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEGaussianBlurElement();
 }
 
 PassRefPtr<SVGFEGaussianBlurElement> SVGFEGaussianBlurElement::create(Document& document)
@@ -111,10 +104,10 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
     if (stdDeviationX()->currentValue()->value() < 0 || stdDeviationY()->currentValue()->value() < 0)
-        return 0;
+        return nullptr;
 
     RefPtr<FilterEffect> effect = FEGaussianBlur::create(filter, stdDeviationX()->currentValue()->value(), stdDeviationY()->currentValue()->value());
     effect->inputEffects().append(input1);
diff --git a/Source/core/svg/SVGFEGaussianBlurElement.h b/Source/core/svg/SVGFEGaussianBlurElement.h
index 063a644..aff2aaa 100644
--- a/Source/core/svg/SVGFEGaussianBlurElement.h
+++ b/Source/core/svg/SVGFEGaussianBlurElement.h
@@ -47,8 +47,6 @@
 
     RefPtr<SVGAnimatedNumberOptionalNumber> m_stdDeviation;
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEGaussianBlurElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEImageElement.cpp b/Source/core/svg/SVGFEImageElement.cpp
index 910af30..58f7a84 100644
--- a/Source/core/svg/SVGFEImageElement.cpp
+++ b/Source/core/svg/SVGFEImageElement.cpp
@@ -34,12 +34,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEImageElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFEImageElement::SVGFEImageElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feImageTag, document)
     , SVGURIReference(this)
@@ -47,7 +41,6 @@
 {
     ScriptWrappable::init(this);
     addToPropertyMap(m_preserveAspectRatio);
-    registerAnimatedPropertiesForSVGFEImageElement();
 }
 
 PassRefPtr<SVGFEImageElement> SVGFEImageElement::create(Document& document)
@@ -75,7 +68,7 @@
         m_cachedImage = 0;
     }
 
-    document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+    document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
 }
 
 void SVGFEImageElement::fetchImageResource()
@@ -99,13 +92,13 @@
         if (id.isEmpty())
             fetchImageResource();
         else {
-            document().accessSVGExtensions()->addPendingResource(id, this);
+            document().accessSVGExtensions().addPendingResource(id, this);
             ASSERT(hasPendingResources());
         }
     } else if (target->isSVGElement()) {
         // Register us with the target in the dependencies map. Any change of hrefElement
         // that leads to relayout/repainting now informs us, so we can react to it.
-        document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target));
+        document().accessSVGExtensions().addElementReferencingTarget(this, toSVGElement(target));
     }
 
     invalidate();
@@ -184,7 +177,7 @@
     Element* parent = parentElement();
     ASSERT(parent);
 
-    if (!parent->hasTagName(SVGNames::filterTag) || !parent->renderer())
+    if (!isSVGFilterElement(*parent) || !parent->renderer())
         return;
 
     if (RenderObject* renderer = this->renderer())
diff --git a/Source/core/svg/SVGFEImageElement.h b/Source/core/svg/SVGFEImageElement.h
index 9e3839b..ac59a2c 100644
--- a/Source/core/svg/SVGFEImageElement.h
+++ b/Source/core/svg/SVGFEImageElement.h
@@ -62,14 +62,10 @@
     virtual void removedFrom(ContainerNode*) OVERRIDE;
 
     RefPtr<SVGAnimatedPreserveAspectRatio> m_preserveAspectRatio;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEImageElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     ResourcePtr<ImageResource> m_cachedImage;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFEImageElement, hasTagName(SVGNames::feImageTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFELightElement.cpp b/Source/core/svg/SVGFELightElement.cpp
index ffd590d..e986cb3 100644
--- a/Source/core/svg/SVGFELightElement.cpp
+++ b/Source/core/svg/SVGFELightElement.cpp
@@ -32,10 +32,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFELightElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 SVGFELightElement::SVGFELightElement(const QualifiedName& tagName, Document& document)
     : SVGElement(tagName, document)
     , m_azimuth(SVGAnimatedNumber::create(this, SVGNames::azimuthAttr, SVGNumber::create()))
@@ -59,23 +55,18 @@
     addToPropertyMap(m_pointsAtZ);
     addToPropertyMap(m_specularExponent);
     addToPropertyMap(m_limitingConeAngle);
-    registerAnimatedPropertiesForSVGFELightElement();
 }
 
-SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement* svgElement)
+SVGFELightElement* SVGFELightElement::findLightElement(const SVGElement& svgElement)
 {
-    for (Node* node = svgElement->firstChild(); node; node = node->nextSibling()) {
-        if (isSVGFELightElement(*node))
-            return toSVGFELightElement(node);
-    }
-    return 0;
+    return Traversal<SVGFELightElement>::firstChild(svgElement);
 }
 
-PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement* svgElement)
+PassRefPtr<LightSource> SVGFELightElement::findLightSource(const SVGElement& svgElement)
 {
     SVGFELightElement* lightNode = findLightElement(svgElement);
     if (!lightNode)
-        return 0;
+        return nullptr;
     return lightNode->lightSource();
 }
 
@@ -159,11 +150,12 @@
         if (!renderer || !renderer->isSVGResourceFilterPrimitive())
             return;
 
-        if (parent->hasTagName(SVGNames::feDiffuseLightingTag)) {
-            toSVGFEDiffuseLightingElement(parent)->lightElementAttributeChanged(this, attrName);
+        if (isSVGFEDiffuseLightingElement(*parent)) {
+            toSVGFEDiffuseLightingElement(*parent).lightElementAttributeChanged(this, attrName);
             return;
-        } else if (parent->hasTagName(SVGNames::feSpecularLightingTag)) {
-            toSVGFESpecularLightingElement(parent)->lightElementAttributeChanged(this, attrName);
+        }
+        if (isSVGFESpecularLightingElement(*parent)) {
+            toSVGFESpecularLightingElement(*parent).lightElementAttributeChanged(this, attrName);
             return;
         }
     }
diff --git a/Source/core/svg/SVGFELightElement.h b/Source/core/svg/SVGFELightElement.h
index a9837bc..bd616ba 100644
--- a/Source/core/svg/SVGFELightElement.h
+++ b/Source/core/svg/SVGFELightElement.h
@@ -32,8 +32,8 @@
 class SVGFELightElement : public SVGElement {
 public:
     virtual PassRefPtr<LightSource> lightSource() const = 0;
-    static SVGFELightElement* findLightElement(const SVGElement*);
-    static PassRefPtr<LightSource> findLightSource(const SVGElement*);
+    static SVGFELightElement* findLightElement(const SVGElement&);
+    static PassRefPtr<LightSource> findLightSource(const SVGElement&);
 
     SVGAnimatedNumber* azimuth() { return m_azimuth.get(); }
     const SVGAnimatedNumber* azimuth() const { return m_azimuth.get(); }
@@ -77,8 +77,6 @@
     RefPtr<SVGAnimatedNumber> m_pointsAtZ;
     RefPtr<SVGAnimatedNumber> m_specularExponent;
     RefPtr<SVGAnimatedNumber> m_limitingConeAngle;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFELightElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 inline bool isSVGFELightElement(const Node& node)
@@ -86,7 +84,7 @@
     return node.hasTagName(SVGNames::feDistantLightTag) || node.hasTagName(SVGNames::fePointLightTag) || node.hasTagName(SVGNames::feSpotLightTag);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGFELightElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGFELightElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGFEMergeElement.cpp b/Source/core/svg/SVGFEMergeElement.cpp
index e400149..36ea949 100644
--- a/Source/core/svg/SVGFEMergeElement.cpp
+++ b/Source/core/svg/SVGFEMergeElement.cpp
@@ -44,17 +44,15 @@
 {
     RefPtr<FilterEffect> effect = FEMerge::create(filter);
     FilterEffectVector& mergeInputs = effect->inputEffects();
-    for (Node* node = firstChild(); node; node = node->nextSibling()) {
-        if (node->hasTagName(SVGNames::feMergeNodeTag)) {
-            FilterEffect* mergeEffect = filterBuilder->getEffectById(AtomicString(toSVGFEMergeNodeElement(node)->in1()->currentValue()->value()));
-            if (!mergeEffect)
-                return 0;
-            mergeInputs.append(mergeEffect);
-        }
+    for (SVGFEMergeNodeElement* element = Traversal<SVGFEMergeNodeElement>::firstChild(*this); element; element = Traversal<SVGFEMergeNodeElement>::nextSibling(*element)) {
+        FilterEffect* mergeEffect = filterBuilder->getEffectById(AtomicString(element->in1()->currentValue()->value()));
+        if (!mergeEffect)
+            return nullptr;
+        mergeInputs.append(mergeEffect);
     }
 
     if (mergeInputs.isEmpty())
-        return 0;
+        return nullptr;
 
     return effect.release();
 }
diff --git a/Source/core/svg/SVGFEMergeNodeElement.cpp b/Source/core/svg/SVGFEMergeNodeElement.cpp
index 45e5b9b..4f33793 100644
--- a/Source/core/svg/SVGFEMergeNodeElement.cpp
+++ b/Source/core/svg/SVGFEMergeNodeElement.cpp
@@ -27,18 +27,12 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEMergeNodeElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFEMergeNodeElement::SVGFEMergeNodeElement(Document& document)
     : SVGElement(SVGNames::feMergeNodeTag, document)
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
 {
     ScriptWrappable::init(this);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEMergeNodeElement();
 }
 
 PassRefPtr<SVGFEMergeNodeElement> SVGFEMergeNodeElement::create(Document& document)
diff --git a/Source/core/svg/SVGFEMergeNodeElement.h b/Source/core/svg/SVGFEMergeNodeElement.h
index d928a07..bcdfda7 100644
--- a/Source/core/svg/SVGFEMergeNodeElement.h
+++ b/Source/core/svg/SVGFEMergeNodeElement.h
@@ -42,12 +42,8 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEMergeNodeElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFEMergeNodeElement, hasTagName(SVGNames::feMergeNodeTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFEMorphologyElement.cpp b/Source/core/svg/SVGFEMorphologyElement.cpp
index c0ea10e..882f8e0 100644
--- a/Source/core/svg/SVGFEMorphologyElement.cpp
+++ b/Source/core/svg/SVGFEMorphologyElement.cpp
@@ -29,25 +29,28 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFEMorphologyElement, SVGNames::operatorAttr, SVGOperator, svgOperator, MorphologyOperatorType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEMorphologyElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(svgOperator)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<MorphologyOperatorType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(FEMORPHOLOGY_OPERATOR_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(FEMORPHOLOGY_OPERATOR_ERODE, "erode"));
+        entries.append(std::make_pair(FEMORPHOLOGY_OPERATOR_DILATE, "dilate"));
+    }
+    return entries;
+}
 
 inline SVGFEMorphologyElement::SVGFEMorphologyElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feMorphologyTag, document)
     , m_radius(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::radiusAttr))
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
-    , m_svgOperator(FEMORPHOLOGY_OPERATOR_ERODE)
+    , m_svgOperator(SVGAnimatedEnumeration<MorphologyOperatorType>::create(this, SVGNames::operatorAttr, FEMORPHOLOGY_OPERATOR_ERODE))
 {
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_radius);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEMorphologyElement();
+    addToPropertyMap(m_svgOperator);
 }
 
 PassRefPtr<SVGFEMorphologyElement> SVGFEMorphologyElement::create(Document& document)
@@ -80,19 +83,14 @@
         return;
     }
 
-    if (name == SVGNames::operatorAttr) {
-        MorphologyOperatorType propertyValue = SVGPropertyTraits<MorphologyOperatorType>::fromString(value);
-        if (propertyValue > 0)
-            setSVGOperatorBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::inAttr)
         m_in1->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::radiusAttr)
         m_radius->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::operatorAttr)
+        m_svgOperator->setBaseValueAsString(value, parseError);
     else
         ASSERT_NOT_REACHED();
 
@@ -103,7 +101,7 @@
 {
     FEMorphology* morphology = static_cast<FEMorphology*>(effect);
     if (attrName == SVGNames::operatorAttr)
-        return morphology->setMorphologyOperator(svgOperatorCurrentValue());
+        return morphology->setMorphologyOperator(m_svgOperator->currentValue()->enumValue());
     if (attrName == SVGNames::radiusAttr) {
         // Both setRadius functions should be evaluated separately.
         bool isRadiusXChanged = morphology->setRadiusX(radiusX()->currentValue()->value());
@@ -144,12 +142,12 @@
     float yRadius = radiusY()->currentValue()->value();
 
     if (!input1)
-        return 0;
+        return nullptr;
 
     if (xRadius < 0 || yRadius < 0)
-        return 0;
+        return nullptr;
 
-    RefPtr<FilterEffect> effect = FEMorphology::create(filter, svgOperatorCurrentValue(), xRadius, yRadius);
+    RefPtr<FilterEffect> effect = FEMorphology::create(filter, m_svgOperator->currentValue()->enumValue(), xRadius, yRadius);
     effect->inputEffects().append(input1);
     return effect.release();
 }
diff --git a/Source/core/svg/SVGFEMorphologyElement.h b/Source/core/svg/SVGFEMorphologyElement.h
index 14591ba..44bbc25 100644
--- a/Source/core/svg/SVGFEMorphologyElement.h
+++ b/Source/core/svg/SVGFEMorphologyElement.h
@@ -27,34 +27,7 @@
 
 namespace WebCore {
 
-template<>
-struct SVGPropertyTraits<MorphologyOperatorType> {
-    static unsigned highestEnumValue() { return FEMORPHOLOGY_OPERATOR_DILATE; }
-
-    static String toString(MorphologyOperatorType type)
-    {
-        switch (type) {
-        case FEMORPHOLOGY_OPERATOR_UNKNOWN:
-            return emptyString();
-        case FEMORPHOLOGY_OPERATOR_ERODE:
-            return "erode";
-        case FEMORPHOLOGY_OPERATOR_DILATE:
-            return "dilate";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static MorphologyOperatorType fromString(const String& value)
-    {
-        if (value == "erode")
-            return FEMORPHOLOGY_OPERATOR_ERODE;
-        if (value == "dilate")
-            return FEMORPHOLOGY_OPERATOR_DILATE;
-        return FEMORPHOLOGY_OPERATOR_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<MorphologyOperatorType>();
 
 class SVGFEMorphologyElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
@@ -65,6 +38,7 @@
     SVGAnimatedNumber* radiusX() { return m_radius->firstNumber(); }
     SVGAnimatedNumber* radiusY() { return m_radius->secondNumber(); }
     SVGAnimatedString* in1() { return m_in1.get(); }
+    SVGAnimatedEnumeration<MorphologyOperatorType>* svgOperator() { return m_svgOperator.get(); }
 
 private:
     explicit SVGFEMorphologyElement(Document&);
@@ -77,9 +51,7 @@
 
     RefPtr<SVGAnimatedNumberOptionalNumber> m_radius;
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEMorphologyElement)
-        DECLARE_ANIMATED_ENUMERATION(SVGOperator, svgOperator, MorphologyOperatorType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<MorphologyOperatorType> > m_svgOperator;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFEOffsetElement.cpp b/Source/core/svg/SVGFEOffsetElement.cpp
index 585a9d4..88cc467 100644
--- a/Source/core/svg/SVGFEOffsetElement.cpp
+++ b/Source/core/svg/SVGFEOffsetElement.cpp
@@ -29,12 +29,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFEOffsetElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFEOffsetElement::SVGFEOffsetElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feOffsetTag, document)
     , m_dx(SVGAnimatedNumber::create(this, SVGNames::dxAttr, SVGNumber::create()))
@@ -46,7 +40,6 @@
     addToPropertyMap(m_dx);
     addToPropertyMap(m_dy);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFEOffsetElement();
 }
 
 PassRefPtr<SVGFEOffsetElement> SVGFEOffsetElement::create(Document& document)
@@ -108,7 +101,7 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
     RefPtr<FilterEffect> effect = FEOffset::create(filter, m_dx->currentValue()->value(), m_dy->currentValue()->value());
     effect->inputEffects().append(input1);
diff --git a/Source/core/svg/SVGFEOffsetElement.h b/Source/core/svg/SVGFEOffsetElement.h
index 4e7dba9..8f10202 100644
--- a/Source/core/svg/SVGFEOffsetElement.h
+++ b/Source/core/svg/SVGFEOffsetElement.h
@@ -45,8 +45,6 @@
     RefPtr<SVGAnimatedNumber> m_dx;
     RefPtr<SVGAnimatedNumber> m_dy;
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFEOffsetElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFESpecularLightingElement.cpp b/Source/core/svg/SVGFESpecularLightingElement.cpp
index 21782cf..6ea66d9 100644
--- a/Source/core/svg/SVGFESpecularLightingElement.cpp
+++ b/Source/core/svg/SVGFESpecularLightingElement.cpp
@@ -31,12 +31,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFESpecularLightingElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFESpecularLightingElement::SVGFESpecularLightingElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feSpecularLightingTag, document)
     , m_specularConstant(SVGAnimatedNumber::create(this, SVGNames::specularConstantAttr, SVGNumber::create(1)))
@@ -52,7 +46,6 @@
     addToPropertyMap(m_surfaceScale);
     addToPropertyMap(m_kernelUnitLength);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFESpecularLightingElement();
 }
 
 PassRefPtr<SVGFESpecularLightingElement> SVGFESpecularLightingElement::create(Document& document)
@@ -116,7 +109,7 @@
         return specularLighting->setSpecularExponent(m_specularExponent->currentValue()->value());
 
     LightSource* lightSource = const_cast<LightSource*>(specularLighting->lightSource());
-    SVGFELightElement* lightElement = SVGFELightElement::findLightElement(this);
+    SVGFELightElement* lightElement = SVGFELightElement::findLightElement(*this);
     ASSERT(lightSource);
     ASSERT(lightElement);
 
@@ -172,7 +165,7 @@
 
 void SVGFESpecularLightingElement::lightElementAttributeChanged(const SVGFELightElement* lightElement, const QualifiedName& attrName)
 {
-    if (SVGFELightElement::findLightElement(this) != lightElement)
+    if (SVGFELightElement::findLightElement(*this) != lightElement)
         return;
 
     // The light element has different attribute names so attrName can identify the requested attribute.
@@ -184,15 +177,15 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
-    RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(this);
+    RefPtr<LightSource> lightSource = SVGFELightElement::findLightSource(*this);
     if (!lightSource)
-        return 0;
+        return nullptr;
 
     RenderObject* renderer = this->renderer();
     if (!renderer)
-        return 0;
+        return nullptr;
 
     ASSERT(renderer->style());
     Color color = renderer->style()->svgStyle()->lightingColor();
diff --git a/Source/core/svg/SVGFESpecularLightingElement.h b/Source/core/svg/SVGFESpecularLightingElement.h
index c3b3367..91e1723 100644
--- a/Source/core/svg/SVGFESpecularLightingElement.h
+++ b/Source/core/svg/SVGFESpecularLightingElement.h
@@ -59,12 +59,8 @@
     RefPtr<SVGAnimatedNumber> m_surfaceScale;
     RefPtr<SVGAnimatedNumberOptionalNumber> m_kernelUnitLength;
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFESpecularLightingElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFESpecularLightingElement, hasTagName(SVGNames::feSpecularLightingTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGFETileElement.cpp b/Source/core/svg/SVGFETileElement.cpp
index ff8c0d7..9f5e475 100644
--- a/Source/core/svg/SVGFETileElement.cpp
+++ b/Source/core/svg/SVGFETileElement.cpp
@@ -29,19 +29,12 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFETileElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFETileElement::SVGFETileElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feTileTag, document)
     , m_in1(SVGAnimatedString::create(this, SVGNames::inAttr, SVGString::create()))
 {
     ScriptWrappable::init(this);
     addToPropertyMap(m_in1);
-    registerAnimatedPropertiesForSVGFETileElement();
 }
 
 PassRefPtr<SVGFETileElement> SVGFETileElement::create(Document& document)
@@ -96,7 +89,7 @@
     FilterEffect* input1 = filterBuilder->getEffectById(AtomicString(m_in1->currentValue()->value()));
 
     if (!input1)
-        return 0;
+        return nullptr;
 
     RefPtr<FilterEffect> effect = FETile::create(filter);
     effect->inputEffects().append(input1);
diff --git a/Source/core/svg/SVGFETileElement.h b/Source/core/svg/SVGFETileElement.h
index 9a5d109..df1a75a 100644
--- a/Source/core/svg/SVGFETileElement.h
+++ b/Source/core/svg/SVGFETileElement.h
@@ -40,8 +40,6 @@
     virtual PassRefPtr<FilterEffect> build(SVGFilterBuilder*, Filter*) OVERRIDE;
 
     RefPtr<SVGAnimatedString> m_in1;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFETileElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFETurbulenceElement.cpp b/Source/core/svg/SVGFETurbulenceElement.cpp
index dfde8b5..c633cf8 100644
--- a/Source/core/svg/SVGFETurbulenceElement.cpp
+++ b/Source/core/svg/SVGFETurbulenceElement.cpp
@@ -28,30 +28,43 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFETurbulenceElement, SVGNames::stitchTilesAttr, StitchTiles, stitchTiles, SVGStitchOptions)
-DEFINE_ANIMATED_ENUMERATION(SVGFETurbulenceElement, SVGNames::typeAttr, Type, type, TurbulenceType)
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGStitchOptions>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVG_STITCHTYPE_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(SVG_STITCHTYPE_STITCH, "stitch"));
+        entries.append(std::make_pair(SVG_STITCHTYPE_NOSTITCH, "noStitch"));
+    }
+    return entries;
+}
 
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFETurbulenceElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(stitchTiles)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(type)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<TurbulenceType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(FETURBULENCE_TYPE_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(FETURBULENCE_TYPE_FRACTALNOISE, "fractalNoise"));
+        entries.append(std::make_pair(FETURBULENCE_TYPE_TURBULENCE, "turbulence"));
+    }
+    return entries;
+}
 
 inline SVGFETurbulenceElement::SVGFETurbulenceElement(Document& document)
     : SVGFilterPrimitiveStandardAttributes(SVGNames::feTurbulenceTag, document)
     , m_baseFrequency(SVGAnimatedNumberOptionalNumber::create(this, SVGNames::baseFrequencyAttr))
     , m_seed(SVGAnimatedNumber::create(this, SVGNames::seedAttr, SVGNumber::create(0)))
+    , m_stitchTiles(SVGAnimatedEnumeration<SVGStitchOptions>::create(this, SVGNames::stitchTilesAttr, SVG_STITCHTYPE_NOSTITCH))
+    , m_type(SVGAnimatedEnumeration<TurbulenceType>::create(this, SVGNames::typeAttr, FETURBULENCE_TYPE_TURBULENCE))
     , m_numOctaves(SVGAnimatedInteger::create(this, SVGNames::numOctavesAttr, SVGInteger::create(1)))
-    , m_stitchTiles(SVG_STITCHTYPE_NOSTITCH)
-    , m_type(FETURBULENCE_TYPE_TURBULENCE)
 {
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_baseFrequency);
     addToPropertyMap(m_seed);
+    addToPropertyMap(m_stitchTiles);
+    addToPropertyMap(m_type);
     addToPropertyMap(m_numOctaves);
-    registerAnimatedPropertiesForSVGFETurbulenceElement();
 }
 
 PassRefPtr<SVGFETurbulenceElement> SVGFETurbulenceElement::create(Document& document)
@@ -79,20 +92,6 @@
         return;
     }
 
-    if (name == SVGNames::typeAttr) {
-        TurbulenceType propertyValue = SVGPropertyTraits<TurbulenceType>::fromString(value);
-        if (propertyValue > 0)
-            setTypeBaseValue(propertyValue);
-        return;
-    }
-
-    if (name == SVGNames::stitchTilesAttr) {
-        SVGStitchOptions propertyValue = SVGPropertyTraits<SVGStitchOptions>::fromString(value);
-        if (propertyValue > 0)
-            setStitchTilesBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
     if (name == SVGNames::baseFrequencyAttr)
@@ -101,6 +100,10 @@
         m_numOctaves->setBaseValueAsString(value, parseError);
     else if (name == SVGNames::seedAttr)
         m_seed->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::stitchTilesAttr)
+        m_stitchTiles->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::typeAttr)
+        m_type->setBaseValueAsString(value, parseError);
     else
         ASSERT_NOT_REACHED();
 
@@ -111,9 +114,9 @@
 {
     FETurbulence* turbulence = static_cast<FETurbulence*>(effect);
     if (attrName == SVGNames::typeAttr)
-        return turbulence->setType(typeCurrentValue());
+        return turbulence->setType(m_type->currentValue()->enumValue());
     if (attrName == SVGNames::stitchTilesAttr)
-        return turbulence->setStitchTiles(stitchTilesCurrentValue());
+        return turbulence->setStitchTiles(m_stitchTiles->currentValue()->enumValue());
     if (attrName == SVGNames::baseFrequencyAttr) {
         bool baseFrequencyXChanged = turbulence->setBaseFrequencyX(baseFrequencyX()->currentValue()->value());
         bool baseFrequencyYChanged = turbulence->setBaseFrequencyY(baseFrequencyY()->currentValue()->value());
@@ -152,8 +155,8 @@
 PassRefPtr<FilterEffect> SVGFETurbulenceElement::build(SVGFilterBuilder*, Filter* filter)
 {
     if (baseFrequencyX()->currentValue()->value() < 0 || baseFrequencyY()->currentValue()->value() < 0)
-        return 0;
-    return FETurbulence::create(filter, typeCurrentValue(), baseFrequencyX()->currentValue()->value(), baseFrequencyY()->currentValue()->value(), m_numOctaves->currentValue()->value(), m_seed->currentValue()->value(), stitchTilesCurrentValue() == SVG_STITCHTYPE_STITCH);
+        return nullptr;
+    return FETurbulence::create(filter, m_type->currentValue()->enumValue(), baseFrequencyX()->currentValue()->value(), baseFrequencyY()->currentValue()->value(), m_numOctaves->currentValue()->value(), m_seed->currentValue()->value(), m_stitchTiles->currentValue()->enumValue() == SVG_STITCHTYPE_STITCH);
 }
 
 }
diff --git a/Source/core/svg/SVGFETurbulenceElement.h b/Source/core/svg/SVGFETurbulenceElement.h
index 467cd9c..8d384c6 100644
--- a/Source/core/svg/SVGFETurbulenceElement.h
+++ b/Source/core/svg/SVGFETurbulenceElement.h
@@ -35,64 +35,9 @@
     SVG_STITCHTYPE_STITCH   = 1,
     SVG_STITCHTYPE_NOSTITCH = 2
 };
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGStitchOptions>();
 
-template<>
-struct SVGPropertyTraits<SVGStitchOptions> {
-    static unsigned highestEnumValue() { return SVG_STITCHTYPE_NOSTITCH; }
-
-    static String toString(SVGStitchOptions type)
-    {
-        switch (type) {
-        case SVG_STITCHTYPE_UNKNOWN:
-            return emptyString();
-        case SVG_STITCHTYPE_STITCH:
-            return "stitch";
-        case SVG_STITCHTYPE_NOSTITCH:
-            return "noStitch";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static SVGStitchOptions fromString(const String& value)
-    {
-        if (value == "stitch")
-            return SVG_STITCHTYPE_STITCH;
-        if (value == "noStitch")
-            return SVG_STITCHTYPE_NOSTITCH;
-        return SVG_STITCHTYPE_UNKNOWN;
-    }
-};
-
-template<>
-struct SVGPropertyTraits<TurbulenceType> {
-    static unsigned highestEnumValue() { return FETURBULENCE_TYPE_TURBULENCE; }
-
-    static String toString(TurbulenceType type)
-    {
-        switch (type) {
-        case FETURBULENCE_TYPE_UNKNOWN:
-            return emptyString();
-        case FETURBULENCE_TYPE_FRACTALNOISE:
-            return "fractalNoise";
-        case FETURBULENCE_TYPE_TURBULENCE:
-            return "turbulence";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static TurbulenceType fromString(const String& value)
-    {
-        if (value == "fractalNoise")
-            return FETURBULENCE_TYPE_FRACTALNOISE;
-        if (value == "turbulence")
-            return FETURBULENCE_TYPE_TURBULENCE;
-        return FETURBULENCE_TYPE_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<TurbulenceType>();
 
 class SVGFETurbulenceElement FINAL : public SVGFilterPrimitiveStandardAttributes {
 public:
@@ -101,6 +46,8 @@
     SVGAnimatedNumber* baseFrequencyX() { return m_baseFrequency->firstNumber(); }
     SVGAnimatedNumber* baseFrequencyY() { return m_baseFrequency->secondNumber(); }
     SVGAnimatedNumber* seed() { return m_seed.get(); }
+    SVGAnimatedEnumeration<SVGStitchOptions>* stitchTiles() { return m_stitchTiles.get(); }
+    SVGAnimatedEnumeration<TurbulenceType>* type() { return m_type.get(); }
     SVGAnimatedInteger* numOctaves() { return m_numOctaves.get(); }
 
 private:
@@ -114,11 +61,9 @@
 
     RefPtr<SVGAnimatedNumberOptionalNumber> m_baseFrequency;
     RefPtr<SVGAnimatedNumber> m_seed;
+    RefPtr<SVGAnimatedEnumeration<SVGStitchOptions> > m_stitchTiles;
+    RefPtr<SVGAnimatedEnumeration<TurbulenceType> > m_type;
     RefPtr<SVGAnimatedInteger> m_numOctaves;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFETurbulenceElement)
-        DECLARE_ANIMATED_ENUMERATION(StitchTiles, stitchTiles, SVGStitchOptions)
-        DECLARE_ANIMATED_ENUMERATION(Type, type, TurbulenceType)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGFilterElement.cpp b/Source/core/svg/SVGFilterElement.cpp
index 83a92de..1e80d2e 100644
--- a/Source/core/svg/SVGFilterElement.cpp
+++ b/Source/core/svg/SVGFilterElement.cpp
@@ -32,15 +32,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGFilterElement, SVGNames::filterUnitsAttr, FilterUnits, filterUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_ENUMERATION(SVGFilterElement, SVGNames::primitiveUnitsAttr, PrimitiveUnits, primitiveUnits, SVGUnitTypes::SVGUnitType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFilterElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(filterUnits)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(primitiveUnits)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFilterElement::SVGFilterElement(Document& document)
     : SVGElement(SVGNames::filterTag, document)
     , SVGURIReference(this)
@@ -48,9 +39,9 @@
     , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight)))
     , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth)))
     , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight)))
+    , m_filterUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::filterUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
+    , m_primitiveUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::primitiveUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
     , m_filterRes(SVGAnimatedIntegerOptionalInteger::create(this, SVGNames::filterResAttr))
-    , m_filterUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
-    , m_primitiveUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
 {
     ScriptWrappable::init(this);
 
@@ -65,8 +56,9 @@
     addToPropertyMap(m_y);
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
+    addToPropertyMap(m_filterUnits);
+    addToPropertyMap(m_primitiveUnits);
     addToPropertyMap(m_filterRes);
-    registerAnimatedPropertiesForSVGFilterElement();
 }
 
 PassRefPtr<SVGFilterElement> SVGFilterElement::create(Document& document)
@@ -103,30 +95,25 @@
 {
     SVGParsingError parseError = NoError;
 
-    if (!isSupportedAttribute(name)) {
+    if (!isSupportedAttribute(name))
         SVGElement::parseAttribute(name, value);
-    } else if (name == SVGNames::filterUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setFilterUnitsBaseValue(propertyValue);
-    } else if (name == SVGNames::primitiveUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setPrimitiveUnitsBaseValue(propertyValue);
-    } else if (name == SVGNames::xAttr) {
+    else if (name == SVGNames::filterUnitsAttr)
+        m_filterUnits->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::primitiveUnitsAttr)
+        m_primitiveUnits->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::xAttr)
         m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError);
-    } else if (name == SVGNames::yAttr) {
+    else if (name == SVGNames::yAttr)
         m_y->setBaseValueAsString(value, AllowNegativeLengths, parseError);
-    } else if (name == SVGNames::widthAttr) {
+    else if (name == SVGNames::widthAttr)
         m_width->setBaseValueAsString(value, ForbidNegativeLengths, parseError);
-    } else if (name == SVGNames::heightAttr) {
+    else if (name == SVGNames::heightAttr)
         m_height->setBaseValueAsString(value, ForbidNegativeLengths, parseError);
-    } else if (name == SVGNames::filterResAttr) {
+    else if (name == SVGNames::filterResAttr)
         m_filterRes->setBaseValueAsString(value, parseError);
-    } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
-    } else {
+    else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+    } else
         ASSERT_NOT_REACHED();
-    }
 
     reportAttributeParsingError(parseError, name, value);
 }
diff --git a/Source/core/svg/SVGFilterElement.h b/Source/core/svg/SVGFilterElement.h
index 80c61b7..184b2d7 100644
--- a/Source/core/svg/SVGFilterElement.h
+++ b/Source/core/svg/SVGFilterElement.h
@@ -48,6 +48,8 @@
     SVGAnimatedLength* y() const { return m_y.get(); }
     SVGAnimatedLength* width() const { return m_width.get(); }
     SVGAnimatedLength* height() const { return m_height.get(); }
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* filterUnits() { return m_filterUnits.get(); }
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* primitiveUnits() { return m_primitiveUnits.get(); }
     SVGAnimatedInteger* filterResX() { return m_filterRes->firstInteger(); }
     SVGAnimatedInteger* filterResY() { return m_filterRes->secondInteger(); }
 
@@ -69,17 +71,13 @@
     RefPtr<SVGAnimatedLength> m_y;
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_filterUnits;
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_primitiveUnits;
     RefPtr<SVGAnimatedIntegerOptionalInteger> m_filterRes;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFilterElement)
-        DECLARE_ANIMATED_ENUMERATION(FilterUnits, filterUnits, SVGUnitTypes::SVGUnitType)
-        DECLARE_ANIMATED_ENUMERATION(PrimitiveUnits, primitiveUnits, SVGUnitTypes::SVGUnitType)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     HashSet<RefPtr<Node> > m_clientsToAdd;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFilterElement, hasTagName(SVGNames::filterTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp b/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp
index dd5cbd7..95d3e51 100644
--- a/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp
+++ b/Source/core/svg/SVGFilterPrimitiveStandardAttributes.cpp
@@ -31,12 +31,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 SVGFilterPrimitiveStandardAttributes::SVGFilterPrimitiveStandardAttributes(const QualifiedName& tagName, Document& document)
     : SVGElement(tagName, document)
     , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth)))
@@ -58,7 +52,6 @@
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
     addToPropertyMap(m_result);
-    registerAnimatedPropertiesForSVGFilterPrimitiveStandardAttributes();
 }
 
 bool SVGFilterPrimitiveStandardAttributes::isSupportedAttribute(const QualifiedName& attrName)
@@ -145,7 +138,7 @@
 
 bool SVGFilterPrimitiveStandardAttributes::rendererIsNeeded(const RenderStyle& style)
 {
-    if (parentNode() && (parentNode()->hasTagName(SVGNames::filterTag)))
+    if (isSVGFilterElement(parentNode()))
         return SVGElement::rendererIsNeeded(style);
 
     return false;
diff --git a/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h b/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h
index 70c8f63..9b66737 100644
--- a/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h
+++ b/Source/core/svg/SVGFilterPrimitiveStandardAttributes.h
@@ -44,11 +44,11 @@
     virtual bool setFilterEffectAttribute(FilterEffect*, const QualifiedName&);
 
     // SVGFilterPrimitiveStandardAttributes JS API.
-    static SVGAnimatedLength* x(SVGFilterPrimitiveStandardAttributes* object) { return object->x(); }
-    static SVGAnimatedLength* y(SVGFilterPrimitiveStandardAttributes* object) { return object->y(); }
-    static SVGAnimatedLength* width(SVGFilterPrimitiveStandardAttributes* object) { return object->width(); }
-    static SVGAnimatedLength* height(SVGFilterPrimitiveStandardAttributes* object) { return object->height(); }
-    static SVGAnimatedString* result(SVGFilterPrimitiveStandardAttributes* object) { return object->result(); }
+    static SVGAnimatedLength* x(SVGFilterPrimitiveStandardAttributes& object) { return object.x(); }
+    static SVGAnimatedLength* y(SVGFilterPrimitiveStandardAttributes& object) { return object.y(); }
+    static SVGAnimatedLength* width(SVGFilterPrimitiveStandardAttributes& object) { return object.width(); }
+    static SVGAnimatedLength* height(SVGFilterPrimitiveStandardAttributes& object) { return object.height(); }
+    static SVGAnimatedString* result(SVGFilterPrimitiveStandardAttributes& object) { return object.result(); }
 
     SVGAnimatedLength* x() const { return m_x.get(); }
     SVGAnimatedLength* y() const { return m_y.get(); }
@@ -83,8 +83,6 @@
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
     RefPtr<SVGAnimatedString> m_result;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFilterPrimitiveStandardAttributes)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 void invalidateFilterPrimitiveParent(SVGElement*);
diff --git a/Source/core/svg/SVGFitToViewBox.h b/Source/core/svg/SVGFitToViewBox.h
index 3620dd4..9bdfaac 100644
--- a/Source/core/svg/SVGFitToViewBox.h
+++ b/Source/core/svg/SVGFitToViewBox.h
@@ -55,11 +55,11 @@
         if (name == SVGNames::viewBoxAttr) {
             m_viewBox->setBaseValueAsString(value, parseError);
             if (m_viewBox->baseValue()->width() < 0.0f) {
-                document.accessSVGExtensions()->reportError("A negative value for ViewBox width is not allowed");
+                document.accessSVGExtensions().reportError("A negative value for ViewBox width is not allowed");
                 m_viewBox->baseValue()->setInvalid();
             }
             if (m_viewBox->baseValue()->height() < 0.0f) {
-                document.accessSVGExtensions()->reportError("A negative value for ViewBox height is not allowed");
+                document.accessSVGExtensions().reportError("A negative value for ViewBox height is not allowed");
                 m_viewBox->baseValue()->setInvalid();
             }
             return true;
@@ -72,8 +72,8 @@
     }
 
     // SVGFitToViewBox JS API.
-    static SVGAnimatedRect* viewBox(SVGFitToViewBox* object) { return object->viewBox(); }
-    static SVGAnimatedPreserveAspectRatio* preserveAspectRatio(SVGFitToViewBox* object) { return object->preserveAspectRatio(); }
+    static SVGAnimatedRect* viewBox(SVGFitToViewBox& object) { return object.viewBox(); }
+    static SVGAnimatedPreserveAspectRatio* preserveAspectRatio(SVGFitToViewBox& object) { return object.preserveAspectRatio(); }
 
     SVGAnimatedRect* viewBox() const { return m_viewBox.get(); }
     bool hasEmptyViewBox() const { return m_viewBox->currentValue()->isValid() && m_viewBox->currentValue()->value().isEmpty(); }
@@ -82,8 +82,8 @@
 protected:
     explicit SVGFitToViewBox(SVGElement*, PropertyMapPolicy = PropertyMapPolicyAdd);
     void updateViewBox(const FloatRect&);
-    void clearViewBox() { m_viewBox = 0; }
-    void clearPreserveAspectRatio() { m_preserveAspectRatio = 0; }
+    void clearViewBox() { m_viewBox = nullptr; }
+    void clearPreserveAspectRatio() { m_preserveAspectRatio = nullptr; }
 
 private:
     RefPtr<SVGAnimatedRect> m_viewBox;
diff --git a/Source/core/svg/SVGFontData.cpp b/Source/core/svg/SVGFontData.cpp
index 962e25d..325d547 100644
--- a/Source/core/svg/SVGFontData.cpp
+++ b/Source/core/svg/SVGFontData.cpp
@@ -45,7 +45,7 @@
 namespace WebCore {
 
 SVGFontData::SVGFontData(SVGFontFaceElement* fontFaceElement)
-    : CustomFontData(false)
+    : CustomFontData()
     , m_svgFontFaceElement(fontFaceElement)
     , m_horizontalOriginX(fontFaceElement->horizontalOriginX())
     , m_horizontalOriginY(fontFaceElement->horizontalOriginY())
@@ -176,8 +176,8 @@
         if (Element* parentRenderObjectElement = toElement(parentRenderObject->node())) {
             language = parentRenderObjectElement->getAttribute(XMLNames::langAttr);
 
-            if (parentRenderObjectElement->hasTagName(SVGNames::altGlyphTag)) {
-                if (!toSVGAltGlyphElement(parentRenderObjectElement)->hasValidGlyphElements(altGlyphNames))
+            if (isSVGAltGlyphElement(*parentRenderObjectElement)) {
+                if (!toSVGAltGlyphElement(*parentRenderObjectElement).hasValidGlyphElements(altGlyphNames))
                     altGlyphNames.clear();
             }
         }
@@ -187,7 +187,7 @@
     size_t altGlyphNamesSize = altGlyphNames.size();
     if (altGlyphNamesSize) {
         for (size_t index = 0; index < altGlyphNamesSize; ++index)
-            associatedFontElement->collectGlyphsForGlyphName(altGlyphNames[index], glyphs);
+            associatedFontElement->collectGlyphsForAltGlyphReference(altGlyphNames[index], glyphs);
 
         // Assign the unicodeStringLength now that its known.
         size_t glyphsSize = glyphs.size();
@@ -198,7 +198,6 @@
         // Later code will fail if we do not do this and the glyph is incompatible.
         if (glyphsSize) {
             SVGGlyph& svgGlyph = glyphs[0];
-            iterator.setLastGlyphName(svgGlyph.glyphName);
             glyphData.glyph = svgGlyph.tableEntry;
             advanceLength = svgGlyph.unicodeStringLength;
             return true;
@@ -213,13 +212,11 @@
             continue;
         if (!isCompatibleGlyph(svgGlyph, isVerticalText, language, arabicForms, currentCharacter, currentCharacter + svgGlyph.unicodeStringLength))
             continue;
-        iterator.setLastGlyphName(svgGlyph.glyphName);
         glyphData.glyph = svgGlyph.tableEntry;
         advanceLength = svgGlyph.unicodeStringLength;
         return true;
     }
 
-    iterator.setLastGlyphName(String());
     return false;
 }
 
diff --git a/Source/core/svg/SVGFontElement.cpp b/Source/core/svg/SVGFontElement.cpp
index 70d80b4..17fbfef 100644
--- a/Source/core/svg/SVGFontElement.cpp
+++ b/Source/core/svg/SVGFontElement.cpp
@@ -24,6 +24,7 @@
 #if ENABLE(SVG_FONTS)
 #include "core/svg/SVGFontElement.h"
 
+#include "core/dom/ElementTraversal.h"
 #include "core/frame/UseCounter.h"
 #include "core/svg/SVGGlyphElement.h"
 #include "core/svg/SVGHKernElement.h"
@@ -33,19 +34,12 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGFontElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGFontElement::SVGFontElement(Document& document)
     : SVGElement(SVGNames::fontTag, document)
     , m_missingGlyph(0)
     , m_isGlyphCacheValid(false)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGFontElement();
 
     UseCounter::count(document, UseCounter::SVGFontElement);
 }
@@ -59,20 +53,15 @@
 {
     if (m_isGlyphCacheValid) {
         m_glyphMap.clear();
-        m_horizontalKerningPairs.clear();
-        m_verticalKerningPairs.clear();
+        m_horizontalKerningTable.clear();
+        m_verticalKerningTable.clear();
     }
     m_isGlyphCacheValid = false;
 }
 
 SVGMissingGlyphElement* SVGFontElement::firstMissingGlyphElement() const
 {
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(SVGNames::missing_glyphTag))
-            return toSVGMissingGlyphElement(child);
-    }
-
-    return 0;
+    return Traversal<SVGMissingGlyphElement>::firstChild(*this);
 }
 
 void SVGFontElement::registerLigaturesInGlyphCache(Vector<String>& ligatures)
@@ -111,35 +100,100 @@
     }
 }
 
+static inline KerningPairKey makeKerningPairKey(Glyph glyphId1, Glyph glyphId2)
+{
+    return glyphId1 << 16 | glyphId2;
+}
+
+Vector<SVGGlyph> SVGFontElement::buildGlyphList(const UnicodeRanges& unicodeRanges, const HashSet<String>& unicodeNames, const HashSet<String>& glyphNames) const
+{
+    Vector<SVGGlyph> glyphs;
+    if (!unicodeRanges.isEmpty()) {
+        const UnicodeRanges::const_iterator end = unicodeRanges.end();
+        for (UnicodeRanges::const_iterator it = unicodeRanges.begin(); it != end; ++it)
+            m_glyphMap.collectGlyphsForUnicodeRange(*it, glyphs);
+    }
+    if (!unicodeNames.isEmpty()) {
+        const HashSet<String>::const_iterator end = unicodeNames.end();
+        for (HashSet<String>::const_iterator it = unicodeNames.begin(); it != end; ++it)
+            m_glyphMap.collectGlyphsForStringExact(*it, glyphs);
+    }
+    if (!glyphNames.isEmpty()) {
+        const HashSet<String>::const_iterator end = glyphNames.end();
+        for (HashSet<String>::const_iterator it = glyphNames.begin(); it != end; ++it) {
+            const SVGGlyph& glyph = m_glyphMap.glyphIdentifierForGlyphName(*it);
+            if (glyph.tableEntry)
+                glyphs.append(glyph);
+        }
+    }
+    return glyphs;
+}
+
+void SVGFontElement::addPairsToKerningTable(const SVGKerningPair& kerningPair, KerningTable& kerningTable)
+{
+    Vector<SVGGlyph> glyphsLhs = buildGlyphList(kerningPair.unicodeRange1, kerningPair.unicodeName1, kerningPair.glyphName1);
+    Vector<SVGGlyph> glyphsRhs = buildGlyphList(kerningPair.unicodeRange2, kerningPair.unicodeName2, kerningPair.glyphName2);
+    if (glyphsLhs.isEmpty() || glyphsRhs.isEmpty())
+        return;
+    size_t glyphsLhsSize = glyphsLhs.size();
+    size_t glyphsRhsSize = glyphsRhs.size();
+    // Enumerate all the valid kerning pairs, and add them to the table.
+    for (size_t lhsIndex = 0; lhsIndex < glyphsLhsSize; ++lhsIndex) {
+        for (size_t rhsIndex = 0; rhsIndex < glyphsRhsSize; ++rhsIndex) {
+            Glyph glyph1 = glyphsLhs[lhsIndex].tableEntry;
+            Glyph glyph2 = glyphsRhs[rhsIndex].tableEntry;
+            ASSERT(glyph1 && glyph2);
+            kerningTable.add(makeKerningPairKey(glyph1, glyph2), kerningPair.kerning);
+        }
+    }
+}
+
+void SVGFontElement::buildKerningTable(const KerningPairVector& kerningPairs, KerningTable& kerningTable)
+{
+    size_t kerningPairsSize = kerningPairs.size();
+    for (size_t i = 0; i < kerningPairsSize; ++i)
+        addPairsToKerningTable(kerningPairs[i], kerningTable);
+}
+
 void SVGFontElement::ensureGlyphCache()
 {
     if (m_isGlyphCacheValid)
         return;
 
+    KerningPairVector horizontalKerningPairs;
+    KerningPairVector verticalKerningPairs;
+
     SVGMissingGlyphElement* firstMissingGlyphElement = 0;
     Vector<String> ligatures;
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
-        if (child->hasTagName(SVGNames::glyphTag)) {
-            SVGGlyphElement* glyph = toSVGGlyphElement(child);
-            AtomicString unicode = glyph->fastGetAttribute(SVGNames::unicodeAttr);
-            AtomicString glyphId = glyph->getIdAttribute();
+    for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
+        if (isSVGGlyphElement(*element)) {
+            SVGGlyphElement& glyph = toSVGGlyphElement(*element);
+            AtomicString unicode = glyph.fastGetAttribute(SVGNames::unicodeAttr);
+            AtomicString glyphId = glyph.getIdAttribute();
             if (glyphId.isEmpty() && unicode.isEmpty())
                 continue;
 
-            m_glyphMap.addGlyph(glyphId, unicode, glyph->buildGlyphIdentifier());
+            m_glyphMap.addGlyph(glyphId, unicode, glyph.buildGlyphIdentifier());
 
             // Register ligatures, if needed, don't mix up with surrogate pairs though!
             if (unicode.length() > 1 && !U16_IS_SURROGATE(unicode[0]))
                 ligatures.append(unicode.string());
-        } else if (child->hasTagName(SVGNames::hkernTag)) {
-            toSVGHKernElement(child)->buildHorizontalKerningPair(m_horizontalKerningPairs);
-        } else if (child->hasTagName(SVGNames::vkernTag)) {
-            toSVGVKernElement(child)->buildVerticalKerningPair(m_verticalKerningPairs);
-        } else if (child->hasTagName(SVGNames::missing_glyphTag) && !firstMissingGlyphElement) {
-            firstMissingGlyphElement = toSVGMissingGlyphElement(child);
+        } else if (isSVGHKernElement(*element)) {
+            toSVGHKernElement(*element).buildHorizontalKerningPair(horizontalKerningPairs);
+        } else if (isSVGVKernElement(*element)) {
+            toSVGVKernElement(*element).buildVerticalKerningPair(verticalKerningPairs);
+        } else if (isSVGMissingGlyphElement(*element) && !firstMissingGlyphElement) {
+            firstMissingGlyphElement = toSVGMissingGlyphElement(element);
         }
     }
 
+    // Build the kerning tables.
+    buildKerningTable(horizontalKerningPairs, m_horizontalKerningTable);
+    buildKerningTable(verticalKerningPairs, m_verticalKerningTable);
+
+    // The glyph-name->glyph-id map won't be needed/used after having built the kerning table(s).
+    m_glyphMap.dropNamedGlyphMap();
+
     // Register each character of each ligature, if needed.
     if (!ligatures.isEmpty())
         registerLigaturesInGlyphCache(ligatures);
@@ -155,76 +209,29 @@
     m_isGlyphCacheValid = true;
 }
 
-static bool stringMatchesUnicodeRange(const String& unicodeString, const UnicodeRanges& ranges, const HashSet<String>& unicodeValues)
+static float kerningForPairOfGlyphs(const KerningTable& kerningTable, Glyph glyphId1, Glyph glyphId2)
 {
-    if (unicodeString.isEmpty())
-        return false;
-
-    if (!ranges.isEmpty()) {
-        UChar firstChar = unicodeString[0];
-        const UnicodeRanges::const_iterator end = ranges.end();
-        for (UnicodeRanges::const_iterator it = ranges.begin(); it != end; ++it) {
-            if (firstChar >= it->first && firstChar <= it->second)
-                return true;
-        }
-    }
-
-    if (!unicodeValues.isEmpty())
-        return unicodeValues.contains(unicodeString);
-
-    return false;
-}
-
-static bool stringMatchesGlyphName(const String& glyphName, const HashSet<String>& glyphValues)
-{
-    if (glyphName.isEmpty())
-        return false;
-
-    if (!glyphValues.isEmpty())
-        return glyphValues.contains(glyphName);
-
-    return false;
-}
-
-static bool matches(const String& u1, const String& g1, const String& u2, const String& g2, const SVGKerningPair& kerningPair)
-{
-    if (!stringMatchesUnicodeRange(u1, kerningPair.unicodeRange1, kerningPair.unicodeName1)
-        && !stringMatchesGlyphName(g1, kerningPair.glyphName1))
-        return false;
-
-    if (!stringMatchesUnicodeRange(u2, kerningPair.unicodeRange2, kerningPair.unicodeName2)
-        && !stringMatchesGlyphName(g2, kerningPair.glyphName2))
-        return false;
-
-    return true;
-}
-
-static float kerningForPairOfStringsAndGlyphs(const KerningPairVector& kerningPairs, const String& u1, const String& g1, const String& u2, const String& g2)
-{
-    KerningPairVector::const_iterator it = kerningPairs.end() - 1;
-    const KerningPairVector::const_iterator begin = kerningPairs.begin() - 1;
-    for (; it != begin; --it) {
-        if (matches(u1, g1, u2, g2, *it))
-            return it->kerning;
-    }
+    KerningTable::const_iterator result = kerningTable.find(makeKerningPairKey(glyphId1, glyphId2));
+    if (result != kerningTable.end())
+        return result->value;
 
     return 0;
 }
 
-float SVGFontElement::horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const
+float SVGFontElement::horizontalKerningForPairOfGlyphs(Glyph glyphId1, Glyph glyphId2) const
 {
-    if (m_horizontalKerningPairs.isEmpty())
+    if (m_horizontalKerningTable.isEmpty())
         return 0;
 
-    return kerningForPairOfStringsAndGlyphs(m_horizontalKerningPairs, u1, g1, u2, g2);
+    return kerningForPairOfGlyphs(m_horizontalKerningTable, glyphId1, glyphId2);
 }
 
-float SVGFontElement::verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const
+float SVGFontElement::verticalKerningForPairOfGlyphs(Glyph glyphId1, Glyph glyphId2) const
 {
-    if (m_verticalKerningPairs.isEmpty())
+    if (m_verticalKerningTable.isEmpty())
         return 0;
 
-    return kerningForPairOfStringsAndGlyphs(m_verticalKerningPairs, u1, g1, u2, g2);
+    return kerningForPairOfGlyphs(m_verticalKerningTable, glyphId1, glyphId2);
 }
 
 void SVGFontElement::collectGlyphsForString(const String& string, Vector<SVGGlyph>& glyphs)
@@ -233,11 +240,11 @@
     m_glyphMap.collectGlyphsForString(string, glyphs);
 }
 
-void SVGFontElement::collectGlyphsForGlyphName(const String& glyphName, Vector<SVGGlyph>& glyphs)
+void SVGFontElement::collectGlyphsForAltGlyphReference(const String& glyphIdentifier, Vector<SVGGlyph>& glyphs)
 {
     ensureGlyphCache();
     // FIXME: We only support glyphName -> single glyph mapping so far.
-    glyphs.append(m_glyphMap.glyphIdentifierForGlyphName(glyphName));
+    glyphs.append(m_glyphMap.glyphIdentifierForAltGlyphReference(glyphIdentifier));
 }
 
 SVGGlyph SVGFontElement::svgGlyphForGlyph(Glyph glyph)
diff --git a/Source/core/svg/SVGFontElement.h b/Source/core/svg/SVGFontElement.h
index c0cea8c..df9fe58 100644
--- a/Source/core/svg/SVGFontElement.h
+++ b/Source/core/svg/SVGFontElement.h
@@ -47,7 +47,9 @@
     }
 };
 
+typedef unsigned KerningPairKey;
 typedef Vector<SVGKerningPair> KerningPairVector;
+typedef HashMap<KerningPairKey, float> KerningTable;
 
 class SVGMissingGlyphElement;
 
@@ -57,10 +59,10 @@
 
     void invalidateGlyphCache();
     void collectGlyphsForString(const String&, Vector<SVGGlyph>&);
-    void collectGlyphsForGlyphName(const String&, Vector<SVGGlyph>&);
+    void collectGlyphsForAltGlyphReference(const String&, Vector<SVGGlyph>&);
 
-    float horizontalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const;
-    float verticalKerningForPairOfStringsAndGlyphs(const String& u1, const String& g1, const String& u2, const String& g2) const;
+    float horizontalKerningForPairOfGlyphs(Glyph, Glyph) const;
+    float verticalKerningForPairOfGlyphs(Glyph, Glyph) const;
 
     // Used by SimpleFontData/WidthIterator.
     SVGGlyph svgGlyphForGlyph(Glyph);
@@ -75,19 +77,18 @@
 
     void ensureGlyphCache();
     void registerLigaturesInGlyphCache(Vector<String>&);
+    Vector<SVGGlyph> buildGlyphList(const UnicodeRanges&, const HashSet<String>& unicodeNames, const HashSet<String>& glyphNames) const;
+    void addPairsToKerningTable(const SVGKerningPair&, KerningTable&);
+    void buildKerningTable(const KerningPairVector&, KerningTable&);
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGFontElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
-    KerningPairVector m_horizontalKerningPairs;
-    KerningPairVector m_verticalKerningPairs;
+    KerningTable m_horizontalKerningTable;
+    KerningTable m_verticalKerningTable;
     SVGGlyphMap m_glyphMap;
     Glyph m_missingGlyph;
     bool m_isGlyphCacheValid;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFontElement, hasTagName(SVGNames::fontTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGFontFaceElement.cpp b/Source/core/svg/SVGFontFaceElement.cpp
index 1c142a7..5430c48 100644
--- a/Source/core/svg/SVGFontFaceElement.cpp
+++ b/Source/core/svg/SVGFontFaceElement.cpp
@@ -28,12 +28,14 @@
 #include "CSSPropertyNames.h"
 #include "CSSValueKeywords.h"
 #include "core/css/CSSFontFaceSrcValue.h"
+#include "core/css/CSSFontSelector.h"
 #include "core/css/CSSStyleSheet.h"
 #include "core/css/CSSValueList.h"
 #include "core/css/StylePropertySet.h"
 #include "core/css/StyleRule.h"
 #include "core/dom/Attribute.h"
 #include "core/dom/Document.h"
+#include "core/dom/StyleEngine.h"
 #include "core/svg/SVGDocumentExtensions.h"
 #include "core/svg/SVGFontElement.h"
 #include "core/svg/SVGFontFaceSrcElement.h"
@@ -111,7 +113,7 @@
 {
     CSSPropertyID propId = cssPropertyIdForFontFaceAttributeName(name);
     if (propId > 0) {
-        m_fontFaceRule->mutableProperties()->setProperty(propId, value, false);
+        m_fontFaceRule->mutableProperties().setProperty(propId, value, false);
         rebuildFontFace();
         return;
     }
@@ -256,13 +258,13 @@
 
 String SVGFontFaceElement::fontFamily() const
 {
-    return m_fontFaceRule->properties()->getPropertyValue(CSSPropertyFontFamily);
+    return m_fontFaceRule->properties().getPropertyValue(CSSPropertyFontFamily);
 }
 
 SVGFontElement* SVGFontFaceElement::associatedFontElement() const
 {
     ASSERT(parentNode() == m_fontElement);
-    ASSERT(!parentNode() || parentNode()->hasTagName(SVGNames::fontTag));
+    ASSERT(!parentNode() || isSVGFontElement(*parentNode()));
     return m_fontElement;
 }
 
@@ -273,7 +275,7 @@
         return;
     }
 
-    bool describesParentFont = parentNode()->hasTagName(SVGNames::fontTag);
+    bool describesParentFont = isSVGFontElement(*parentNode());
     RefPtrWillBeRawPtr<CSSValueList> list;
 
     if (describesParentFont) {
@@ -284,23 +286,19 @@
     } else {
         m_fontElement = 0;
         // we currently ignore all but the last src element, alternatively we could concat them
-        for (Node* child = lastChild(); child && !list; child = child->previousSibling()) {
-            if (child->hasTagName(font_face_srcTag)) {
-                list = toSVGFontFaceSrcElement(child)->srcValue();
-                break;
-            }
-        }
+        if (SVGFontFaceSrcElement* element = Traversal<SVGFontFaceSrcElement>::lastChild(*this))
+            list = element->srcValue();
     }
 
     if (!list || !list->length())
         return;
 
     // Parse in-memory CSS rules
-    m_fontFaceRule->mutableProperties()->addParsedProperty(CSSProperty(CSSPropertySrc, list));
+    m_fontFaceRule->mutableProperties().addParsedProperty(CSSProperty(CSSPropertySrc, list));
 
     if (describesParentFont) {
         // Traverse parsed CSS values and associate CSSFontFaceSrcValue elements with ourselves.
-        RefPtr<CSSValue> src = m_fontFaceRule->properties()->getPropertyCSSValue(CSSPropertySrc);
+        RefPtrWillBeRawPtr<CSSValue> src = m_fontFaceRule->properties().getPropertyCSSValue(CSSPropertySrc);
         CSSValueList* srcList = toCSSValueList(src.get());
 
         unsigned srcLength = srcList ? srcList->length() : 0;
@@ -320,7 +318,7 @@
         ASSERT(!m_fontElement);
         return InsertionDone;
     }
-    document().accessSVGExtensions()->registerSVGFontFaceElement(this);
+    document().accessSVGExtensions().registerSVGFontFaceElement(this);
 
     rebuildFontFace();
     return InsertionDone;
@@ -332,8 +330,13 @@
 
     if (rootParent->inDocument()) {
         m_fontElement = 0;
-        document().accessSVGExtensions()->unregisterSVGFontFaceElement(this);
-        m_fontFaceRule->mutableProperties()->clear();
+        document().accessSVGExtensions().unregisterSVGFontFaceElement(this);
+        // FIXME: HTMLTemplateElement's document or imported  document can be active?
+        // If so, we also need to check whether fontSelector() is nullptr or not.
+        // Otherwise, we will use just document().isActive() here.
+        if (document().isActive() && document().styleEngine()->fontSelector())
+            document().styleEngine()->fontSelector()->fontFaceCache()->remove(m_fontFaceRule.get());
+        m_fontFaceRule->mutableProperties().clear();
 
         document().styleResolverChanged(RecalcStyleDeferred);
     } else
diff --git a/Source/core/svg/SVGFontFaceElement.h b/Source/core/svg/SVGFontFaceElement.h
index 8406a14..8690053 100644
--- a/Source/core/svg/SVGFontFaceElement.h
+++ b/Source/core/svg/SVGFontFaceElement.h
@@ -63,12 +63,10 @@
 
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 
-    RefPtr<StyleRuleFontFace> m_fontFaceRule;
+    RefPtrWillBePersistent<StyleRuleFontFace> m_fontFaceRule;
     SVGFontElement* m_fontElement;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFontFaceElement, hasTagName(SVGNames::font_faceTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGFontFaceFormatElement.cpp b/Source/core/svg/SVGFontFaceFormatElement.cpp
index 5468bdb..5aaef55 100644
--- a/Source/core/svg/SVGFontFaceFormatElement.cpp
+++ b/Source/core/svg/SVGFontFaceFormatElement.cpp
@@ -44,15 +44,15 @@
 {
     SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!parentNode() || !parentNode()->hasTagName(font_face_uriTag))
+    if (!isSVGFontFaceUriElement(parentNode()))
         return;
 
     ContainerNode* ancestor = parentNode()->parentNode();
-    if (!ancestor || !ancestor->hasTagName(font_face_srcTag))
+    if (!isSVGFontFaceSrcElement(ancestor))
         return;
 
     ancestor = ancestor->parentNode();
-    if (ancestor && ancestor->hasTagName(font_faceTag))
+    if (isSVGFontFaceElement(ancestor))
         toSVGFontFaceElement(ancestor)->rebuildFontFace();
 }
 
diff --git a/Source/core/svg/SVGFontFaceNameElement.h b/Source/core/svg/SVGFontFaceNameElement.h
index 2f0cdab..de0ab7b 100644
--- a/Source/core/svg/SVGFontFaceNameElement.h
+++ b/Source/core/svg/SVGFontFaceNameElement.h
@@ -40,8 +40,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFontFaceNameElement, hasTagName(SVGNames::font_face_nameTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGFontFaceSource.cpp b/Source/core/svg/SVGFontFaceSource.cpp
new file mode 100644
index 0000000..ccacb8c
--- /dev/null
+++ b/Source/core/svg/SVGFontFaceSource.cpp
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+
+#if ENABLE(SVG_FONTS)
+#include "core/svg/SVGFontFaceSource.h"
+
+#include "core/svg/SVGFontData.h"
+#include "core/svg/SVGFontFaceElement.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+
+namespace WebCore {
+
+SVGFontFaceSource::SVGFontFaceSource(PassRefPtr<SVGFontFaceElement> element)
+    : m_svgFontFaceElement(element)
+{
+}
+
+PassRefPtr<SimpleFontData> SVGFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+    return SimpleFontData::create(
+        SVGFontData::create(m_svgFontFaceElement.get()),
+        fontDescription.effectiveFontSize(),
+        fontDescription.isSyntheticBold(),
+        fontDescription.isSyntheticItalic());
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGFontFaceSource.h b/Source/core/svg/SVGFontFaceSource.h
new file mode 100644
index 0000000..9211727
--- /dev/null
+++ b/Source/core/svg/SVGFontFaceSource.h
@@ -0,0 +1,29 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SVGFontFaceSource_h
+#define SVGFontFaceSource_h
+
+#if ENABLE(SVG_FONTS)
+
+#include "core/css/CSSFontFaceSource.h"
+
+namespace WebCore {
+
+class SVGFontFaceElement;
+
+class SVGFontFaceSource : public CSSFontFaceSource {
+public:
+    SVGFontFaceSource(PassRefPtr<SVGFontFaceElement>);
+
+private:
+    virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+    RefPtr<SVGFontFaceElement> m_svgFontFaceElement;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
+#endif
diff --git a/Source/core/svg/SVGFontFaceSrcElement.cpp b/Source/core/svg/SVGFontFaceSrcElement.cpp
index 5bb34db..f1cd5a5 100644
--- a/Source/core/svg/SVGFontFaceSrcElement.cpp
+++ b/Source/core/svg/SVGFontFaceSrcElement.cpp
@@ -25,6 +25,7 @@
 #include "SVGNames.h"
 #include "core/css/CSSFontFaceSrcValue.h"
 #include "core/css/CSSValueList.h"
+#include "core/dom/ElementTraversal.h"
 #include "core/svg/SVGFontFaceElement.h"
 #include "core/svg/SVGFontFaceNameElement.h"
 #include "core/svg/SVGFontFaceUriElement.h"
@@ -47,12 +48,12 @@
 PassRefPtrWillBeRawPtr<CSSValueList> SVGFontFaceSrcElement::srcValue() const
 {
     RefPtrWillBeRawPtr<CSSValueList> list = CSSValueList::createCommaSeparated();
-    for (Node* child = firstChild(); child; child = child->nextSibling()) {
+    for (SVGElement* element = Traversal<SVGElement>::firstChild(*this); element; element = Traversal<SVGElement>::nextSibling(*element)) {
         RefPtrWillBeRawPtr<CSSFontFaceSrcValue> srcValue;
-        if (child->hasTagName(font_face_uriTag))
-            srcValue = toSVGFontFaceUriElement(child)->srcValue();
-        else if (child->hasTagName(font_face_nameTag))
-            srcValue = toSVGFontFaceNameElement(child)->srcValue();
+        if (isSVGFontFaceUriElement(*element))
+            srcValue = toSVGFontFaceUriElement(*element).srcValue();
+        else if (isSVGFontFaceNameElement(*element))
+            srcValue = toSVGFontFaceNameElement(*element).srcValue();
 
         if (srcValue && srcValue->resource().length())
             list->append(srcValue);
@@ -63,8 +64,8 @@
 void SVGFontFaceSrcElement::childrenChanged(bool changedByParser, Node* beforeChange, Node* afterChange, int childCountDelta)
 {
     SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
-    if (parentNode() && parentNode()->hasTagName(font_faceTag))
-        toSVGFontFaceElement(parentNode())->rebuildFontFace();
+    if (isSVGFontFaceElement(parentNode()))
+        toSVGFontFaceElement(*parentNode()).rebuildFontFace();
 }
 
 }
diff --git a/Source/core/svg/SVGFontFaceSrcElement.h b/Source/core/svg/SVGFontFaceSrcElement.h
index 1d53c88..100acae 100644
--- a/Source/core/svg/SVGFontFaceSrcElement.h
+++ b/Source/core/svg/SVGFontFaceSrcElement.h
@@ -41,8 +41,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFontFaceSrcElement, hasTagName(SVGNames::font_face_srcTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGFontFaceUriElement.cpp b/Source/core/svg/SVGFontFaceUriElement.cpp
index f4b2b27..3f05f8a 100644
--- a/Source/core/svg/SVGFontFaceUriElement.cpp
+++ b/Source/core/svg/SVGFontFaceUriElement.cpp
@@ -71,12 +71,12 @@
 {
     SVGElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
 
-    if (!parentNode() || !parentNode()->hasTagName(font_face_srcTag))
+    if (!isSVGFontFaceSrcElement(parentNode()))
         return;
 
     ContainerNode* grandparent = parentNode()->parentNode();
-    if (grandparent && grandparent->hasTagName(font_faceTag))
-        toSVGFontFaceElement(grandparent)->rebuildFontFace();
+    if (isSVGFontFaceElement(grandparent))
+        toSVGFontFaceElement(*grandparent).rebuildFontFace();
 }
 
 Node::InsertionNotificationRequest SVGFontFaceUriElement::insertedInto(ContainerNode* rootParent)
diff --git a/Source/core/svg/SVGFontFaceUriElement.h b/Source/core/svg/SVGFontFaceUriElement.h
index c545bec..73c80e4 100644
--- a/Source/core/svg/SVGFontFaceUriElement.h
+++ b/Source/core/svg/SVGFontFaceUriElement.h
@@ -52,8 +52,6 @@
     ResourcePtr<FontResource> m_resource;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGFontFaceUriElement, hasTagName(SVGNames::font_face_uriTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGForeignObjectElement.cpp b/Source/core/svg/SVGForeignObjectElement.cpp
index 0a8428a..1dec0e0 100644
--- a/Source/core/svg/SVGForeignObjectElement.cpp
+++ b/Source/core/svg/SVGForeignObjectElement.cpp
@@ -30,12 +30,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGForeignObjectElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGForeignObjectElement::SVGForeignObjectElement(Document& document)
     : SVGGraphicsElement(SVGNames::foreignObjectTag, document)
     , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth)))
@@ -49,7 +43,6 @@
     addToPropertyMap(m_y);
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
-    registerAnimatedPropertiesForSVGForeignObjectElement();
 }
 
 PassRefPtr<SVGForeignObjectElement> SVGForeignObjectElement::create(Document& document)
diff --git a/Source/core/svg/SVGForeignObjectElement.h b/Source/core/svg/SVGForeignObjectElement.h
index 70a8aa5..3dfa6fa 100644
--- a/Source/core/svg/SVGForeignObjectElement.h
+++ b/Source/core/svg/SVGForeignObjectElement.h
@@ -53,12 +53,8 @@
     RefPtr<SVGAnimatedLength> m_y;
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGForeignObjectElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGForeignObjectElement, hasTagName(SVGNames::foreignObjectTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGGElement.cpp b/Source/core/svg/SVGGElement.cpp
index 88beb1b..ed9496e 100644
--- a/Source/core/svg/SVGGElement.cpp
+++ b/Source/core/svg/SVGGElement.cpp
@@ -30,17 +30,10 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 SVGGElement::SVGGElement(Document& document, ConstructionType constructionType)
     : SVGGraphicsElement(SVGNames::gTag, document, constructionType)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGGElement();
 }
 
 PassRefPtr<SVGGElement> SVGGElement::create(Document& document)
diff --git a/Source/core/svg/SVGGElement.h b/Source/core/svg/SVGGElement.h
index 3a7c85f..dfc0a05 100644
--- a/Source/core/svg/SVGGElement.h
+++ b/Source/core/svg/SVGGElement.h
@@ -44,8 +44,6 @@
 
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGGlyphElement.cpp b/Source/core/svg/SVGGlyphElement.cpp
index ace7f98..51866ba 100644
--- a/Source/core/svg/SVGGlyphElement.cpp
+++ b/Source/core/svg/SVGGlyphElement.cpp
@@ -44,8 +44,8 @@
 void SVGGlyphElement::invalidateGlyphCache()
 {
     ContainerNode* fontNode = parentNode();
-    if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
-        toSVGFontElement(fontNode)->invalidateGlyphCache();
+    if (isSVGFontElement(fontNode))
+        toSVGFontElement(*fontNode).invalidateGlyphCache();
 }
 
 void SVGGlyphElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
diff --git a/Source/core/svg/SVGGlyphElement.h b/Source/core/svg/SVGGlyphElement.h
index b4741e7..42f920f 100644
--- a/Source/core/svg/SVGGlyphElement.h
+++ b/Source/core/svg/SVGGlyphElement.h
@@ -58,8 +58,6 @@
     void invalidateGlyphCache();
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGGlyphElement, hasTagName(SVGNames::glyphTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGGlyphMap.h b/Source/core/svg/SVGGlyphMap.h
index 8e20f06..bfef32e 100644
--- a/Source/core/svg/SVGGlyphMap.h
+++ b/Source/core/svg/SVGGlyphMap.h
@@ -21,6 +21,7 @@
 #define SVGGlyphMap_h
 
 #if ENABLE(SVG_FONTS)
+#include "core/svg/SVGParserUtilities.h"
 #include "platform/fonts/Latin1TextIterator.h"
 #include "platform/fonts/SVGGlyph.h"
 #include "platform/text/SurrogatePairAwareTextIterator.h"
@@ -49,16 +50,16 @@
 public:
     SVGGlyphMap() : m_currentPriority(0) { }
 
-    void addGlyph(const String& glyphName, const String& unicodeString, SVGGlyph glyph)
+    void addGlyph(const String& glyphIdentifier, const String& unicodeString, SVGGlyph glyph)
     {
-        ASSERT(!glyphName.isEmpty() || !unicodeString.isEmpty());
+        ASSERT(!glyphIdentifier.isEmpty() || !unicodeString.isEmpty());
 
-        bool hasGlyphName = !glyphName.isEmpty();
+        bool hasGlyphIdentifier = !glyphIdentifier.isEmpty();
         if (unicodeString.isEmpty()) {
-            // Register named glyph in the named glyph map and in the glyph table.
-            ASSERT(hasGlyphName);
+            // Register glyphs with 'id's in the id glyph map and in the glyph table.
+            ASSERT(hasGlyphIdentifier);
             appendToGlyphTable(glyph);
-            m_namedGlyphs.add(glyphName, glyph.tableEntry);
+            m_idGlyphs.add(glyphIdentifier, glyph.tableEntry);
             return;
         }
 
@@ -83,8 +84,10 @@
 
         // If the glyph is named, also add it to the named glyph name, and to the glyph table in both cases.
         appendToGlyphTable(lastGlyph);
-        if (hasGlyphName)
-            m_namedGlyphs.add(glyphName, lastGlyph.tableEntry);
+        if (!lastGlyph.glyphName.isEmpty())
+            m_namedGlyphs.add(lastGlyph.glyphName, lastGlyph.tableEntry);
+        if (hasGlyphIdentifier)
+            m_idGlyphs.add(glyphIdentifier, lastGlyph.tableEntry);
     }
 
     void appendToGlyphTable(SVGGlyph& glyph)
@@ -120,13 +123,48 @@
         std::sort(glyphs.begin(), glyphs.end(), compareGlyphPriority);
     }
 
+    void collectGlyphsForStringExact(const String& string, Vector<SVGGlyph>& glyphs) const
+    {
+        unsigned length = string.length();
+
+        if (!length)
+            return;
+
+        RefPtr<GlyphMapNode> node;
+        if (string.is8Bit()) {
+            Latin1TextIterator textIterator(string.characters8(), 0, length, length);
+            node = findNode(textIterator);
+        } else {
+            SurrogatePairAwareTextIterator textIterator(string.characters16(), 0, length, length);
+            node = findNode(textIterator);
+        }
+
+        if (node)
+            glyphs.appendVector(node->glyphs);
+    }
+
+    void collectGlyphsForUnicodeRange(const UnicodeRange& unicodeRange, Vector<SVGGlyph>& glyphs) const
+    {
+        for (unsigned character = unicodeRange.first; character <= unicodeRange.second; ++character) {
+            if (RefPtr<GlyphMapNode> node = m_rootLayer.get(character))
+                glyphs.appendVector(node->glyphs);
+        }
+    }
+
     void clear()
     {
         m_rootLayer.clear();
         m_glyphTable.clear();
+        m_idGlyphs.clear();
+        m_namedGlyphs.clear();
         m_currentPriority = 0;
     }
 
+    void dropNamedGlyphMap()
+    {
+        m_namedGlyphs.clear();
+    }
+
     const SVGGlyph& svgGlyphForGlyph(Glyph glyph) const
     {
         if (!glyph || glyph > m_glyphTable.size()) {
@@ -136,6 +174,11 @@
         return m_glyphTable[glyph - 1];
     }
 
+    const SVGGlyph& glyphIdentifierForAltGlyphReference(const String& glyphIdentifier) const
+    {
+        return svgGlyphForGlyph(m_idGlyphs.get(glyphIdentifier));
+    }
+
     const SVGGlyph& glyphIdentifierForGlyphName(const String& glyphName) const
     {
         return svgGlyphForGlyph(m_namedGlyphs.get(glyphName));
@@ -164,6 +207,25 @@
     }
 
     template<typename Iterator>
+    PassRefPtr<GlyphMapNode> findNode(Iterator& textIterator) const
+    {
+        const GlyphMapLayer* currentLayer = &m_rootLayer;
+
+        RefPtr<GlyphMapNode> node;
+        UChar32 character = 0;
+        unsigned clusterLength = 0;
+        while (textIterator.consume(character, clusterLength)) {
+            node = currentLayer->get(character);
+            if (!node)
+                break;
+            currentLayer = &node->children;
+            textIterator.advance(clusterLength);
+        }
+
+        return node.release();
+    }
+
+    template<typename Iterator>
     void collectGlyphsForIterator(Iterator& textIterator, Vector<SVGGlyph>& glyphs)
     {
         GlyphMapLayer* currentLayer = &m_rootLayer;
@@ -174,7 +236,7 @@
             RefPtr<GlyphMapNode> node = currentLayer->get(character);
             if (!node)
                 break;
-            glyphs.append(node->glyphs);
+            glyphs.appendVector(node->glyphs);
             currentLayer = &node->children;
             textIterator.advance(clusterLength);
         }
@@ -183,6 +245,7 @@
     GlyphMapLayer m_rootLayer;
     Vector<SVGGlyph> m_glyphTable;
     HashMap<String, Glyph> m_namedGlyphs;
+    HashMap<String, Glyph> m_idGlyphs;
     int m_currentPriority;
 };
 
diff --git a/Source/core/svg/SVGGlyphRefElement.cpp b/Source/core/svg/SVGGlyphRefElement.cpp
index 2385cad..1d62b08 100644
--- a/Source/core/svg/SVGGlyphRefElement.cpp
+++ b/Source/core/svg/SVGGlyphRefElement.cpp
@@ -28,12 +28,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGlyphRefElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGGlyphRefElement::SVGGlyphRefElement(Document& document)
     : SVGElement(SVGNames::glyphRefTag, document)
     , SVGURIReference(this)
@@ -43,7 +37,6 @@
     , m_dy(0)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGGlyphRefElement();
 }
 
 PassRefPtr<SVGGlyphRefElement> SVGGlyphRefElement::create(Document& document)
@@ -56,9 +49,7 @@
     // FIXME: We only support xlink:href so far.
     // https://bugs.webkit.org/show_bug.cgi?id=64787
     Element* element = targetElementFromIRIString(getAttribute(XLinkNames::hrefAttr), document(), &glyphName);
-    if (!element || !element->hasTagName(SVGNames::glyphTag))
-        return false;
-    return true;
+    return isSVGGlyphElement(element);
 }
 
 template<typename CharType>
diff --git a/Source/core/svg/SVGGlyphRefElement.h b/Source/core/svg/SVGGlyphRefElement.h
index 259da0e..509e99e 100644
--- a/Source/core/svg/SVGGlyphRefElement.h
+++ b/Source/core/svg/SVGGlyphRefElement.h
@@ -55,8 +55,6 @@
 
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGlyphRefElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     float m_x;
     float m_y;
@@ -64,8 +62,6 @@
     float m_dy;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGGlyphRefElement, hasTagName(SVGNames::glyphRefTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGGradientElement.cpp b/Source/core/svg/SVGGradientElement.cpp
index 6d1ca06..68229f9 100644
--- a/Source/core/svg/SVGGradientElement.cpp
+++ b/Source/core/svg/SVGGradientElement.cpp
@@ -35,26 +35,29 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGGradientElement, SVGNames::spreadMethodAttr, SpreadMethod, spreadMethod, SVGSpreadMethodType)
-DEFINE_ANIMATED_ENUMERATION(SVGGradientElement, SVGNames::gradientUnitsAttr, GradientUnits, gradientUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_TRANSFORM_LIST(SVGGradientElement, SVGNames::gradientTransformAttr, GradientTransform, gradientTransform)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGradientElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(spreadMethod)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(gradientUnits)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(gradientTransform)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGSpreadMethodType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVGSpreadMethodUnknown, emptyString()));
+        entries.append(std::make_pair(SVGSpreadMethodPad, "pad"));
+        entries.append(std::make_pair(SVGSpreadMethodReflect, "reflect"));
+        entries.append(std::make_pair(SVGSpreadMethodRepeat, "repeat"));
+    }
+    return entries;
+}
 
 SVGGradientElement::SVGGradientElement(const QualifiedName& tagName, Document& document)
     : SVGElement(tagName, document)
     , SVGURIReference(this)
-    , m_spreadMethod(SVGSpreadMethodPad)
-    , m_gradientUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
+    , m_gradientTransform(SVGAnimatedTransformList::create(this, SVGNames::gradientTransformAttr, SVGTransformList::create()))
+    , m_spreadMethod(SVGAnimatedEnumeration<SVGSpreadMethodType>::create(this, SVGNames::spreadMethodAttr, SVGSpreadMethodPad))
+    , m_gradientUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::gradientUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGGradientElement();
+    addToPropertyMap(m_gradientTransform);
+    addToPropertyMap(m_spreadMethod);
+    addToPropertyMap(m_gradientUnits);
 }
 
 bool SVGGradientElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -76,34 +79,17 @@
         return;
     }
 
-    if (name == SVGNames::gradientUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setGradientUnitsBaseValue(propertyValue);
-        return;
-    }
-
-    if (name == SVGNames::gradientTransformAttr) {
-        SVGTransformList newList;
-        newList.parse(value);
-        detachAnimatedGradientTransformListWrappers(newList.size());
-        setGradientTransformBaseValue(newList);
-        return;
-    }
-
-    if (name == SVGNames::spreadMethodAttr) {
-        SVGSpreadMethodType propertyValue = SVGPropertyTraits<SVGSpreadMethodType>::fromString(value);
-        if (propertyValue > 0)
-            setSpreadMethodBaseValue(propertyValue);
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
-    if (SVGURIReference::parseAttribute(name, value, parseError)) {
-    } else {
+    if (name == SVGNames::gradientTransformAttr)
+        m_gradientTransform->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::gradientUnitsAttr)
+        m_gradientUnits->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::spreadMethodAttr)
+        m_spreadMethod->setBaseValueAsString(value, parseError);
+    else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+    } else
         ASSERT_NOT_REACHED();
-    }
 
     reportAttributeParsingError(parseError, name, value);
 }
@@ -138,25 +124,13 @@
     Vector<Gradient::ColorStop> stops;
 
     float previousOffset = 0.0f;
-    for (Node* n = firstChild(); n; n = n->nextSibling()) {
-        SVGElement* element = n->isSVGElement() ? toSVGElement(n) : 0;
-        if (!element || !element->isGradientStop())
-            continue;
-
-        SVGStopElement* stop = toSVGStopElement(element);
-        Color color = stop->stopColorIncludingOpacity();
-
+    for (SVGStopElement* stop = Traversal<SVGStopElement>::firstChild(*this); stop; stop = Traversal<SVGStopElement>::nextSibling(*stop)) {
         // Figure out right monotonic offset
         float offset = stop->offset()->currentValue()->value();
         offset = std::min(std::max(previousOffset, offset), 1.0f);
         previousOffset = offset;
 
-        // Extract individual channel values
-        // FIXME: Why doesn't ColorStop take a Color and an offset??
-        float r, g, b, a;
-        color.getRGBA(r, g, b, a);
-
-        stops.append(Gradient::ColorStop(offset, r, g, b, a));
+        stops.append(Gradient::ColorStop(offset, stop->stopColorIncludingOpacity()));
     }
 
     return stops;
diff --git a/Source/core/svg/SVGGradientElement.h b/Source/core/svg/SVGGradientElement.h
index e57eb6b..1b90734 100644
--- a/Source/core/svg/SVGGradientElement.h
+++ b/Source/core/svg/SVGGradientElement.h
@@ -38,39 +38,7 @@
     SVGSpreadMethodReflect,
     SVGSpreadMethodRepeat
 };
-
-template<>
-struct SVGPropertyTraits<SVGSpreadMethodType> {
-    static unsigned highestEnumValue() { return SVGSpreadMethodRepeat; }
-
-    static String toString(SVGSpreadMethodType type)
-    {
-        switch (type) {
-        case SVGSpreadMethodUnknown:
-            return emptyString();
-        case SVGSpreadMethodPad:
-            return "pad";
-        case SVGSpreadMethodReflect:
-            return "reflect";
-        case SVGSpreadMethodRepeat:
-            return "repeat";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static SVGSpreadMethodType fromString(const String& value)
-    {
-        if (value == "pad")
-            return SVGSpreadMethodPad;
-        if (value == "reflect")
-            return SVGSpreadMethodReflect;
-        if (value == "repeat")
-            return SVGSpreadMethodRepeat;
-        return SVGSpreadMethodUnknown;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGSpreadMethodType>();
 
 class SVGGradientElement : public SVGElement,
                            public SVGURIReference {
@@ -84,6 +52,10 @@
 
     Vector<Gradient::ColorStop> buildStops();
 
+    SVGAnimatedTransformList* gradientTransform() { return m_gradientTransform.get(); }
+    SVGAnimatedEnumeration<SVGSpreadMethodType>* spreadMethod() { return m_spreadMethod.get(); }
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* gradientUnits() { return m_gradientUnits.get(); }
+
 protected:
     SVGGradientElement(const QualifiedName&, Document&);
 
@@ -96,11 +68,9 @@
 
     virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0) OVERRIDE FINAL;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGradientElement)
-        DECLARE_ANIMATED_ENUMERATION(SpreadMethod, spreadMethod, SVGSpreadMethodType)
-        DECLARE_ANIMATED_ENUMERATION(GradientUnits, gradientUnits, SVGUnitTypes::SVGUnitType)
-        DECLARE_ANIMATED_TRANSFORM_LIST(GradientTransform, gradientTransform)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedTransformList> m_gradientTransform;
+    RefPtr<SVGAnimatedEnumeration<SVGSpreadMethodType> > m_spreadMethod;
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_gradientUnits;
 };
 
 inline bool isSVGGradientElement(const Node& node)
@@ -108,7 +78,7 @@
     return node.hasTagName(SVGNames::radialGradientTag) || node.hasTagName(SVGNames::linearGradientTag);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGGradientElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGradientElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGGraphicsElement.cpp b/Source/core/svg/SVGGraphicsElement.cpp
index b02670e..6d66cff 100644
--- a/Source/core/svg/SVGGraphicsElement.cpp
+++ b/Source/core/svg/SVGGraphicsElement.cpp
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -31,26 +32,19 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_TRANSFORM_LIST(SVGGraphicsElement, SVGNames::transformAttr, Transform, transform)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGGraphicsElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(transform)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 SVGGraphicsElement::SVGGraphicsElement(const QualifiedName& tagName, Document& document, ConstructionType constructionType)
     : SVGElement(tagName, document, constructionType)
     , SVGTests(this)
+    , m_transform(SVGAnimatedTransformList::create(this, SVGNames::transformAttr, SVGTransformList::create()))
 {
-    registerAnimatedPropertiesForSVGGraphicsElement();
+    addToPropertyMap(m_transform);
 }
 
 SVGGraphicsElement::~SVGGraphicsElement()
 {
 }
 
-AffineTransform SVGGraphicsElement::getTransformToElement(SVGElement* target, ExceptionState& exceptionState)
+PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getTransformToElement(SVGElement* target, ExceptionState& exceptionState)
 {
     AffineTransform ctm = getCTM(AllowStyleUpdate);
 
@@ -58,32 +52,51 @@
         AffineTransform targetCTM = toSVGGraphicsElement(target)->getCTM(AllowStyleUpdate);
         if (!targetCTM.isInvertible()) {
             exceptionState.throwDOMException(InvalidStateError, "The target transformation is not invertable.");
-            return ctm;
+            return nullptr;
         }
         ctm = targetCTM.inverse() * ctm;
     }
 
-    return ctm;
+    return SVGMatrixTearOff::create(ctm);
 }
 
-static AffineTransform computeCTM(SVGGraphicsElement* element, SVGElement::CTMScope mode, SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy)
+static bool isViewportElement(const Element& element)
 {
-    ASSERT(element);
-    if (styleUpdateStrategy == SVGGraphicsElement::AllowStyleUpdate)
-        element->document().updateLayoutIgnorePendingStylesheets();
+    return (isSVGSVGElement(element)
+        || isSVGSymbolElement(element)
+        || isSVGForeignObjectElement(element)
+        || isSVGImageElement(element));
+}
+
+AffineTransform SVGGraphicsElement::computeCTM(SVGElement::CTMScope mode,
+    SVGGraphicsElement::StyleUpdateStrategy styleUpdateStrategy, const SVGGraphicsElement* ancestor) const
+{
+    if (styleUpdateStrategy == AllowStyleUpdate)
+        document().updateLayoutIgnorePendingStylesheets();
 
     AffineTransform ctm;
+    bool done = false;
 
-    SVGElement* stopAtElement = mode == SVGGraphicsElement::NearestViewportScope ? element->nearestViewportElement() : 0;
-    for (Element* currentElement = element; currentElement; currentElement = currentElement->parentOrShadowHostElement()) {
+    for (const Element* currentElement = this; currentElement && !done;
+        currentElement = currentElement->parentOrShadowHostElement()) {
         if (!currentElement->isSVGElement())
             break;
 
         ctm = toSVGElement(currentElement)->localCoordinateSpaceTransform(mode).multiply(ctm);
 
-        // For getCTM() computation, stop at the nearest viewport element
-        if (currentElement == stopAtElement)
+        switch (mode) {
+        case NearestViewportScope:
+            // Stop at the nearest viewport ancestor.
+            done = currentElement != this && isViewportElement(*currentElement);
             break;
+        case AncestorScope:
+            // Stop at the designated ancestor.
+            done = currentElement == ancestor;
+            break;
+        default:
+            ASSERT(mode == ScreenScope);
+            break;
+        }
     }
 
     return ctm;
@@ -91,12 +104,22 @@
 
 AffineTransform SVGGraphicsElement::getCTM(StyleUpdateStrategy styleUpdateStrategy)
 {
-    return computeCTM(this, NearestViewportScope, styleUpdateStrategy);
+    return computeCTM(NearestViewportScope, styleUpdateStrategy);
 }
 
 AffineTransform SVGGraphicsElement::getScreenCTM(StyleUpdateStrategy styleUpdateStrategy)
 {
-    return computeCTM(this, ScreenScope, styleUpdateStrategy);
+    return computeCTM(ScreenScope, styleUpdateStrategy);
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getCTMFromJavascript()
+{
+    return SVGMatrixTearOff::create(getCTM());
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGGraphicsElement::getScreenCTMFromJavascript()
+{
+    return SVGMatrixTearOff::create(getScreenCTM());
 }
 
 AffineTransform SVGGraphicsElement::animatedLocalTransform() const
@@ -122,7 +145,7 @@
             matrix.setF(matrix.f() / zoom);
         }
     } else {
-        transformCurrentValue().concatenate(matrix);
+        m_transform->currentValue()->concatenate(matrix);
     }
 
     if (m_supplementalTransform)
@@ -154,17 +177,16 @@
         return;
     }
 
-    if (name == SVGNames::transformAttr) {
-        SVGTransformList newList;
-        newList.parse(value);
-        detachAnimatedTransformListWrappers(newList.size());
-        setTransformBaseValue(newList);
-        return;
-    } else if (SVGTests::parseAttribute(name, value)) {
-        return;
-    }
+    SVGParsingError parseError = NoError;
 
-    ASSERT_NOT_REACHED();
+    if (name == SVGNames::transformAttr)
+        m_transform->setBaseValueAsString(value, parseError);
+    else if (SVGTests::parseAttribute(name, value))
+        return;
+    else
+        ASSERT_NOT_REACHED();
+
+    reportAttributeParsingError(parseError, name, value);
 }
 
 void SVGGraphicsElement::svgAttributeChanged(const QualifiedName& attrName)
@@ -195,18 +217,10 @@
     ASSERT_NOT_REACHED();
 }
 
-static bool isViewportElement(Node* node)
-{
-    return (node->hasTagName(SVGNames::svgTag)
-        || node->hasTagName(SVGNames::symbolTag)
-        || node->hasTagName(SVGNames::foreignObjectTag)
-        || node->hasTagName(SVGNames::imageTag));
-}
-
 SVGElement* SVGGraphicsElement::nearestViewportElement() const
 {
     for (Element* current = parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) {
-        if (isViewportElement(current))
+        if (isViewportElement(*current))
             return toSVGElement(current);
     }
 
@@ -217,7 +231,7 @@
 {
     SVGElement* farthest = 0;
     for (Element* current = parentOrShadowHostElement(); current; current = current->parentOrShadowHostElement()) {
-        if (isViewportElement(current))
+        if (isViewportElement(*current))
             farthest = toSVGElement(current);
     }
     return farthest;
diff --git a/Source/core/svg/SVGGraphicsElement.h b/Source/core/svg/SVGGraphicsElement.h
index 8e1f311..1f14744 100644
--- a/Source/core/svg/SVGGraphicsElement.h
+++ b/Source/core/svg/SVGGraphicsElement.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -30,6 +31,7 @@
 
 class AffineTransform;
 class Path;
+class SVGMatrixTearOff;
 
 class SVGGraphicsElement : public SVGElement, public SVGTests {
 public:
@@ -39,7 +41,11 @@
 
     AffineTransform getCTM(StyleUpdateStrategy = AllowStyleUpdate);
     AffineTransform getScreenCTM(StyleUpdateStrategy = AllowStyleUpdate);
-    AffineTransform getTransformToElement(SVGElement*, ExceptionState&);
+    PassRefPtr<SVGMatrixTearOff> getCTMFromJavascript();
+    PassRefPtr<SVGMatrixTearOff> getScreenCTMFromJavascript();
+
+    PassRefPtr<SVGMatrixTearOff> getTransformToElement(SVGElement*, ExceptionState&);
+
     SVGElement* nearestViewportElement() const;
     SVGElement* farthestViewportElement() const;
 
@@ -56,6 +62,12 @@
 
     virtual bool isValid() const OVERRIDE FINAL { return SVGTests::isValid(); }
 
+    SVGAnimatedTransformList* transform() { return m_transform.get(); }
+    const SVGAnimatedTransformList* transform() const { return m_transform.get(); }
+
+    AffineTransform computeCTM(SVGElement::CTMScope mode, SVGGraphicsElement::StyleUpdateStrategy,
+        const SVGGraphicsElement* ancestor = 0) const;
+
 protected:
     SVGGraphicsElement(const QualifiedName&, Document&, ConstructionType = CreateSVGElement);
 
@@ -63,9 +75,7 @@
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
     virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGGraphicsElement)
-        DECLARE_ANIMATED_TRANSFORM_LIST(Transform, transform)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedTransformList> m_transform;
 
 private:
     virtual bool isSVGGraphicsElement() const OVERRIDE FINAL { return true; }
@@ -79,7 +89,7 @@
     return node.isSVGElement() && toSVGElement(node).isSVGGraphicsElement();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGGraphicsElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGGraphicsElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGGraphicsElement.idl b/Source/core/svg/SVGGraphicsElement.idl
index 7666cdc..f1de0b0 100644
--- a/Source/core/svg/SVGGraphicsElement.idl
+++ b/Source/core/svg/SVGGraphicsElement.idl
@@ -28,16 +28,18 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGGraphicsElement : SVGElement {
+[
+    StrictTypeChecking,
+] interface SVGGraphicsElement : SVGElement {
     readonly attribute SVGAnimatedTransformList transform;
 
     [MeasureAs=SVGLocatableNearestViewportElement] readonly attribute SVGElement nearestViewportElement;
     [MeasureAs=SVGLocatableFarthestViewportElement] readonly attribute SVGElement farthestViewportElement;
 
     [ImplementedAs=getBBoxFromJavascript] SVGRect getBBox();
-    SVGMatrix getCTM();
-    SVGMatrix getScreenCTM();
-    [RaisesException] SVGMatrix getTransformToElement([Default=Undefined] optional SVGElement element);
+    [ImplementedAs=getCTMFromJavascript] SVGMatrix getCTM();
+    [ImplementedAs=getScreenCTMFromJavascript] SVGMatrix getScreenCTM();
+    [RaisesException] SVGMatrix getTransformToElement(SVGElement element);
 };
 
 SVGGraphicsElement implements SVGTests;
diff --git a/Source/core/svg/SVGHKernElement.cpp b/Source/core/svg/SVGHKernElement.cpp
index cfd9229..29042cd 100644
--- a/Source/core/svg/SVGHKernElement.cpp
+++ b/Source/core/svg/SVGHKernElement.cpp
@@ -41,8 +41,8 @@
 Node::InsertionNotificationRequest SVGHKernElement::insertedInto(ContainerNode* rootParent)
 {
     ContainerNode* fontNode = parentNode();
-    if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
-        toSVGFontElement(fontNode)->invalidateGlyphCache();
+    if (isSVGFontElement(fontNode))
+        toSVGFontElement(*fontNode).invalidateGlyphCache();
 
     return SVGElement::insertedInto(rootParent);
 }
@@ -50,8 +50,8 @@
 void SVGHKernElement::removedFrom(ContainerNode* rootParent)
 {
     ContainerNode* fontNode = parentNode();
-    if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
-        toSVGFontElement(fontNode)->invalidateGlyphCache();
+    if (isSVGFontElement(fontNode))
+        toSVGFontElement(*fontNode).invalidateGlyphCache();
 
     SVGElement::removedFrom(rootParent);
 }
diff --git a/Source/core/svg/SVGHKernElement.h b/Source/core/svg/SVGHKernElement.h
index 7cb6665..cfecedf 100644
--- a/Source/core/svg/SVGHKernElement.h
+++ b/Source/core/svg/SVGHKernElement.h
@@ -43,8 +43,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGHKernElement, hasTagName(SVGNames::hkernTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGImageElement.cpp b/Source/core/svg/SVGImageElement.cpp
index 21ed9fe..083d2a8 100644
--- a/Source/core/svg/SVGImageElement.cpp
+++ b/Source/core/svg/SVGImageElement.cpp
@@ -32,12 +32,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGImageElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGImageElement::SVGImageElement(Document& document)
     : SVGGraphicsElement(SVGNames::imageTag, document)
     , SVGURIReference(this)
@@ -47,6 +41,7 @@
     , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight)))
     , m_preserveAspectRatio(SVGAnimatedPreserveAspectRatio::create(this, SVGNames::preserveAspectRatioAttr, SVGPreserveAspectRatio::create()))
     , m_imageLoader(this)
+    , m_needsLoaderURIUpdate(true)
 {
     ScriptWrappable::init(this);
 
@@ -54,9 +49,7 @@
     addToPropertyMap(m_y);
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
-
     addToPropertyMap(m_preserveAspectRatio);
-    registerAnimatedPropertiesForSVGImageElement();
 }
 
 PassRefPtr<SVGImageElement> SVGImageElement::create(Document& document)
@@ -149,7 +142,10 @@
         updateRelativeLengthsInformation();
 
     if (SVGURIReference::isKnownAttribute(attrName)) {
-        m_imageLoader.updateFromElementIgnoringPreviousError();
+        if (inDocument())
+            m_imageLoader.updateFromElementIgnoringPreviousError();
+        else
+            m_needsLoaderURIUpdate = true;
         return;
     }
 
@@ -186,7 +182,7 @@
 
 bool SVGImageElement::haveLoadedRequiredResources()
 {
-    return !m_imageLoader.hasPendingActivity();
+    return !m_needsLoaderURIUpdate && !m_imageLoader.hasPendingActivity();
 }
 
 void SVGImageElement::attach(const AttachContext& context)
@@ -206,9 +202,19 @@
     SVGGraphicsElement::insertedInto(rootParent);
     if (!rootParent->inDocument())
         return InsertionDone;
-    // Update image loader, as soon as we're living in the tree.
-    // We can only resolve base URIs properly, after that!
-    m_imageLoader.updateFromElement();
+
+    // We can only resolve base URIs properly after tree insertion - hence, URI mutations while
+    // detached are deferred until this point.
+    if (m_needsLoaderURIUpdate) {
+        m_imageLoader.updateFromElementIgnoringPreviousError();
+        m_needsLoaderURIUpdate = false;
+    } else {
+        // A previous loader update may have failed to actually fetch the image if the document
+        // was inactive. In that case, force a re-update (but don't clear previous errors).
+        if (!m_imageLoader.image())
+            m_imageLoader.updateFromElement();
+    }
+
     return InsertionDone;
 }
 
diff --git a/Source/core/svg/SVGImageElement.h b/Source/core/svg/SVGImageElement.h
index f3bf328..95aa39e 100644
--- a/Source/core/svg/SVGImageElement.h
+++ b/Source/core/svg/SVGImageElement.h
@@ -73,14 +73,11 @@
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
     RefPtr<SVGAnimatedPreserveAspectRatio> m_preserveAspectRatio;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGImageElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     SVGImageLoader m_imageLoader;
+    bool m_needsLoaderURIUpdate : 1;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGImageElement, hasTagName(SVGNames::imageTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGLengthContext.cpp b/Source/core/svg/SVGLengthContext.cpp
index d168eb5..31b54e1 100644
--- a/Source/core/svg/SVGLengthContext.cpp
+++ b/Source/core/svg/SVGLengthContext.cpp
@@ -24,6 +24,7 @@
 #include "core/svg/SVGLengthContext.h"
 
 #include "SVGNames.h"
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "core/css/CSSHelper.h"
 #include "core/dom/ExceptionCode.h"
@@ -109,7 +110,7 @@
 
     switch (fromUnit) {
     case LengthTypeUnknown:
-        exceptionState.throwDOMException(NotSupportedError, "The fromUnit provided is invalid.");
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(3, "SVGLengthType"));
         return 0;
     case LengthTypeNumber:
         return value;
@@ -141,7 +142,7 @@
 {
     switch (toUnit) {
     case LengthTypeUnknown:
-        exceptionState.throwDOMException(NotSupportedError, "The toUnit provided is invalid.");
+        exceptionState.throwDOMException(NotSupportedError, ExceptionMessages::argumentNullOrIncorrectType(3, "SVGLengthType"));
         return 0;
     case LengthTypeNumber:
         return value;
@@ -307,13 +308,13 @@
 
     // Take size from nearest viewport element.
     SVGElement* viewportElement = m_context->viewportElement();
-    if (!viewportElement || !viewportElement->isSVGSVGElement())
+    if (!isSVGSVGElement(viewportElement))
         return false;
 
-    const SVGSVGElement* svg = toSVGSVGElement(viewportElement);
-    viewportSize = svg->currentViewBoxRect().size();
+    const SVGSVGElement& svg = toSVGSVGElement(*viewportElement);
+    viewportSize = svg.currentViewBoxRect().size();
     if (viewportSize.isEmpty())
-        viewportSize = svg->currentViewportSize();
+        viewportSize = svg.currentViewportSize();
 
     return true;
 }
diff --git a/Source/core/svg/SVGLengthList.cpp b/Source/core/svg/SVGLengthList.cpp
index e6dbf56..c967231 100644
--- a/Source/core/svg/SVGLengthList.cpp
+++ b/Source/core/svg/SVGLengthList.cpp
@@ -119,11 +119,11 @@
 {
     RefPtr<SVGLengthList> otherList = toSVGLengthList(other);
 
-    if (numberOfItems() != otherList->numberOfItems())
+    if (length() != otherList->length())
         return;
 
     SVGLengthContext lengthContext(contextElement);
-    for (size_t i = 0; i < numberOfItems(); ++i)
+    for (size_t i = 0; i < length(); ++i)
         at(i)->setValue(at(i)->value(lengthContext) + otherList->at(i)->value(lengthContext), lengthContext, ASSERT_NO_EXCEPTION);
 }
 
@@ -133,12 +133,12 @@
     RefPtr<SVGLengthList> toList = passToList;
 
     // If no 'to' value is given, nothing to animate.
-    size_t toListSize = toList->numberOfItems();
+    size_t toListSize = toList->length();
     if (!toListSize)
         return false;
 
     // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
-    size_t fromListSize = fromList->numberOfItems();
+    size_t fromListSize = fromList->length();
     if (fromListSize != toListSize && fromListSize) {
         if (percentage < 0.5) {
             if (!isToAnimation)
@@ -151,8 +151,8 @@
     }
 
     ASSERT(!fromListSize || fromListSize == toListSize);
-    if (resizeAnimatedListIfNeeded && numberOfItems() < toListSize) {
-        size_t paddingCount = toListSize - numberOfItems();
+    if (resizeAnimatedListIfNeeded && length() < toListSize) {
+        size_t paddingCount = toListSize - length();
         for (size_t i = 0; i < paddingCount; ++i)
             append(SVGLength::create(m_mode));
     }
@@ -169,9 +169,9 @@
     SVGLengthContext lengthContext(contextElement);
     ASSERT(m_mode == SVGLength::lengthModeForAnimatedLengthAttribute(animationElement->attributeName()));
 
-    size_t fromLengthListSize = fromList->numberOfItems();
-    size_t toLengthListSize = toList->numberOfItems();
-    size_t toAtEndOfDurationListSize = toAtEndOfDurationList->numberOfItems();
+    size_t fromLengthListSize = fromList->length();
+    size_t toLengthListSize = toList->length();
+    size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();
 
     if (!adjustFromToListValues(fromList, toList, percentage, animationElement->animationMode() == ToAnimation, true))
         return;
diff --git a/Source/core/svg/SVGLengthList.idl b/Source/core/svg/SVGLengthList.idl
index eb9e607..9cb7d31 100644
--- a/Source/core/svg/SVGLengthList.idl
+++ b/Source/core/svg/SVGLengthList.idl
@@ -29,11 +29,13 @@
     SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGLengthList {
-    readonly attribute unsigned long numberOfItems;
+    readonly attribute unsigned long length;
+    [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
 
     [RaisesException] void clear();
     [RaisesException] SVGLength initialize(SVGLength item);
-    [RaisesException] SVGLength getItem(unsigned long index);
+    [RaisesException] getter SVGLength getItem(unsigned long index);
+    [RaisesException] setter SVGLength (unsigned long index, SVGLength value);
     [RaisesException] SVGLength insertItemBefore(SVGLength item, unsigned long index);
     [RaisesException] SVGLength replaceItem(SVGLength item, unsigned long index);
     [RaisesException] SVGLength removeItem(unsigned long index);
diff --git a/Source/core/svg/SVGLineElement.cpp b/Source/core/svg/SVGLineElement.cpp
index 1d9f7e9..1f9f828 100644
--- a/Source/core/svg/SVGLineElement.cpp
+++ b/Source/core/svg/SVGLineElement.cpp
@@ -28,11 +28,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGLineElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGLineElement::SVGLineElement(Document& document)
     : SVGGeometryElement(SVGNames::lineTag, document)
     , m_x1(SVGAnimatedLength::create(this, SVGNames::x1Attr, SVGLength::create(LengthModeWidth)))
@@ -46,7 +41,6 @@
     addToPropertyMap(m_y1);
     addToPropertyMap(m_x2);
     addToPropertyMap(m_y2);
-    registerAnimatedPropertiesForSVGLineElement();
 }
 
 PassRefPtr<SVGLineElement> SVGLineElement::create(Document& document)
diff --git a/Source/core/svg/SVGLineElement.h b/Source/core/svg/SVGLineElement.h
index 59a25be..e90c432 100644
--- a/Source/core/svg/SVGLineElement.h
+++ b/Source/core/svg/SVGLineElement.h
@@ -54,12 +54,8 @@
     RefPtr<SVGAnimatedLength> m_y1;
     RefPtr<SVGAnimatedLength> m_x2;
     RefPtr<SVGAnimatedLength> m_y2;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGLineElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGLineElement, hasTagName(SVGNames::lineTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGLinearGradientElement.cpp b/Source/core/svg/SVGLinearGradientElement.cpp
index 205f232..37b5c65 100644
--- a/Source/core/svg/SVGLinearGradientElement.cpp
+++ b/Source/core/svg/SVGLinearGradientElement.cpp
@@ -33,11 +33,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGLinearGradientElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGradientElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGLinearGradientElement::SVGLinearGradientElement(Document& document)
     : SVGGradientElement(SVGNames::linearGradientTag, document)
     , m_x1(SVGAnimatedLength::create(this, SVGNames::x1Attr, SVGLength::create(LengthModeWidth)))
@@ -54,7 +49,6 @@
     addToPropertyMap(m_y1);
     addToPropertyMap(m_x2);
     addToPropertyMap(m_y2);
-    registerAnimatedPropertiesForSVGLinearGradientElement();
 }
 
 PassRefPtr<SVGLinearGradientElement> SVGLinearGradientElement::create(Document& document)
@@ -117,15 +111,15 @@
 
 static void setGradientAttributes(SVGGradientElement* element, LinearGradientAttributes& attributes, bool isLinear = true)
 {
-    if (!attributes.hasSpreadMethod() && element->spreadMethodSpecified())
-        attributes.setSpreadMethod(element->spreadMethodCurrentValue());
+    if (!attributes.hasSpreadMethod() && element->spreadMethod()->isSpecified())
+        attributes.setSpreadMethod(element->spreadMethod()->currentValue()->enumValue());
 
-    if (!attributes.hasGradientUnits() && element->gradientUnitsSpecified())
-        attributes.setGradientUnits(element->gradientUnitsCurrentValue());
+    if (!attributes.hasGradientUnits() && element->gradientUnits()->isSpecified())
+        attributes.setGradientUnits(element->gradientUnits()->currentValue()->enumValue());
 
-    if (!attributes.hasGradientTransform() && element->gradientTransformSpecified()) {
+    if (!attributes.hasGradientTransform() && element->gradientTransform()->isSpecified()) {
         AffineTransform transform;
-        element->gradientTransformCurrentValue().concatenate(transform);
+        element->gradientTransform()->currentValue()->concatenate(transform);
         attributes.setGradientTransform(transform);
     }
 
@@ -176,7 +170,7 @@
             if (!current->renderer())
                 return false;
 
-            setGradientAttributes(current, attributes, current->hasTagName(SVGNames::linearGradientTag));
+            setGradientAttributes(current, attributes, isSVGLinearGradientElement(*current));
             processedGradients.add(current);
         } else {
             return true;
diff --git a/Source/core/svg/SVGLinearGradientElement.h b/Source/core/svg/SVGLinearGradientElement.h
index 58ad6d4..57681a5 100644
--- a/Source/core/svg/SVGLinearGradientElement.h
+++ b/Source/core/svg/SVGLinearGradientElement.h
@@ -55,12 +55,8 @@
     RefPtr<SVGAnimatedLength> m_y1;
     RefPtr<SVGAnimatedLength> m_x2;
     RefPtr<SVGAnimatedLength> m_y2;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGLinearGradientElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGLinearGradientElement, hasTagName(SVGNames::linearGradientTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGMPathElement.cpp b/Source/core/svg/SVGMPathElement.cpp
index 155f96b..991b428 100644
--- a/Source/core/svg/SVGMPathElement.cpp
+++ b/Source/core/svg/SVGMPathElement.cpp
@@ -25,21 +25,16 @@
 #include "core/dom/Document.h"
 #include "core/svg/SVGAnimateMotionElement.h"
 #include "core/svg/SVGDocumentExtensions.h"
+#include "core/svg/SVGElementInstance.h"
 #include "core/svg/SVGPathElement.h"
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMPathElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGMPathElement::SVGMPathElement(Document& document)
     : SVGElement(SVGNames::mpathTag, document)
     , SVGURIReference(this)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGMPathElement();
 }
 
 PassRefPtr<SVGMPathElement> SVGMPathElement::create(Document& document)
@@ -62,17 +57,17 @@
     Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), document(), &id);
     if (!target) {
         // Do not register as pending if we are already pending this resource.
-        if (document().accessSVGExtensions()->isElementPendingResource(this, id))
+        if (document().accessSVGExtensions().isElementPendingResource(this, id))
             return;
 
         if (!id.isEmpty()) {
-            document().accessSVGExtensions()->addPendingResource(id, this);
+            document().accessSVGExtensions().addPendingResource(id, this);
             ASSERT(hasPendingResources());
         }
     } else if (target->isSVGElement()) {
         // Register us with the target in the dependencies map. Any change of hrefElement
         // that leads to relayout/repainting now informs us, so we can react to it.
-        document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target));
+        document().accessSVGExtensions().addElementReferencingTarget(this, toSVGElement(target));
     }
 
     targetPathChanged();
@@ -80,7 +75,7 @@
 
 void SVGMPathElement::clearResourceReferences()
 {
-    document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+    document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
 }
 
 Node::InsertionNotificationRequest SVGMPathElement::insertedInto(ContainerNode* rootParent)
@@ -142,9 +137,7 @@
 SVGPathElement* SVGMPathElement::pathElement()
 {
     Element* target = targetElementFromIRIString(hrefString(), document());
-    if (target && target->hasTagName(SVGNames::pathTag))
-        return toSVGPathElement(target);
-    return 0;
+    return isSVGPathElement(target) ? toSVGPathElement(target) : 0;
 }
 
 void SVGMPathElement::targetPathChanged()
@@ -154,7 +147,7 @@
 
 void SVGMPathElement::notifyParentOfPathChange(ContainerNode* parent)
 {
-    if (parent && parent->hasTagName(SVGNames::animateMotionTag))
+    if (isSVGAnimateMotionElement(parent))
         toSVGAnimateMotionElement(parent)->updateAnimationPath();
 }
 
diff --git a/Source/core/svg/SVGMPathElement.h b/Source/core/svg/SVGMPathElement.h
index 3799d83..929222e 100644
--- a/Source/core/svg/SVGMPathElement.h
+++ b/Source/core/svg/SVGMPathElement.h
@@ -56,12 +56,8 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
     void notifyParentOfPathChange(ContainerNode*);
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMPathElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGMPathElement, hasTagName(SVGNames::mpathTag));
-
 } // namespace WebCore
 
 #endif // SVGMPathElement_h
diff --git a/Source/core/svg/SVGMarkerElement.cpp b/Source/core/svg/SVGMarkerElement.cpp
index 7ca8285..1e54c65 100644
--- a/Source/core/svg/SVGMarkerElement.cpp
+++ b/Source/core/svg/SVGMarkerElement.cpp
@@ -25,35 +25,22 @@
 
 #include "SVGNames.h"
 #include "core/rendering/svg/RenderSVGResourceMarker.h"
+#include "core/svg/SVGAngleTearOff.h"
 #include "core/svg/SVGElementInstance.h"
 
 namespace WebCore {
 
-// Define custom animated property 'orientType'.
-const SVGPropertyInfo* SVGMarkerElement::orientTypePropertyInfo()
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerUnitsType>()
 {
-    static const SVGPropertyInfo* s_propertyInfo = 0;
-    if (!s_propertyInfo) {
-        s_propertyInfo = new SVGPropertyInfo(AnimatedEnumeration,
-                                             PropertyIsReadWrite,
-                                             SVGNames::orientAttr,
-                                             orientTypeIdentifier(),
-                                             &SVGMarkerElement::synchronizeOrientType,
-                                             &SVGMarkerElement::lookupOrCreateOrientTypeWrapper);
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVGMarkerUnitsUnknown, emptyString()));
+        entries.append(std::make_pair(SVGMarkerUnitsUserSpaceOnUse, "userSpaceOnUse"));
+        entries.append(std::make_pair(SVGMarkerUnitsStrokeWidth, "strokeWidth"));
     }
-    return s_propertyInfo;
+    return entries;
 }
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGMarkerElement, SVGNames::markerUnitsAttr, MarkerUnits, markerUnits, SVGMarkerUnitsType)
-DEFINE_ANIMATED_ANGLE_AND_ENUMERATION(SVGMarkerElement, SVGNames::orientAttr, orientAngleIdentifier(), OrientAngle, orientAngle)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMarkerElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(markerUnits)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(orientAngle)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(orientType)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
 
 inline SVGMarkerElement::SVGMarkerElement(Document& document)
     : SVGElement(SVGNames::markerTag, document)
@@ -62,8 +49,8 @@
     , m_refY(SVGAnimatedLength::create(this, SVGNames::refXAttr, SVGLength::create(LengthModeWidth)))
     , m_markerWidth(SVGAnimatedLength::create(this, SVGNames::markerWidthAttr, SVGLength::create(LengthModeWidth)))
     , m_markerHeight(SVGAnimatedLength::create(this, SVGNames::markerHeightAttr, SVGLength::create(LengthModeHeight)))
-    , m_orientType(SVGMarkerOrientAngle)
-    , m_markerUnits(SVGMarkerUnitsStrokeWidth)
+    , m_orientAngle(SVGAnimatedAngle::create(this))
+    , m_markerUnits(SVGAnimatedEnumeration<SVGMarkerUnitsType>::create(this, SVGNames::markerUnitsAttr, SVGMarkerUnitsStrokeWidth))
 {
     ScriptWrappable::init(this);
 
@@ -75,8 +62,8 @@
     addToPropertyMap(m_refY);
     addToPropertyMap(m_markerWidth);
     addToPropertyMap(m_markerHeight);
-
-    registerAnimatedPropertiesForSVGMarkerElement();
+    addToPropertyMap(m_orientAngle);
+    addToPropertyMap(m_markerUnits);
 }
 
 PassRefPtr<SVGMarkerElement> SVGMarkerElement::create(Document& document)
@@ -84,18 +71,6 @@
     return adoptRef(new SVGMarkerElement(document));
 }
 
-const AtomicString& SVGMarkerElement::orientTypeIdentifier()
-{
-    DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientType", AtomicString::ConstructFromLiteral));
-    return s_identifier;
-}
-
-const AtomicString& SVGMarkerElement::orientAngleIdentifier()
-{
-    DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGOrientAngle", AtomicString::ConstructFromLiteral));
-    return s_identifier;
-}
-
 AffineTransform SVGMarkerElement::viewBoxToViewTransform(float viewWidth, float viewHeight) const
 {
     return SVGFitToViewBox::viewBoxToViewTransform(viewBox()->currentValue()->value(), preserveAspectRatio()->currentValue(), viewWidth, viewHeight);
@@ -122,11 +97,9 @@
 
     if (!isSupportedAttribute(name))
         SVGElement::parseAttribute(name, value);
-    else if (name == SVGNames::markerUnitsAttr) {
-        SVGMarkerUnitsType propertyValue = SVGPropertyTraits<SVGMarkerUnitsType>::fromString(value);
-        if (propertyValue > 0)
-            setMarkerUnitsBaseValue(propertyValue);
-    } else if (name == SVGNames::refXAttr)
+    else if (name == SVGNames::markerUnitsAttr)
+        m_markerUnits->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::refXAttr)
         m_refX->setBaseValueAsString(value, AllowNegativeLengths, parseError);
     else if (name == SVGNames::refYAttr)
         m_refY->setBaseValueAsString(value, AllowNegativeLengths, parseError);
@@ -134,17 +107,11 @@
         m_markerWidth->setBaseValueAsString(value, ForbidNegativeLengths, parseError);
     else if (name == SVGNames::markerHeightAttr)
         m_markerHeight->setBaseValueAsString(value, ForbidNegativeLengths, parseError);
-    else if (name == SVGNames::orientAttr) {
-        SVGAngle angle;
-        SVGMarkerOrientType orientType = SVGPropertyTraits<SVGMarkerOrientType>::fromString(value, angle);
-        if (orientType > 0)
-            setOrientTypeBaseValue(orientType);
-        if (orientType == SVGMarkerOrientAngle)
-            setOrientAngleBaseValue(angle);
-    } else if (SVGFitToViewBox::parseAttribute(name, value, document(), parseError)) {
-    } else {
+    else if (name == SVGNames::orientAttr)
+        m_orientAngle->setBaseValueAsString(value, parseError);
+    else if (SVGFitToViewBox::parseAttribute(name, value, document(), parseError)) {
+    } else
         ASSERT_NOT_REACHED();
-    }
 
     reportAttributeParsingError(parseError, name, value);
 }
@@ -182,26 +149,18 @@
 
 void SVGMarkerElement::setOrientToAuto()
 {
-    setOrientTypeBaseValue(SVGMarkerOrientAuto);
-    setOrientAngleBaseValue(SVGAngle());
-
-    // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization.
-    m_orientAngle.shouldSynchronize = true;
-    m_orientType.shouldSynchronize = true;
+    m_orientAngle->baseValue()->orientType()->setEnumValue(SVGMarkerOrientAuto);
     invalidateSVGAttributes();
-    svgAttributeChanged(orientAnglePropertyInfo()->attributeName);
+    svgAttributeChanged(SVGNames::orientAttr);
 }
 
-void SVGMarkerElement::setOrientToAngle(const SVGAngle& angle)
+void SVGMarkerElement::setOrientToAngle(PassRefPtr<SVGAngleTearOff> angle)
 {
-    setOrientTypeBaseValue(SVGMarkerOrientAngle);
-    setOrientAngleBaseValue(angle);
-
-    // Mark orientAttr dirty - the next XML DOM access of that attribute kicks in synchronization.
-    m_orientAngle.shouldSynchronize = true;
-    m_orientType.shouldSynchronize = true;
+    ASSERT(angle);
+    RefPtr<SVGAngle> target = angle->target();
+    m_orientAngle->baseValue()->newValueSpecifiedUnits(target->unitType(), target->valueInSpecifiedUnits());
     invalidateSVGAttributes();
-    svgAttributeChanged(orientAnglePropertyInfo()->attributeName);
+    svgAttributeChanged(SVGNames::orientAttr);
 }
 
 RenderObject* SVGMarkerElement::createRenderer(RenderStyle*)
@@ -217,33 +176,4 @@
         || m_markerHeight->currentValue()->isRelative();
 }
 
-void SVGMarkerElement::synchronizeOrientType(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement);
-    if (!ownerType->m_orientType.shouldSynchronize)
-        return;
-
-    // If orient is not auto, the previous call to synchronizeOrientAngle already set the orientAttr to the right angle.
-    if (ownerType->m_orientType.value != SVGMarkerOrientAuto)
-        return;
-
-    DEFINE_STATIC_LOCAL(AtomicString, autoString, ("auto", AtomicString::ConstructFromLiteral));
-    ownerType->m_orientType.synchronize(ownerType, orientTypePropertyInfo()->attributeName, autoString);
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGMarkerElement::lookupOrCreateOrientTypeWrapper(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    SVGMarkerElement* ownerType = toSVGMarkerElement(contextElement);
-    return SVGAnimatedProperty::lookupOrCreateWrapper<SVGMarkerElement, SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType>, SVGMarkerOrientType>
-           (ownerType, orientTypePropertyInfo(), ownerType->m_orientType.value);
-}
-
-PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType> > SVGMarkerElement::orientType()
-{
-    m_orientType.shouldSynchronize = true;
-    return static_pointer_cast<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType> >(lookupOrCreateOrientTypeWrapper(this));
-}
-
 }
diff --git a/Source/core/svg/SVGMarkerElement.h b/Source/core/svg/SVGMarkerElement.h
index 03e627c..1231b68 100644
--- a/Source/core/svg/SVGMarkerElement.h
+++ b/Source/core/svg/SVGMarkerElement.h
@@ -36,60 +36,7 @@
     SVGMarkerUnitsUserSpaceOnUse,
     SVGMarkerUnitsStrokeWidth
 };
-
-enum SVGMarkerOrientType {
-    SVGMarkerOrientUnknown = 0,
-    SVGMarkerOrientAuto,
-    SVGMarkerOrientAngle
-};
-
-template<>
-struct SVGPropertyTraits<SVGMarkerUnitsType> {
-    static unsigned highestEnumValue() { return SVGMarkerUnitsStrokeWidth; }
-
-    static String toString(SVGMarkerUnitsType type)
-    {
-        switch (type) {
-        case SVGMarkerUnitsUnknown:
-            return emptyString();
-        case SVGMarkerUnitsUserSpaceOnUse:
-            return "userSpaceOnUse";
-        case SVGMarkerUnitsStrokeWidth:
-            return "strokeWidth";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static SVGMarkerUnitsType fromString(const String& value)
-    {
-        if (value == "userSpaceOnUse")
-            return SVGMarkerUnitsUserSpaceOnUse;
-        if (value == "strokeWidth")
-            return SVGMarkerUnitsStrokeWidth;
-        return SVGMarkerUnitsUnknown;
-    }
-};
-
-template<>
-struct SVGPropertyTraits<SVGMarkerOrientType> {
-    static unsigned highestEnumValue() { return SVGMarkerOrientAngle; }
-
-    // toString is not needed, synchronizeOrientType() handles this on its own.
-
-    static SVGMarkerOrientType fromString(const String& value, SVGAngle& angle)
-    {
-        if (value == "auto")
-            return SVGMarkerOrientAuto;
-
-        TrackExceptionState exceptionState;
-        angle.setValueAsString(value, exceptionState);
-        if (!exceptionState.hadException())
-            return SVGMarkerOrientAngle;
-        return SVGMarkerOrientUnknown;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGMarkerUnitsType>();
 
 class SVGMarkerElement FINAL : public SVGElement,
                                public SVGFitToViewBox {
@@ -112,22 +59,15 @@
     AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
 
     void setOrientToAuto();
-    void setOrientToAngle(const SVGAngle&);
-
-    static const SVGPropertyInfo* orientTypePropertyInfo();
+    void setOrientToAngle(PassRefPtr<SVGAngleTearOff>);
 
     SVGAnimatedLength* refX() const { return m_refX.get(); }
     SVGAnimatedLength* refY() const { return m_refY.get(); }
     SVGAnimatedLength* markerWidth() const { return m_markerWidth.get(); }
     SVGAnimatedLength* markerHeight() const { return m_markerHeight.get(); }
-
-    // Custom 'orientType' property.
-    static void synchronizeOrientType(SVGElement* contextElement);
-    static PassRefPtr<SVGAnimatedProperty> lookupOrCreateOrientTypeWrapper(SVGElement* contextElement);
-    SVGMarkerOrientType& orientTypeCurrentValue() const { return m_orientType.value; }
-    SVGMarkerOrientType& orientTypeBaseValue() const { return m_orientType.value; }
-    void setOrientTypeBaseValue(const SVGMarkerOrientType& type) { m_orientType.value = type; }
-    PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<SVGMarkerOrientType> > orientType();
+    SVGAnimatedEnumeration<SVGMarkerUnitsType>* markerUnits() { return m_markerUnits.get(); }
+    SVGAnimatedAngle* orientAngle() { return m_orientAngle.get(); }
+    SVGAnimatedEnumeration<SVGMarkerOrientType>* orientType() { return m_orientAngle->orientType(); }
 
 private:
     explicit SVGMarkerElement(Document&);
@@ -144,24 +84,14 @@
 
     virtual bool selfHasRelativeLengths() const OVERRIDE;
 
-    void synchronizeOrientType();
-
-    static const AtomicString& orientTypeIdentifier();
-    static const AtomicString& orientAngleIdentifier();
-
     RefPtr<SVGAnimatedLength> m_refX;
     RefPtr<SVGAnimatedLength> m_refY;
     RefPtr<SVGAnimatedLength> m_markerWidth;
     RefPtr<SVGAnimatedLength> m_markerHeight;
-    mutable SVGSynchronizableAnimatedProperty<SVGMarkerOrientType> m_orientType;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMarkerElement)
-        DECLARE_ANIMATED_ENUMERATION(MarkerUnits, markerUnits, SVGMarkerUnitsType)
-        DECLARE_ANIMATED_ANGLE(OrientAngle, orientAngle)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedAngle> m_orientAngle;
+    RefPtr<SVGAnimatedEnumeration<SVGMarkerUnitsType> > m_markerUnits;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGMarkerElement, hasTagName(SVGNames::markerTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGMarkerElement.idl b/Source/core/svg/SVGMarkerElement.idl
index 0e22319..73593ee 100644
--- a/Source/core/svg/SVGMarkerElement.idl
+++ b/Source/core/svg/SVGMarkerElement.idl
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGMarkerElement : SVGElement {
+[
+    StrictTypeChecking,
+] interface SVGMarkerElement : SVGElement {
     // Marker Unit Types
     const unsigned short SVG_MARKERUNITS_UNKNOWN        = 0;
     const unsigned short SVG_MARKERUNITS_USERSPACEONUSE = 1;
@@ -43,7 +45,7 @@
     readonly attribute SVGAnimatedAngle       orientAngle;
 
     void setOrientToAuto();
-    void setOrientToAngle([Default=Undefined] optional SVGAngle angle);
+    void setOrientToAngle(SVGAngle angle);
 };
 
 SVGMarkerElement implements SVGFitToViewBox;
diff --git a/Source/core/svg/SVGMaskElement.cpp b/Source/core/svg/SVGMaskElement.cpp
index 98343fb..f53976f 100644
--- a/Source/core/svg/SVGMaskElement.cpp
+++ b/Source/core/svg/SVGMaskElement.cpp
@@ -30,16 +30,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGMaskElement, SVGNames::maskUnitsAttr, MaskUnits, maskUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_ENUMERATION(SVGMaskElement, SVGNames::maskContentUnitsAttr, MaskContentUnits, maskContentUnits, SVGUnitTypes::SVGUnitType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGMaskElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(maskUnits)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(maskContentUnits)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGMaskElement::SVGMaskElement(Document& document)
     : SVGElement(SVGNames::maskTag, document)
     , SVGTests(this)
@@ -47,8 +37,8 @@
     , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight)))
     , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth)))
     , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight)))
-    , m_maskUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
-    , m_maskContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
+    , m_maskUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
+    , m_maskContentUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::maskContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
 {
     ScriptWrappable::init(this);
 
@@ -64,7 +54,8 @@
     addToPropertyMap(m_y);
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
-    registerAnimatedPropertiesForSVGMaskElement();
+    addToPropertyMap(m_maskUnits);
+    addToPropertyMap(m_maskContentUnits);
 }
 
 PassRefPtr<SVGMaskElement> SVGMaskElement::create(Document& document)
@@ -93,17 +84,11 @@
 
     if (!isSupportedAttribute(name))
         SVGElement::parseAttribute(name, value);
-    else if (name == SVGNames::maskUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setMaskUnitsBaseValue(propertyValue);
-        return;
-    } else if (name == SVGNames::maskContentUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setMaskContentUnitsBaseValue(propertyValue);
-        return;
-    } else if (name == SVGNames::xAttr)
+    else if (name == SVGNames::maskUnitsAttr)
+        m_maskUnits->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::maskContentUnitsAttr)
+        m_maskContentUnits->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::xAttr)
         m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError);
     else if (name == SVGNames::yAttr)
         m_y->setBaseValueAsString(value, AllowNegativeLengths, parseError);
diff --git a/Source/core/svg/SVGMaskElement.h b/Source/core/svg/SVGMaskElement.h
index e599a9f..b1b227a 100644
--- a/Source/core/svg/SVGMaskElement.h
+++ b/Source/core/svg/SVGMaskElement.h
@@ -39,6 +39,8 @@
     SVGAnimatedLength* y() const { return m_y.get(); }
     SVGAnimatedLength* width() const { return m_width.get(); }
     SVGAnimatedLength* height() const { return m_height.get(); }
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* maskUnits() { return m_maskUnits.get(); }
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* maskContentUnits() { return m_maskContentUnits.get(); }
 
 private:
     explicit SVGMaskElement(Document&);
@@ -59,14 +61,10 @@
     RefPtr<SVGAnimatedLength> m_y;
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGMaskElement)
-        DECLARE_ANIMATED_ENUMERATION(MaskUnits, maskUnits, SVGUnitTypes::SVGUnitType)
-        DECLARE_ANIMATED_ENUMERATION(MaskContentUnits, maskContentUnits, SVGUnitTypes::SVGUnitType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_maskUnits;
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_maskContentUnits;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGMaskElement, hasTagName(SVGNames::maskTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGMatrix.h b/Source/core/svg/SVGMatrix.h
deleted file mode 100644
index df536b5..0000000
--- a/Source/core/svg/SVGMatrix.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGMatrix_h
-#define SVGMatrix_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "platform/transforms/AffineTransform.h"
-
-namespace WebCore {
-
-// Only used in the bindings.
-class SVGMatrix : public AffineTransform {
-public:
-    SVGMatrix() { }
-    SVGMatrix(const AffineTransform& other)
-        : AffineTransform(other)
-    {
-    }
-
-    SVGMatrix(double a, double b, double c, double d, double e, double f)
-        : AffineTransform(a, b, c, d, e, f)
-    {
-    }
-
-    SVGMatrix translate(double tx, double ty)
-    {
-        AffineTransform copy = *this;
-        copy.translate(tx, ty);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix scale(double s)
-    {
-        AffineTransform copy = *this;
-        copy.scale(s, s);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix scaleNonUniform(double sx, double sy)
-    {
-        AffineTransform copy = *this;
-        copy.scale(sx, sy);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix rotate(double d)
-    {
-        AffineTransform copy = *this;
-        copy.rotate(d);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix flipX()
-    {
-        AffineTransform copy = *this;
-        copy.flipX();
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix flipY()
-    {
-        AffineTransform copy = *this;
-        copy.flipY();
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix skewX(double angle)
-    {
-        AffineTransform copy = *this;
-        copy.skewX(angle);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix skewY(double angle)
-    {
-        AffineTransform copy = *this;
-        copy.skewY(angle);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix multiply(const SVGMatrix& other)
-    {
-        AffineTransform copy = *this;
-        copy *= static_cast<const AffineTransform&>(other);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-    SVGMatrix inverse(ExceptionState& exceptionState) const
-    {
-        AffineTransform transform = AffineTransform::inverse();
-        if (!isInvertible())
-            exceptionState.throwDOMException(InvalidStateError, "The matrix is not invertible.");
-
-        return transform;
-    }
-
-    SVGMatrix rotateFromVector(double x, double y, ExceptionState& exceptionState)
-    {
-        if (!x || !y)
-            exceptionState.throwDOMException(InvalidAccessError, "Arguments cannot be zero.");
-
-        AffineTransform copy = *this;
-        copy.rotateFromVector(x, y);
-        return static_cast<SVGMatrix>(copy);
-    }
-
-};
-
-} // namespace WebCore
-
-#endif
diff --git a/Source/core/svg/SVGMatrix.idl b/Source/core/svg/SVGMatrix.idl
index eb28daa..5090cf7 100644
--- a/Source/core/svg/SVGMatrix.idl
+++ b/Source/core/svg/SVGMatrix.idl
@@ -21,28 +21,29 @@
  */
 
 [
-    SetWrapperReferenceTo(SVGTransform parent),
     StrictTypeChecking,
+    ImplementedAs=SVGMatrixTearOff,
+    SetWrapperReferenceTo(SVGTransform contextTransform)
 ] interface SVGMatrix {
     // FIXME: these attributes should all be floats but since we implement
     // AffineTransform with doubles setting these as doubles makes more sense.
-    attribute double a;
-    attribute double b;
-    attribute double c;
-    attribute double d;
-    attribute double e;
-    attribute double f;
+    [RaisesException=Setter] attribute double a;
+    [RaisesException=Setter] attribute double b;
+    [RaisesException=Setter] attribute double c;
+    [RaisesException=Setter] attribute double d;
+    [RaisesException=Setter] attribute double e;
+    [RaisesException=Setter] attribute double f;
 
     SVGMatrix multiply(SVGMatrix secondMatrix);
     [RaisesException] SVGMatrix inverse();
-    [Immutable] SVGMatrix translate(float x, float y);
-    [Immutable] SVGMatrix scale(float scaleFactor);
-    [Immutable] SVGMatrix scaleNonUniform(float scaleFactorX, float scaleFactorY);
-    [Immutable] SVGMatrix rotate(float angle);
+    SVGMatrix translate(float x, float y);
+    SVGMatrix scale(float scaleFactor);
+    SVGMatrix scaleNonUniform(float scaleFactorX, float scaleFactorY);
+    SVGMatrix rotate(float angle);
     [RaisesException] SVGMatrix rotateFromVector(float x, float y);
-    [Immutable] SVGMatrix flipX();
-    [Immutable] SVGMatrix flipY();
-    [Immutable] SVGMatrix skewX(float angle);
-    [Immutable] SVGMatrix skewY(float angle);
+    SVGMatrix flipX();
+    SVGMatrix flipY();
+    SVGMatrix skewX(float angle);
+    SVGMatrix skewY(float angle);
 };
 
diff --git a/Source/core/svg/SVGMatrixTearOff.cpp b/Source/core/svg/SVGMatrixTearOff.cpp
new file mode 100644
index 0000000..c43e555
--- /dev/null
+++ b/Source/core/svg/SVGMatrixTearOff.cpp
@@ -0,0 +1,179 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGMatrixTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGTransformTearOff.h"
+
+namespace WebCore {
+
+SVGMatrixTearOff::SVGMatrixTearOff(const AffineTransform& staticValue)
+    : m_staticValue(staticValue)
+    , m_contextTransform(0)
+{
+    ScriptWrappable::init(this);
+}
+
+SVGMatrixTearOff::SVGMatrixTearOff(SVGTransformTearOff* transform)
+    : m_contextTransform(transform)
+{
+    ASSERT(transform);
+    ScriptWrappable::init(this);
+}
+
+SVGMatrixTearOff::~SVGMatrixTearOff()
+{
+}
+
+const AffineTransform& SVGMatrixTearOff::value() const
+{
+    return m_contextTransform ? m_contextTransform->target()->matrix() : m_staticValue;
+}
+
+AffineTransform* SVGMatrixTearOff::mutableValue()
+{
+    return m_contextTransform ? m_contextTransform->target()->mutableMatrix() : &m_staticValue;
+}
+
+void SVGMatrixTearOff::commitChange()
+{
+    if (!m_contextTransform)
+        return;
+
+    m_contextTransform->target()->onMatrixChange();
+    m_contextTransform->commitChange();
+}
+
+#define DEFINE_SETTER(ATTRIBUTE) \
+    void SVGMatrixTearOff::set##ATTRIBUTE(double f, ExceptionState& exceptionState) \
+    { \
+        if (m_contextTransform && m_contextTransform->isImmutable()) { \
+            exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only."); \
+            return; \
+        } \
+        mutableValue()->set##ATTRIBUTE(f); \
+        commitChange(); \
+    }
+
+DEFINE_SETTER(A);
+DEFINE_SETTER(B);
+DEFINE_SETTER(C);
+DEFINE_SETTER(D);
+DEFINE_SETTER(E);
+DEFINE_SETTER(F);
+
+#undef DEFINE_SETTER
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::translate(double tx, double ty)
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->translate(tx, ty);
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::scale(double s)
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->scale(s, s);
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::scaleNonUniform(double sx, double sy)
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->scale(sx, sy);
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::rotate(double d)
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->rotate(d);
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::flipX()
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->flipX();
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::flipY()
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->flipY();
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::skewX(double angle)
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->skewX(angle);
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::skewY(double angle)
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    matrix->mutableValue()->skewY(angle);
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::multiply(PassRefPtr<SVGMatrixTearOff> other)
+{
+    RefPtr<SVGMatrixTearOff> matrix = create(value());
+    *matrix->mutableValue() *= other->value();
+    return matrix.release();
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::inverse(ExceptionState& exceptionState)
+{
+    AffineTransform transform = value().inverse();
+    if (!value().isInvertible())
+        exceptionState.throwDOMException(InvalidStateError, "The matrix is not invertible.");
+
+    return create(transform);
+}
+
+PassRefPtr<SVGMatrixTearOff> SVGMatrixTearOff::rotateFromVector(double x, double y, ExceptionState& exceptionState)
+{
+    if (!x || !y)
+        exceptionState.throwDOMException(InvalidAccessError, "Arguments cannot be zero.");
+
+    AffineTransform copy = value();
+    copy.rotateFromVector(x, y);
+    return create(copy);
+}
+
+}
diff --git a/Source/core/svg/SVGMatrixTearOff.h b/Source/core/svg/SVGMatrixTearOff.h
new file mode 100644
index 0000000..94583e7
--- /dev/null
+++ b/Source/core/svg/SVGMatrixTearOff.h
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGMatrixTearOff_h
+#define SVGMatrixTearOff_h
+
+#include "bindings/v8/ExceptionState.h"
+#include "bindings/v8/ScriptWrappable.h"
+#include "platform/transforms/AffineTransform.h"
+#include "wtf/RefCounted.h"
+
+namespace WebCore {
+
+class SVGTransformTearOff;
+
+// SVGMatrixTearOff wraps a AffineTransform for Javascript.
+// Its instance can either hold a static value, or this can be teared off from |SVGTransform.matrix|.
+// This does not derive from NewSVGPropertyTearOff, as its instances are never tied to an animated property nor an XML attribute.
+class SVGMatrixTearOff FINAL : public RefCounted<SVGMatrixTearOff>, public ScriptWrappable {
+public:
+    static PassRefPtr<SVGMatrixTearOff> create(const AffineTransform& value)
+    {
+        return adoptRef(new SVGMatrixTearOff(value));
+    }
+
+    static PassRefPtr<SVGMatrixTearOff> create(SVGTransformTearOff* target)
+    {
+        return adoptRef(new SVGMatrixTearOff(target));
+    }
+
+    ~SVGMatrixTearOff();
+
+    double a() { return value().a(); }
+    double b() { return value().b(); }
+    double c() { return value().c(); }
+    double d() { return value().d(); }
+    double e() { return value().e(); }
+    double f() { return value().f(); }
+
+    void setA(double, ExceptionState&);
+    void setB(double, ExceptionState&);
+    void setC(double, ExceptionState&);
+    void setD(double, ExceptionState&);
+    void setE(double, ExceptionState&);
+    void setF(double, ExceptionState&);
+
+    PassRefPtr<SVGMatrixTearOff> translate(double tx, double ty);
+    PassRefPtr<SVGMatrixTearOff> scale(double);
+    PassRefPtr<SVGMatrixTearOff> scaleNonUniform(double sx, double sy);
+    PassRefPtr<SVGMatrixTearOff> rotate(double);
+    PassRefPtr<SVGMatrixTearOff> flipX();
+    PassRefPtr<SVGMatrixTearOff> flipY();
+    PassRefPtr<SVGMatrixTearOff> skewX(double);
+    PassRefPtr<SVGMatrixTearOff> skewY(double);
+    PassRefPtr<SVGMatrixTearOff> multiply(PassRefPtr<SVGMatrixTearOff>);
+    PassRefPtr<SVGMatrixTearOff> inverse(ExceptionState&);
+    PassRefPtr<SVGMatrixTearOff> rotateFromVector(double x, double y, ExceptionState&);
+
+    SVGTransformTearOff* contextTransform() { return m_contextTransform; }
+
+    const AffineTransform& value() const;
+
+private:
+    SVGMatrixTearOff(const AffineTransform&);
+    SVGMatrixTearOff(SVGTransformTearOff*);
+
+    AffineTransform* mutableValue();
+    void commitChange();
+
+    AffineTransform m_staticValue;
+
+    // FIXME: oilpan: This is raw-ptr to avoid reference cycles. Should be Member in oilpan.
+    SVGTransformTearOff* m_contextTransform;
+};
+
+} // namespace WebCore
+
+#endif // SVGMatrixTearOff_h_
diff --git a/Source/core/svg/SVGMissingGlyphElement.h b/Source/core/svg/SVGMissingGlyphElement.h
index fa1ef31..7548afc 100644
--- a/Source/core/svg/SVGMissingGlyphElement.h
+++ b/Source/core/svg/SVGMissingGlyphElement.h
@@ -36,8 +36,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGMissingGlyphElement, hasTagName(SVGNames::missing_glyphTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGNumberList.cpp b/Source/core/svg/SVGNumberList.cpp
index cf515fc..3794258 100644
--- a/Source/core/svg/SVGNumberList.cpp
+++ b/Source/core/svg/SVGNumberList.cpp
@@ -120,10 +120,10 @@
 {
     RefPtr<SVGNumberList> otherList = toSVGNumberList(other);
 
-    if (numberOfItems() != otherList->numberOfItems())
+    if (length() != otherList->length())
         return;
 
-    for (size_t i = 0; i < numberOfItems(); ++i)
+    for (size_t i = 0; i < length(); ++i)
         at(i)->setValue(at(i)->value() + otherList->at(i)->value());
 }
 
@@ -133,12 +133,12 @@
     RefPtr<SVGNumberList> toList = passToList;
 
     // If no 'to' value is given, nothing to animate.
-    size_t toListSize = toList->numberOfItems();
+    size_t toListSize = toList->length();
     if (!toListSize)
         return false;
 
     // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
-    size_t fromListSize = fromList->numberOfItems();
+    size_t fromListSize = fromList->length();
     if (fromListSize != toListSize && fromListSize) {
         if (percentage < 0.5) {
             if (!isToAnimation)
@@ -151,8 +151,8 @@
     }
 
     ASSERT(!fromListSize || fromListSize == toListSize);
-    if (resizeAnimatedListIfNeeded && numberOfItems() < toListSize) {
-        size_t paddingCount = toListSize - numberOfItems();
+    if (resizeAnimatedListIfNeeded && length() < toListSize) {
+        size_t paddingCount = toListSize - length();
         for (size_t i = 0; i < paddingCount; ++i)
             append(SVGNumber::create());
     }
@@ -166,9 +166,9 @@
     RefPtr<SVGNumberList> toList = toSVGNumberList(toValue);
     RefPtr<SVGNumberList> toAtEndOfDurationList = toSVGNumberList(toAtEndOfDurationValue);
 
-    size_t fromListSize = fromList->numberOfItems();
-    size_t toListSize = toList->numberOfItems();
-    size_t toAtEndOfDurationListSize = toAtEndOfDurationList->numberOfItems();
+    size_t fromListSize = fromList->length();
+    size_t toListSize = toList->length();
+    size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();
 
     if (!adjustFromToListValues(fromList, toList, percentage, animationElement->animationMode() == ToAnimation, true))
         return;
@@ -193,8 +193,8 @@
 Vector<float> SVGNumberList::toFloatVector() const
 {
     Vector<float> vec;
-    vec.reserveInitialCapacity(numberOfItems());
-    for (size_t i = 0; i < numberOfItems(); ++i)
+    vec.reserveInitialCapacity(length());
+    for (size_t i = 0; i < length(); ++i)
         vec.uncheckedAppend(at(i)->value());
     return vec;
 }
diff --git a/Source/core/svg/SVGNumberList.idl b/Source/core/svg/SVGNumberList.idl
index 1bc3a5b..818fe69 100644
--- a/Source/core/svg/SVGNumberList.idl
+++ b/Source/core/svg/SVGNumberList.idl
@@ -29,11 +29,13 @@
     SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGNumberList {
-    readonly attribute unsigned long numberOfItems;
+    readonly attribute unsigned long length;
+    [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
 
     [RaisesException] void clear();
     [RaisesException] SVGNumber initialize(SVGNumber item);
-    [RaisesException] SVGNumber getItem(unsigned long index);
+    [RaisesException] getter SVGNumber getItem(unsigned long index);
+    [RaisesException] setter SVGNumber (unsigned long index, SVGNumber value);
     [RaisesException] SVGNumber insertItemBefore(SVGNumber item, unsigned long index);
     [RaisesException] SVGNumber replaceItem(SVGNumber item, unsigned long index);
     [RaisesException] SVGNumber removeItem(unsigned long index);
diff --git a/Source/core/svg/SVGPaint.cpp b/Source/core/svg/SVGPaint.cpp
index f7e85f1..7eb67bd 100644
--- a/Source/core/svg/SVGPaint.cpp
+++ b/Source/core/svg/SVGPaint.cpp
@@ -24,50 +24,18 @@
 
 #include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
+#include "core/css/RGBColor.h"
+#include "core/css/parser/BisonCSSParser.h"
 
 namespace WebCore {
 
-static inline SVGColor::SVGColorType colorTypeForPaintType(const SVGPaint::SVGPaintType& paintType)
-{
-    switch (paintType) {
-    case SVGPaint::SVG_PAINTTYPE_NONE:
-    case SVGPaint::SVG_PAINTTYPE_UNKNOWN:
-    case SVGPaint::SVG_PAINTTYPE_URI:
-    case SVGPaint::SVG_PAINTTYPE_URI_NONE:
-        return SVGColor::SVG_COLORTYPE_UNKNOWN;
-    case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR:
-    case SVGPaint::SVG_PAINTTYPE_RGBCOLOR:
-        return SVGColor::SVG_COLORTYPE_RGBCOLOR;
-    case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
-    case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
-        return SVGColor::SVG_COLORTYPE_RGBCOLOR_ICCCOLOR;
-    case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR:
-    case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR:
-        return SVGColor::SVG_COLORTYPE_CURRENTCOLOR;
-    }
-
-    ASSERT_NOT_REACHED();
-    return SVGColor::SVG_COLORTYPE_UNKNOWN;
-}
-
 SVGPaint::SVGPaint(const SVGPaintType& paintType, const String& uri)
-    : SVGColor(SVGPaintClass, colorTypeForPaintType(paintType))
+    : CSSValue(SVGPaintClass)
     , m_paintType(paintType)
     , m_uri(uri)
 {
 }
 
-void SVGPaint::setUri(const String&)
-{
-    // The whole SVGPaint interface is deprecated in SVG 1.1 (2nd edition).
-    // The setters are the most problematic part so we remove the support for those first.
-}
-
-void SVGPaint::setPaint(unsigned short, const String&, const String&, const String&, ExceptionState& exceptionState)
-{
-    exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
-}
-
 String SVGPaint::customCSSText() const
 {
     switch (m_paintType) {
@@ -75,19 +43,18 @@
         return String();
     case SVG_PAINTTYPE_RGBCOLOR:
     case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
+        return m_color.serializedAsCSSComponentValue();
     case SVG_PAINTTYPE_CURRENTCOLOR:
-        return SVGColor::customCSSText();
+        return "currentColor";
     case SVG_PAINTTYPE_NONE:
         return "none";
     case SVG_PAINTTYPE_URI_NONE:
         return m_uri + " none";
     case SVG_PAINTTYPE_URI_CURRENTCOLOR:
+        return "url(" + m_uri + ") currentColor";
     case SVG_PAINTTYPE_URI_RGBCOLOR:
     case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: {
-        String color = SVGColor::customCSSText();
-        if (color.isEmpty())
-            return m_uri;
-        return "url(" + m_uri + ") " + color;
+        return "url(" + m_uri + ") " + m_color.serializedAsCSSComponentValue();
     }
     case SVG_PAINTTYPE_URI:
         return "url(" + m_uri + ')';
@@ -98,20 +65,31 @@
 }
 
 SVGPaint::SVGPaint(const SVGPaint& cloneFrom)
-    : SVGColor(SVGPaintClass, cloneFrom)
+    : CSSValue(SVGPaintClass, /*isCSSOMSafe*/ true)
     , m_paintType(cloneFrom.m_paintType)
+    , m_color(cloneFrom.m_color)
     , m_uri(cloneFrom.m_uri)
 {
 }
 
 PassRefPtrWillBeRawPtr<SVGPaint> SVGPaint::cloneForCSSOM() const
 {
-    return adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(*this));
+    return adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(*this));
 }
 
 bool SVGPaint::equals(const SVGPaint& other) const
 {
-    return m_paintType == other.m_paintType && m_uri == other.m_uri && SVGColor::equals(other);
+    return m_paintType == other.m_paintType && m_uri == other.m_uri && m_color == other.m_color;
+}
+
+StyleColor SVGPaint::colorFromRGBColorString(const String& colorString)
+{
+    // FIXME: Rework css parser so it is more SVG aware.
+    RGBA32 color;
+    if (BisonCSSParser::parseColor(color, colorString.stripWhiteSpace()))
+        return StyleColor(color);
+    // FIXME: This branch catches the string currentColor, but we should error if we have an illegal color value.
+    return StyleColor::currentColor();
 }
 
 }
diff --git a/Source/core/svg/SVGPaint.h b/Source/core/svg/SVGPaint.h
index 488c2e8..7a42113 100644
--- a/Source/core/svg/SVGPaint.h
+++ b/Source/core/svg/SVGPaint.h
@@ -23,14 +23,16 @@
 #ifndef SVGPaint_h
 #define SVGPaint_h
 
-#include "core/svg/SVGColor.h"
+#include "core/css/CSSValue.h"
+#include "core/css/StyleColor.h"
+#include "platform/graphics/Color.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
 class ExceptionState;
 
-class SVGPaint : public SVGColor {
+class SVGPaint : public CSSValue {
 public:
     enum SVGPaintType {
         SVG_PAINTTYPE_UNKNOWN = 0,
@@ -47,72 +49,74 @@
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createUnknown()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_UNKNOWN));
+        return adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_UNKNOWN));
     }
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createNone()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_NONE));
+        return adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_NONE));
     }
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createCurrentColor()
     {
-        return adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_CURRENTCOLOR));
+        return adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_CURRENTCOLOR));
     }
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createColor(const Color& color)
     {
-        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_RGBCOLOR));
-        paint->setColor(color);
+        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_RGBCOLOR));
+        paint->m_color = color;
         return paint.release();
     }
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createURI(const String& uri)
     {
-        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI, uri));
+        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI, uri));
         return paint.release();
     }
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createURIAndColor(const String& uri, const Color& color)
     {
-        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI_RGBCOLOR, uri));
-        paint->setColor(color);
+        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI_RGBCOLOR, uri));
+        paint->m_color = color;
         return paint.release();
     }
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createURIAndNone(const String& uri)
     {
-        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI_NONE, uri));
+        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI_NONE, uri));
         return paint.release();
     }
 
     static PassRefPtrWillBeRawPtr<SVGPaint> createURIAndCurrentColor(const String& uri)
     {
-        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI_CURRENTCOLOR, uri));
+        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(SVG_PAINTTYPE_URI_CURRENTCOLOR, uri));
         return paint.release();
     }
 
     const SVGPaintType& paintType() const { return m_paintType; }
     String uri() const { return m_uri; }
 
-    void setUri(const String&);
-    void setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionState&);
-
     String customCSSText() const;
 
     PassRefPtrWillBeRawPtr<SVGPaint> cloneForCSSOM() const;
 
     bool equals(const SVGPaint&) const;
 
-    void traceAfterDispatch(Visitor* visitor) { SVGColor::traceAfterDispatch(visitor); }
+    void traceAfterDispatch(Visitor* visitor) { CSSValue::traceAfterDispatch(visitor); }
+
+    Color color() const { return m_color; }
+    void setColor(const Color& color) { m_color = color; m_paintType = SVG_PAINTTYPE_RGBCOLOR; }
+
+    static StyleColor colorFromRGBColorString(const String&);
 
 private:
     friend class CSSComputedStyleDeclaration;
 
     static PassRefPtrWillBeRawPtr<SVGPaint> create(const SVGPaintType& type, const String& uri, const Color& color)
     {
-        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefCountedWillBeRefCountedGarbageCollected(new SVGPaint(type, uri));
-        paint->setColor(color);
+        RefPtrWillBeRawPtr<SVGPaint> paint = adoptRefWillBeRefCountedGarbageCollected(new SVGPaint(type, uri));
+        paint->m_color = color;
         return paint.release();
     }
 
@@ -121,6 +125,7 @@
     SVGPaint(const SVGPaint& cloneFrom);
 
     SVGPaintType m_paintType;
+    Color m_color;
     String m_uri;
 };
 
diff --git a/Source/core/svg/SVGParserUtilities.cpp b/Source/core/svg/SVGParserUtilities.cpp
index 7bedbb4..8d39b65 100644
--- a/Source/core/svg/SVGParserUtilities.cpp
+++ b/Source/core/svg/SVGParserUtilities.cpp
@@ -25,7 +25,6 @@
 
 #include "core/dom/Document.h"
 #include "core/svg/SVGPointList.h"
-#include "core/svg/SVGTransformList.h"
 #include "platform/geometry/FloatRect.h"
 #include "platform/transforms/AffineTransform.h"
 #include "wtf/ASCIICType.h"
@@ -165,20 +164,6 @@
     return genericParseNumber(ptr, end, number, skip);
 }
 
-bool parseNumberFromString(const String& string, float& number, bool skip)
-{
-    if (string.isEmpty())
-        return false;
-    if (string.is8Bit()) {
-        const LChar* ptr = string.characters8();
-        const LChar* end = ptr + string.length();
-        return genericParseNumber(ptr, end, number, skip) && ptr == end;
-    }
-    const UChar* ptr = string.characters16();
-    const UChar* end = ptr + string.length();
-    return genericParseNumber(ptr, end, number, skip) && ptr == end;
-}
-
 // only used to parse largeArcFlag and sweepFlag which must be a "0" or "1"
 // and might not have any whitespace/comma after it
 template <typename CharType>
@@ -489,117 +474,6 @@
 template bool parseFloatPoint3(const LChar*& current, const LChar* end, FloatPoint& point1, FloatPoint& point2, FloatPoint& point3);
 template bool parseFloatPoint3(const UChar*& current, const UChar* end, FloatPoint& point1, FloatPoint& point2, FloatPoint& point3);
 
-template<typename CharType>
-static int parseTransformParamList(const CharType*& ptr, const CharType* end, float* values, int required, int optional)
-{
-    int optionalParams = 0, requiredParams = 0;
-
-    if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(')
-        return -1;
-
-    ptr++;
-
-    skipOptionalSVGSpaces(ptr, end);
-
-    while (requiredParams < required) {
-        if (ptr >= end || !parseNumber(ptr, end, values[requiredParams], false))
-            return -1;
-        requiredParams++;
-        if (requiredParams < required)
-            skipOptionalSVGSpacesOrDelimiter(ptr, end);
-    }
-    if (!skipOptionalSVGSpaces(ptr, end))
-        return -1;
-
-    bool delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end);
-
-    if (ptr >= end)
-        return -1;
-
-    if (*ptr == ')') { // skip optionals
-        ptr++;
-        if (delimParsed)
-            return -1;
-    } else {
-        while (optionalParams < optional) {
-            if (ptr >= end || !parseNumber(ptr, end, values[requiredParams + optionalParams], false))
-                return -1;
-            optionalParams++;
-            if (optionalParams < optional)
-                skipOptionalSVGSpacesOrDelimiter(ptr, end);
-        }
-
-        if (!skipOptionalSVGSpaces(ptr, end))
-            return -1;
-
-        delimParsed = skipOptionalSVGSpacesOrDelimiter(ptr, end);
-
-        if (ptr >= end || *ptr != ')' || delimParsed)
-            return -1;
-        ptr++;
-    }
-
-    return requiredParams + optionalParams;
-}
-
-// These should be kept in sync with enum SVGTransformType
-static const int requiredValuesForType[] =  {0, 6, 1, 1, 1, 1, 1};
-static const int optionalValuesForType[] =  {0, 0, 1, 1, 2, 0, 0};
-
-template<typename CharType>
-static bool parseTransformValueInternal(unsigned type, const CharType*& ptr, const CharType* end, SVGTransform& transform)
-{
-    if (type == SVGTransform::SVG_TRANSFORM_UNKNOWN)
-        return false;
-
-    int valueCount = 0;
-    float values[] = {0, 0, 0, 0, 0, 0};
-    if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0)
-        return false;
-
-    switch (type) {
-    case SVGTransform::SVG_TRANSFORM_SKEWX:
-        transform.setSkewX(values[0]);
-        break;
-    case SVGTransform::SVG_TRANSFORM_SKEWY:
-        transform.setSkewY(values[0]);
-        break;
-    case SVGTransform::SVG_TRANSFORM_SCALE:
-        if (valueCount == 1) // Spec: if only one param given, assume uniform scaling
-            transform.setScale(values[0], values[0]);
-        else
-            transform.setScale(values[0], values[1]);
-        break;
-    case SVGTransform::SVG_TRANSFORM_TRANSLATE:
-        if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0
-            transform.setTranslate(values[0], 0);
-        else
-            transform.setTranslate(values[0], values[1]);
-        break;
-    case SVGTransform::SVG_TRANSFORM_ROTATE:
-        if (valueCount == 1)
-            transform.setRotate(values[0], 0, 0);
-        else
-            transform.setRotate(values[0], values[1], values[2]);
-        break;
-    case SVGTransform::SVG_TRANSFORM_MATRIX:
-        transform.setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5]));
-        break;
-    }
-
-    return true;
-}
-
-bool parseTransformValue(unsigned type, const LChar*& ptr, const LChar* end, SVGTransform& transform)
-{
-    return parseTransformValueInternal(type, ptr, end, transform);
-}
-
-bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform& transform)
-{
-    return parseTransformValueInternal(type, ptr, end, transform);
-}
-
 static const LChar skewXDesc[] =  {'s', 'k', 'e', 'w', 'X'};
 static const LChar skewYDesc[] =  {'s', 'k', 'e', 'w', 'Y'};
 static const LChar scaleDesc[] =  {'s', 'c', 'a', 'l', 'e'};
@@ -608,88 +482,50 @@
 static const LChar matrixDesc[] =  {'m', 'a', 't', 'r', 'i', 'x'};
 
 template<typename CharType>
-static inline bool parseAndSkipType(const CharType*& ptr, const CharType* end, unsigned short& type)
+bool parseAndSkipTransformType(const CharType*& ptr, const CharType* end, SVGTransformType& type)
 {
     if (ptr >= end)
         return false;
 
     if (*ptr == 's') {
         if (skipString(ptr, end, skewXDesc, WTF_ARRAY_LENGTH(skewXDesc)))
-            type = SVGTransform::SVG_TRANSFORM_SKEWX;
+            type = SVG_TRANSFORM_SKEWX;
         else if (skipString(ptr, end, skewYDesc, WTF_ARRAY_LENGTH(skewYDesc)))
-            type = SVGTransform::SVG_TRANSFORM_SKEWY;
+            type = SVG_TRANSFORM_SKEWY;
         else if (skipString(ptr, end, scaleDesc, WTF_ARRAY_LENGTH(scaleDesc)))
-            type = SVGTransform::SVG_TRANSFORM_SCALE;
+            type = SVG_TRANSFORM_SCALE;
         else
             return false;
     } else if (skipString(ptr, end, translateDesc, WTF_ARRAY_LENGTH(translateDesc)))
-        type = SVGTransform::SVG_TRANSFORM_TRANSLATE;
+        type = SVG_TRANSFORM_TRANSLATE;
     else if (skipString(ptr, end, rotateDesc, WTF_ARRAY_LENGTH(rotateDesc)))
-        type = SVGTransform::SVG_TRANSFORM_ROTATE;
+        type = SVG_TRANSFORM_ROTATE;
     else if (skipString(ptr, end, matrixDesc, WTF_ARRAY_LENGTH(matrixDesc)))
-        type = SVGTransform::SVG_TRANSFORM_MATRIX;
+        type = SVG_TRANSFORM_MATRIX;
     else
         return false;
 
     return true;
 }
 
-SVGTransform::SVGTransformType parseTransformType(const String& string)
+template bool parseAndSkipTransformType(const UChar*& current, const UChar* end, SVGTransformType&);
+template bool parseAndSkipTransformType(const LChar*& current, const LChar* end, SVGTransformType&);
+
+SVGTransformType parseTransformType(const String& string)
 {
     if (string.isEmpty())
-        return SVGTransform::SVG_TRANSFORM_UNKNOWN;
-    unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
+        return SVG_TRANSFORM_UNKNOWN;
+    SVGTransformType type = SVG_TRANSFORM_UNKNOWN;
     if (string.is8Bit()) {
         const LChar* ptr = string.characters8();
         const LChar* end = ptr + string.length();
-        parseAndSkipType(ptr, end, type);
+        parseAndSkipTransformType(ptr, end, type);
     } else {
         const UChar* ptr = string.characters16();
         const UChar* end = ptr + string.length();
-        parseAndSkipType(ptr, end, type);
+        parseAndSkipTransformType(ptr, end, type);
     }
-    return static_cast<SVGTransform::SVGTransformType>(type);
-}
-
-template<typename CharType>
-bool parseTransformAttributeInternal(SVGTransformList& list, const CharType*& ptr, const CharType* end, TransformParsingMode mode)
-{
-    if (mode == ClearList)
-        list.clear();
-
-    bool delimParsed = false;
-    while (ptr < end) {
-        delimParsed = false;
-        unsigned short type = SVGTransform::SVG_TRANSFORM_UNKNOWN;
-        skipOptionalSVGSpaces(ptr, end);
-
-        if (!parseAndSkipType(ptr, end, type))
-            return false;
-
-        SVGTransform transform;
-        if (!parseTransformValue(type, ptr, end, transform))
-            return false;
-
-        list.append(transform);
-        skipOptionalSVGSpaces(ptr, end);
-        if (ptr < end && *ptr == ',') {
-            delimParsed = true;
-            ++ptr;
-        }
-        skipOptionalSVGSpaces(ptr, end);
-    }
-
-    return !delimParsed;
-}
-
-bool parseTransformAttribute(SVGTransformList& list, const LChar*& ptr, const LChar* end, TransformParsingMode mode)
-{
-    return parseTransformAttributeInternal(list, ptr, end, mode);
-}
-
-bool parseTransformAttribute(SVGTransformList& list, const UChar*& ptr, const UChar* end, TransformParsingMode mode)
-{
-    return parseTransformAttributeInternal(list, ptr, end, mode);
+    return type;
 }
 
 }
diff --git a/Source/core/svg/SVGParserUtilities.h b/Source/core/svg/SVGParserUtilities.h
index ef48605..6e2e423 100644
--- a/Source/core/svg/SVGParserUtilities.h
+++ b/Source/core/svg/SVGParserUtilities.h
@@ -34,13 +34,11 @@
 class FloatPoint;
 class FloatRect;
 class SVGPointList;
-class SVGTransformList;
 
 template <typename CharType>
 bool parseSVGNumber(CharType* ptr, size_t length, double& number);
 bool parseNumber(const LChar*& ptr, const LChar* end, float& number, bool skip = true);
 bool parseNumber(const UChar*& ptr, const UChar* end, float& number, bool skip = true);
-bool parseNumberFromString(const String&, float& number, bool skip = true);
 bool parseNumberOptionalNumber(const String& s, float& h, float& v);
 bool parseArcFlag(const LChar*& ptr, const LChar* end, bool& flag);
 bool parseArcFlag(const UChar*& ptr, const UChar* end, bool& flag);
@@ -82,23 +80,13 @@
     return ptr < end;
 }
 
-bool pointsListFromSVGData(SVGPointList& pointsList, const String& points);
 Vector<String> parseDelimitedString(const String& input, const char seperator);
 bool parseKerningUnicodeString(const String& input, UnicodeRanges&, HashSet<String>& stringList);
 bool parseGlyphName(const String& input, HashSet<String>& values);
 
-enum TransformParsingMode {
-    ClearList,
-    DoNotClearList
-};
-
-bool parseTransformAttribute(SVGTransformList&, const LChar*& ptr, const LChar* end, TransformParsingMode = ClearList);
-bool parseTransformAttribute(SVGTransformList&, const UChar*& ptr, const UChar* end, TransformParsingMode = ClearList);
-
-bool parseTransformValue(unsigned type, const LChar*& ptr, const LChar* end, SVGTransform&);
-bool parseTransformValue(unsigned type, const UChar*& ptr, const UChar* end, SVGTransform&);
-
-SVGTransform::SVGTransformType parseTransformType(const String&);
+template<typename CharType>
+bool parseAndSkipTransformType(const CharType*& ptr, const CharType* end, SVGTransformType&);
+SVGTransformType parseTransformType(const String&);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGPathByteStream.h b/Source/core/svg/SVGPathByteStream.h
index 1fedc1e..05940cf 100644
--- a/Source/core/svg/SVGPathByteStream.h
+++ b/Source/core/svg/SVGPathByteStream.h
@@ -40,7 +40,7 @@
         return adoptPtr(new SVGPathByteStream);
     }
 
-    PassOwnPtr<SVGPathByteStream> copy()
+    PassOwnPtr<SVGPathByteStream> copy() const
     {
         return adoptPtr(new SVGPathByteStream(m_data));
     }
@@ -48,22 +48,19 @@
     typedef Vector<unsigned char> Data;
     typedef Data::const_iterator DataIterator;
 
-    DataIterator begin() { return m_data.begin(); }
-    DataIterator end() { return m_data.end(); }
+    DataIterator begin() const { return m_data.begin(); }
+    DataIterator end() const { return m_data.end(); }
     void append(unsigned char byte) { m_data.append(byte); }
-    void append(SVGPathByteStream* other) { m_data.append(other->m_data); }
+    void append(SVGPathByteStream* other) { m_data.appendVector(other->m_data); }
     void clear() { m_data.clear(); }
     void reserveInitialCapacity(size_t size) { m_data.reserveInitialCapacity(size); }
     void shrinkToFit() { m_data.shrinkToFit(); }
     bool isEmpty() const { return m_data.isEmpty(); }
     unsigned size() const { return m_data.size(); }
 
-    // Only defined to let SVGAnimatedPathAnimator use the standard list code paths - this method is never called.
-    void resize(unsigned) { }
-
 private:
     SVGPathByteStream() { }
-    SVGPathByteStream(Data& data)
+    SVGPathByteStream(const Data& data)
         : m_data(data)
     {
     }
diff --git a/Source/core/svg/SVGPathByteStreamSource.cpp b/Source/core/svg/SVGPathByteStreamSource.cpp
index 613ef85..efabe89 100644
--- a/Source/core/svg/SVGPathByteStreamSource.cpp
+++ b/Source/core/svg/SVGPathByteStreamSource.cpp
@@ -23,7 +23,7 @@
 
 namespace WebCore {
 
-SVGPathByteStreamSource::SVGPathByteStreamSource(SVGPathByteStream* stream)
+SVGPathByteStreamSource::SVGPathByteStreamSource(const SVGPathByteStream* stream)
 {
     ASSERT(stream);
     m_streamCurrent = stream->begin();
diff --git a/Source/core/svg/SVGPathByteStreamSource.h b/Source/core/svg/SVGPathByteStreamSource.h
index 17ff698..a834905 100644
--- a/Source/core/svg/SVGPathByteStreamSource.h
+++ b/Source/core/svg/SVGPathByteStreamSource.h
@@ -29,14 +29,9 @@
 
 class SVGPathByteStreamSource FINAL : public SVGPathSource {
 public:
-    static PassOwnPtr<SVGPathByteStreamSource> create(SVGPathByteStream* stream)
-    {
-        return adoptPtr(new SVGPathByteStreamSource(stream));
-    }
+    explicit SVGPathByteStreamSource(const SVGPathByteStream*);
 
 private:
-    SVGPathByteStreamSource(SVGPathByteStream*);
-
     virtual bool hasMoreData() const OVERRIDE;
     virtual bool moveToNextToken() OVERRIDE { return true; }
     virtual bool parseSVGSegmentType(SVGPathSegType&) OVERRIDE;
diff --git a/Source/core/svg/SVGPathElement.cpp b/Source/core/svg/SVGPathElement.cpp
index 4fcb1f1..1b5bf37 100644
--- a/Source/core/svg/SVGPathElement.cpp
+++ b/Source/core/svg/SVGPathElement.cpp
@@ -47,42 +47,18 @@
 #include "core/svg/SVGPathSegMovetoRel.h"
 #include "core/svg/SVGPathUtilities.h"
 #include "core/svg/SVGPointTearOff.h"
-#include "core/svg/properties/SVGPathSegListPropertyTearOff.h"
 
 namespace WebCore {
 
-// Define custom animated property 'd'.
-const SVGPropertyInfo* SVGPathElement::dPropertyInfo()
-{
-    static const SVGPropertyInfo* s_propertyInfo = 0;
-    if (!s_propertyInfo) {
-        s_propertyInfo = new SVGPropertyInfo(AnimatedPath,
-                                             PropertyIsReadWrite,
-                                             SVGNames::dAttr,
-                                             SVGNames::dAttr.localName(),
-                                             &SVGPathElement::synchronizeD,
-                                             &SVGPathElement::lookupOrCreateDWrapper);
-    }
-    return s_propertyInfo;
-}
-
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGPathElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(d)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGPathElement::SVGPathElement(Document& document)
     : SVGGeometryElement(SVGNames::pathTag, document)
-    , m_pathByteStream(SVGPathByteStream::create())
-    , m_pathSegList(PathSegUnalteredRole)
-    , m_isAnimValObserved(false)
     , m_pathLength(SVGAnimatedNumber::create(this, SVGNames::pathLengthAttr, SVGNumber::create()))
+    , m_pathSegList(SVGAnimatedPath::create(this, SVGNames::dAttr))
 {
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_pathLength);
-    registerAnimatedPropertiesForSVGPathElement();
+    addToPropertyMap(m_pathSegList);
 }
 
 PassRefPtr<SVGPathElement> SVGPathElement::create(Document& document)
@@ -111,99 +87,99 @@
     return pathSeg;
 }
 
-PassRefPtr<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath(SVGPathSegRole role)
+PassRefPtr<SVGPathSegClosePath> SVGPathElement::createSVGPathSegClosePath()
 {
-    return SVGPathSegClosePath::create(this, role);
+    return SVGPathSegClosePath::create(0, PathSegUndefinedRole);
 }
 
-PassRefPtr<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegMovetoAbs> SVGPathElement::createSVGPathSegMovetoAbs(float x, float y)
 {
-    return SVGPathSegMovetoAbs::create(this, role, x, y);
+    return SVGPathSegMovetoAbs::create(0, PathSegUndefinedRole, x, y);
 }
 
-PassRefPtr<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegMovetoRel> SVGPathElement::createSVGPathSegMovetoRel(float x, float y)
 {
-    return SVGPathSegMovetoRel::create(this, role, x, y);
+    return SVGPathSegMovetoRel::create(0, PathSegUndefinedRole, x, y);
 }
 
-PassRefPtr<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoAbs> SVGPathElement::createSVGPathSegLinetoAbs(float x, float y)
 {
-    return SVGPathSegLinetoAbs::create(this, role, x, y);
+    return SVGPathSegLinetoAbs::create(0, PathSegUndefinedRole, x, y);
 }
 
-PassRefPtr<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoRel> SVGPathElement::createSVGPathSegLinetoRel(float x, float y)
 {
-    return SVGPathSegLinetoRel::create(this, role, x, y);
+    return SVGPathSegLinetoRel::create(0, PathSegUndefinedRole, x, y);
 }
 
-PassRefPtr<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicAbs> SVGPathElement::createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2)
 {
-    return SVGPathSegCurvetoCubicAbs::create(this, role, x, y, x1, y1, x2, y2);
+    return SVGPathSegCurvetoCubicAbs::create(0, PathSegUndefinedRole, x, y, x1, y1, x2, y2);
 }
 
-PassRefPtr<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicRel> SVGPathElement::createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2)
 {
-    return SVGPathSegCurvetoCubicRel::create(this, role, x, y, x1, y1, x2, y2);
+    return SVGPathSegCurvetoCubicRel::create(0, PathSegUndefinedRole, x, y, x1, y1, x2, y2);
 }
 
-PassRefPtr<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1)
 {
-    return SVGPathSegCurvetoQuadraticAbs::create(this, role, x, y, x1, y1);
+    return SVGPathSegCurvetoQuadraticAbs::create(0, PathSegUndefinedRole, x, y, x1, y1);
 }
 
-PassRefPtr<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticRel> SVGPathElement::createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1)
 {
-    return SVGPathSegCurvetoQuadraticRel::create(this, role, x, y, x1, y1);
+    return SVGPathSegCurvetoQuadraticRel::create(0, PathSegUndefinedRole, x, y, x1, y1);
 }
 
-PassRefPtr<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role)
+PassRefPtr<SVGPathSegArcAbs> SVGPathElement::createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
 {
-    return SVGPathSegArcAbs::create(this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
+    return SVGPathSegArcAbs::create(0, PathSegUndefinedRole, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
 }
 
-PassRefPtr<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role)
+PassRefPtr<SVGPathSegArcRel> SVGPathElement::createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag)
 {
-    return SVGPathSegArcRel::create(this, role, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
+    return SVGPathSegArcRel::create(0, PathSegUndefinedRole, x, y, r1, r2, angle, largeArcFlag, sweepFlag);
 }
 
-PassRefPtr<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoHorizontalAbs> SVGPathElement::createSVGPathSegLinetoHorizontalAbs(float x)
 {
-    return SVGPathSegLinetoHorizontalAbs::create(this, role, x);
+    return SVGPathSegLinetoHorizontalAbs::create(0, PathSegUndefinedRole, x);
 }
 
-PassRefPtr<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoHorizontalRel> SVGPathElement::createSVGPathSegLinetoHorizontalRel(float x)
 {
-    return SVGPathSegLinetoHorizontalRel::create(this, role, x);
+    return SVGPathSegLinetoHorizontalRel::create(0, PathSegUndefinedRole, x);
 }
 
-PassRefPtr<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoVerticalAbs> SVGPathElement::createSVGPathSegLinetoVerticalAbs(float y)
 {
-    return SVGPathSegLinetoVerticalAbs::create(this, role, y);
+    return SVGPathSegLinetoVerticalAbs::create(0, PathSegUndefinedRole, y);
 }
 
-PassRefPtr<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegLinetoVerticalRel> SVGPathElement::createSVGPathSegLinetoVerticalRel(float y)
 {
-    return SVGPathSegLinetoVerticalRel::create(this, role, y);
+    return SVGPathSegLinetoVerticalRel::create(0, PathSegUndefinedRole, y);
 }
 
-PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> SVGPathElement::createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2)
 {
-    return SVGPathSegCurvetoCubicSmoothAbs::create(this, role, x, y, x2, y2);
+    return SVGPathSegCurvetoCubicSmoothAbs::create(0, PathSegUndefinedRole, x, y, x2, y2);
 }
 
-PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> SVGPathElement::createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2)
 {
-    return SVGPathSegCurvetoCubicSmoothRel::create(this, role, x, y, x2, y2);
+    return SVGPathSegCurvetoCubicSmoothRel::create(0, PathSegUndefinedRole, x, y, x2, y2);
 }
 
-PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y)
 {
-    return SVGPathSegCurvetoQuadraticSmoothAbs::create(this, role, x, y);
+    return SVGPathSegCurvetoQuadraticSmoothAbs::create(0, PathSegUndefinedRole, x, y);
 }
 
-PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole role)
+PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> SVGPathElement::createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y)
 {
-    return SVGPathSegCurvetoQuadraticSmoothRel::create(this, role, x, y);
+    return SVGPathSegCurvetoQuadraticSmoothRel::create(0, PathSegUndefinedRole, x, y);
 }
 
 bool SVGPathElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -223,18 +199,14 @@
         return;
     }
 
-    if (name == SVGNames::dAttr) {
-        if (!buildSVGPathByteStreamFromString(value, m_pathByteStream.get(), UnalteredParsing))
-            document().accessSVGExtensions()->reportError("Problem parsing d=\"" + value + "\"");
-        return;
-    }
-
     SVGParsingError parseError = NoError;
 
-    if (name == SVGNames::pathLengthAttr) {
+    if (name == SVGNames::dAttr) {
+        m_pathSegList->setBaseValueAsString(value, parseError);
+    } else if (name == SVGNames::pathLengthAttr) {
         m_pathLength->setBaseValueAsString(value, parseError);
         if (parseError == NoError && m_pathLength->baseValue()->value() < 0)
-            document().accessSVGExtensions()->reportError("A negative value for path attribute <pathLength> is not allowed");
+            document().accessSVGExtensions().reportError("A negative value for path attribute <pathLength> is not allowed");
     } else {
         ASSERT_NOT_REACHED();
     }
@@ -254,12 +226,6 @@
     RenderSVGPath* renderer = toRenderSVGPath(this->renderer());
 
     if (attrName == SVGNames::dAttr) {
-        if (m_pathSegList.shouldSynchronize && !SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(this, dPropertyInfo())->isAnimating()) {
-            SVGPathSegList newList(PathSegUnalteredRole);
-            buildSVGPathSegListFromByteStream(m_pathByteStream.get(), this, newList, UnalteredParsing);
-            m_pathSegList.value = newList;
-        }
-
         if (renderer)
             renderer->setNeedsShapeUpdate();
 
@@ -274,10 +240,10 @@
 {
     // <mpath> can only reference <path> but this dependency is not handled in
     // markForLayoutAndParentResourceInvalidation so we update any mpath dependencies manually.
-    if (HashSet<SVGElement*>* dependencies = document().accessSVGExtensions()->setOfElementsReferencingTarget(this)) {
+    if (HashSet<SVGElement*>* dependencies = document().accessSVGExtensions().setOfElementsReferencingTarget(this)) {
         HashSet<SVGElement*>::iterator end = dependencies->end();
         for (HashSet<SVGElement*>::iterator it = dependencies->begin(); it != end; ++it) {
-            if ((*it)->hasTagName(SVGNames::mpathTag))
+            if (isSVGMPathElement(**it))
                 toSVGMPathElement(*it)->targetPathChanged();
         }
     }
@@ -296,79 +262,9 @@
     invalidateMPathDependencies();
 }
 
-SVGPathByteStream* SVGPathElement::pathByteStream() const
+void SVGPathElement::pathSegListChanged(ListModification listModification)
 {
-    SVGAnimatedProperty* property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(this, dPropertyInfo());
-    if (!property || !property->isAnimating())
-        return m_pathByteStream.get();
-    return static_cast<SVGAnimatedPathSegListPropertyTearOff*>(property)->animatedPathByteStream();
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGPathElement::lookupOrCreateDWrapper(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    SVGPathElement* ownerType = toSVGPathElement(contextElement);
-
-    if (SVGAnimatedProperty* property = SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(ownerType, dPropertyInfo()))
-        return property;
-
-    // Build initial SVGPathSegList.
-    buildSVGPathSegListFromByteStream(ownerType->m_pathByteStream.get(), ownerType, ownerType->m_pathSegList.value, UnalteredParsing);
-
-    return SVGAnimatedProperty::lookupOrCreateWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff, SVGPathSegList>
-           (ownerType, dPropertyInfo(), ownerType->m_pathSegList.value);
-}
-
-void SVGPathElement::synchronizeD(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    SVGPathElement* ownerType = toSVGPathElement(contextElement);
-    if (!ownerType->m_pathSegList.shouldSynchronize)
-        return;
-    ownerType->m_pathSegList.synchronize(ownerType, dPropertyInfo()->attributeName, AtomicString(ownerType->m_pathSegList.value.valueAsString()));
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::pathSegList()
-{
-    m_pathSegList.shouldSynchronize = true;
-    return static_cast<SVGPathSegListPropertyTearOff*>(static_pointer_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->baseVal());
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::normalizedPathSegList()
-{
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
-    return 0;
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::animatedPathSegList()
-{
-    m_pathSegList.shouldSynchronize = true;
-    m_isAnimValObserved = true;
-    return static_cast<SVGPathSegListPropertyTearOff*>(static_pointer_cast<SVGAnimatedPathSegListPropertyTearOff>(lookupOrCreateDWrapper(this))->animVal());
-}
-
-SVGPathSegListPropertyTearOff* SVGPathElement::animatedNormalizedPathSegList()
-{
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
-    return 0;
-}
-
-void SVGPathElement::pathSegListChanged(SVGPathSegRole role, ListModification listModification)
-{
-    switch (role) {
-    case PathSegNormalizedRole:
-        // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
-        break;
-    case PathSegUnalteredRole:
-        if (listModification == ListModificationAppend) {
-            ASSERT(!m_pathSegList.value.isEmpty());
-            appendSVGPathByteStreamFromSVGPathSeg(m_pathSegList.value.last(), m_pathByteStream.get(), UnalteredParsing);
-        } else
-            buildSVGPathByteStreamFromSVGPathSegList(m_pathSegList.value, m_pathByteStream.get(), UnalteredParsing);
-        break;
-    case PathSegUndefinedRole:
-        return;
-    }
+    m_pathSegList->baseValue()->clearByteStream();
 
     invalidateSVGAttributes();
 
diff --git a/Source/core/svg/SVGPathElement.h b/Source/core/svg/SVGPathElement.h
index 99722ab..7f01e4e 100644
--- a/Source/core/svg/SVGPathElement.h
+++ b/Source/core/svg/SVGPathElement.h
@@ -24,9 +24,10 @@
 #include "SVGNames.h"
 #include "core/svg/SVGAnimatedBoolean.h"
 #include "core/svg/SVGAnimatedNumber.h"
+#include "core/svg/SVGAnimatedPath.h"
 #include "core/svg/SVGGeometryElement.h"
 #include "core/svg/SVGPathByteStream.h"
-#include "core/svg/SVGPathSegList.h"
+#include "wtf/WeakPtr.h"
 
 namespace WebCore {
 
@@ -49,7 +50,6 @@
 class SVGPathSegCurvetoCubicSmoothRel;
 class SVGPathSegCurvetoQuadraticSmoothAbs;
 class SVGPathSegCurvetoQuadraticSmoothRel;
-class SVGPathSegListPropertyTearOff;
 
 class SVGPathElement FINAL : public SVGGeometryElement {
 public:
@@ -61,42 +61,40 @@
 
     SVGAnimatedNumber* pathLength() { return m_pathLength.get(); }
 
-    PassRefPtr<SVGPathSegClosePath> createSVGPathSegClosePath(SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegMovetoAbs> createSVGPathSegMovetoAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegMovetoRel> createSVGPathSegMovetoRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegLinetoAbs> createSVGPathSegLinetoAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegLinetoRel> createSVGPathSegLinetoRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoCubicAbs> createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoCubicRel> createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoQuadraticAbs> createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoQuadraticRel> createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegArcAbs> createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegArcRel> createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegLinetoHorizontalAbs> createSVGPathSegLinetoHorizontalAbs(float x, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegLinetoHorizontalRel> createSVGPathSegLinetoHorizontalRel(float x, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegLinetoVerticalAbs> createSVGPathSegLinetoVerticalAbs(float y, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegLinetoVerticalRel> createSVGPathSegLinetoVerticalRel(float y, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
-    PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y, SVGPathSegRole role = PathSegUndefinedRole);
+    PassRefPtr<SVGPathSegClosePath> createSVGPathSegClosePath();
+    PassRefPtr<SVGPathSegMovetoAbs> createSVGPathSegMovetoAbs(float x, float y);
+    PassRefPtr<SVGPathSegMovetoRel> createSVGPathSegMovetoRel(float x, float y);
+    PassRefPtr<SVGPathSegLinetoAbs> createSVGPathSegLinetoAbs(float x, float y);
+    PassRefPtr<SVGPathSegLinetoRel> createSVGPathSegLinetoRel(float x, float y);
+    PassRefPtr<SVGPathSegCurvetoCubicAbs> createSVGPathSegCurvetoCubicAbs(float x, float y, float x1, float y1, float x2, float y2);
+    PassRefPtr<SVGPathSegCurvetoCubicRel> createSVGPathSegCurvetoCubicRel(float x, float y, float x1, float y1, float x2, float y2);
+    PassRefPtr<SVGPathSegCurvetoQuadraticAbs> createSVGPathSegCurvetoQuadraticAbs(float x, float y, float x1, float y1);
+    PassRefPtr<SVGPathSegCurvetoQuadraticRel> createSVGPathSegCurvetoQuadraticRel(float x, float y, float x1, float y1);
+    PassRefPtr<SVGPathSegArcAbs> createSVGPathSegArcAbs(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag);
+    PassRefPtr<SVGPathSegArcRel> createSVGPathSegArcRel(float x, float y, float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag);
+    PassRefPtr<SVGPathSegLinetoHorizontalAbs> createSVGPathSegLinetoHorizontalAbs(float x);
+    PassRefPtr<SVGPathSegLinetoHorizontalRel> createSVGPathSegLinetoHorizontalRel(float x);
+    PassRefPtr<SVGPathSegLinetoVerticalAbs> createSVGPathSegLinetoVerticalAbs(float y);
+    PassRefPtr<SVGPathSegLinetoVerticalRel> createSVGPathSegLinetoVerticalRel(float y);
+    PassRefPtr<SVGPathSegCurvetoCubicSmoothAbs> createSVGPathSegCurvetoCubicSmoothAbs(float x, float y, float x2, float y2);
+    PassRefPtr<SVGPathSegCurvetoCubicSmoothRel> createSVGPathSegCurvetoCubicSmoothRel(float x, float y, float x2, float y2);
+    PassRefPtr<SVGPathSegCurvetoQuadraticSmoothAbs> createSVGPathSegCurvetoQuadraticSmoothAbs(float x, float y);
+    PassRefPtr<SVGPathSegCurvetoQuadraticSmoothRel> createSVGPathSegCurvetoQuadraticSmoothRel(float x, float y);
 
     // Used in the bindings only.
-    SVGPathSegListPropertyTearOff* pathSegList();
-    SVGPathSegListPropertyTearOff* animatedPathSegList();
-    SVGPathSegListPropertyTearOff* normalizedPathSegList();
-    SVGPathSegListPropertyTearOff* animatedNormalizedPathSegList();
+    SVGPathSegListTearOff* pathSegList() { return m_pathSegList->baseVal(); }
+    SVGPathSegListTearOff* animatedPathSegList() { return m_pathSegList->animVal(); }
 
-    SVGPathByteStream* pathByteStream() const;
+    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
+    SVGPathSegListTearOff* normalizedPathSegList() { return 0; }
+    SVGPathSegListTearOff* animatedNormalizedPathSegList() { return 0; }
 
-    void pathSegListChanged(SVGPathSegRole, ListModification = ListModificationUnknown);
+    const SVGPathByteStream* pathByteStream() const { return m_pathSegList->currentValue()->byteStream(); }
+
+    void pathSegListChanged(ListModification = ListModificationUnknown);
 
     virtual FloatRect getBBox() OVERRIDE;
 
-    static const SVGPropertyInfo* dPropertyInfo();
-
-    bool isAnimValObserved() const { return m_isAnimValObserved; }
-
 private:
     explicit SVGPathElement(Document&);
 
@@ -107,26 +105,15 @@
     virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
     virtual bool supportsMarkers() const OVERRIDE { return true; }
 
-    // Custom 'd' property
-    static void synchronizeD(SVGElement* contextElement);
-    static PassRefPtr<SVGAnimatedProperty> lookupOrCreateDWrapper(SVGElement* contextElement);
-
     virtual Node::InsertionNotificationRequest insertedInto(ContainerNode*) OVERRIDE;
     virtual void removedFrom(ContainerNode*) OVERRIDE;
 
     void invalidateMPathDependencies();
 
-    OwnPtr<SVGPathByteStream> m_pathByteStream;
-    mutable SVGSynchronizableAnimatedProperty<SVGPathSegList> m_pathSegList;
-    bool m_isAnimValObserved;
-
     RefPtr<SVGAnimatedNumber> m_pathLength;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPathElement)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedPath> m_pathSegList;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGPathElement, hasTagName(SVGNames::pathTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGPathParser.cpp b/Source/core/svg/SVGPathParser.cpp
index 6b7ac43..57ba8a5 100644
--- a/Source/core/svg/SVGPathParser.cpp
+++ b/Source/core/svg/SVGPathParser.cpp
@@ -456,9 +456,9 @@
 
     float thetaArc = theta2 - theta1;
     if (thetaArc < 0 && sweepFlag)
-        thetaArc += 2 * piFloat;
+        thetaArc += twoPiFloat;
     else if (thetaArc > 0 && !sweepFlag)
-        thetaArc -= 2 * piFloat;
+        thetaArc -= twoPiFloat;
 
     pointTransform.makeIdentity();
     pointTransform.rotate(angle);
diff --git a/Source/core/fetch/CachedMetadata.cpp b/Source/core/svg/SVGPathSeg.cpp
similarity index 78%
rename from Source/core/fetch/CachedMetadata.cpp
rename to Source/core/svg/SVGPathSeg.cpp
index 7edcac5..2babb63 100644
--- a/Source/core/fetch/CachedMetadata.cpp
+++ b/Source/core/svg/SVGPathSeg.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2011 Google Inc. All rights reserved.
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -29,8 +29,23 @@
  */
 
 #include "config.h"
-#include "core/fetch/CachedMetadata.h"
+#include "core/svg/SVGPathSeg.h"
+
+#include "core/svg/SVGPathElement.h"
 
 namespace WebCore {
 
-} // namespace WebCore
+SVGPathSeg::SVGPathSeg(SVGPathElement* contextElement)
+    : m_ownerList(0)
+    , m_contextElement(contextElement)
+{
+    ScriptWrappable::init(this);
+}
+
+void SVGPathSeg::commitChange()
+{
+    if (m_contextElement)
+        toSVGPathElement(m_contextElement)->pathSegListChanged();
+}
+
+}
diff --git a/Source/core/svg/SVGPathSeg.h b/Source/core/svg/SVGPathSeg.h
index 565bfa0..92f3175 100644
--- a/Source/core/svg/SVGPathSeg.h
+++ b/Source/core/svg/SVGPathSeg.h
@@ -27,6 +27,14 @@
 
 namespace WebCore {
 
+enum ListModification {
+    ListModificationUnknown = 0,
+    ListModificationInsert = 1,
+    ListModificationReplace = 2,
+    ListModificationRemove = 3,
+    ListModificationAppend = 4
+};
+
 enum SVGPathSegType {
     PathSegUnknown = 0,
     PathSegClosePath = 1,
@@ -56,12 +64,17 @@
     PathSegUndefinedRole = 2
 };
 
+class NewSVGPropertyBase;
+class SVGPathElement;
+class SVGElement;
+
 class SVGPathSeg : public RefCounted<SVGPathSeg>, public ScriptWrappable {
 public:
-    SVGPathSeg()
-    {
-        ScriptWrappable::init(this);
-    }
+    // SVGPathSeg itself is used as a tear-off type.
+    // FIXME: A tear-off type should be introduced to distinguish animVal/baseVal
+    typedef SVGPathSeg TearOffType;
+
+    explicit SVGPathSeg(SVGPathElement* contextElement);
 
     virtual ~SVGPathSeg() { }
 
@@ -91,6 +104,32 @@
 
     virtual unsigned short pathSegType() const = 0;
     virtual String pathSegTypeAsLetter() const = 0;
+
+    NewSVGPropertyBase* ownerList() const
+    {
+        return m_ownerList;
+    }
+
+    void setOwnerList(NewSVGPropertyBase* ownerList)
+    {
+        // Previous owner list must be cleared before setting new owner list.
+        ASSERT((!ownerList && m_ownerList) || (ownerList && !m_ownerList));
+
+        m_ownerList = ownerList;
+    }
+
+    void setContextElement(SVGElement* contextElement)
+    {
+        m_contextElement = contextElement;
+    }
+
+protected:
+    void commitChange();
+
+private:
+    // FIXME: oilpan: These are kept as raw ptrs to break reference cycle. Should be Member in oilpan.
+    NewSVGPropertyBase* m_ownerList;
+    SVGElement* m_contextElement;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGPathSeg.idl b/Source/core/svg/SVGPathSeg.idl
index 60ed633..4b9ce79 100644
--- a/Source/core/svg/SVGPathSeg.idl
+++ b/Source/core/svg/SVGPathSeg.idl
@@ -26,6 +26,7 @@
 
 [
     Custom=Wrap,
+    DependentLifetime,
 ] interface SVGPathSeg {
     // Path Segment Types
     const unsigned short PATHSEG_UNKNOWN = 0;
@@ -52,4 +53,3 @@
     readonly attribute unsigned short pathSegType;
     readonly attribute DOMString pathSegTypeAsLetter;
 };
-
diff --git a/Source/core/svg/SVGPathSegClosePath.idl b/Source/core/svg/SVGPathSegClosePath.idl
index e05ca79..bb47b28 100644
--- a/Source/core/svg/SVGPathSegClosePath.idl
+++ b/Source/core/svg/SVGPathSegClosePath.idl
@@ -26,4 +26,3 @@
 
 interface SVGPathSegClosePath : SVGPathSeg {
 };
-
diff --git a/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl b/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl
index c8703d6..abf351d 100644
--- a/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl
+++ b/Source/core/svg/SVGPathSegCurvetoCubicAbs.idl
@@ -34,4 +34,3 @@
     attribute float x2;
     attribute float y2;
 };
-
diff --git a/Source/core/svg/SVGPathSegCurvetoCubicRel.idl b/Source/core/svg/SVGPathSegCurvetoCubicRel.idl
index 645276d..c13d8b8 100644
--- a/Source/core/svg/SVGPathSegCurvetoCubicRel.idl
+++ b/Source/core/svg/SVGPathSegCurvetoCubicRel.idl
@@ -34,4 +34,3 @@
     attribute float x2;
     attribute float y2;
 };
-
diff --git a/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl b/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl
index 34294a0..8b05bd8 100644
--- a/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl
+++ b/Source/core/svg/SVGPathSegCurvetoCubicSmoothRel.idl
@@ -32,4 +32,3 @@
     attribute float x2;
     attribute float y2;
 };
-
diff --git a/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl b/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl
index 7500b40..b271ae0 100644
--- a/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl
+++ b/Source/core/svg/SVGPathSegCurvetoQuadraticAbs.idl
@@ -32,4 +32,3 @@
     attribute float x1;
     attribute float y1;
 };
-
diff --git a/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl b/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl
index 7554dfe..61c6378 100644
--- a/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl
+++ b/Source/core/svg/SVGPathSegCurvetoQuadraticRel.idl
@@ -32,4 +32,3 @@
     attribute float x1;
     attribute float y1;
 };
-
diff --git a/Source/core/svg/SVGPathSegList.cpp b/Source/core/svg/SVGPathSegList.cpp
index 475a043..defed36 100644
--- a/Source/core/svg/SVGPathSegList.cpp
+++ b/Source/core/svg/SVGPathSegList.cpp
@@ -25,22 +25,215 @@
 #include "core/svg/SVGPathSegList.h"
 
 #include "SVGNames.h"
+#include "core/svg/SVGAnimationElement.h"
+#include "core/svg/SVGPathBlender.h"
+#include "core/svg/SVGPathByteStreamBuilder.h"
+#include "core/svg/SVGPathByteStreamSource.h"
 #include "core/svg/SVGPathElement.h"
+#include "core/svg/SVGPathParser.h"
+#include "core/svg/SVGPathSegListBuilder.h"
+#include "core/svg/SVGPathSegListSource.h"
 #include "core/svg/SVGPathUtilities.h"
 
 namespace WebCore {
 
-String SVGPathSegList::valueAsString() const
-{
-    String pathString;
-    buildStringFromSVGPathSegList(*this, pathString, UnalteredParsing);
-    return pathString;
-}
-
-void SVGPathSegList::commitChange(SVGElement* contextElement, ListModification listModification)
+SVGPathSegList::SVGPathSegList(SVGPathElement* contextElement, SVGPathSegRole role)
+    : m_contextElement(contextElement)
+    , m_role(role)
+    , m_listSyncedToByteStream(true)
 {
     ASSERT(contextElement);
-    toSVGPathElement(contextElement)->pathSegListChanged(m_role, listModification);
+}
+
+SVGPathSegList::SVGPathSegList(SVGPathElement* contextElement, SVGPathSegRole role, PassOwnPtr<SVGPathByteStream> byteStream)
+    : m_contextElement(contextElement)
+    , m_role(role)
+    , m_byteStream(byteStream)
+    , m_listSyncedToByteStream(true)
+{
+    ASSERT(contextElement);
+}
+
+SVGPathSegList::~SVGPathSegList()
+{
+}
+
+PassRefPtr<SVGPathSegList> SVGPathSegList::clone()
+{
+    RefPtr<SVGPathSegList> svgPathSegList = adoptRef(new SVGPathSegList(m_contextElement, m_role, byteStream()->copy()));
+    svgPathSegList->invalidateList();
+    return svgPathSegList.release();
+}
+
+PassRefPtr<NewSVGPropertyBase> SVGPathSegList::cloneForAnimation(const String& value) const
+{
+    RefPtr<SVGPathSegList> svgPathSegList = SVGPathSegList::create(m_contextElement);
+    svgPathSegList->setValueAsString(value, IGNORE_EXCEPTION);
+    return svgPathSegList;
+}
+
+const SVGPathByteStream* SVGPathSegList::byteStream() const
+{
+    if (!m_byteStream) {
+        m_byteStream = SVGPathByteStream::create();
+
+        if (!Base::isEmpty()) {
+            SVGPathByteStreamBuilder builder;
+            builder.setCurrentByteStream(m_byteStream.get());
+
+            SVGPathSegListSource source(begin(), end());
+
+            SVGPathParser parser;
+            parser.setCurrentConsumer(&builder);
+            parser.setCurrentSource(&source);
+            parser.parsePathDataFromSource(UnalteredParsing);
+        }
+    }
+
+    return m_byteStream.get();
+}
+
+void SVGPathSegList::updateListFromByteStream()
+{
+    if (m_listSyncedToByteStream)
+        return;
+
+    Base::clear();
+
+    if (m_byteStream && !m_byteStream->isEmpty()) {
+        SVGPathSegListBuilder builder;
+        builder.setCurrentSVGPathElement(m_contextElement);
+        builder.setCurrentSVGPathSegList(this);
+        builder.setCurrentSVGPathSegRole(PathSegUnalteredRole);
+
+        SVGPathByteStreamSource source(m_byteStream.get());
+
+        SVGPathParser parser;
+        parser.setCurrentConsumer(&builder);
+        parser.setCurrentSource(&source);
+        parser.parsePathDataFromSource(UnalteredParsing);
+    }
+
+    m_listSyncedToByteStream = true;
+}
+
+void SVGPathSegList::invalidateList()
+{
+    m_listSyncedToByteStream = false;
+    Base::clear();
+}
+
+PassRefPtr<SVGPathSeg> SVGPathSegList::appendItem(PassRefPtr<SVGPathSeg> passItem)
+{
+    updateListFromByteStream();
+    RefPtr<SVGPathSeg> item = Base::appendItem(passItem);
+
+    if (m_byteStream) {
+        SVGPathByteStreamBuilder builder;
+        builder.setCurrentByteStream(m_byteStream.get());
+
+        SVGPathSegListSource source(lastAppended(), end());
+
+        SVGPathParser parser;
+        parser.setCurrentConsumer(&builder);
+        parser.setCurrentSource(&source);
+        parser.parsePathDataFromSource(UnalteredParsing, false);
+    }
+
+    return item.release();
+}
+
+String SVGPathSegList::valueAsString() const
+{
+    String string;
+    buildStringFromByteStream(byteStream(), string, UnalteredParsing);
+    return string;
+}
+
+void SVGPathSegList::setValueAsString(const String& string, ExceptionState& exceptionState)
+{
+    invalidateList();
+    if (!m_byteStream)
+        m_byteStream = SVGPathByteStream::create();
+    if (!buildSVGPathByteStreamFromString(string, m_byteStream.get(), UnalteredParsing))
+        exceptionState.throwDOMException(SyntaxError, "Problem parsing path \"" + string + "\"");
+}
+
+void SVGPathSegList::add(PassRefPtr<NewSVGPropertyBase> other, SVGElement*)
+{
+    RefPtr<SVGPathSegList> otherList = toSVGPathSegList(other);
+    if (length() != otherList->length())
+        return;
+
+    byteStream(); // create |m_byteStream| if not exist.
+    addToSVGPathByteStream(m_byteStream.get(), otherList->byteStream());
+    invalidateList();
+}
+
+void SVGPathSegList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> fromValue, PassRefPtr<NewSVGPropertyBase> toValue, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement*)
+{
+    invalidateList();
+
+    ASSERT(animationElement);
+    bool isToAnimation = animationElement->animationMode() == ToAnimation;
+
+    const RefPtr<SVGPathSegList> from = toSVGPathSegList(fromValue);
+    const RefPtr<SVGPathSegList> to = toSVGPathSegList(toValue);
+    const RefPtr<SVGPathSegList> toAtEndOfDuration = toSVGPathSegList(toAtEndOfDurationValue);
+
+    const SVGPathByteStream* toStream = to->byteStream();
+    const SVGPathByteStream* fromStream = from->byteStream();
+    OwnPtr<SVGPathByteStream> copy;
+
+    // If no 'to' value is given, nothing to animate.
+    if (!toStream->size())
+        return;
+
+    if (isToAnimation) {
+        copy = byteStream()->copy();
+        fromStream = copy.get();
+    }
+
+    // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
+    if (fromStream->size() != toStream->size() && fromStream->size()) {
+        if (percentage < 0.5) {
+            if (!isToAnimation) {
+                m_byteStream = fromStream->copy();
+                return;
+            }
+        } else {
+            m_byteStream = toStream->copy();
+            return;
+        }
+    }
+
+    OwnPtr<SVGPathByteStream> lastAnimatedStream = m_byteStream.release();
+
+    m_byteStream = SVGPathByteStream::create();
+    SVGPathByteStreamBuilder builder;
+    builder.setCurrentByteStream(m_byteStream.get());
+
+    SVGPathByteStreamSource fromSource(fromStream);
+    SVGPathByteStreamSource toSource(toStream);
+
+    SVGPathBlender blender;
+    blender.blendAnimatedPath(percentage, &fromSource, &toSource, &builder);
+
+    // Handle additive='sum'.
+    if (!fromStream->size() || (animationElement->isAdditive() && !isToAnimation))
+        addToSVGPathByteStream(m_byteStream.get(), lastAnimatedStream.get());
+
+    // Handle accumulate='sum'.
+    if (animationElement->isAccumulated() && repeatCount) {
+        const SVGPathByteStream* toAtEndOfDurationStream = toAtEndOfDuration->byteStream();
+        addToSVGPathByteStream(m_byteStream.get(), toAtEndOfDurationStream, repeatCount);
+    }
+}
+
+float SVGPathSegList::calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement*)
+{
+    // FIXME: Support paced animations.
+    return -1;
 }
 
 }
diff --git a/Source/core/svg/SVGPathSegList.h b/Source/core/svg/SVGPathSegList.h
index cca091e..403bf75 100644
--- a/Source/core/svg/SVGPathSegList.h
+++ b/Source/core/svg/SVGPathSegList.h
@@ -1,56 +1,178 @@
 /*
- * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef SVGPathSegList_h
 #define SVGPathSegList_h
 
+#include "core/svg/SVGPathByteStream.h"
 #include "core/svg/SVGPathSeg.h"
-#include "core/svg/properties/SVGListProperty.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/Vector.h"
-#include "wtf/text/WTFString.h"
+#include "core/svg/properties/NewSVGAnimatedProperty.h"
+#include "core/svg/properties/NewSVGListPropertyHelper.h"
+#include "wtf/WeakPtr.h"
 
 namespace WebCore {
 
-class SVGElement;
+class SVGPathElement;
+class SVGPathSegListTearOff;
 
-class SVGPathSegList : public Vector<RefPtr<SVGPathSeg> > {
+class SVGPathSegList : public NewSVGListPropertyHelper<SVGPathSegList, SVGPathSeg> {
 public:
-    SVGPathSegList(SVGPathSegRole role)
-        : m_role(role)
+    typedef void PrimitiveType;
+    typedef SVGPathSeg ItemPropertyType;
+    typedef SVGPathSegListTearOff TearOffType;
+    typedef NewSVGListPropertyHelper<SVGPathSegList, SVGPathSeg> Base;
+
+    static PassRefPtr<SVGPathSegList> create(SVGPathElement* contextElement, SVGPathSegRole role = PathSegUndefinedRole)
     {
+        return adoptRef(new SVGPathSegList(contextElement, role));
     }
 
-    String valueAsString() const;
+    virtual ~SVGPathSegList();
 
-    // Only used by SVGPathSegListPropertyTearOff.
-    void commitChange(SVGElement* contextElement, ListModification);
+    const SVGPathByteStream* byteStream() const;
+    void clearByteStream() { m_byteStream.clear(); }
+
+    // NewSVGListPropertyHelper methods with |m_byteStream| sync:
+
+    ItemPropertyType* at(size_t index)
+    {
+        updateListFromByteStream();
+        return Base::at(index);
+    }
+
+    size_t length()
+    {
+        updateListFromByteStream();
+        return Base::length();
+    }
+
+    bool isEmpty() const
+    {
+        if (m_listSyncedToByteStream)
+            return Base::isEmpty();
+
+        return !m_byteStream || m_byteStream->isEmpty();
+    }
+
+    void clear()
+    {
+        clearByteStream();
+        Base::clear();
+    }
+
+    void append(PassRefPtr<ItemPropertyType> passNewItem)
+    {
+        updateListFromByteStream();
+        clearByteStream();
+        Base::append(passNewItem);
+    }
+
+    PassRefPtr<ItemPropertyType> initialize(PassRefPtr<ItemPropertyType> passItem)
+    {
+        clearByteStream();
+        return Base::initialize(passItem);
+    }
+
+    PassRefPtr<ItemPropertyType> getItem(size_t index, ExceptionState& exceptionState)
+    {
+        updateListFromByteStream();
+        return Base::getItem(index, exceptionState);
+    }
+
+    PassRefPtr<ItemPropertyType> insertItemBefore(PassRefPtr<ItemPropertyType> passItem, size_t index)
+    {
+        updateListFromByteStream();
+        clearByteStream();
+        return Base::insertItemBefore(passItem, index);
+    }
+
+    PassRefPtr<ItemPropertyType> replaceItem(PassRefPtr<ItemPropertyType> passItem, size_t index, ExceptionState& exceptionState)
+    {
+        updateListFromByteStream();
+        clearByteStream();
+        return Base::replaceItem(passItem, index, exceptionState);
+    }
+
+    PassRefPtr<ItemPropertyType> removeItem(size_t index, ExceptionState& exceptionState)
+    {
+        updateListFromByteStream();
+        clearByteStream();
+        return Base::removeItem(index, exceptionState);
+    }
+
+    PassRefPtr<ItemPropertyType> appendItem(PassRefPtr<ItemPropertyType> passItem);
+
+    // NewSVGPropertyBase:
+    PassRefPtr<SVGPathSegList> clone();
+    virtual PassRefPtr<NewSVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+    virtual String valueAsString() const OVERRIDE;
+    void setValueAsString(const String&, ExceptionState&);
+
+    virtual void add(PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+    virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> fromValue, PassRefPtr<NewSVGPropertyBase> toValue, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+    virtual float calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+    static AnimatedPropertyType classType() { return AnimatedPath; }
 
 private:
+    SVGPathSegList(SVGPathElement*, SVGPathSegRole);
+    SVGPathSegList(SVGPathElement*, SVGPathSegRole, PassOwnPtr<SVGPathByteStream>);
+
+    friend class SVGPathSegListBuilder;
+    // This is only to be called from SVGPathSegListBuilder.
+    void appendWithoutByteStreamSync(PassRefPtr<ItemPropertyType> passNewItem)
+    {
+        Base::append(passNewItem);
+    }
+
+    void updateListFromByteStream();
+    void invalidateList();
+
+    // FIXME: This pointer should be removed after SVGPathSeg has a tear-off.
+    // FIXME: oilpan: This is raw-ptr to avoid reference cycles.
+    //        SVGPathSegList is either owned by SVGAnimatedPath or
+    //        SVGPathSegListTearOff. Both keep |contextElement| alive,
+    //        so this ptr is always valid.
+    SVGPathElement* m_contextElement;
+
     SVGPathSegRole m_role;
+    mutable OwnPtr<SVGPathByteStream> m_byteStream;
+    bool m_listSyncedToByteStream;
 };
 
-template<>
-struct SVGPropertyTraits<SVGPathSegList> {
-    static SVGPathSegList initialValue() { return SVGPathSegList(PathSegUndefinedRole); }
-    typedef RefPtr<SVGPathSeg> ListItemType;
-};
+inline PassRefPtr<SVGPathSegList> toSVGPathSegList(PassRefPtr<NewSVGPropertyBase> passBase)
+{
+    RefPtr<NewSVGPropertyBase> base = passBase;
+    ASSERT(base->type() == SVGPathSegList::classType());
+    return static_pointer_cast<SVGPathSegList>(base.release());
+}
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGPathSegList.idl b/Source/core/svg/SVGPathSegList.idl
index 5214f9d..0d6a66f 100644
--- a/Source/core/svg/SVGPathSegList.idl
+++ b/Source/core/svg/SVGPathSegList.idl
@@ -26,12 +26,16 @@
 
 [
     StrictTypeChecking,
+    SetWrapperReferenceTo(SVGElement contextElement),
+    ImplementedAs=SVGPathSegListTearOff
 ] interface SVGPathSegList {
-    readonly attribute unsigned long numberOfItems;
+    readonly attribute unsigned long length;
+    [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
 
     [RaisesException] void clear();
     [RaisesException] SVGPathSeg initialize(SVGPathSeg newItem);
-    [RaisesException] SVGPathSeg getItem(unsigned long index);
+    [RaisesException] getter SVGPathSeg getItem(unsigned long index);
+    [RaisesException] setter SVGPathSeg (unsigned long index, SVGPathSeg value);
     [RaisesException] SVGPathSeg insertItemBefore(SVGPathSeg newItem, unsigned long index);
     [RaisesException] SVGPathSeg replaceItem(SVGPathSeg newItem, unsigned long index);
     [RaisesException] SVGPathSeg removeItem(unsigned long index);
diff --git a/Source/core/svg/SVGPathSegListBuilder.cpp b/Source/core/svg/SVGPathSegListBuilder.cpp
index b394f52..ce061aa 100644
--- a/Source/core/svg/SVGPathSegListBuilder.cpp
+++ b/Source/core/svg/SVGPathSegListBuilder.cpp
@@ -51,7 +51,7 @@
 
 SVGPathSegListBuilder::SVGPathSegListBuilder()
     : m_pathElement(0)
-    , m_pathSegList(0)
+    , m_pathSegList(nullptr)
     , m_pathSegRole(PathSegUndefinedRole)
 {
 }
@@ -61,9 +61,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegMovetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegMovetoAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegMovetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegMovetoRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
 }
 
 void SVGPathSegListBuilder::lineTo(const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -71,9 +71,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
 }
 
 void SVGPathSegListBuilder::lineToHorizontal(float x, PathCoordinateMode mode)
@@ -81,9 +81,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalAbs(x, m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoHorizontalAbs::create(m_pathElement, m_pathSegRole, x));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoHorizontalRel(x, m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoHorizontalRel::create(m_pathElement, m_pathSegRole, x));
 }
 
 void SVGPathSegListBuilder::lineToVertical(float y, PathCoordinateMode mode)
@@ -91,9 +91,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalAbs(y, m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoVerticalAbs::create(m_pathElement, m_pathSegRole, y));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegLinetoVerticalRel(y, m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegLinetoVerticalRel::create(m_pathElement, m_pathSegRole, y));
 }
 
 void SVGPathSegListBuilder::curveToCubic(const FloatPoint& point1, const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -101,9 +101,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y()));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), point2.x(), point2.y()));
 }
 
 void SVGPathSegListBuilder::curveToCubicSmooth(const FloatPoint& point2, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -111,9 +111,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothAbs(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicSmoothAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point2.x(), point2.y()));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoCubicSmoothRel(targetPoint.x(), targetPoint.y(), point2.x(), point2.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoCubicSmoothRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point2.x(), point2.y()));
 }
 
 void SVGPathSegListBuilder::curveToQuadratic(const FloatPoint& point1, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -121,9 +121,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticAbs(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y()));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticRel(targetPoint.x(), targetPoint.y(), point1.x(), point1.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), point1.x(), point1.y()));
 }
 
 void SVGPathSegListBuilder::curveToQuadraticSmooth(const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -131,9 +131,9 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothAbs(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticSmoothAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegCurvetoQuadraticSmoothRel(targetPoint.x(), targetPoint.y(), m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegCurvetoQuadraticSmoothRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y()));
 }
 
 void SVGPathSegListBuilder::arcTo(float r1, float r2, float angle, bool largeArcFlag, bool sweepFlag, const FloatPoint& targetPoint, PathCoordinateMode mode)
@@ -141,16 +141,16 @@
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
     if (mode == AbsoluteCoordinates)
-        m_pathSegList->append(m_pathElement->createSVGPathSegArcAbs(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegArcAbs::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag));
     else
-        m_pathSegList->append(m_pathElement->createSVGPathSegArcRel(targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag, m_pathSegRole));
+        m_pathSegList->appendWithoutByteStreamSync(SVGPathSegArcRel::create(m_pathElement, m_pathSegRole, targetPoint.x(), targetPoint.y(), r1, r2, angle, largeArcFlag, sweepFlag));
 }
 
 void SVGPathSegListBuilder::closePath()
 {
     ASSERT(m_pathElement);
     ASSERT(m_pathSegList);
-    m_pathSegList->append(m_pathElement->createSVGPathSegClosePath(m_pathSegRole));
+    m_pathSegList->appendWithoutByteStreamSync(SVGPathSegClosePath::create(m_pathElement, m_pathSegRole));
 }
 
 }
diff --git a/Source/core/svg/SVGPathSegListBuilder.h b/Source/core/svg/SVGPathSegListBuilder.h
index 8b209c6..e5e7641 100644
--- a/Source/core/svg/SVGPathSegListBuilder.h
+++ b/Source/core/svg/SVGPathSegListBuilder.h
@@ -37,7 +37,7 @@
     SVGPathSegListBuilder();
 
     void setCurrentSVGPathElement(SVGPathElement* pathElement) { m_pathElement = pathElement; }
-    void setCurrentSVGPathSegList(SVGPathSegList& pathSegList) { m_pathSegList = &pathSegList; }
+    void setCurrentSVGPathSegList(PassRefPtr<SVGPathSegList> pathSegList) { m_pathSegList = pathSegList; }
     void setCurrentSVGPathSegRole(SVGPathSegRole pathSegRole) { m_pathSegRole = pathSegRole; }
 
 private:
@@ -46,7 +46,7 @@
     virtual void cleanup() OVERRIDE
     {
         m_pathElement = 0;
-        m_pathSegList = 0;
+        m_pathSegList = nullptr;
         m_pathSegRole = PathSegUndefinedRole;
     }
 
@@ -65,7 +65,7 @@
     virtual void arcTo(float, float, float, bool largeArcFlag, bool sweepFlag, const FloatPoint&, PathCoordinateMode) OVERRIDE;
 
     SVGPathElement* m_pathElement;
-    SVGPathSegList* m_pathSegList;
+    RefPtr<SVGPathSegList> m_pathSegList;
     SVGPathSegRole m_pathSegRole;
 };
 
diff --git a/Source/core/svg/SVGPathSegListSource.cpp b/Source/core/svg/SVGPathSegListSource.cpp
index 2df5505..c58a68c 100644
--- a/Source/core/svg/SVGPathSegListSource.cpp
+++ b/Source/core/svg/SVGPathSegListSource.cpp
@@ -30,31 +30,30 @@
 
 namespace WebCore {
 
-SVGPathSegListSource::SVGPathSegListSource(const SVGPathSegList& pathSegList)
-    : m_pathSegList(pathSegList)
+SVGPathSegListSource::SVGPathSegListSource(SVGPathSegList::ConstIterator itBegin, SVGPathSegList::ConstIterator itEnd)
+    : m_itCurrent(itBegin)
+    , m_itEnd(itEnd)
 {
-    m_itemCurrent = 0;
-    m_itemEnd = m_pathSegList.size();
 }
 
 bool SVGPathSegListSource::hasMoreData() const
 {
-    return m_itemCurrent < m_itemEnd;
+    return m_itCurrent != m_itEnd;
 }
 
 bool SVGPathSegListSource::parseSVGSegmentType(SVGPathSegType& pathSegType)
 {
-    m_segment = m_pathSegList.at(m_itemCurrent);
+    m_segment = *m_itCurrent;
     pathSegType = static_cast<SVGPathSegType>(m_segment->pathSegType());
-    ++m_itemCurrent;
+    ++m_itCurrent;
     return true;
 }
 
 SVGPathSegType SVGPathSegListSource::nextCommand(SVGPathSegType)
 {
-    m_segment = m_pathSegList.at(m_itemCurrent);
+    m_segment = *m_itCurrent;
     SVGPathSegType pathSegType = static_cast<SVGPathSegType>(m_segment->pathSegType());
-    ++m_itemCurrent;
+    ++m_itCurrent;
     return pathSegType;
 }
 
diff --git a/Source/core/svg/SVGPathSegListSource.h b/Source/core/svg/SVGPathSegListSource.h
index edcd67f..03e40b4 100644
--- a/Source/core/svg/SVGPathSegListSource.h
+++ b/Source/core/svg/SVGPathSegListSource.h
@@ -29,16 +29,13 @@
 
 namespace WebCore {
 
+class SVGPathSegList;
+
 class SVGPathSegListSource FINAL : public SVGPathSource {
 public:
-    static PassOwnPtr<SVGPathSegListSource> create(const SVGPathSegList& pathSegList)
-    {
-        return adoptPtr(new SVGPathSegListSource(pathSegList));
-    }
+    SVGPathSegListSource(SVGPathSegList::ConstIterator, SVGPathSegList::ConstIterator);
 
 private:
-    SVGPathSegListSource(const SVGPathSegList&);
-
     virtual bool hasMoreData() const OVERRIDE;
     virtual bool moveToNextToken() OVERRIDE { return true; }
     virtual bool parseSVGSegmentType(SVGPathSegType&) OVERRIDE;
@@ -54,10 +51,9 @@
     virtual bool parseCurveToQuadraticSmoothSegment(FloatPoint&) OVERRIDE;
     virtual bool parseArcToSegment(float&, float&, float&, bool&, bool&, FloatPoint&) OVERRIDE;
 
-    const SVGPathSegList& m_pathSegList;
     RefPtr<SVGPathSeg> m_segment;
-    int m_itemCurrent;
-    int m_itemEnd;
+    SVGPathSegList::ConstIterator m_itCurrent;
+    SVGPathSegList::ConstIterator m_itEnd;
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGPathSegListTearOff.h b/Source/core/svg/SVGPathSegListTearOff.h
new file mode 100644
index 0000000..a18a373
--- /dev/null
+++ b/Source/core/svg/SVGPathSegListTearOff.h
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGPathSegListTearOff_h
+#define SVGPathSegListTearOff_h
+
+#include "core/svg/SVGPathSegList.h"
+#include "core/svg/properties/NewSVGListPropertyTearOffHelper.h"
+
+namespace WebCore {
+
+template<>
+class ListItemPropertyTraits<SVGPathSeg> {
+public:
+    typedef SVGPathSeg ItemPropertyType;
+    // FIXME: Currently SVGPathSegitself is a tear-off.
+    typedef SVGPathSeg ItemTearOffType;
+
+    static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem)
+    {
+        return passNewItem;
+    }
+
+    static PassRefPtr<ItemTearOffType> createTearOff(PassRefPtr<ItemPropertyType> passValue, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName&)
+    {
+        RefPtr<SVGPathSeg> value = passValue;
+        value->setContextElement(contextElement);
+        return value.release();
+    }
+};
+
+class SVGPathSegListTearOff FINAL :
+    public NewSVGListPropertyTearOffHelper<SVGPathSegListTearOff, SVGPathSegList>,
+    public ScriptWrappable {
+public:
+    static PassRefPtr<SVGPathSegListTearOff> create(PassRefPtr<SVGPathSegList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = nullQName())
+    {
+        return adoptRef(new SVGPathSegListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+    }
+
+private:
+    SVGPathSegListTearOff(PassRefPtr<SVGPathSegList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = nullQName())
+        : NewSVGListPropertyTearOffHelper<SVGPathSegListTearOff, SVGPathSegList>(target, contextElement, propertyIsAnimVal, attributeName)
+    {
+        ScriptWrappable::init(this);
+    }
+};
+
+} // namespace WebCore
+
+#endif // SVGPathSegListTearOff_h_
diff --git a/Source/core/svg/SVGPathSegWithContext.h b/Source/core/svg/SVGPathSegWithContext.h
index c12689d..45093cd 100644
--- a/Source/core/svg/SVGPathSegWithContext.h
+++ b/Source/core/svg/SVGPathSegWithContext.h
@@ -20,56 +20,20 @@
 #ifndef SVGPathSegWithContext_h
 #define SVGPathSegWithContext_h
 
-#include "core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h"
+#include "core/svg/SVGPathSeg.h"
 
 namespace WebCore {
 
+class SVGElement;
+
+// FIXME: This should be deprecated.
 class SVGPathSegWithContext : public SVGPathSeg {
 public:
-    SVGPathSegWithContext(SVGPathElement* element, SVGPathSegRole role)
-        : m_role(role)
-        , m_element(element)
+    // FIXME: remove second unused argument from all derived classes.
+    SVGPathSegWithContext(SVGPathElement* contextElement, SVGPathSegRole)
+        : SVGPathSeg(contextElement)
     {
     }
-
-    SVGAnimatedProperty* animatedProperty() const
-    {
-        switch (m_role) {
-        case PathSegUndefinedRole:
-            return 0;
-        case PathSegUnalteredRole:
-            return SVGAnimatedProperty::lookupWrapper<SVGPathElement, SVGAnimatedPathSegListPropertyTearOff>(m_element, SVGPathElement::dPropertyInfo());
-        case PathSegNormalizedRole:
-            // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
-            return 0;
-        };
-
-        return 0;
-    }
-
-    SVGPathElement* contextElement() const { return m_element; }
-    SVGPathSegRole role() const { return m_role; }
-
-    void setContextAndRole(SVGPathElement* element, SVGPathSegRole role)
-    {
-        m_role = role;
-        m_element = element;
-    }
-
-protected:
-    void commitChange()
-    {
-        if (!m_element) {
-            ASSERT(m_role == PathSegUndefinedRole);
-            return;
-        }
-
-        m_element->pathSegListChanged(m_role);
-    }
-
-private:
-    SVGPathSegRole m_role;
-    SVGPathElement* m_element;
 };
 
 class SVGPathSegSingleCoordinate : public SVGPathSegWithContext {
diff --git a/Source/core/svg/SVGPathUtilities.cpp b/Source/core/svg/SVGPathUtilities.cpp
index 9106d89..51cce51 100644
--- a/Source/core/svg/SVGPathUtilities.cpp
+++ b/Source/core/svg/SVGPathUtilities.cpp
@@ -45,18 +45,6 @@
     return s_builder;
 }
 
-static SVGPathSegListBuilder* globalSVGPathSegListBuilder(SVGPathElement* element, SVGPathSegRole role, SVGPathSegList& result)
-{
-    static SVGPathSegListBuilder* s_builder = 0;
-    if (!s_builder)
-        s_builder = new SVGPathSegListBuilder;
-
-    s_builder->setCurrentSVGPathElement(element);
-    s_builder->setCurrentSVGPathSegList(result);
-    s_builder->setCurrentSVGPathSegRole(role);
-    return s_builder;
-}
-
 static SVGPathByteStreamBuilder* globalSVGPathByteStreamBuilder(SVGPathByteStream* result)
 {
     static SVGPathByteStreamBuilder* s_builder = 0;
@@ -121,45 +109,7 @@
     return ok;
 }
 
-bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList& list, SVGPathByteStream* result, PathParsingMode parsingMode)
-{
-    ASSERT(result);
-    result->clear();
-    if (list.isEmpty())
-        return false;
-
-    SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
-
-    OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
-    bool ok = parser->parsePathDataFromSource(parsingMode);
-    parser->cleanup();
-    return ok;
-}
-
-bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg> pathSeg, SVGPathByteStream* result, PathParsingMode parsingMode)
-{
-    ASSERT(result);
-    // FIXME: https://bugs.webkit.org/show_bug.cgi?id=15412 - Implement normalized path segment lists!
-    ASSERT(parsingMode == UnalteredParsing);
-
-    SVGPathSegList appendedItemList(PathSegUnalteredRole);
-    appendedItemList.append(pathSeg);
-    OwnPtr<SVGPathByteStream> appendedByteStream = SVGPathByteStream::create();
-
-    SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(appendedByteStream.get());
-    OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(appendedItemList);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
-    bool ok = parser->parsePathDataFromSource(parsingMode, false);
-    parser->cleanup();
-
-    if (ok)
-        result->append(appendedByteStream.get());
-
-    return ok;
-}
-
-bool buildPathFromByteStream(SVGPathByteStream* stream, Path& result)
+bool buildPathFromByteStream(const SVGPathByteStream* stream, Path& result)
 {
     ASSERT(stream);
     if (stream->isEmpty())
@@ -167,29 +117,14 @@
 
     SVGPathBuilder* builder = globalSVGPathBuilder(result);
 
-    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+    SVGPathByteStreamSource source(stream);
+    SVGPathParser* parser = globalSVGPathParser(&source, builder);
     bool ok = parser->parsePathDataFromSource(NormalizedParsing);
     parser->cleanup();
     return ok;
 }
 
-bool buildSVGPathSegListFromByteStream(SVGPathByteStream* stream, SVGPathElement* element, SVGPathSegList& result, PathParsingMode parsingMode)
-{
-    ASSERT(stream);
-    if (stream->isEmpty())
-        return false;
-
-    SVGPathSegListBuilder* builder = globalSVGPathSegListBuilder(element, parsingMode == NormalizedParsing ? PathSegNormalizedRole : PathSegUnalteredRole, result);
-
-    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
-    bool ok = parser->parsePathDataFromSource(parsingMode);
-    parser->cleanup();
-    return ok;
-}
-
-bool buildStringFromByteStream(SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
+bool buildStringFromByteStream(const SVGPathByteStream* stream, String& result, PathParsingMode parsingMode)
 {
     ASSERT(stream);
     if (stream->isEmpty())
@@ -197,24 +132,8 @@
 
     SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
 
-    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
-    bool ok = parser->parsePathDataFromSource(parsingMode);
-    result = builder->result();
-    parser->cleanup();
-    return ok;
-}
-
-bool buildStringFromSVGPathSegList(const SVGPathSegList& list, String& result, PathParsingMode parsingMode)
-{
-    result = String();
-    if (list.isEmpty())
-        return false;
-
-    SVGPathStringBuilder* builder = globalSVGPathStringBuilder();
-
-    OwnPtr<SVGPathSegListSource> source = SVGPathSegListSource::create(list);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+    SVGPathByteStreamSource source(stream);
+    SVGPathParser* parser = globalSVGPathParser(&source, builder);
     bool ok = parser->parsePathDataFromSource(parsingMode);
     result = builder->result();
     parser->cleanup();
@@ -243,28 +162,7 @@
     return ok;
 }
 
-bool buildAnimatedSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* toStream, SVGPathByteStream* result, float progress)
-{
-    ASSERT(fromStream);
-    ASSERT(toStream);
-    ASSERT(result);
-    ASSERT(toStream != result);
-
-    result->clear();
-    if (toStream->isEmpty())
-        return false;
-
-    SVGPathByteStreamBuilder* builder = globalSVGPathByteStreamBuilder(result);
-
-    OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStream);
-    OwnPtr<SVGPathByteStreamSource> toSource = SVGPathByteStreamSource::create(toStream);
-    SVGPathBlender* blender = globalSVGPathBlender();
-    bool ok = blender->blendAnimatedPath(progress, fromSource.get(), toSource.get(), builder);
-    blender->cleanup();
-    return ok;
-}
-
-bool addToSVGPathByteStream(SVGPathByteStream* fromStream, SVGPathByteStream* byStream, unsigned repeatCount)
+bool addToSVGPathByteStream(SVGPathByteStream* fromStream, const SVGPathByteStream* byStream, unsigned repeatCount)
 {
     ASSERT(fromStream);
     ASSERT(byStream);
@@ -276,15 +174,15 @@
     OwnPtr<SVGPathByteStream> fromStreamCopy = fromStream->copy();
     fromStream->clear();
 
-    OwnPtr<SVGPathByteStreamSource> fromSource = SVGPathByteStreamSource::create(fromStreamCopy.get());
-    OwnPtr<SVGPathByteStreamSource> bySource = SVGPathByteStreamSource::create(byStream);
+    SVGPathByteStreamSource fromSource(fromStreamCopy.get());
+    SVGPathByteStreamSource bySource(byStream);
     SVGPathBlender* blender = globalSVGPathBlender();
-    bool ok = blender->addAnimatedPath(fromSource.get(), bySource.get(), builder, repeatCount);
+    bool ok = blender->addAnimatedPath(&fromSource, &bySource, builder, repeatCount);
     blender->cleanup();
     return ok;
 }
 
-bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream* stream, float length, unsigned& pathSeg)
+bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream* stream, float length, unsigned& pathSeg)
 {
     ASSERT(stream);
     if (stream->isEmpty())
@@ -293,15 +191,15 @@
     PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength);
     SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
 
-    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+    SVGPathByteStreamSource source(stream);
+    SVGPathParser* parser = globalSVGPathParser(&source, builder);
     bool ok = parser->parsePathDataFromSource(NormalizedParsing);
     pathSeg = builder->pathSegmentIndex();
     parser->cleanup();
     return ok;
 }
 
-bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream* stream, float& totalLength)
+bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream* stream, float& totalLength)
 {
     ASSERT(stream);
     if (stream->isEmpty())
@@ -310,15 +208,15 @@
     PathTraversalState traversalState(PathTraversalState::TraversalTotalLength);
     SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, 0);
 
-    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+    SVGPathByteStreamSource source(stream);
+    SVGPathParser* parser = globalSVGPathParser(&source, builder);
     bool ok = parser->parsePathDataFromSource(NormalizedParsing);
     totalLength = builder->totalLength();
     parser->cleanup();
     return ok;
 }
 
-bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream* stream, float length, FloatPoint& point)
+bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream* stream, float length, FloatPoint& point)
 {
     ASSERT(stream);
     if (stream->isEmpty())
@@ -327,8 +225,8 @@
     PathTraversalState traversalState(PathTraversalState::TraversalPointAtLength);
     SVGPathTraversalStateBuilder* builder = globalSVGPathTraversalStateBuilder(traversalState, length);
 
-    OwnPtr<SVGPathByteStreamSource> source = SVGPathByteStreamSource::create(stream);
-    SVGPathParser* parser = globalSVGPathParser(source.get(), builder);
+    SVGPathByteStreamSource source(stream);
+    SVGPathParser* parser = globalSVGPathParser(&source, builder);
     bool ok = parser->parsePathDataFromSource(NormalizedParsing);
     point = builder->currentPoint();
     parser->cleanup();
diff --git a/Source/core/svg/SVGPathUtilities.h b/Source/core/svg/SVGPathUtilities.h
index 007a72e..d460335 100644
--- a/Source/core/svg/SVGPathUtilities.h
+++ b/Source/core/svg/SVGPathUtilities.h
@@ -35,26 +35,21 @@
 
 // String/SVGPathByteStream -> Path
 bool buildPathFromString(const String&, Path&);
-bool buildPathFromByteStream(SVGPathByteStream*, Path&);
+bool buildPathFromByteStream(const SVGPathByteStream*, Path&);
 
 // SVGPathSegList/String -> SVGPathByteStream
-bool buildSVGPathByteStreamFromSVGPathSegList(const SVGPathSegList&, SVGPathByteStream*, PathParsingMode);
 bool appendSVGPathByteStreamFromSVGPathSeg(PassRefPtr<SVGPathSeg>, SVGPathByteStream*, PathParsingMode);
 bool buildSVGPathByteStreamFromString(const String&, SVGPathByteStream*, PathParsingMode);
 
 // SVGPathByteStream/SVGPathSegList -> String
-bool buildStringFromByteStream(SVGPathByteStream*, String&, PathParsingMode);
-bool buildStringFromSVGPathSegList(const SVGPathSegList&, String&, PathParsingMode);
+bool buildStringFromByteStream(const SVGPathByteStream*, String&, PathParsingMode);
+bool buildStringFromSVGPathSegList(PassRefPtr<SVGPathSegList>, String&, PathParsingMode);
 
-// SVGPathByteStream -> SVGPathSegList
-bool buildSVGPathSegListFromByteStream(SVGPathByteStream*, SVGPathElement*, SVGPathSegList&, PathParsingMode);
+bool addToSVGPathByteStream(SVGPathByteStream*, const SVGPathByteStream*, unsigned repeatCount = 1);
 
-bool buildAnimatedSVGPathByteStream(SVGPathByteStream*, SVGPathByteStream*, SVGPathByteStream*, float);
-bool addToSVGPathByteStream(SVGPathByteStream*, SVGPathByteStream*, unsigned repeatCount = 1);
-
-bool getSVGPathSegAtLengthFromSVGPathByteStream(SVGPathByteStream*, float length, unsigned& pathSeg);
-bool getTotalLengthOfSVGPathByteStream(SVGPathByteStream*, float& totalLength);
-bool getPointAtLengthOfSVGPathByteStream(SVGPathByteStream*, float length, FloatPoint&);
+bool getSVGPathSegAtLengthFromSVGPathByteStream(const SVGPathByteStream*, float length, unsigned& pathSeg);
+bool getTotalLengthOfSVGPathByteStream(const SVGPathByteStream*, float& totalLength);
+bool getPointAtLengthOfSVGPathByteStream(const SVGPathByteStream*, float length, FloatPoint&);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGPatternElement.cpp b/Source/core/svg/SVGPatternElement.cpp
index 661e234..fa6db5c 100644
--- a/Source/core/svg/SVGPatternElement.cpp
+++ b/Source/core/svg/SVGPatternElement.cpp
@@ -32,18 +32,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGPatternElement, SVGNames::patternUnitsAttr, PatternUnits, patternUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_ENUMERATION(SVGPatternElement, SVGNames::patternContentUnitsAttr, PatternContentUnits, patternContentUnits, SVGUnitTypes::SVGUnitType)
-DEFINE_ANIMATED_TRANSFORM_LIST(SVGPatternElement, SVGNames::patternTransformAttr, PatternTransform, patternTransform)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGPatternElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(patternUnits)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(patternContentUnits)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(patternTransform)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGPatternElement::SVGPatternElement(Document& document)
     : SVGElement(SVGNames::patternTag, document)
     , SVGURIReference(this)
@@ -53,8 +41,9 @@
     , m_y(SVGAnimatedLength::create(this, SVGNames::yAttr, SVGLength::create(LengthModeHeight)))
     , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth)))
     , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight)))
-    , m_patternUnits(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
-    , m_patternContentUnits(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE)
+    , m_patternTransform(SVGAnimatedTransformList::create(this, SVGNames::patternTransformAttr, SVGTransformList::create()))
+    , m_patternUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::patternUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX))
+    , m_patternContentUnits(SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>::create(this, SVGNames::patternContentUnitsAttr, SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE))
 {
     ScriptWrappable::init(this);
 
@@ -62,7 +51,9 @@
     addToPropertyMap(m_y);
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
-    registerAnimatedPropertiesForSVGPatternElement();
+    addToPropertyMap(m_patternTransform);
+    addToPropertyMap(m_patternUnits);
+    addToPropertyMap(m_patternContentUnits);
 }
 
 PassRefPtr<SVGPatternElement> SVGPatternElement::create(Document& document)
@@ -95,21 +86,11 @@
     if (!isSupportedAttribute(name)) {
         SVGElement::parseAttribute(name, value);
     } else if (name == SVGNames::patternUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setPatternUnitsBaseValue(propertyValue);
-        return;
+        m_patternUnits->setBaseValueAsString(value, parseError);
     } else if (name == SVGNames::patternContentUnitsAttr) {
-        SVGUnitTypes::SVGUnitType propertyValue = SVGPropertyTraits<SVGUnitTypes::SVGUnitType>::fromString(value);
-        if (propertyValue > 0)
-            setPatternContentUnitsBaseValue(propertyValue);
-        return;
+        m_patternContentUnits->setBaseValueAsString(value, parseError);
     } else if (name == SVGNames::patternTransformAttr) {
-        SVGTransformList newList;
-        newList.parse(value);
-        detachAnimatedPatternTransformListWrappers(newList.size());
-        setPatternTransformBaseValue(newList);
-        return;
+        m_patternTransform->setBaseValueAsString(value, parseError);
     } else if (name == SVGNames::xAttr) {
         m_x->setBaseValueAsString(value, AllowNegativeLengths, parseError);
     } else if (name == SVGNames::yAttr) {
@@ -184,15 +165,15 @@
     if (!attributes.hasPreserveAspectRatio() && element->preserveAspectRatio()->isSpecified())
         attributes.setPreserveAspectRatio(element->preserveAspectRatio()->currentValue());
 
-    if (!attributes.hasPatternUnits() && element->patternUnitsSpecified())
-        attributes.setPatternUnits(element->patternUnitsCurrentValue());
+    if (!attributes.hasPatternUnits() && element->patternUnits()->isSpecified())
+        attributes.setPatternUnits(element->patternUnits()->currentValue()->enumValue());
 
-    if (!attributes.hasPatternContentUnits() && element->patternContentUnitsSpecified())
-        attributes.setPatternContentUnits(element->patternContentUnitsCurrentValue());
+    if (!attributes.hasPatternContentUnits() && element->patternContentUnits()->isSpecified())
+        attributes.setPatternContentUnits(element->patternContentUnits()->currentValue()->enumValue());
 
-    if (!attributes.hasPatternTransform() && element->patternTransformSpecified()) {
+    if (!attributes.hasPatternTransform() && element->patternTransform()->isSpecified()) {
         AffineTransform transform;
-        element->patternTransformCurrentValue().concatenate(transform);
+        element->patternTransform()->currentValue()->concatenate(transform);
         attributes.setPatternTransform(transform);
     }
 
@@ -211,8 +192,8 @@
 
         // Respect xlink:href, take attributes from referenced element
         Node* refNode = SVGURIReference::targetElementFromIRIString(current->hrefString(), document());
-        if (refNode && refNode->hasTagName(SVGNames::patternTag)) {
-            current = toSVGPatternElement(const_cast<const Node*>(refNode));
+        if (isSVGPatternElement(refNode)) {
+            current = toSVGPatternElement(refNode);
 
             // Cycle detection
             if (processedPatterns.contains(current))
@@ -228,7 +209,7 @@
 AffineTransform SVGPatternElement::localCoordinateSpaceTransform(SVGElement::CTMScope) const
 {
     AffineTransform matrix;
-    patternTransformCurrentValue().concatenate(matrix);
+    m_patternTransform->currentValue()->concatenate(matrix);
     return matrix;
 }
 
diff --git a/Source/core/svg/SVGPatternElement.h b/Source/core/svg/SVGPatternElement.h
index 44cf6f9..8fc1a46 100644
--- a/Source/core/svg/SVGPatternElement.h
+++ b/Source/core/svg/SVGPatternElement.h
@@ -51,6 +51,12 @@
     SVGAnimatedLength* y() const { return m_y.get(); }
     SVGAnimatedLength* width() const { return m_width.get(); }
     SVGAnimatedLength* height() const { return m_height.get(); }
+    SVGAnimatedTransformList* patternTransform() { return m_patternTransform.get(); }
+    const SVGAnimatedTransformList* patternTransform() const { return m_patternTransform.get(); }
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternUnits() { return m_patternUnits.get(); }
+    SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternContentUnits() { return m_patternContentUnits.get(); }
+    const SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternUnits() const { return m_patternUnits.get(); }
+    const SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType>* patternContentUnits() const { return m_patternContentUnits.get(); }
 
 private:
     explicit SVGPatternElement(Document&);
@@ -71,15 +77,11 @@
     RefPtr<SVGAnimatedLength> m_y;
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPatternElement)
-        DECLARE_ANIMATED_ENUMERATION(PatternUnits, patternUnits, SVGUnitTypes::SVGUnitType)
-        DECLARE_ANIMATED_ENUMERATION(PatternContentUnits, patternContentUnits, SVGUnitTypes::SVGUnitType)
-        DECLARE_ANIMATED_TRANSFORM_LIST(PatternTransform, patternTransform)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedTransformList> m_patternTransform;
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_patternUnits;
+    RefPtr<SVGAnimatedEnumeration<SVGUnitTypes::SVGUnitType> > m_patternContentUnits;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGPatternElement, hasTagName(SVGNames::patternTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGPointList.cpp b/Source/core/svg/SVGPointList.cpp
index e0910d6..09e01a4 100644
--- a/Source/core/svg/SVGPointList.cpp
+++ b/Source/core/svg/SVGPointList.cpp
@@ -105,7 +105,6 @@
         }
 
         // check end of list
-        skipOptionalSVGSpaces(ptr, end);
         if (ptr >= end)
             return true;
     }
@@ -137,10 +136,10 @@
 {
     RefPtr<SVGPointList> otherList = toSVGPointList(other);
 
-    if (numberOfItems() != otherList->numberOfItems())
+    if (length() != otherList->length())
         return;
 
-    for (size_t i = 0; i < numberOfItems(); ++i)
+    for (size_t i = 0; i < length(); ++i)
         at(i)->setValue(at(i)->value() + otherList->at(i)->value());
 }
 
@@ -150,12 +149,12 @@
     RefPtr<SVGPointList> toList = passToList;
 
     // If no 'to' value is given, nothing to animate.
-    size_t toListSize = toList->numberOfItems();
+    size_t toListSize = toList->length();
     if (!toListSize)
         return false;
 
     // If the 'from' value is given and it's length doesn't match the 'to' value list length, fallback to a discrete animation.
-    size_t fromListSize = fromList->numberOfItems();
+    size_t fromListSize = fromList->length();
     if (fromListSize != toListSize && fromListSize) {
         if (percentage < 0.5) {
             if (!isToAnimation)
@@ -168,8 +167,8 @@
     }
 
     ASSERT(!fromListSize || fromListSize == toListSize);
-    if (resizeAnimatedListIfNeeded && numberOfItems() < toListSize) {
-        size_t paddingCount = toListSize - numberOfItems();
+    if (resizeAnimatedListIfNeeded && length() < toListSize) {
+        size_t paddingCount = toListSize - length();
         for (size_t i = 0; i < paddingCount; ++i)
             append(SVGPoint::create());
     }
@@ -183,9 +182,9 @@
     RefPtr<SVGPointList> toList = toSVGPointList(toValue);
     RefPtr<SVGPointList> toAtEndOfDurationList = toSVGPointList(toAtEndOfDurationValue);
 
-    size_t fromPointListSize = fromList->numberOfItems();
-    size_t toPointListSize = toList->numberOfItems();
-    size_t toAtEndOfDurationListSize = toAtEndOfDurationList->numberOfItems();
+    size_t fromPointListSize = fromList->length();
+    size_t toPointListSize = toList->length();
+    size_t toAtEndOfDurationListSize = toAtEndOfDurationList->length();
 
     if (!adjustFromToListValues(fromList, toList, percentage, animationElement->animationMode() == ToAnimation, true))
         return;
diff --git a/Source/core/svg/SVGPointList.idl b/Source/core/svg/SVGPointList.idl
index 51aba12..d066e57 100644
--- a/Source/core/svg/SVGPointList.idl
+++ b/Source/core/svg/SVGPointList.idl
@@ -28,11 +28,13 @@
     SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGPointList {
-    readonly attribute unsigned long numberOfItems;
+    readonly attribute unsigned long length;
+    [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
 
     [RaisesException] void clear();
     [RaisesException] SVGPoint initialize(SVGPoint item);
-    [RaisesException] SVGPoint getItem(unsigned long index);
+    [RaisesException] getter SVGPoint getItem(unsigned long index);
+    [RaisesException] setter SVGPoint (unsigned long index, SVGPoint value);
     [RaisesException] SVGPoint insertItemBefore(SVGPoint item, unsigned long index);
     [RaisesException] SVGPoint replaceItem(SVGPoint item, unsigned long index);
     [RaisesException] SVGPoint removeItem(unsigned long index);
diff --git a/Source/core/svg/SVGPointTearOff.cpp b/Source/core/svg/SVGPointTearOff.cpp
index 5081029..0f29a8e 100644
--- a/Source/core/svg/SVGPointTearOff.cpp
+++ b/Source/core/svg/SVGPointTearOff.cpp
@@ -34,7 +34,7 @@
 
 #include "bindings/v8/ExceptionState.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/svg/SVGMatrix.h"
+#include "core/svg/SVGMatrixTearOff.h"
 
 namespace WebCore {
 
@@ -66,9 +66,9 @@
     commitChange();
 }
 
-PassRefPtr<SVGPointTearOff> SVGPointTearOff::matrixTransform(SVGMatrix matrix)
+PassRefPtr<SVGPointTearOff> SVGPointTearOff::matrixTransform(PassRefPtr<SVGMatrixTearOff> matrix)
 {
-    FloatPoint point = target()->matrixTransform(matrix);
+    FloatPoint point = target()->matrixTransform(matrix->value());
     return SVGPointTearOff::create(SVGPoint::create(point), 0, PropertyIsNotAnimVal);
 }
 
diff --git a/Source/core/svg/SVGPointTearOff.h b/Source/core/svg/SVGPointTearOff.h
index 88d0ad9..0560f71 100644
--- a/Source/core/svg/SVGPointTearOff.h
+++ b/Source/core/svg/SVGPointTearOff.h
@@ -37,7 +37,7 @@
 
 namespace WebCore {
 
-class SVGMatrix;
+class SVGMatrixTearOff;
 
 class SVGPointTearOff : public NewSVGPropertyTearOff<SVGPoint>, public ScriptWrappable {
 public:
@@ -51,7 +51,7 @@
     float x() { return target()->x(); }
     float y() { return target()->y(); }
 
-    PassRefPtr<SVGPointTearOff> matrixTransform(SVGMatrix);
+    PassRefPtr<SVGPointTearOff> matrixTransform(PassRefPtr<SVGMatrixTearOff>);
 
 protected:
     SVGPointTearOff(PassRefPtr<SVGPoint>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName = nullQName());
diff --git a/Source/core/svg/SVGPolyElement.cpp b/Source/core/svg/SVGPolyElement.cpp
index eea18f4..7e3b3ae 100644
--- a/Source/core/svg/SVGPolyElement.cpp
+++ b/Source/core/svg/SVGPolyElement.cpp
@@ -30,18 +30,11 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGPolyElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 SVGPolyElement::SVGPolyElement(const QualifiedName& tagName, Document& document)
     : SVGGeometryElement(tagName, document)
     , m_points(SVGAnimatedPointList::create(this, SVGNames::pointsAttr, SVGPointList::create()))
 {
     addToPropertyMap(m_points);
-    registerAnimatedPropertiesForSVGPolyElement();
 }
 
 bool SVGPolyElement::isSupportedAttribute(const QualifiedName& attrName)
diff --git a/Source/core/svg/SVGPolyElement.h b/Source/core/svg/SVGPolyElement.h
index 28e6f03..c830f0d 100644
--- a/Source/core/svg/SVGPolyElement.h
+++ b/Source/core/svg/SVGPolyElement.h
@@ -50,8 +50,6 @@
 private:
     RefPtr<SVGAnimatedPointList> m_points;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGPolyElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 inline bool isSVGPolyElement(const Node& node)
@@ -59,7 +57,7 @@
     return node.hasTagName(SVGNames::polygonTag) || node.hasTagName(SVGNames::polylineTag);
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGPolyElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGPolyElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGPolygonElement.h b/Source/core/svg/SVGPolygonElement.h
index 89571f7..6088564 100644
--- a/Source/core/svg/SVGPolygonElement.h
+++ b/Source/core/svg/SVGPolygonElement.h
@@ -34,8 +34,6 @@
     explicit SVGPolygonElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGPolygonElement, hasTagName(SVGNames::polygonTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGPolylineElement.h b/Source/core/svg/SVGPolylineElement.h
index 4283143..a9b303d 100644
--- a/Source/core/svg/SVGPolylineElement.h
+++ b/Source/core/svg/SVGPolylineElement.h
@@ -34,8 +34,6 @@
     explicit SVGPolylineElement(Document&);
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGPolylineElement, hasTagName(SVGNames::polylineTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGRadialGradientElement.cpp b/Source/core/svg/SVGRadialGradientElement.cpp
index a65b00b..7e83196 100644
--- a/Source/core/svg/SVGRadialGradientElement.cpp
+++ b/Source/core/svg/SVGRadialGradientElement.cpp
@@ -32,12 +32,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGRadialGradientElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGradientElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGRadialGradientElement::SVGRadialGradientElement(Document& document)
     : SVGGradientElement(SVGNames::radialGradientTag, document)
     , m_cx(SVGAnimatedLength::create(this, SVGNames::cxAttr, SVGLength::create(LengthModeWidth)))
@@ -63,7 +57,6 @@
     addToPropertyMap(m_fx);
     addToPropertyMap(m_fy);
     addToPropertyMap(m_fr);
-    registerAnimatedPropertiesForSVGRadialGradientElement();
 }
 
 PassRefPtr<SVGRadialGradientElement> SVGRadialGradientElement::create(Document& document)
@@ -132,15 +125,15 @@
 
 static void setGradientAttributes(SVGGradientElement* element, RadialGradientAttributes& attributes, bool isRadial = true)
 {
-    if (!attributes.hasSpreadMethod() && element->spreadMethodSpecified())
-        attributes.setSpreadMethod(element->spreadMethodCurrentValue());
+    if (!attributes.hasSpreadMethod() && element->spreadMethod()->isSpecified())
+        attributes.setSpreadMethod(element->spreadMethod()->currentValue()->enumValue());
 
-    if (!attributes.hasGradientUnits() && element->gradientUnitsSpecified())
-        attributes.setGradientUnits(element->gradientUnitsCurrentValue());
+    if (!attributes.hasGradientUnits() && element->gradientUnits()->isSpecified())
+        attributes.setGradientUnits(element->gradientUnits()->currentValue()->enumValue());
 
-    if (!attributes.hasGradientTransform() && element->gradientTransformSpecified()) {
+    if (!attributes.hasGradientTransform() && element->gradientTransform()->isSpecified()) {
         AffineTransform transform;
-        element->gradientTransformCurrentValue().concatenate(transform);
+        element->gradientTransform()->currentValue()->concatenate(transform);
         attributes.setGradientTransform(transform);
     }
 
@@ -197,7 +190,7 @@
             if (!current->renderer())
                 return false;
 
-            setGradientAttributes(current, attributes, current->hasTagName(SVGNames::radialGradientTag));
+            setGradientAttributes(current, attributes, isSVGRadialGradientElement(*current));
             processedGradients.add(current);
         } else {
             break;
diff --git a/Source/core/svg/SVGRadialGradientElement.h b/Source/core/svg/SVGRadialGradientElement.h
index a4d9fa8..30ad402 100644
--- a/Source/core/svg/SVGRadialGradientElement.h
+++ b/Source/core/svg/SVGRadialGradientElement.h
@@ -59,12 +59,8 @@
     RefPtr<SVGAnimatedLength> m_fx;
     RefPtr<SVGAnimatedLength> m_fy;
     RefPtr<SVGAnimatedLength> m_fr;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGRadialGradientElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGRadialGradientElement, hasTagName(SVGNames::radialGradientTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGRectElement.cpp b/Source/core/svg/SVGRectElement.cpp
index e3fa044..8142d91 100644
--- a/Source/core/svg/SVGRectElement.cpp
+++ b/Source/core/svg/SVGRectElement.cpp
@@ -29,11 +29,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGRectElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGRectElement::SVGRectElement(Document& document)
     : SVGGeometryElement(SVGNames::rectTag, document)
     , m_x(SVGAnimatedLength::create(this, SVGNames::xAttr, SVGLength::create(LengthModeWidth)))
@@ -51,8 +46,6 @@
     addToPropertyMap(m_height);
     addToPropertyMap(m_rx);
     addToPropertyMap(m_ry);
-
-    registerAnimatedPropertiesForSVGRectElement();
 }
 
 PassRefPtr<SVGRectElement> SVGRectElement::create(Document& document)
diff --git a/Source/core/svg/SVGRectElement.h b/Source/core/svg/SVGRectElement.h
index c838080..da32aa8 100644
--- a/Source/core/svg/SVGRectElement.h
+++ b/Source/core/svg/SVGRectElement.h
@@ -58,12 +58,8 @@
     RefPtr<SVGAnimatedLength> m_height;
     RefPtr<SVGAnimatedLength> m_rx;
     RefPtr<SVGAnimatedLength> m_ry;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGRectElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGRectElement, hasTagName(SVGNames::rectTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGRemoteFontFaceSource.cpp b/Source/core/svg/SVGRemoteFontFaceSource.cpp
new file mode 100644
index 0000000..ad5e073
--- /dev/null
+++ b/Source/core/svg/SVGRemoteFontFaceSource.cpp
@@ -0,0 +1,67 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "config.h"
+#if ENABLE(SVG_FONTS)
+#include "core/svg/SVGRemoteFontFaceSource.h"
+
+#include "SVGNames.h"
+#include "core/dom/ElementTraversal.h"
+#include "core/svg/SVGFontData.h"
+#include "core/svg/SVGFontElement.h"
+#include "core/svg/SVGFontFaceElement.h"
+#include "platform/fonts/FontDescription.h"
+#include "platform/fonts/SimpleFontData.h"
+
+namespace WebCore {
+
+SVGRemoteFontFaceSource::SVGRemoteFontFaceSource(const String& uri, FontResource* font)
+    : RemoteFontFaceSource(font)
+    , m_uri(uri)
+{
+}
+
+SVGRemoteFontFaceSource::~SVGRemoteFontFaceSource()
+{
+}
+
+bool SVGRemoteFontFaceSource::ensureFontData()
+{
+    return resource()->ensureSVGFontData();
+}
+
+PassRefPtr<SimpleFontData> SVGRemoteFontFaceSource::createFontData(const FontDescription& fontDescription)
+{
+    if (!isLoaded())
+        return createLoadingFallbackFontData(fontDescription);
+
+    // Parse the external SVG document, and extract the <font> element.
+    if (!resource()->ensureSVGFontData())
+        return nullptr;
+
+    if (!m_externalSVGFontElement) {
+        String fragmentIdentifier;
+        size_t start = m_uri.find('#');
+        if (start != kNotFound)
+            fragmentIdentifier = m_uri.substring(start + 1);
+        m_externalSVGFontElement = resource()->getSVGFontById(fragmentIdentifier);
+    }
+
+    if (!m_externalSVGFontElement)
+        return nullptr;
+
+    // Select first <font-face> child
+    if (SVGFontFaceElement* fontFaceElement = Traversal<SVGFontFaceElement>::firstChild(*m_externalSVGFontElement)) {
+        return SimpleFontData::create(
+            SVGFontData::create(fontFaceElement),
+            fontDescription.effectiveFontSize(),
+            fontDescription.isSyntheticBold(),
+            fontDescription.isSyntheticItalic());
+    }
+    return nullptr;
+}
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGRemoteFontFaceSource.h b/Source/core/svg/SVGRemoteFontFaceSource.h
new file mode 100644
index 0000000..0d09016
--- /dev/null
+++ b/Source/core/svg/SVGRemoteFontFaceSource.h
@@ -0,0 +1,33 @@
+// Copyright 2014 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef SVGRemoteFontFaceSource_h
+#define SVGRemoteFontFaceSource_h
+
+#if ENABLE(SVG_FONTS)
+
+#include "core/css/RemoteFontFaceSource.h"
+
+namespace WebCore {
+
+class SVGFontElement;
+
+class SVGRemoteFontFaceSource : public RemoteFontFaceSource {
+public:
+    SVGRemoteFontFaceSource(const String& uri, FontResource*);
+    ~SVGRemoteFontFaceSource();
+    virtual bool isSVGFontFaceSource() const OVERRIDE { return true; }
+    virtual bool ensureFontData() OVERRIDE;
+
+private:
+    virtual PassRefPtr<SimpleFontData> createFontData(const FontDescription&) OVERRIDE;
+
+    String m_uri;
+    RefPtr<SVGFontElement> m_externalSVGFontElement;
+};
+
+} // namespace WebCore
+
+#endif // ENABLE(SVG_FONTS)
+#endif
diff --git a/Source/core/svg/SVGRenderingIntent.idl b/Source/core/svg/SVGRenderingIntent.idl
index 4092cda..2cdc2f4 100644
--- a/Source/core/svg/SVGRenderingIntent.idl
+++ b/Source/core/svg/SVGRenderingIntent.idl
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGRenderingIntent {
+[
+    DependentLifetime,
+] interface SVGRenderingIntent {
     // Rendering Intent Types
     const unsigned short RENDERING_INTENT_UNKNOWN               = 0;
     const unsigned short RENDERING_INTENT_AUTO                  = 1;
diff --git a/Source/core/svg/SVGSVGElement.cpp b/Source/core/svg/SVGSVGElement.cpp
index c2df77e..dbe9c07 100644
--- a/Source/core/svg/SVGSVGElement.cpp
+++ b/Source/core/svg/SVGSVGElement.cpp
@@ -2,6 +2,7 @@
  * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Rob Buis <buis@kde.org>
  * Copyright (C) 2007 Apple Inc. All rights reserved.
+ * Copyright (C) 2014 Google, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -34,7 +35,7 @@
 #include "core/editing/FrameSelection.h"
 #include "core/events/EventListener.h"
 #include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/page/FrameTree.h"
 #include "core/frame/FrameView.h"
 #include "core/frame/UseCounter.h"
@@ -44,13 +45,14 @@
 #include "core/rendering/svg/RenderSVGResource.h"
 #include "core/rendering/svg/RenderSVGRoot.h"
 #include "core/rendering/svg/RenderSVGViewportContainer.h"
-#include "core/svg/SVGAngle.h"
+#include "core/svg/SVGAngleTearOff.h"
 #include "core/svg/SVGElementInstance.h"
 #include "core/svg/SVGNumberTearOff.h"
 #include "core/svg/SVGPreserveAspectRatio.h"
 #include "core/svg/SVGRectTearOff.h"
 #include "core/svg/SVGTransform.h"
 #include "core/svg/SVGTransformList.h"
+#include "core/svg/SVGTransformTearOff.h"
 #include "core/svg/SVGViewElement.h"
 #include "core/svg/SVGViewSpec.h"
 #include "core/svg/animation/SMILTimeContainer.h"
@@ -62,12 +64,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGSVGElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGSVGElement::SVGSVGElement(Document& doc)
     : SVGGraphicsElement(SVGNames::svgTag, doc)
     , SVGFitToViewBox(this)
@@ -76,7 +72,7 @@
     , m_width(SVGAnimatedLength::create(this, SVGNames::widthAttr, SVGLength::create(LengthModeWidth)))
     , m_height(SVGAnimatedLength::create(this, SVGNames::heightAttr, SVGLength::create(LengthModeHeight)))
     , m_useCurrentView(false)
-    , m_timeContainer(SMILTimeContainer::create(this))
+    , m_timeContainer(SMILTimeContainer::create(*this))
     , m_translation(SVGPoint::create())
 {
     ScriptWrappable::init(this);
@@ -88,7 +84,6 @@
     addToPropertyMap(m_y);
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
-    registerAnimatedPropertiesForSVGSVGElement();
 
     UseCounter::count(doc, UseCounter::SVGSVGElement);
 }
@@ -105,9 +100,9 @@
 
     // There are cases where removedFromDocument() is not called.
     // see ContainerNode::removeAllChildren, called by its destructor.
-    document().accessSVGExtensions()->removeTimeContainer(this);
+    document().accessSVGExtensions().removeTimeContainer(this);
 
-    ASSERT(inDocument() || !accessDocumentSVGExtensions()->isSVGRootWithRelativeLengthDescendents(this));
+    ASSERT(inDocument() || !accessDocumentSVGExtensions().isSVGRootWithRelativeLengthDescendents(this));
 }
 
 const AtomicString& SVGSVGElement::contentScriptType() const
@@ -173,7 +168,7 @@
     if (!inDocument() || !isOutermostSVGSVGElement())
         return 1;
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return 1;
 
@@ -190,7 +185,7 @@
     if (!inDocument() || !isOutermostSVGSVGElement())
         return;
 
-    Frame* frame = document().frame();
+    LocalFrame* frame = document().frame();
     if (!frame)
         return;
 
@@ -328,54 +323,114 @@
     SVGGraphicsElement::svgAttributeChanged(attrName);
 }
 
-PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const FloatRect& rect, SVGElement* referenceElement, CollectIntersectionOrEnclosure collect) const
+// FloatRect::intersects does not consider horizontal or vertical lines (because of isEmpty()).
+static bool intersectsAllowingEmpty(const FloatRect& r1, const FloatRect& r2)
+{
+    if (r1.width() < 0 || r1.height() < 0 || r2.width() < 0 || r2.height() < 0)
+        return false;
+
+    return r1.x() < r2.maxX() && r2.x() < r1.maxX()
+        && r1.y() < r2.maxY() && r2.y() < r1.maxY();
+}
+
+// One of the element types that can cause graphics to be drawn onto the target canvas.
+// Specifically: circle, ellipse, image, line, path, polygon, polyline, rect, text and use.
+static bool isIntersectionOrEnclosureTarget(RenderObject* renderer)
+{
+    return renderer->isSVGShape()
+        || renderer->isSVGText()
+        || renderer->isSVGImage()
+        || isSVGUseElement(*renderer->node());
+}
+
+bool SVGSVGElement::checkIntersectionOrEnclosure(const SVGElement& element, const FloatRect& rect,
+    CheckIntersectionOrEnclosure mode) const
+{
+    RenderObject* renderer = element.renderer();
+    ASSERT(!renderer || renderer->style());
+    if (!renderer || renderer->style()->pointerEvents() == PE_NONE)
+        return false;
+
+    if (!isIntersectionOrEnclosureTarget(renderer))
+        return false;
+
+    AffineTransform ctm = toSVGGraphicsElement(element).computeCTM(AncestorScope, DisallowStyleUpdate, this);
+    FloatRect mappedRepaintRect = ctm.mapRect(renderer->repaintRectInLocalCoordinates());
+
+    bool result = false;
+    switch (mode) {
+    case CheckIntersection:
+        result = intersectsAllowingEmpty(rect, mappedRepaintRect);
+        break;
+    case CheckEnclosure:
+        result = rect.contains(mappedRepaintRect);
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+
+    return result;
+}
+
+PassRefPtr<NodeList> SVGSVGElement::collectIntersectionOrEnclosureList(const FloatRect& rect,
+    SVGElement* referenceElement, CheckIntersectionOrEnclosure mode) const
 {
     Vector<RefPtr<Node> > nodes;
-    Element* element = ElementTraversal::next(*(referenceElement ? referenceElement : this));
-    while (element) {
-        if (element->isSVGElement()) {
-            SVGElement* svgElement = toSVGElement(element);
-            if (collect == CollectIntersectionList) {
-                if (RenderSVGModelObject::checkIntersection(svgElement->renderer(), rect))
-                    nodes.append(element);
-            } else {
-                if (RenderSVGModelObject::checkEnclosure(svgElement->renderer(), rect))
-                    nodes.append(element);
-            }
-        }
 
-        element = ElementTraversal::next(*element, referenceElement ? referenceElement : this);
+    const SVGElement* root = this;
+    if (referenceElement) {
+        // Only the common subtree needs to be traversed.
+        if (contains(referenceElement)) {
+            root = referenceElement;
+        } else if (!isDescendantOf(referenceElement)) {
+            // No common subtree.
+            return StaticNodeList::adopt(nodes);
+        }
     }
+
+    for (SVGGraphicsElement* element = Traversal<SVGGraphicsElement>::firstWithin(*root); element;
+        element = Traversal<SVGGraphicsElement>::next(*element, root)) {
+        if (checkIntersectionOrEnclosure(*element, rect, mode))
+            nodes.append(element);
+    }
+
     return StaticNodeList::adopt(nodes);
 }
 
-PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(PassRefPtr<SVGRectTearOff> passRect, SVGElement* referenceElement) const
+PassRefPtr<NodeList> SVGSVGElement::getIntersectionList(PassRefPtr<SVGRectTearOff> rect, SVGElement* referenceElement) const
 {
-    RefPtr<SVGRectTearOff> rect = passRect;
-    return collectIntersectionOrEnclosureList(rect->target()->value(), referenceElement, CollectIntersectionList);
+    document().updateLayoutIgnorePendingStylesheets();
+
+    return collectIntersectionOrEnclosureList(rect->target()->value(), referenceElement, CheckIntersection);
 }
 
-PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(PassRefPtr<SVGRectTearOff> passRect, SVGElement* referenceElement) const
+PassRefPtr<NodeList> SVGSVGElement::getEnclosureList(PassRefPtr<SVGRectTearOff> rect, SVGElement* referenceElement) const
 {
-    RefPtr<SVGRectTearOff> rect = passRect;
-    return collectIntersectionOrEnclosureList(rect->target()->value(), referenceElement, CollectEnclosureList);
+    document().updateLayoutIgnorePendingStylesheets();
+
+    return collectIntersectionOrEnclosureList(rect->target()->value(), referenceElement, CheckEnclosure);
 }
 
-bool SVGSVGElement::checkIntersection(SVGElement* element, PassRefPtr<SVGRectTearOff> passRect) const
+bool SVGSVGElement::checkIntersection(SVGElement* element, PassRefPtr<SVGRectTearOff> rect) const
 {
-    RefPtr<SVGRectTearOff> rect = passRect;
-    return RenderSVGModelObject::checkIntersection(element->renderer(), rect->target()->value());
+    ASSERT(element);
+    document().updateLayoutIgnorePendingStylesheets();
+
+    return checkIntersectionOrEnclosure(*element, rect->target()->value(), CheckIntersection);
 }
 
-bool SVGSVGElement::checkEnclosure(SVGElement* element, PassRefPtr<SVGRectTearOff> passRect) const
+bool SVGSVGElement::checkEnclosure(SVGElement* element, PassRefPtr<SVGRectTearOff> rect) const
 {
-    RefPtr<SVGRectTearOff> rect = passRect;
-    return RenderSVGModelObject::checkEnclosure(element->renderer(), rect->target()->value());
+    ASSERT(element);
+    document().updateLayoutIgnorePendingStylesheets();
+
+    return checkIntersectionOrEnclosure(*element, rect->target()->value(), CheckEnclosure);
 }
 
 void SVGSVGElement::deselectAll()
 {
-    if (Frame* frame = document().frame())
+    if (LocalFrame* frame = document().frame())
         frame->selection().clear();
 }
 
@@ -389,9 +444,9 @@
     return SVGLengthTearOff::create(SVGLength::create(), 0, PropertyIsNotAnimVal);
 }
 
-SVGAngle SVGSVGElement::createSVGAngle()
+PassRefPtr<SVGAngleTearOff> SVGSVGElement::createSVGAngle()
 {
-    return SVGAngle();
+    return SVGAngleTearOff::create(SVGAngle::create(), 0, PropertyIsNotAnimVal);
 }
 
 PassRefPtr<SVGPointTearOff> SVGSVGElement::createSVGPoint()
@@ -399,9 +454,9 @@
     return SVGPointTearOff::create(SVGPoint::create(), 0, PropertyIsNotAnimVal);
 }
 
-SVGMatrix SVGSVGElement::createSVGMatrix()
+PassRefPtr<SVGMatrixTearOff> SVGSVGElement::createSVGMatrix()
 {
-    return SVGMatrix();
+    return SVGMatrixTearOff::create(AffineTransform());
 }
 
 PassRefPtr<SVGRectTearOff> SVGSVGElement::createSVGRect()
@@ -409,14 +464,14 @@
     return SVGRectTearOff::create(SVGRect::create(), 0, PropertyIsNotAnimVal);
 }
 
-SVGTransform SVGSVGElement::createSVGTransform()
+PassRefPtr<SVGTransformTearOff> SVGSVGElement::createSVGTransform()
 {
-    return SVGTransform(SVGTransform::SVG_TRANSFORM_MATRIX);
+    return SVGTransformTearOff::create(SVGTransform::create(SVG_TRANSFORM_MATRIX), 0, PropertyIsNotAnimVal);
 }
 
-SVGTransform SVGSVGElement::createSVGTransformFromMatrix(const SVGMatrix& matrix)
+PassRefPtr<SVGTransformTearOff> SVGSVGElement::createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff> matrix)
 {
-    return SVGTransform(static_cast<const AffineTransform&>(matrix));
+    return SVGTransformTearOff::create(SVGTransform::create(matrix->value()), 0, PropertyIsNotAnimVal);
 }
 
 AffineTransform SVGSVGElement::localCoordinateSpaceTransform(SVGElement::CTMScope mode) const
@@ -490,7 +545,7 @@
     if (rootParent->inDocument()) {
         UseCounter::count(document(), UseCounter::SVGSVGElementInDocument);
 
-        document().accessSVGExtensions()->addTimeContainer(this);
+        document().accessSVGExtensions().addTimeContainer(this);
 
         // Animations are started at the end of document parsing and after firing the load event,
         // but if we miss that train (deferred programmatic element insertion for example) we need
@@ -504,9 +559,9 @@
 void SVGSVGElement::removedFrom(ContainerNode* rootParent)
 {
     if (rootParent->inDocument()) {
-        SVGDocumentExtensions* svgExtensions = document().accessSVGExtensions();
-        svgExtensions->removeTimeContainer(this);
-        svgExtensions->removeSVGRootWithRelativeLengthDescendents(this);
+        SVGDocumentExtensions& svgExtensions = document().accessSVGExtensions();
+        svgExtensions.removeTimeContainer(this);
+        svgExtensions.removeSVGRootWithRelativeLengthDescendents(this);
     }
 
     SVGGraphicsElement::removedFrom(rootParent);
@@ -675,12 +730,12 @@
         return SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), preserveAspectRatio()->currentValue(), viewWidth, viewHeight);
 
     AffineTransform ctm = SVGFitToViewBox::viewBoxToViewTransform(currentViewBoxRect(), m_viewSpec->preserveAspectRatio()->currentValue(), viewWidth, viewHeight);
-    const SVGTransformList& transformList = m_viewSpec->transformBaseValue();
-    if (transformList.isEmpty())
+    RefPtr<SVGTransformList> transformList = m_viewSpec->transform();
+    if (transformList->isEmpty())
         return ctm;
 
     AffineTransform transform;
-    if (transformList.concatenate(transform))
+    if (transformList->concatenate(transform))
         ctm *= transform;
 
     return ctm;
@@ -721,13 +776,11 @@
     // or MyDrawing.svg#xpointer(id('MyView'))) then the closest ancestor ‘svg’ element is displayed in the viewport.
     // Any view specification attributes included on the given ‘view’ element override the corresponding view specification
     // attributes on the closest ancestor ‘svg’ element.
-    if (anchorNode && anchorNode->hasTagName(SVGNames::viewTag)) {
-        SVGViewElement* viewElement = toSVGViewElement(anchorNode);
-        if (!viewElement)
-            return;
+    if (isSVGViewElement(anchorNode)) {
+        SVGViewElement& viewElement = toSVGViewElement(*anchorNode);
 
-        if (SVGSVGElement* svg = viewElement->ownerSVGElement()) {
-            svg->inheritViewAttributes(viewElement);
+        if (SVGSVGElement* svg = viewElement.ownerSVGElement()) {
+            svg->inheritViewAttributes(&viewElement);
 
             if (RenderObject* renderer = svg->renderer())
                 RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer);
diff --git a/Source/core/svg/SVGSVGElement.h b/Source/core/svg/SVGSVGElement.h
index 0941693..1a6170e 100644
--- a/Source/core/svg/SVGSVGElement.h
+++ b/Source/core/svg/SVGSVGElement.h
@@ -1,6 +1,7 @@
 /*
  * Copyright (C) 2004, 2005, 2006 Nikolas Zimmermann <zimmermann@kde.org>
  * Copyright (C) 2004, 2005, 2006, 2007, 2010 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google, Inc.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -31,10 +32,10 @@
 
 namespace WebCore {
 
-class SVGAngle;
-class SVGMatrix;
+class SVGMatrixTearOff;
+class SVGAngleTearOff;
 class SVGNumberTearOff;
-class SVGTransform;
+class SVGTransformTearOff;
 class SVGViewSpec;
 class SVGViewElement;
 class SMILTimeContainer;
@@ -108,12 +109,12 @@
 
     static PassRefPtr<SVGNumberTearOff> createSVGNumber();
     static PassRefPtr<SVGLengthTearOff> createSVGLength();
-    static SVGAngle createSVGAngle();
+    static PassRefPtr<SVGAngleTearOff> createSVGAngle();
     static PassRefPtr<SVGPointTearOff> createSVGPoint();
-    static SVGMatrix createSVGMatrix();
+    static PassRefPtr<SVGMatrixTearOff> createSVGMatrix();
     static PassRefPtr<SVGRectTearOff> createSVGRect();
-    static SVGTransform createSVGTransform();
-    static SVGTransform createSVGTransformFromMatrix(const SVGMatrix&);
+    static PassRefPtr<SVGTransformTearOff> createSVGTransform();
+    static PassRefPtr<SVGTransformTearOff> createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff>);
 
     AffineTransform viewBoxToViewTransform(float viewWidth, float viewHeight) const;
 
@@ -133,8 +134,6 @@
     explicit SVGSVGElement(Document&);
     virtual ~SVGSVGElement();
 
-    virtual bool isSVGSVGElement() const OVERRIDE { return true; }
-
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
 
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
@@ -151,19 +150,18 @@
 
     void updateCurrentTranslate();
 
-    enum CollectIntersectionOrEnclosure {
-        CollectIntersectionList,
-        CollectEnclosureList
+    enum CheckIntersectionOrEnclosure {
+        CheckIntersection,
+        CheckEnclosure
     };
 
-    PassRefPtr<NodeList> collectIntersectionOrEnclosureList(const FloatRect&, SVGElement*, CollectIntersectionOrEnclosure) const;
+    bool checkIntersectionOrEnclosure(const SVGElement&, const FloatRect&, CheckIntersectionOrEnclosure) const;
+    PassRefPtr<NodeList> collectIntersectionOrEnclosureList(const FloatRect&, SVGElement*, CheckIntersectionOrEnclosure) const;
 
     RefPtr<SVGAnimatedLength> m_x;
     RefPtr<SVGAnimatedLength> m_y;
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSVGElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     virtual AffineTransform localCoordinateSpaceTransform(SVGElement::CTMScope) const OVERRIDE;
 
@@ -175,13 +173,6 @@
     friend class SVGCurrentTranslateTearOff;
 };
 
-inline bool isSVGSVGElement(const Node& node)
-{
-    return node.isSVGElement() && toSVGElement(node).isSVGSVGElement();
-}
-
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGSVGElement);
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGScriptElement.cpp b/Source/core/svg/SVGScriptElement.cpp
index 5d121fa..e2d91b8 100644
--- a/Source/core/svg/SVGScriptElement.cpp
+++ b/Source/core/svg/SVGScriptElement.cpp
@@ -30,15 +30,9 @@
 #include "core/dom/ScriptLoader.h"
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/svg/SVGElementInstance.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGScriptElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGScriptElement::SVGScriptElement(Document& document, bool wasInsertedByParser, bool alreadyStarted)
     : SVGElement(SVGNames::scriptTag, document)
     , SVGURIReference(this)
@@ -46,7 +40,6 @@
     , m_loader(ScriptLoader::create(this, wasInsertedByParser, alreadyStarted))
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGScriptElement();
 }
 
 PassRefPtr<SVGScriptElement> SVGScriptElement::create(Document& document, bool insertedByParser)
diff --git a/Source/core/svg/SVGScriptElement.h b/Source/core/svg/SVGScriptElement.h
index b11f5be..bff65b6 100644
--- a/Source/core/svg/SVGScriptElement.h
+++ b/Source/core/svg/SVGScriptElement.h
@@ -39,9 +39,6 @@
 public:
     static PassRefPtr<SVGScriptElement> create(Document&, bool wasInsertedByParser);
 
-    String type() const;
-    void setType(const String&);
-
     ScriptLoader* loader() const { return m_loader.get(); }
 
 #ifndef NDEBUG
@@ -81,15 +78,11 @@
 
     virtual Timer<SVGElement>* svgLoadEventTimer() OVERRIDE { return &m_svgLoadEventTimer; }
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGScriptElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     Timer<SVGElement> m_svgLoadEventTimer;
     OwnPtr<ScriptLoader> m_loader;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGScriptElement, hasTagName(SVGNames::scriptTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGStaticStringList.cpp b/Source/core/svg/SVGStaticStringList.cpp
index 7a2697e..73077d7 100644
--- a/Source/core/svg/SVGStaticStringList.cpp
+++ b/Source/core/svg/SVGStaticStringList.cpp
@@ -57,7 +57,7 @@
 PassRefPtr<NewSVGPropertyBase> SVGStaticStringList::createAnimatedValue()
 {
     ASSERT_NOT_REACHED();
-    return 0;
+    return nullptr;
 }
 
 void SVGStaticStringList::setAnimatedValue(PassRefPtr<NewSVGPropertyBase>)
@@ -70,16 +70,6 @@
     ASSERT_NOT_REACHED();
 }
 
-void SVGStaticStringList::animValWillChange()
-{
-    ASSERT_NOT_REACHED();
-}
-
-void SVGStaticStringList::animValDidChange()
-{
-    ASSERT_NOT_REACHED();
-}
-
 bool SVGStaticStringList::needsSynchronizeAttribute()
 {
     return m_tearOff;
diff --git a/Source/core/svg/SVGStaticStringList.h b/Source/core/svg/SVGStaticStringList.h
index e45cb9e..5518fe6 100644
--- a/Source/core/svg/SVGStaticStringList.h
+++ b/Source/core/svg/SVGStaticStringList.h
@@ -55,8 +55,6 @@
     virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() OVERRIDE;
     virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) OVERRIDE;
     virtual void animationEnded() OVERRIDE;
-    virtual void animValWillChange() OVERRIDE;
-    virtual void animValDidChange() OVERRIDE;
     virtual bool needsSynchronizeAttribute() OVERRIDE;
 
     void setBaseValueAsString(const String& value, SVGParsingError& parseError);
diff --git a/Source/core/svg/SVGStopElement.cpp b/Source/core/svg/SVGStopElement.cpp
index 2421deb..294797b 100644
--- a/Source/core/svg/SVGStopElement.cpp
+++ b/Source/core/svg/SVGStopElement.cpp
@@ -28,11 +28,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGStopElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGStopElement::SVGStopElement(Document& document)
     : SVGElement(SVGNames::stopTag, document)
     , m_offset(SVGAnimatedNumber::create(this, SVGNames::offsetAttr, SVGNumberAcceptPercentage::create()))
@@ -40,7 +35,6 @@
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_offset);
-    registerAnimatedPropertiesForSVGStopElement();
 }
 
 PassRefPtr<SVGStopElement> SVGStopElement::create(Document& document)
diff --git a/Source/core/svg/SVGStopElement.h b/Source/core/svg/SVGStopElement.h
index fcd5215..c884dfc 100644
--- a/Source/core/svg/SVGStopElement.h
+++ b/Source/core/svg/SVGStopElement.h
@@ -42,23 +42,12 @@
     virtual void parseAttribute(const QualifiedName&, const AtomicString&) OVERRIDE;
     virtual void svgAttributeChanged(const QualifiedName&) OVERRIDE;
 
-    virtual bool isGradientStop() const OVERRIDE { return true; }
-
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE;
 
     RefPtr<SVGAnimatedNumber> m_offset;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGStopElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-inline bool isSVGStopElement(const Node& node)
-{
-    return node.isSVGElement() && toSVGElement(node).isGradientStop();
-}
-
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGStopElement);
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGStringList.h b/Source/core/svg/SVGStringList.h
index 946f571..0e531b9 100644
--- a/Source/core/svg/SVGStringList.h
+++ b/Source/core/svg/SVGStringList.h
@@ -64,7 +64,7 @@
     const Vector<String>& values() const { return m_values; }
 
     // SVGStringList DOM Spec implementation. These are only to be called from SVGStringListTearOff:
-    unsigned long numberOfItems() { return m_values.size(); }
+    unsigned long length() { return m_values.size(); }
     void clear() { m_values.clear(); }
     void initialize(const String&);
     String getItem(size_t, ExceptionState&);
diff --git a/Source/core/svg/SVGStringList.idl b/Source/core/svg/SVGStringList.idl
index 0b5dc41..dce367c 100644
--- a/Source/core/svg/SVGStringList.idl
+++ b/Source/core/svg/SVGStringList.idl
@@ -28,11 +28,13 @@
     SetWrapperReferenceTo(SVGElement contextElement),
     ImplementedAs=SVGStringListTearOff
 ] interface SVGStringList {
-    readonly attribute unsigned long numberOfItems;
+    readonly attribute unsigned long length;
+    [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
 
     [RaisesException] void clear();
     [RaisesException] DOMString initialize(DOMString item);
-    [RaisesException] DOMString getItem(unsigned long index);
+    [RaisesException] getter DOMString getItem(unsigned long index);
+    [RaisesException] setter DOMString (unsigned long index, DOMString value);
     [RaisesException] DOMString insertItemBefore(DOMString item, unsigned long index);
     [RaisesException] DOMString replaceItem(DOMString item, unsigned long index);
     [RaisesException] DOMString removeItem(unsigned long index);
diff --git a/Source/core/svg/SVGStringListTearOff.h b/Source/core/svg/SVGStringListTearOff.h
index 3e16f5c..ed7419a 100644
--- a/Source/core/svg/SVGStringListTearOff.h
+++ b/Source/core/svg/SVGStringListTearOff.h
@@ -46,9 +46,9 @@
     // SVGStringList DOM interface:
 
     // WebIDL requires "unsigned long" type instead of size_t.
-    unsigned long numberOfItems()
+    unsigned long length()
     {
-        return target()->numberOfItems();
+        return target()->length();
     }
 
     void clear(ExceptionState& exceptionState)
@@ -106,6 +106,12 @@
         return item;
     }
 
+    bool anonymousIndexedSetter(unsigned index, const String& item, ExceptionState& exceptionState)
+    {
+        replaceItem(item, index, exceptionState);
+        return true;
+    }
+
     String removeItem(unsigned long index, ExceptionState& exceptionState)
     {
         if (isImmutable()) {
diff --git a/Source/core/svg/SVGStyleElement.h b/Source/core/svg/SVGStyleElement.h
index 6aeed2f..1490667 100644
--- a/Source/core/svg/SVGStyleElement.h
+++ b/Source/core/svg/SVGStyleElement.h
@@ -67,8 +67,6 @@
     Timer<SVGElement> m_svgLoadEventTimer;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGStyleElement, hasTagName(SVGNames::styleTag));
-
 } // namespace WebCore
 
 #endif // SVGStyleElement_h
diff --git a/Source/core/svg/SVGSwitchElement.cpp b/Source/core/svg/SVGSwitchElement.cpp
index 539ef59..1fba933 100644
--- a/Source/core/svg/SVGSwitchElement.cpp
+++ b/Source/core/svg/SVGSwitchElement.cpp
@@ -28,17 +28,10 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGSwitchElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGSwitchElement::SVGSwitchElement(Document& document)
     : SVGGraphicsElement(SVGNames::switchTag, document)
 {
     ScriptWrappable::init(this);
-    registerAnimatedPropertiesForSVGSwitchElement();
 
     UseCounter::count(document, UseCounter::SVGSwitchElement);
 }
diff --git a/Source/core/svg/SVGSwitchElement.h b/Source/core/svg/SVGSwitchElement.h
index 89cc2eb..03aac86 100644
--- a/Source/core/svg/SVGSwitchElement.h
+++ b/Source/core/svg/SVGSwitchElement.h
@@ -37,8 +37,6 @@
 
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSwitchElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGSymbolElement.cpp b/Source/core/svg/SVGSymbolElement.cpp
index 4035b25..1acac8b 100644
--- a/Source/core/svg/SVGSymbolElement.cpp
+++ b/Source/core/svg/SVGSymbolElement.cpp
@@ -28,19 +28,11 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGSymbolElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGSymbolElement::SVGSymbolElement(Document& document)
     : SVGElement(SVGNames::symbolTag, document)
     , SVGFitToViewBox(this)
 {
     ScriptWrappable::init(this);
-
-    registerAnimatedPropertiesForSVGSymbolElement();
 }
 
 PassRefPtr<SVGSymbolElement> SVGSymbolElement::create(Document& document)
diff --git a/Source/core/svg/SVGSymbolElement.h b/Source/core/svg/SVGSymbolElement.h
index 5cebf40..bcb3e0e 100644
--- a/Source/core/svg/SVGSymbolElement.h
+++ b/Source/core/svg/SVGSymbolElement.h
@@ -45,8 +45,6 @@
 
     virtual bool selfHasRelativeLengths() const OVERRIDE;
 
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGSymbolElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGTSpanElement.cpp b/Source/core/svg/SVGTSpanElement.cpp
index 9aa1a93..f8e2f69 100644
--- a/Source/core/svg/SVGTSpanElement.cpp
+++ b/Source/core/svg/SVGTSpanElement.cpp
@@ -46,13 +46,13 @@
 bool SVGTSpanElement::rendererIsNeeded(const RenderStyle& style)
 {
     if (parentNode()
-        && (parentNode()->hasTagName(SVGNames::aTag)
+        && (isSVGAElement(*parentNode())
 #if ENABLE(SVG_FONTS)
-            || parentNode()->hasTagName(SVGNames::altGlyphTag)
+            || isSVGAltGlyphElement(*parentNode())
 #endif
-            || parentNode()->hasTagName(SVGNames::textTag)
-            || parentNode()->hasTagName(SVGNames::textPathTag)
-            || parentNode()->hasTagName(SVGNames::tspanTag)))
+            || isSVGTextElement(*parentNode())
+            || isSVGTextPathElement(*parentNode())
+            || isSVGTSpanElement(*parentNode())))
         return Element::rendererIsNeeded(style);
 
     return false;
diff --git a/Source/core/svg/SVGTagNames.in b/Source/core/svg/SVGTagNames.in
index db346cf..0bd5081 100644
--- a/Source/core/svg/SVGTagNames.in
+++ b/Source/core/svg/SVGTagNames.in
@@ -9,7 +9,7 @@
 altGlyphDef
 altGlyphItem
 #endif
-animate
+animate noTypeHelpers
 animateColor interfaceName=SVGUnknownElement, JSInterfaceName=SVGElement, noConstructor
 animateMotion
 animateTransform
diff --git a/Source/core/svg/SVGTests.cpp b/Source/core/svg/SVGTests.cpp
index b555983..92ce90e 100644
--- a/Source/core/svg/SVGTests.cpp
+++ b/Source/core/svg/SVGTests.cpp
@@ -41,7 +41,7 @@
     contextElement->addToPropertyMap(m_systemLanguage);
 }
 
-bool SVGTests::hasExtension(SVGTests*, const String&)
+bool SVGTests::hasExtension(SVGTests&, const String&)
 {
     // FIXME: Implement me!
     return false;
diff --git a/Source/core/svg/SVGTests.h b/Source/core/svg/SVGTests.h
index 3113f51..7cd5eb3 100644
--- a/Source/core/svg/SVGTests.h
+++ b/Source/core/svg/SVGTests.h
@@ -32,11 +32,11 @@
 
 class SVGTests {
 public:
-    static SVGStringListTearOff* requiredFeatures(SVGTests* object) { return object->m_requiredFeatures->tearOff(); }
-    static SVGStringListTearOff* requiredExtensions(SVGTests* object) { return object->m_requiredExtensions->tearOff(); }
-    static SVGStringListTearOff* systemLanguage(SVGTests* object) { return object->m_systemLanguage->tearOff(); }
+    static SVGStringListTearOff* requiredFeatures(SVGTests& object) { return object.m_requiredFeatures->tearOff(); }
+    static SVGStringListTearOff* requiredExtensions(SVGTests& object) { return object.m_requiredExtensions->tearOff(); }
+    static SVGStringListTearOff* systemLanguage(SVGTests& object) { return object.m_systemLanguage->tearOff(); }
 
-    static bool hasExtension(SVGTests*, const String&);
+    static bool hasExtension(SVGTests&, const String&);
     bool isValid() const;
 
     bool parseAttribute(const QualifiedName&, const AtomicString&);
diff --git a/Source/core/svg/SVGTextContentElement.cpp b/Source/core/svg/SVGTextContentElement.cpp
index c5b8e0f..e1cd1cb 100644
--- a/Source/core/svg/SVGTextContentElement.cpp
+++ b/Source/core/svg/SVGTextContentElement.cpp
@@ -29,7 +29,7 @@
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
 #include "core/editing/FrameSelection.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/svg/RenderSVGResource.h"
 #include "core/rendering/svg/SVGTextQuery.h"
@@ -37,7 +37,16 @@
 
 namespace WebCore {
 
-// Animated property definitions
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGLengthAdjustType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVGLengthAdjustUnknown, emptyString()));
+        entries.append(std::make_pair(SVGLengthAdjustSpacing, "spacing"));
+        entries.append(std::make_pair(SVGLengthAdjustSpacingAndGlyphs, "spacingAndGlyphs"));
+    }
+    return entries;
+}
 
 // SVGTextContentElement's 'textLength' attribute needs special handling.
 // It should return getComputedTextLength() when textLength is not specified manually.
@@ -64,23 +73,17 @@
     }
 };
 
-DEFINE_ANIMATED_ENUMERATION(SVGTextContentElement, SVGNames::lengthAdjustAttr, LengthAdjust, lengthAdjust, SVGLengthAdjustType)
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextContentElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(lengthAdjust)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
 
 SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Document& document)
     : SVGGraphicsElement(tagName, document)
     , m_textLength(SVGAnimatedTextLength::create(this))
     , m_textLengthIsSpecifiedByUser(false)
-    , m_lengthAdjust(SVGLengthAdjustSpacing)
+    , m_lengthAdjust(SVGAnimatedEnumeration<SVGLengthAdjustType>::create(this, SVGNames::lengthAdjustAttr, SVGLengthAdjustSpacing))
 {
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_textLength);
-    registerAnimatedPropertiesForSVGTextContentElement();
+    addToPropertyMap(m_lengthAdjust);
 }
 
 unsigned SVGTextContentElement::getNumberOfChars()
@@ -117,7 +120,7 @@
 
     if (charnum > getNumberOfChars()) {
         exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
-        return 0;
+        return nullptr;
     }
 
     FloatPoint point = SVGTextQuery(renderer()).startPositionOfCharacter(charnum);
@@ -130,7 +133,7 @@
 
     if (charnum > getNumberOfChars()) {
         exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
-        return 0;
+        return nullptr;
     }
 
     FloatPoint point = SVGTextQuery(renderer()).endPositionOfCharacter(charnum);
@@ -143,7 +146,7 @@
 
     if (charnum > getNumberOfChars()) {
         exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("charnum", charnum, getNumberOfChars()));
-        return 0;
+        return nullptr;
     }
 
     FloatRect rect = SVGTextQuery(renderer()).extentOfCharacter(charnum);
@@ -233,9 +236,7 @@
     if (!isSupportedAttribute(name))
         SVGGraphicsElement::parseAttribute(name, value);
     else if (name == SVGNames::lengthAdjustAttr) {
-        SVGLengthAdjustType propertyValue = SVGPropertyTraits<SVGLengthAdjustType>::fromString(value);
-        if (propertyValue > 0)
-            setLengthAdjustBaseValue(propertyValue);
+        m_lengthAdjust->setBaseValueAsString(value, parseError);
     } else if (name == SVGNames::textLengthAttr) {
         m_textLength->setBaseValueAsString(value, ForbidNegativeLengths, parseError);
     } else if (name.matches(XMLNames::spaceAttr)) {
@@ -279,11 +280,7 @@
 
     SVGElement* element = toSVGElement(renderer->node());
     ASSERT(element);
-
-    if (!element->isTextContent())
-        return 0;
-
-    return toSVGTextContentElement(element);
+    return isSVGTextContentElement(*element) ? toSVGTextContentElement(element) : 0;
 }
 
 }
diff --git a/Source/core/svg/SVGTextContentElement.h b/Source/core/svg/SVGTextContentElement.h
index 1bd13f1..6dbe404 100644
--- a/Source/core/svg/SVGTextContentElement.h
+++ b/Source/core/svg/SVGTextContentElement.h
@@ -36,35 +36,7 @@
     SVGLengthAdjustSpacing,
     SVGLengthAdjustSpacingAndGlyphs
 };
-
-template<>
-struct SVGPropertyTraits<SVGLengthAdjustType> {
-    static unsigned highestEnumValue() { return SVGLengthAdjustSpacingAndGlyphs; }
-
-    static String toString(SVGLengthAdjustType type)
-    {
-        switch (type) {
-        case SVGLengthAdjustUnknown:
-            return emptyString();
-        case SVGLengthAdjustSpacing:
-            return "spacing";
-        case SVGLengthAdjustSpacingAndGlyphs:
-            return "spacingAndGlyphs";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static SVGLengthAdjustType fromString(const String& value)
-    {
-        if (value == "spacingAndGlyphs")
-            return SVGLengthAdjustSpacingAndGlyphs;
-        if (value == "spacing")
-            return SVGLengthAdjustSpacing;
-        return SVGLengthAdjustUnknown;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGLengthAdjustType>();
 
 class SVGAnimatedTextLength;
 
@@ -91,6 +63,7 @@
 
     SVGAnimatedLength* textLength() { return m_textLength.get(); }
     bool textLengthIsSpecifiedByUser() { return m_textLengthIsSpecifiedByUser; }
+    SVGAnimatedEnumeration<SVGLengthAdjustType>* lengthAdjust() { return m_lengthAdjust.get(); }
 
 protected:
     SVGTextContentElement(const QualifiedName&, Document&);
@@ -108,9 +81,7 @@
 
     RefPtr<SVGAnimatedLength> m_textLength;
     bool m_textLengthIsSpecifiedByUser;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextContentElement)
-        DECLARE_ANIMATED_ENUMERATION(LengthAdjust, lengthAdjust, SVGLengthAdjustType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<SVGLengthAdjustType> > m_lengthAdjust;
 };
 
 inline bool isSVGTextContentElement(const Node& node)
@@ -118,7 +89,7 @@
     return node.isSVGElement() && toSVGElement(node).isTextContent();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGTextContentElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGTextContentElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGTextElement.cpp b/Source/core/svg/SVGTextElement.cpp
index 523ab0a..dde5fd0 100644
--- a/Source/core/svg/SVGTextElement.cpp
+++ b/Source/core/svg/SVGTextElement.cpp
@@ -55,7 +55,7 @@
         // Flatten any 3D transform
         matrix = t.toAffineTransform();
     } else {
-        transformCurrentValue().concatenate(matrix);
+        transform()->currentValue()->concatenate(matrix);
     }
 
     const AffineTransform* transform = const_cast<SVGTextElement*>(this)->supplementalTransform();
diff --git a/Source/core/svg/SVGTextElement.h b/Source/core/svg/SVGTextElement.h
index 28284a1..a132868 100644
--- a/Source/core/svg/SVGTextElement.h
+++ b/Source/core/svg/SVGTextElement.h
@@ -40,8 +40,6 @@
     virtual RenderObject* createRenderer(RenderStyle*) OVERRIDE;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGTextElement, hasTagName(SVGNames::textTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGTextPathElement.cpp b/Source/core/svg/SVGTextPathElement.cpp
index 2697861..8b9b4e0 100644
--- a/Source/core/svg/SVGTextPathElement.cpp
+++ b/Source/core/svg/SVGTextPathElement.cpp
@@ -29,27 +29,40 @@
 
 namespace WebCore {
 
-// Animated property definitions
-DEFINE_ANIMATED_ENUMERATION(SVGTextPathElement, SVGNames::methodAttr, Method, method, SVGTextPathMethodType)
-DEFINE_ANIMATED_ENUMERATION(SVGTextPathElement, SVGNames::spacingAttr, Spacing, spacing, SVGTextPathSpacingType)
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathMethodType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVGTextPathMethodUnknown, emptyString()));
+        entries.append(std::make_pair(SVGTextPathMethodAlign, "align"));
+        entries.append(std::make_pair(SVGTextPathMethodStretch, "stretch"));
+    }
+    return entries;
+}
 
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPathElement)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(method)
-    REGISTER_LOCAL_ANIMATED_PROPERTY(spacing)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement)
-END_REGISTER_ANIMATED_PROPERTIES
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathSpacingType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVGTextPathSpacingUnknown, emptyString()));
+        entries.append(std::make_pair(SVGTextPathSpacingAuto, "auto"));
+        entries.append(std::make_pair(SVGTextPathSpacingExact, "exact"));
+    }
+    return entries;
+}
 
 inline SVGTextPathElement::SVGTextPathElement(Document& document)
     : SVGTextContentElement(SVGNames::textPathTag, document)
     , SVGURIReference(this)
     , m_startOffset(SVGAnimatedLength::create(this, SVGNames::startOffsetAttr, SVGLength::create(LengthModeOther)))
-    , m_method(SVGTextPathMethodAlign)
-    , m_spacing(SVGTextPathSpacingExact)
+    , m_method(SVGAnimatedEnumeration<SVGTextPathMethodType>::create(this, SVGNames::methodAttr, SVGTextPathMethodAlign))
+    , m_spacing(SVGAnimatedEnumeration<SVGTextPathSpacingType>::create(this, SVGNames::spacingAttr, SVGTextPathSpacingExact))
 {
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_startOffset);
-    registerAnimatedPropertiesForSVGTextPathElement();
+    addToPropertyMap(m_method);
+    addToPropertyMap(m_spacing);
 }
 
 PassRefPtr<SVGTextPathElement> SVGTextPathElement::create(Document& document)
@@ -64,7 +77,7 @@
 
 void SVGTextPathElement::clearResourceReferences()
 {
-    document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+    document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
 }
 
 bool SVGTextPathElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -83,22 +96,17 @@
 {
     SVGParsingError parseError = NoError;
 
-    if (!isSupportedAttribute(name)) {
+    if (!isSupportedAttribute(name))
         SVGTextContentElement::parseAttribute(name, value);
-    } else if (name == SVGNames::startOffsetAttr) {
+    else if (name == SVGNames::startOffsetAttr)
         m_startOffset->setBaseValueAsString(value, AllowNegativeLengths, parseError);
-    } else if (name == SVGNames::methodAttr) {
-        SVGTextPathMethodType propertyValue = SVGPropertyTraits<SVGTextPathMethodType>::fromString(value);
-        if (propertyValue > 0)
-            setMethodBaseValue(propertyValue);
-    } else if (name == SVGNames::spacingAttr) {
-        SVGTextPathSpacingType propertyValue = SVGPropertyTraits<SVGTextPathSpacingType>::fromString(value);
-        if (propertyValue > 0)
-            setSpacingBaseValue(propertyValue);
-    } else if (SVGURIReference::parseAttribute(name, value, parseError)) {
-    } else {
+    else if (name == SVGNames::methodAttr)
+        m_method->setBaseValueAsString(value, parseError);
+    else if (name == SVGNames::spacingAttr)
+        m_spacing->setBaseValueAsString(value, parseError);
+    else if (SVGURIReference::parseAttribute(name, value, parseError)) {
+    } else
         ASSERT_NOT_REACHED();
-    }
 
     reportAttributeParsingError(parseError, name, value);
 }
@@ -131,9 +139,7 @@
 
 bool SVGTextPathElement::rendererIsNeeded(const RenderStyle& style)
 {
-    if (parentNode()
-        && (parentNode()->hasTagName(SVGNames::aTag)
-            || parentNode()->hasTagName(SVGNames::textTag)))
+    if (parentNode() && (isSVGAElement(*parentNode()) || isSVGTextElement(*parentNode())))
         return Element::rendererIsNeeded(style);
 
     return false;
@@ -149,17 +155,17 @@
     Element* target = SVGURIReference::targetElementFromIRIString(hrefString(), document(), &id);
     if (!target) {
         // Do not register as pending if we are already pending this resource.
-        if (document().accessSVGExtensions()->isElementPendingResource(this, id))
+        if (document().accessSVGExtensions().isElementPendingResource(this, id))
             return;
 
         if (!id.isEmpty()) {
-            document().accessSVGExtensions()->addPendingResource(id, this);
+            document().accessSVGExtensions().addPendingResource(id, this);
             ASSERT(hasPendingResources());
         }
-    } else if (target->hasTagName(SVGNames::pathTag)) {
+    } else if (isSVGPathElement(*target)) {
         // Register us with the target in the dependencies map. Any change of hrefElement
         // that leads to relayout/repainting now informs us, so we can react to it.
-        document().accessSVGExtensions()->addElementReferencingTarget(this, toSVGElement(target));
+        document().accessSVGExtensions().addElementReferencingTarget(this, toSVGElement((target)));
     }
 }
 
diff --git a/Source/core/svg/SVGTextPathElement.h b/Source/core/svg/SVGTextPathElement.h
index aff4f1d..75fcad4 100644
--- a/Source/core/svg/SVGTextPathElement.h
+++ b/Source/core/svg/SVGTextPathElement.h
@@ -38,63 +38,8 @@
     SVGTextPathSpacingExact
 };
 
-template<>
-struct SVGPropertyTraits<SVGTextPathMethodType> {
-    static unsigned highestEnumValue() { return SVGTextPathMethodStretch; }
-
-    static String toString(SVGTextPathMethodType type)
-    {
-        switch (type) {
-        case SVGTextPathMethodUnknown:
-            return emptyString();
-        case SVGTextPathMethodAlign:
-            return "align";
-        case SVGTextPathMethodStretch:
-            return "stretch";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static SVGTextPathMethodType fromString(const String& value)
-    {
-        if (value == "align")
-            return SVGTextPathMethodAlign;
-        if (value == "stretch")
-            return SVGTextPathMethodStretch;
-        return SVGTextPathMethodUnknown;
-    }
-};
-
-template<>
-struct SVGPropertyTraits<SVGTextPathSpacingType> {
-    static unsigned highestEnumValue() { return SVGTextPathSpacingExact; }
-
-    static String toString(SVGTextPathSpacingType type)
-    {
-        switch (type) {
-        case SVGTextPathSpacingUnknown:
-            return emptyString();
-        case SVGTextPathSpacingAuto:
-            return "auto";
-        case SVGTextPathSpacingExact:
-            return "exact";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static SVGTextPathSpacingType fromString(const String& value)
-    {
-        if (value == "auto")
-            return SVGTextPathSpacingAuto;
-        if (value == "exact")
-            return SVGTextPathSpacingExact;
-        return SVGTextPathSpacingUnknown;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathMethodType>();
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGTextPathSpacingType>();
 
 class SVGTextPathElement FINAL : public SVGTextContentElement,
                                  public SVGURIReference {
@@ -112,6 +57,8 @@
     static PassRefPtr<SVGTextPathElement> create(Document&);
 
     SVGAnimatedLength* startOffset() const { return m_startOffset.get(); }
+    SVGAnimatedEnumeration<SVGTextPathMethodType>* method() { return m_method.get(); }
+    SVGAnimatedEnumeration<SVGTextPathSpacingType>* spacing() { return m_spacing.get(); }
 
 private:
     explicit SVGTextPathElement(Document&);
@@ -134,14 +81,10 @@
     virtual bool selfHasRelativeLengths() const OVERRIDE;
 
     RefPtr<SVGAnimatedLength> m_startOffset;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextPathElement)
-        DECLARE_ANIMATED_ENUMERATION(Method, method, SVGTextPathMethodType)
-        DECLARE_ANIMATED_ENUMERATION(Spacing, spacing, SVGTextPathSpacingType)
-    END_DECLARE_ANIMATED_PROPERTIES
+    RefPtr<SVGAnimatedEnumeration<SVGTextPathMethodType> > m_method;
+    RefPtr<SVGAnimatedEnumeration<SVGTextPathSpacingType> > m_spacing;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGTextPathElement, hasTagName(SVGNames::textPathTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGTextPositioningElement.cpp b/Source/core/svg/SVGTextPositioningElement.cpp
index b9340cc..b73b7e1 100644
--- a/Source/core/svg/SVGTextPositioningElement.cpp
+++ b/Source/core/svg/SVGTextPositioningElement.cpp
@@ -31,12 +31,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGTextPositioningElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGTextContentElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 SVGTextPositioningElement::SVGTextPositioningElement(const QualifiedName& tagName, Document& document)
     : SVGTextContentElement(tagName, document)
     , m_x(SVGAnimatedLengthList::create(this, SVGNames::xAttr, SVGLengthList::create(LengthModeWidth)))
@@ -52,7 +46,6 @@
     addToPropertyMap(m_dx);
     addToPropertyMap(m_dy);
     addToPropertyMap(m_rotate);
-    registerAnimatedPropertiesForSVGTextPositioningElement();
 }
 
 bool SVGTextPositioningElement::isSupportedAttribute(const QualifiedName& attrName)
@@ -136,14 +129,7 @@
     ASSERT(node);
     ASSERT(node->isSVGElement());
 
-    if (!node->hasTagName(SVGNames::textTag)
-#if ENABLE(SVG_FONTS)
-        && !node->hasTagName(SVGNames::altGlyphTag)
-#endif
-        && !node->hasTagName(SVGNames::tspanTag))
-        return 0;
-
-    return toSVGTextPositioningElement(node);
+    return isSVGTextPositioningElement(*node) ? toSVGTextPositioningElement(node) : 0;
 }
 
 }
diff --git a/Source/core/svg/SVGTextPositioningElement.h b/Source/core/svg/SVGTextPositioningElement.h
index 126cf87..5e70c3d 100644
--- a/Source/core/svg/SVGTextPositioningElement.h
+++ b/Source/core/svg/SVGTextPositioningElement.h
@@ -51,8 +51,6 @@
     RefPtr<SVGAnimatedLengthList> m_dx;
     RefPtr<SVGAnimatedLengthList> m_dy;
     RefPtr<SVGAnimatedNumberList> m_rotate;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGTextPositioningElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
 inline bool isSVGTextPositioningElement(const Node& node)
@@ -60,7 +58,7 @@
     return node.isSVGElement() && toSVGElement(node).isTextPositioning();
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGTextPositioningElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGTextPositioningElement);
 
 } // namespace WebCore
 
diff --git a/Source/core/svg/SVGTransform.cpp b/Source/core/svg/SVGTransform.cpp
index 8cf0ef2..6ad3096 100644
--- a/Source/core/svg/SVGTransform.cpp
+++ b/Source/core/svg/SVGTransform.cpp
@@ -29,13 +29,15 @@
 namespace WebCore {
 
 SVGTransform::SVGTransform()
-    : m_type(SVG_TRANSFORM_UNKNOWN)
+    : NewSVGPropertyBase(classType())
+    , m_transformType(SVG_TRANSFORM_UNKNOWN)
     , m_angle(0)
 {
 }
 
-SVGTransform::SVGTransform(SVGTransformType type, ConstructionMode mode)
-    : m_type(type)
+SVGTransform::SVGTransform(SVGTransformType transformType, ConstructionMode mode)
+    : NewSVGPropertyBase(classType())
+    , m_transformType(transformType)
     , m_angle(0)
 {
     if (mode == ConstructZeroTransform)
@@ -43,31 +45,53 @@
 }
 
 SVGTransform::SVGTransform(const AffineTransform& matrix)
-    : m_type(SVG_TRANSFORM_MATRIX)
+    : NewSVGPropertyBase(classType())
+    , m_transformType(SVG_TRANSFORM_MATRIX)
     , m_angle(0)
     , m_matrix(matrix)
 {
 }
 
+SVGTransform::SVGTransform(SVGTransformType transformType, float angle, const FloatPoint& center, const AffineTransform& matrix)
+    : NewSVGPropertyBase(classType())
+    , m_transformType(transformType)
+    , m_angle(angle)
+    , m_center(center)
+    , m_matrix(matrix)
+{
+}
+
+SVGTransform::~SVGTransform()
+{
+}
+
+PassRefPtr<SVGTransform> SVGTransform::clone() const
+{
+    return adoptRef(new SVGTransform(m_transformType, m_angle, m_center, m_matrix));
+}
+
+PassRefPtr<NewSVGPropertyBase> SVGTransform::cloneForAnimation(const String&) const
+{
+    // SVGTransform is never animated.
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
 void SVGTransform::setMatrix(const AffineTransform& matrix)
 {
-    m_type = SVG_TRANSFORM_MATRIX;
-    m_angle = 0;
+    onMatrixChange();
     m_matrix = matrix;
 }
 
-void SVGTransform::updateSVGMatrix()
+void SVGTransform::onMatrixChange()
 {
-    // The underlying matrix has been changed, alter the transformation type.
-    // Spec: In case the matrix object is changed directly (i.e., without using the methods on the SVGTransform interface itself)
-    // then the type of the SVGTransform changes to SVG_TRANSFORM_MATRIX.
-    m_type = SVG_TRANSFORM_MATRIX;
+    m_transformType = SVG_TRANSFORM_MATRIX;
     m_angle = 0;
 }
 
 void SVGTransform::setTranslate(float tx, float ty)
 {
-    m_type = SVG_TRANSFORM_TRANSLATE;
+    m_transformType = SVG_TRANSFORM_TRANSLATE;
     m_angle = 0;
 
     m_matrix.makeIdentity();
@@ -81,7 +105,7 @@
 
 void SVGTransform::setScale(float sx, float sy)
 {
-    m_type = SVG_TRANSFORM_SCALE;
+    m_transformType = SVG_TRANSFORM_SCALE;
     m_angle = 0;
     m_center = FloatPoint();
 
@@ -96,7 +120,7 @@
 
 void SVGTransform::setRotate(float angle, float cx, float cy)
 {
-    m_type = SVG_TRANSFORM_ROTATE;
+    m_transformType = SVG_TRANSFORM_ROTATE;
     m_angle = angle;
     m_center = FloatPoint(cx, cy);
 
@@ -109,7 +133,7 @@
 
 void SVGTransform::setSkewX(float angle)
 {
-    m_type = SVG_TRANSFORM_SKEWX;
+    m_transformType = SVG_TRANSFORM_SKEWX;
     m_angle = angle;
 
     m_matrix.makeIdentity();
@@ -118,14 +142,16 @@
 
 void SVGTransform::setSkewY(float angle)
 {
-    m_type = SVG_TRANSFORM_SKEWY;
+    m_transformType = SVG_TRANSFORM_SKEWY;
     m_angle = angle;
 
     m_matrix.makeIdentity();
     m_matrix.skewY(angle);
 }
 
-const String& SVGTransform::transformTypePrefixForParsing(SVGTransformType type)
+namespace {
+
+const String& transformTypePrefixForParsing(SVGTransformType type)
 {
     switch (type) {
     case SVG_TRANSFORM_UNKNOWN:
@@ -160,10 +186,12 @@
     return emptyString();
 }
 
+}
+
 String SVGTransform::valueAsString() const
 {
-    const String& prefix = transformTypePrefixForParsing(m_type);
-    switch (m_type) {
+    const String& prefix = transformTypePrefixForParsing(m_transformType);
+    switch (m_transformType) {
     case SVG_TRANSFORM_UNKNOWN:
         return prefix;
     case SVG_TRANSFORM_MATRIX: {
@@ -196,4 +224,24 @@
     return emptyString();
 }
 
+void SVGTransform::add(PassRefPtr<NewSVGPropertyBase>, SVGElement*)
+{
+    // SVGTransform is not animated by itself.
+    ASSERT_NOT_REACHED();
+}
+
+void SVGTransform::calculateAnimatedValue(SVGAnimationElement*, float, unsigned, PassRefPtr<NewSVGPropertyBase>, PassRefPtr<NewSVGPropertyBase>, PassRefPtr<NewSVGPropertyBase>, SVGElement*)
+{
+    // SVGTransform is not animated by itself.
+    ASSERT_NOT_REACHED();
+}
+
+float SVGTransform::calculateDistance(PassRefPtr<NewSVGPropertyBase>, SVGElement*)
+{
+    // SVGTransform is not animated by itself.
+    ASSERT_NOT_REACHED();
+
+    return -1;
+}
+
 } // namespace WebCore
diff --git a/Source/core/svg/SVGTransform.h b/Source/core/svg/SVGTransform.h
index 71f7668..e7487a1 100644
--- a/Source/core/svg/SVGTransform.h
+++ b/Source/core/svg/SVGTransform.h
@@ -21,40 +21,62 @@
 #ifndef SVGTransform_h
 #define SVGTransform_h
 
-#include "core/svg/SVGMatrix.h"
+#include "core/svg/properties/NewSVGProperty.h"
 #include "platform/geometry/FloatPoint.h"
+#include "platform/transforms/AffineTransform.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
 class FloatSize;
+class SVGTransformTearOff;
 
-class SVGTransform {
+enum SVGTransformType {
+    SVG_TRANSFORM_UNKNOWN = 0,
+    SVG_TRANSFORM_MATRIX = 1,
+    SVG_TRANSFORM_TRANSLATE = 2,
+    SVG_TRANSFORM_SCALE = 3,
+    SVG_TRANSFORM_ROTATE = 4,
+    SVG_TRANSFORM_SKEWX = 5,
+    SVG_TRANSFORM_SKEWY = 6
+};
+
+class SVGTransform : public NewSVGPropertyBase {
 public:
-    enum SVGTransformType {
-        SVG_TRANSFORM_UNKNOWN = 0,
-        SVG_TRANSFORM_MATRIX = 1,
-        SVG_TRANSFORM_TRANSLATE = 2,
-        SVG_TRANSFORM_SCALE = 3,
-        SVG_TRANSFORM_ROTATE = 4,
-        SVG_TRANSFORM_SKEWX = 5,
-        SVG_TRANSFORM_SKEWY = 6
-    };
+    typedef SVGTransformTearOff TearOffType;
 
     enum ConstructionMode {
         ConstructIdentityTransform,
         ConstructZeroTransform
     };
 
-    SVGTransform();
-    SVGTransform(SVGTransformType, ConstructionMode = ConstructIdentityTransform);
-    explicit SVGTransform(const AffineTransform&);
+    static PassRefPtr<SVGTransform> create()
+    {
+        return adoptRef(new SVGTransform());
+    }
 
-    SVGTransformType type() const { return m_type; }
+    static PassRefPtr<SVGTransform> create(SVGTransformType type, ConstructionMode mode = ConstructIdentityTransform)
+    {
+        return adoptRef(new SVGTransform(type, mode));
+    }
 
-    SVGMatrix& svgMatrix() { return static_cast<SVGMatrix&>(m_matrix); }
-    AffineTransform matrix() const { return m_matrix; }
-    void updateSVGMatrix();
+    static PassRefPtr<SVGTransform> create(const AffineTransform& affineTransform)
+    {
+        return adoptRef(new SVGTransform(affineTransform));
+    }
+
+    virtual ~SVGTransform();
+
+    PassRefPtr<SVGTransform> clone() const;
+    virtual PassRefPtr<NewSVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+
+    SVGTransformType transformType() const { return m_transformType; }
+
+    const AffineTransform& matrix() const { return m_matrix; }
+
+    // |onMatrixChange| must be called after modifications via |mutableMatrix|.
+    AffineTransform* mutableMatrix() { return &m_matrix; }
+    void onMatrixChange();
 
     float angle() const { return m_angle; }
     FloatPoint rotationCenter() const { return m_center; }
@@ -70,15 +92,25 @@
     FloatPoint translate() const;
     FloatSize scale() const;
 
-    bool isValid() const { return m_type != SVG_TRANSFORM_UNKNOWN; }
-    String valueAsString() const;
+    bool isValid() const { return m_transformType != SVG_TRANSFORM_UNKNOWN; }
 
-    static const String& transformTypePrefixForParsing(SVGTransformType);
+    virtual String valueAsString() const OVERRIDE;
+
+    virtual void add(PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+    virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> from, PassRefPtr<NewSVGPropertyBase> to, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement) OVERRIDE;
+    virtual float calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement* contextElement) OVERRIDE;
+
+    static AnimatedPropertyType classType() { return AnimatedTransform; }
 
 private:
+    SVGTransform();
+    SVGTransform(SVGTransformType, ConstructionMode);
+    explicit SVGTransform(const AffineTransform&);
+    SVGTransform(SVGTransformType, float, const FloatPoint&, const AffineTransform&);
+
     friend bool operator==(const SVGTransform& a, const SVGTransform& b);
 
-    SVGTransformType m_type;
+    SVGTransformType m_transformType;
     float m_angle;
     FloatPoint m_center;
     AffineTransform m_matrix;
@@ -86,7 +118,7 @@
 
 inline bool operator==(const SVGTransform& a, const SVGTransform& b)
 {
-    return a.m_type == b.m_type && a.m_angle == b.m_angle && a.m_matrix == b.m_matrix;
+    return a.m_transformType == b.m_transformType && a.m_angle == b.m_angle && a.m_matrix == b.m_matrix;
 }
 
 inline bool operator!=(const SVGTransform& a, const SVGTransform& b)
@@ -94,6 +126,13 @@
     return !(a == b);
 }
 
+inline PassRefPtr<SVGTransform> toSVGTransform(PassRefPtr<NewSVGPropertyBase> passBase)
+{
+    RefPtr<NewSVGPropertyBase> base = passBase;
+    ASSERT(base->type() == SVGTransform::classType());
+    return static_pointer_cast<SVGTransform>(base.release());
+}
+
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGTransform.idl b/Source/core/svg/SVGTransform.idl
index 96c0058..cf9cc12 100644
--- a/Source/core/svg/SVGTransform.idl
+++ b/Source/core/svg/SVGTransform.idl
@@ -21,6 +21,8 @@
 
 [
     StrictTypeChecking,
+    ImplementedAs=SVGTransformTearOff,
+    SetWrapperReferenceTo(SVGElement contextElement),
 ] interface SVGTransform {
     // Transform Types
     const unsigned short SVG_TRANSFORM_UNKNOWN = 0;
@@ -31,15 +33,15 @@
     const unsigned short SVG_TRANSFORM_SKEWX = 5;
     const unsigned short SVG_TRANSFORM_SKEWY = 6;
 
-    readonly attribute unsigned short type;
-    [ImplementedAs=svgMatrix] readonly attribute SVGMatrix matrix;
+    [ImplementedAs=transformType] readonly attribute unsigned short type;
+    readonly attribute SVGMatrix matrix;
     readonly attribute float angle;
 
-    void setMatrix(SVGMatrix matrix);
-    void setTranslate(float tx, float ty);
-    void setScale(float sx, float sy);
-    void setRotate(float angle, float cx, float cy);
-    void setSkewX(float angle);
-    void setSkewY(float angle);
+    [RaisesException] void setMatrix(SVGMatrix matrix);
+    [RaisesException] void setTranslate(float tx, float ty);
+    [RaisesException] void setScale(float sx, float sy);
+    [RaisesException] void setRotate(float angle, float cx, float cy);
+    [RaisesException] void setSkewX(float angle);
+    [RaisesException] void setSkewY(float angle);
 };
 
diff --git a/Source/core/svg/SVGTransformDistance.cpp b/Source/core/svg/SVGTransformDistance.cpp
index 1108f32..a4f860b 100644
--- a/Source/core/svg/SVGTransformDistance.cpp
+++ b/Source/core/svg/SVGTransformDistance.cpp
@@ -28,15 +28,15 @@
 namespace WebCore {
 
 SVGTransformDistance::SVGTransformDistance()
-    : m_type(SVGTransform::SVG_TRANSFORM_UNKNOWN)
+    : m_transformType(SVG_TRANSFORM_UNKNOWN)
     , m_angle(0)
     , m_cx(0)
     , m_cy(0)
 {
 }
 
-SVGTransformDistance::SVGTransformDistance(SVGTransform::SVGTransformType type, float angle, float cx, float cy, const AffineTransform& transform)
-    : m_type(type)
+SVGTransformDistance::SVGTransformDistance(SVGTransformType transformType, float angle, float cx, float cy, const AffineTransform& transform)
+    : m_transformType(transformType)
     , m_angle(angle)
     , m_cx(cx)
     , m_cy(cy)
@@ -44,169 +44,170 @@
 {
 }
 
-SVGTransformDistance::SVGTransformDistance(const SVGTransform& fromSVGTransform, const SVGTransform& toSVGTransform)
-    : m_type(fromSVGTransform.type())
-    , m_angle(0)
+SVGTransformDistance::SVGTransformDistance(PassRefPtr<SVGTransform> passFromSVGTransform, PassRefPtr<SVGTransform> passToSVGTransform)
+    : m_angle(0)
     , m_cx(0)
     , m_cy(0)
 {
-    ASSERT(m_type == toSVGTransform.type());
+    RefPtr<SVGTransform> fromSVGTransform = passFromSVGTransform;
+    RefPtr<SVGTransform> toSVGTransform = passToSVGTransform;
 
-    switch (m_type) {
-    case SVGTransform::SVG_TRANSFORM_MATRIX:
+    m_transformType = fromSVGTransform->transformType();
+    ASSERT(m_transformType == toSVGTransform->transformType());
+
+    switch (m_transformType) {
+    case SVG_TRANSFORM_MATRIX:
         ASSERT_NOT_REACHED();
-    case SVGTransform::SVG_TRANSFORM_UNKNOWN:
+    case SVG_TRANSFORM_UNKNOWN:
         break;
-    case SVGTransform::SVG_TRANSFORM_ROTATE: {
-        FloatSize centerDistance = toSVGTransform.rotationCenter() - fromSVGTransform.rotationCenter();
-        m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
+    case SVG_TRANSFORM_ROTATE: {
+        FloatSize centerDistance = toSVGTransform->rotationCenter() - fromSVGTransform->rotationCenter();
+        m_angle = toSVGTransform->angle() - fromSVGTransform->angle();
         m_cx = centerDistance.width();
         m_cy = centerDistance.height();
         break;
     }
-    case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
-        FloatSize translationDistance = toSVGTransform.translate() - fromSVGTransform.translate();
+    case SVG_TRANSFORM_TRANSLATE: {
+        FloatSize translationDistance = toSVGTransform->translate() - fromSVGTransform->translate();
         m_transform.translate(translationDistance.width(), translationDistance.height());
         break;
     }
-    case SVGTransform::SVG_TRANSFORM_SCALE: {
-        float scaleX = toSVGTransform.scale().width() - fromSVGTransform.scale().width();
-        float scaleY = toSVGTransform.scale().height() - fromSVGTransform.scale().height();
+    case SVG_TRANSFORM_SCALE: {
+        float scaleX = toSVGTransform->scale().width() - fromSVGTransform->scale().width();
+        float scaleY = toSVGTransform->scale().height() - fromSVGTransform->scale().height();
         m_transform.scaleNonUniform(scaleX, scaleY);
         break;
     }
-    case SVGTransform::SVG_TRANSFORM_SKEWX:
-    case SVGTransform::SVG_TRANSFORM_SKEWY:
-        m_angle = toSVGTransform.angle() - fromSVGTransform.angle();
+    case SVG_TRANSFORM_SKEWX:
+    case SVG_TRANSFORM_SKEWY:
+        m_angle = toSVGTransform->angle() - fromSVGTransform->angle();
         break;
     }
 }
 
 SVGTransformDistance SVGTransformDistance::scaledDistance(float scaleFactor) const
 {
-    switch (m_type) {
-    case SVGTransform::SVG_TRANSFORM_MATRIX:
+    switch (m_transformType) {
+    case SVG_TRANSFORM_MATRIX:
         ASSERT_NOT_REACHED();
-    case SVGTransform::SVG_TRANSFORM_UNKNOWN:
+    case SVG_TRANSFORM_UNKNOWN:
         return SVGTransformDistance();
-    case SVGTransform::SVG_TRANSFORM_ROTATE:
-        return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
-    case SVGTransform::SVG_TRANSFORM_SCALE:
-        return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
-    case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
+    case SVG_TRANSFORM_ROTATE:
+        return SVGTransformDistance(m_transformType, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
+    case SVG_TRANSFORM_SCALE:
+        return SVGTransformDistance(m_transformType, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform(m_transform).scale(scaleFactor));
+    case SVG_TRANSFORM_TRANSLATE: {
         AffineTransform newTransform(m_transform);
         newTransform.setE(m_transform.e() * scaleFactor);
         newTransform.setF(m_transform.f() * scaleFactor);
-        return SVGTransformDistance(m_type, 0, 0, 0, newTransform);
+        return SVGTransformDistance(m_transformType, 0, 0, 0, newTransform);
     }
-    case SVGTransform::SVG_TRANSFORM_SKEWX:
-    case SVGTransform::SVG_TRANSFORM_SKEWY:
-        return SVGTransformDistance(m_type, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
+    case SVG_TRANSFORM_SKEWX:
+    case SVG_TRANSFORM_SKEWY:
+        return SVGTransformDistance(m_transformType, m_angle * scaleFactor, m_cx * scaleFactor, m_cy * scaleFactor, AffineTransform());
     }
 
     ASSERT_NOT_REACHED();
     return SVGTransformDistance();
 }
 
-SVGTransform SVGTransformDistance::addSVGTransforms(const SVGTransform& first, const SVGTransform& second, unsigned repeatCount)
+PassRefPtr<SVGTransform> SVGTransformDistance::addSVGTransforms(PassRefPtr<SVGTransform> passFirst, PassRefPtr<SVGTransform> passSecond, unsigned repeatCount)
 {
-    ASSERT(first.type() == second.type());
+    RefPtr<SVGTransform> first = passFirst;
+    RefPtr<SVGTransform> second = passSecond;
+    ASSERT(first->transformType() == second->transformType());
 
-    SVGTransform transform;
+    RefPtr<SVGTransform> transform = SVGTransform::create();
 
-    switch (first.type()) {
-    case SVGTransform::SVG_TRANSFORM_MATRIX:
+    switch (first->transformType()) {
+    case SVG_TRANSFORM_MATRIX:
         ASSERT_NOT_REACHED();
-    case SVGTransform::SVG_TRANSFORM_UNKNOWN:
-        return SVGTransform();
-    case SVGTransform::SVG_TRANSFORM_ROTATE: {
-        transform.setRotate(first.angle() + second.angle() * repeatCount, first.rotationCenter().x() + second.rotationCenter().x() * repeatCount, first.rotationCenter().y() + second.rotationCenter().y() * repeatCount);
-        return transform;
+    case SVG_TRANSFORM_UNKNOWN:
+        return transform.release();
+    case SVG_TRANSFORM_ROTATE: {
+        transform->setRotate(first->angle() + second->angle() * repeatCount, first->rotationCenter().x() + second->rotationCenter().x() * repeatCount, first->rotationCenter().y() + second->rotationCenter().y() * repeatCount);
+        return transform.release();
     }
-    case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
-        float dx = first.translate().x() + second.translate().x() * repeatCount;
-        float dy = first.translate().y() + second.translate().y() * repeatCount;
-        transform.setTranslate(dx, dy);
-        return transform;
+    case SVG_TRANSFORM_TRANSLATE: {
+        float dx = first->translate().x() + second->translate().x() * repeatCount;
+        float dy = first->translate().y() + second->translate().y() * repeatCount;
+        transform->setTranslate(dx, dy);
+        return transform.release();
     }
-    case SVGTransform::SVG_TRANSFORM_SCALE: {
-        FloatSize scale = second.scale();
+    case SVG_TRANSFORM_SCALE: {
+        FloatSize scale = second->scale();
         scale.scale(repeatCount);
-        scale += first.scale();
-        transform.setScale(scale.width(), scale.height());
-        return transform;
+        scale += first->scale();
+        transform->setScale(scale.width(), scale.height());
+        return transform.release();
     }
-    case SVGTransform::SVG_TRANSFORM_SKEWX:
-        transform.setSkewX(first.angle() + second.angle() * repeatCount);
-        return transform;
-    case SVGTransform::SVG_TRANSFORM_SKEWY:
-        transform.setSkewY(first.angle() + second.angle() * repeatCount);
-        return transform;
+    case SVG_TRANSFORM_SKEWX:
+        transform->setSkewX(first->angle() + second->angle() * repeatCount);
+        return transform.release();
+    case SVG_TRANSFORM_SKEWY:
+        transform->setSkewY(first->angle() + second->angle() * repeatCount);
+        return transform.release();
     }
     ASSERT_NOT_REACHED();
-    return SVGTransform();
+    return transform.release();
 }
 
-SVGTransform SVGTransformDistance::addToSVGTransform(const SVGTransform& transform) const
+PassRefPtr<SVGTransform> SVGTransformDistance::addToSVGTransform(PassRefPtr<SVGTransform> passTransform) const
 {
-    ASSERT(m_type == transform.type() || transform == SVGTransform());
+    RefPtr<SVGTransform> transform = passTransform;
+    ASSERT(m_transformType == transform->transformType() || m_transformType == SVG_TRANSFORM_UNKNOWN);
 
-    SVGTransform newTransform(transform);
+    RefPtr<SVGTransform> newTransform = transform->clone();
 
-    switch (m_type) {
-    case SVGTransform::SVG_TRANSFORM_MATRIX:
+    switch (m_transformType) {
+    case SVG_TRANSFORM_MATRIX:
         ASSERT_NOT_REACHED();
-    case SVGTransform::SVG_TRANSFORM_UNKNOWN:
-        return SVGTransform();
-    case SVGTransform::SVG_TRANSFORM_TRANSLATE: {
-        FloatPoint translation = transform.translate();
+    case SVG_TRANSFORM_UNKNOWN:
+        return SVGTransform::create();
+    case SVG_TRANSFORM_TRANSLATE: {
+        FloatPoint translation = transform->translate();
         translation += FloatSize::narrowPrecision(m_transform.e(), m_transform.f());
-        newTransform.setTranslate(translation.x(), translation.y());
-        return newTransform;
+        newTransform->setTranslate(translation.x(), translation.y());
+        return newTransform.release();
     }
-    case SVGTransform::SVG_TRANSFORM_SCALE: {
-        FloatSize scale = transform.scale();
+    case SVG_TRANSFORM_SCALE: {
+        FloatSize scale = transform->scale();
         scale += FloatSize::narrowPrecision(m_transform.a(), m_transform.d());
-        newTransform.setScale(scale.width(), scale.height());
-        return newTransform;
+        newTransform->setScale(scale.width(), scale.height());
+        return newTransform.release();
     }
-    case SVGTransform::SVG_TRANSFORM_ROTATE: {
-        FloatPoint center = transform.rotationCenter();
-        newTransform.setRotate(transform.angle() + m_angle, center.x() + m_cx, center.y() + m_cy);
-        return newTransform;
+    case SVG_TRANSFORM_ROTATE: {
+        FloatPoint center = transform->rotationCenter();
+        newTransform->setRotate(transform->angle() + m_angle, center.x() + m_cx, center.y() + m_cy);
+        return newTransform.release();
     }
-    case SVGTransform::SVG_TRANSFORM_SKEWX:
-        newTransform.setSkewX(transform.angle() + m_angle);
-        return newTransform;
-    case SVGTransform::SVG_TRANSFORM_SKEWY:
-        newTransform.setSkewY(transform.angle() + m_angle);
-        return newTransform;
+    case SVG_TRANSFORM_SKEWX:
+        newTransform->setSkewX(transform->angle() + m_angle);
+        return newTransform.release();
+    case SVG_TRANSFORM_SKEWY:
+        newTransform->setSkewY(transform->angle() + m_angle);
+        return newTransform.release();
     }
 
     ASSERT_NOT_REACHED();
-    return SVGTransform();
-}
-
-bool SVGTransformDistance::isZero() const
-{
-    return m_transform.isIdentity() && !m_angle;
+    return newTransform.release();
 }
 
 float SVGTransformDistance::distance() const
 {
-    switch (m_type) {
-    case SVGTransform::SVG_TRANSFORM_MATRIX:
+    switch (m_transformType) {
+    case SVG_TRANSFORM_MATRIX:
         ASSERT_NOT_REACHED();
-    case SVGTransform::SVG_TRANSFORM_UNKNOWN:
+    case SVG_TRANSFORM_UNKNOWN:
         return 0;
-    case SVGTransform::SVG_TRANSFORM_ROTATE:
+    case SVG_TRANSFORM_ROTATE:
         return sqrtf(m_angle * m_angle + m_cx * m_cx + m_cy * m_cy);
-    case SVGTransform::SVG_TRANSFORM_SCALE:
+    case SVG_TRANSFORM_SCALE:
         return static_cast<float>(sqrt(m_transform.a() * m_transform.a() + m_transform.d() * m_transform.d()));
-    case SVGTransform::SVG_TRANSFORM_TRANSLATE:
+    case SVG_TRANSFORM_TRANSLATE:
         return static_cast<float>(sqrt(m_transform.e() * m_transform.e() + m_transform.f() * m_transform.f()));
-    case SVGTransform::SVG_TRANSFORM_SKEWX:
-    case SVGTransform::SVG_TRANSFORM_SKEWY:
+    case SVG_TRANSFORM_SKEWX:
+    case SVG_TRANSFORM_SKEWY:
         return m_angle;
     }
     ASSERT_NOT_REACHED();
diff --git a/Source/core/svg/SVGTransformDistance.h b/Source/core/svg/SVGTransformDistance.h
index 32dd5d0..f2fc740 100644
--- a/Source/core/svg/SVGTransformDistance.h
+++ b/Source/core/svg/SVGTransformDistance.h
@@ -29,20 +29,19 @@
 class SVGTransformDistance {
 public:
     SVGTransformDistance();
-    SVGTransformDistance(const SVGTransform& fromTransform, const SVGTransform& toTransform);
+    SVGTransformDistance(PassRefPtr<SVGTransform> fromTransform, PassRefPtr<SVGTransform> toTransform);
 
     SVGTransformDistance scaledDistance(float scaleFactor) const;
-    SVGTransform addToSVGTransform(const SVGTransform&) const;
+    PassRefPtr<SVGTransform> addToSVGTransform(PassRefPtr<SVGTransform>) const;
 
-    static SVGTransform addSVGTransforms(const SVGTransform&, const SVGTransform&, unsigned repeatCount = 1);
-
-    bool isZero() const;
+    static PassRefPtr<SVGTransform> addSVGTransforms(PassRefPtr<SVGTransform>, PassRefPtr<SVGTransform>, unsigned repeatCount = 1);
 
     float distance() const;
-private:
-    SVGTransformDistance(SVGTransform::SVGTransformType, float angle, float cx, float cy, const AffineTransform&);
 
-    SVGTransform::SVGTransformType m_type;
+private:
+    SVGTransformDistance(SVGTransformType, float angle, float cx, float cy, const AffineTransform&);
+
+    SVGTransformType m_transformType;
     float m_angle;
     float m_cx;
     float m_cy;
diff --git a/Source/core/svg/SVGTransformList.cpp b/Source/core/svg/SVGTransformList.cpp
index f09a010..5e1698d 100644
--- a/Source/core/svg/SVGTransformList.cpp
+++ b/Source/core/svg/SVGTransformList.cpp
@@ -1,6 +1,9 @@
 /*
  * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
+ * Copyright (C) 2007 Eric Seidel <eric@webkit.org>
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2012. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -19,77 +22,335 @@
  */
 
 #include "config.h"
+
 #include "core/svg/SVGTransformList.h"
 
+#include "SVGNames.h"
+#include "core/svg/SVGAnimateTransformElement.h"
+#include "core/svg/SVGAnimatedNumber.h"
 #include "core/svg/SVGParserUtilities.h"
-#include "core/svg/SVGSVGElement.h"
-#include "platform/transforms/AffineTransform.h"
+#include "core/svg/SVGTransformDistance.h"
 #include "wtf/text/StringBuilder.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-SVGTransform SVGTransformList::createSVGTransformFromMatrix(const SVGMatrix& matrix) const
+inline PassRefPtr<SVGTransformList> toSVGTransformList(PassRefPtr<NewSVGPropertyBase> passBase)
 {
-    return SVGSVGElement::createSVGTransformFromMatrix(matrix);
+    RefPtr<NewSVGPropertyBase> base = passBase;
+    ASSERT(base->type() == SVGTransformList::classType());
+    return static_pointer_cast<SVGTransformList>(base.release());
 }
 
-SVGTransform SVGTransformList::consolidate()
+SVGTransformList::SVGTransformList()
+{
+}
+
+SVGTransformList::~SVGTransformList()
+{
+}
+
+PassRefPtr<SVGTransform> SVGTransformList::consolidate()
 {
     AffineTransform matrix;
     if (!concatenate(matrix))
-        return SVGTransform();
+        return SVGTransform::create();
 
-    SVGTransform transform(matrix);
+    RefPtr<SVGTransform> transform = SVGTransform::create(matrix);
     clear();
-    append(transform);
-    return transform;
+    return appendItem(transform);
 }
 
 bool SVGTransformList::concatenate(AffineTransform& result) const
 {
-    unsigned size = this->size();
-    if (!size)
+    if (isEmpty())
         return false;
 
-    for (unsigned i = 0; i < size; ++i)
-        result *= at(i).matrix();
+    ConstIterator it = begin();
+    ConstIterator itEnd = end();
+    for (; it != itEnd; ++it)
+        result *= it->matrix();
 
     return true;
 }
 
+PassRefPtr<SVGTransformList> SVGTransformList::clone()
+{
+    RefPtr<SVGTransformList> svgTransformList = SVGTransformList::create();
+    svgTransformList->deepCopy(this);
+    return svgTransformList.release();
+}
+
+namespace {
+
+template<typename CharType>
+int parseTransformParamList(const CharType*& ptr, const CharType* end, float* values, int required, int optional)
+{
+    int parsedParams = 0;
+    int maxPossibleParams = required + optional;
+
+    bool trailingDelimiter = false;
+
+    skipOptionalSVGSpaces(ptr, end);
+    while (parsedParams < maxPossibleParams) {
+        if (!parseNumber(ptr, end, values[parsedParams], false))
+            break;
+
+        ++parsedParams;
+
+        if (skipOptionalSVGSpaces(ptr, end) && *ptr == ',') {
+            ++ptr;
+            skipOptionalSVGSpaces(ptr, end);
+
+            trailingDelimiter = true;
+        } else {
+            trailingDelimiter = false;
+        }
+    }
+
+    if (trailingDelimiter || !(parsedParams == required || parsedParams == maxPossibleParams))
+        return -1;
+
+    return parsedParams;
+}
+
+// These should be kept in sync with enum SVGTransformType
+static const int requiredValuesForType[] =  {0, 6, 1, 1, 1, 1, 1};
+static const int optionalValuesForType[] =  {0, 0, 1, 1, 2, 0, 0};
+
+template<typename CharType>
+PassRefPtr<SVGTransform> parseTransformOfType(unsigned type, const CharType*& ptr, const CharType* end)
+{
+    if (type == SVG_TRANSFORM_UNKNOWN)
+        return nullptr;
+
+    int valueCount = 0;
+    float values[] = {0, 0, 0, 0, 0, 0};
+    if ((valueCount = parseTransformParamList(ptr, end, values, requiredValuesForType[type], optionalValuesForType[type])) < 0) {
+        return nullptr;
+    }
+
+    RefPtr<SVGTransform> transform = SVGTransform::create();
+
+    switch (type) {
+    case SVG_TRANSFORM_SKEWX:
+        transform->setSkewX(values[0]);
+        break;
+    case SVG_TRANSFORM_SKEWY:
+        transform->setSkewY(values[0]);
+        break;
+    case SVG_TRANSFORM_SCALE:
+        if (valueCount == 1) // Spec: if only one param given, assume uniform scaling
+            transform->setScale(values[0], values[0]);
+        else
+            transform->setScale(values[0], values[1]);
+        break;
+    case SVG_TRANSFORM_TRANSLATE:
+        if (valueCount == 1) // Spec: if only one param given, assume 2nd param to be 0
+            transform->setTranslate(values[0], 0);
+        else
+            transform->setTranslate(values[0], values[1]);
+        break;
+    case SVG_TRANSFORM_ROTATE:
+        if (valueCount == 1)
+            transform->setRotate(values[0], 0, 0);
+        else
+            transform->setRotate(values[0], values[1], values[2]);
+        break;
+    case SVG_TRANSFORM_MATRIX:
+        transform->setMatrix(AffineTransform(values[0], values[1], values[2], values[3], values[4], values[5]));
+        break;
+    }
+
+    return transform.release();
+}
+
+}
+
+template<typename CharType>
+bool SVGTransformList::parseInternal(const CharType*& ptr, const CharType* end)
+{
+    clear();
+
+    bool delimParsed = false;
+    while (ptr < end) {
+        delimParsed = false;
+        SVGTransformType transformType = SVG_TRANSFORM_UNKNOWN;
+        skipOptionalSVGSpaces(ptr, end);
+
+        if (!parseAndSkipTransformType(ptr, end, transformType))
+            return false;
+
+        if (!skipOptionalSVGSpaces(ptr, end) || *ptr != '(')
+            return false;
+        ptr++;
+
+        RefPtr<SVGTransform> transform = parseTransformOfType(transformType, ptr, end);
+        if (!transform)
+            return false;
+
+        if (!skipOptionalSVGSpaces(ptr, end) || *ptr != ')')
+            return false;
+        ptr++;
+
+        append(transform.release());
+
+        skipOptionalSVGSpaces(ptr, end);
+        if (ptr < end && *ptr == ',') {
+            delimParsed = true;
+            ++ptr;
+            skipOptionalSVGSpaces(ptr, end);
+        }
+    }
+
+    return !delimParsed;
+}
+
+bool SVGTransformList::parse(const UChar*& ptr, const UChar* end)
+{
+    return parseInternal(ptr, end);
+}
+
+bool SVGTransformList::parse(const LChar*& ptr, const LChar* end)
+{
+    return parseInternal(ptr, end);
+}
+
 String SVGTransformList::valueAsString() const
 {
     StringBuilder builder;
-    unsigned size = this->size();
-    for (unsigned i = 0; i < size; ++i) {
-        if (i > 0)
-            builder.append(' ');
 
-        builder.append(at(i).valueAsString());
+    ConstIterator it = begin();
+    ConstIterator itEnd = end();
+    while (it != itEnd) {
+        builder.append(it->valueAsString());
+        ++it;
+        if (it != itEnd)
+            builder.append(' ');
     }
 
     return builder.toString();
 }
 
-void SVGTransformList::parse(const String& transform)
+void SVGTransformList::setValueAsString(const String& value, ExceptionState& exceptionState)
 {
-    if (transform.isEmpty()) {
-        // FIXME: The parseTransformAttribute function secretly calls clear()
-        // based on a |mode| parameter. We should study whether we should
-        // remove the |mode| parameter and force callers to call clear()
-        // themselves.
+    if (value.isEmpty()) {
         clear();
-    } else if (transform.is8Bit()) {
-        const LChar* ptr = transform.characters8();
-        const LChar* end = ptr + transform.length();
-        if (!parseTransformAttribute(*this, ptr, end))
-            clear();
+        return;
+    }
+
+    bool valid = false;
+    if (value.is8Bit()) {
+        const LChar* ptr = value.characters8();
+        const LChar* end = ptr + value.length();
+        valid = parse(ptr, end);
     } else {
-        const UChar* ptr = transform.characters16();
-        const UChar* end = ptr + transform.length();
-        if (!parseTransformAttribute(*this, ptr, end))
-            clear();
+        const UChar* ptr = value.characters16();
+        const UChar* end = ptr + value.length();
+        valid = parse(ptr, end);
+    }
+
+    if (!valid) {
+        clear();
+        exceptionState.throwDOMException(SyntaxError, "Problem parsing transform list=\""+value+"\"");
     }
 }
 
-} // namespace WebCore
+PassRefPtr<NewSVGPropertyBase> SVGTransformList::cloneForAnimation(const String& value) const
+{
+    ASSERT_NOT_REACHED();
+    return nullptr;
+}
+
+PassRefPtr<SVGTransformList> SVGTransformList::create(SVGTransformType transformType, const String& value)
+{
+    RefPtr<SVGTransform> transform;
+    if (value.isEmpty()) {
+    } else if (value.is8Bit()) {
+        const LChar* ptr = value.characters8();
+        const LChar* end = ptr + value.length();
+        transform = parseTransformOfType(transformType, ptr, end);
+    } else {
+        const UChar* ptr = value.characters16();
+        const UChar* end = ptr + value.length();
+        transform = parseTransformOfType(transformType, ptr, end);
+    }
+
+    RefPtr<SVGTransformList> svgTransformList = SVGTransformList::create();
+    if (transform)
+        svgTransformList->append(transform);
+    return svgTransformList.release();
+}
+
+void SVGTransformList::add(PassRefPtr<NewSVGPropertyBase> other, SVGElement* contextElement)
+{
+    if (isEmpty())
+        return;
+
+    RefPtr<SVGTransformList> otherList = toSVGTransformList(other);
+    if (length() != otherList->length())
+        return;
+
+    ASSERT(length() == 1);
+    RefPtr<SVGTransform> fromTransform = at(0);
+    RefPtr<SVGTransform> toTransform = otherList->at(0);
+
+    ASSERT(fromTransform->transformType() == toTransform->transformType());
+    clear();
+    append(SVGTransformDistance::addSVGTransforms(fromTransform, toTransform));
+}
+
+void SVGTransformList::calculateAnimatedValue(SVGAnimationElement* animationElement, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> fromValue, PassRefPtr<NewSVGPropertyBase> toValue, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement* contextElement)
+{
+    ASSERT(animationElement);
+    bool isToAnimation = animationElement->animationMode() == ToAnimation;
+
+    // Spec: To animations provide specific functionality to get a smooth change from the underlying value to the
+    // ‘to’ attribute value, which conflicts mathematically with the requirement for additive transform animations
+    // to be post-multiplied. As a consequence, in SVG 1.1 the behavior of to animations for ‘animateTransform’ is undefined
+    // FIXME: This is not taken into account yet.
+    RefPtr<SVGTransformList> fromList = isToAnimation ? this : toSVGTransformList(fromValue);
+    RefPtr<SVGTransformList> toList = toSVGTransformList(toValue);
+    RefPtr<SVGTransformList> toAtEndOfDurationList = toSVGTransformList(toAtEndOfDurationValue);
+
+    size_t fromListSize = fromList->length();
+    size_t toListSize = toList->length();
+
+    if (!toListSize)
+        return;
+
+    // Never resize the animatedTransformList to the toList size, instead either clear the list or append to it.
+    if (!isEmpty() && !animationElement->isAdditive())
+        clear();
+
+    RefPtr<SVGTransform> toTransform = toList->at(0);
+    RefPtr<SVGTransform> effectiveFrom = fromListSize ? fromList->at(0) : SVGTransform::create(toTransform->transformType(), SVGTransform::ConstructZeroTransform);
+    RefPtr<SVGTransform> currentTransform = SVGTransformDistance(effectiveFrom, toTransform).scaledDistance(percentage).addToSVGTransform(effectiveFrom);
+    if (animationElement->isAccumulated() && repeatCount) {
+        RefPtr<SVGTransform> effectiveToAtEnd = !toAtEndOfDurationList->isEmpty() ? toAtEndOfDurationList->at(0) : SVGTransform::create(toTransform->transformType(), SVGTransform::ConstructZeroTransform);
+        append(SVGTransformDistance::addSVGTransforms(currentTransform, effectiveToAtEnd, repeatCount));
+    } else {
+        append(currentTransform);
+    }
+}
+
+float SVGTransformList::calculateDistance(PassRefPtr<NewSVGPropertyBase> toValue, SVGElement*)
+{
+    // FIXME: This is not correct in all cases. The spec demands that each component (translate x and y for example)
+    // is paced separately. To implement this we need to treat each component as individual animation everywhere.
+
+    RefPtr<SVGTransformList> toList = toSVGTransformList(toValue);
+    if (isEmpty() || length() != toList->length())
+        return -1;
+
+    ASSERT(length() == 1);
+    if (at(0)->transformType() == toList->at(0)->transformType())
+        return -1;
+
+    // Spec: http://www.w3.org/TR/SVG/animate.html#complexDistances
+    // Paced animations assume a notion of distance between the various animation values defined by the ‘to’, ‘from’, ‘by’ and ‘values’ attributes.
+    // Distance is defined only for scalar types (such as <length>), colors and the subset of transformation types that are supported by ‘animateTransform’.
+    return SVGTransformDistance(at(0), toList->at(0)).distance();
+}
+
+}
diff --git a/Source/core/svg/SVGTransformList.h b/Source/core/svg/SVGTransformList.h
index 4904a88..afa23e9 100644
--- a/Source/core/svg/SVGTransformList.h
+++ b/Source/core/svg/SVGTransformList.h
@@ -1,51 +1,84 @@
 /*
- * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
+ * Copyright (C) 2014 Google Inc. All rights reserved.
  *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
  *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
  *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef SVGTransformList_h
 #define SVGTransformList_h
 
+#include "bindings/v8/ScriptWrappable.h"
 #include "core/svg/SVGTransform.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/Vector.h"
+#include "core/svg/properties/NewSVGListPropertyHelper.h"
 
 namespace WebCore {
 
-class SVGTransformList : public Vector<SVGTransform> {
+class SVGTransformListTearOff;
+
+class SVGTransformList FINAL : public NewSVGListPropertyHelper<SVGTransformList, SVGTransform> {
 public:
-    SVGTransformList() { }
+    typedef SVGTransformListTearOff TearOffType;
 
-    SVGTransform createSVGTransformFromMatrix(const SVGMatrix&) const;
-    SVGTransform consolidate();
+    static PassRefPtr<SVGTransformList> create()
+    {
+        return adoptRef(new SVGTransformList());
+    }
 
-    // Internal use only
+    static PassRefPtr<SVGTransformList> create(SVGTransformType, const String&);
+
+    virtual ~SVGTransformList();
+
+    PassRefPtr<SVGTransform> createSVGTransformFromMatrix(const AffineTransform&) const;
+    PassRefPtr<SVGTransform> consolidate();
+
     bool concatenate(AffineTransform& result) const;
 
-    String valueAsString() const;
-    void parse(const String&);
-};
+    // NewSVGPropertyBase:
+    virtual PassRefPtr<NewSVGPropertyBase> cloneForAnimation(const String&) const OVERRIDE;
+    PassRefPtr<SVGTransformList> clone();
 
-template<>
-struct SVGPropertyTraits<SVGTransformList> {
-    static SVGTransformList initialValue() { return SVGTransformList(); }
-    static String toString(const SVGTransformList& type) { return type.valueAsString(); }
-    typedef SVGTransform ListItemType;
+    virtual String valueAsString() const OVERRIDE;
+    void setValueAsString(const String&, ExceptionState&);
+    bool parse(const UChar*& ptr, const UChar* end);
+    bool parse(const LChar*& ptr, const LChar* end);
+
+    virtual void add(PassRefPtr<NewSVGPropertyBase>, SVGElement*) OVERRIDE;
+    virtual void calculateAnimatedValue(SVGAnimationElement*, float percentage, unsigned repeatCount, PassRefPtr<NewSVGPropertyBase> fromValue, PassRefPtr<NewSVGPropertyBase> toValue, PassRefPtr<NewSVGPropertyBase> toAtEndOfDurationValue, SVGElement*) OVERRIDE;
+    virtual float calculateDistance(PassRefPtr<NewSVGPropertyBase> to, SVGElement*) OVERRIDE;
+
+    static AnimatedPropertyType classType() { return AnimatedTransformList; }
+
+private:
+    SVGTransformList();
+
+    bool adjustFromToListValues(PassRefPtr<SVGTransformList> fromList, PassRefPtr<SVGTransformList> toList, float percentage, bool isToAnimation, bool resizeAnimatedListIfNeeded);
+
+    template <typename CharType>
+    bool parseInternal(const CharType*& ptr, const CharType* end);
 };
 
 } // namespace WebCore
diff --git a/Source/core/svg/SVGTransformList.idl b/Source/core/svg/SVGTransformList.idl
index fe57a7a..a28cb78 100644
--- a/Source/core/svg/SVGTransformList.idl
+++ b/Source/core/svg/SVGTransformList.idl
@@ -25,13 +25,17 @@
  */
 
 [
+    ImplementedAs=SVGTransformListTearOff,
+    SetWrapperReferenceTo(SVGElement contextElement),
     StrictTypeChecking,
 ] interface SVGTransformList {
-    readonly attribute unsigned long numberOfItems;
+    readonly attribute unsigned long length;
+    [ImplementedAs=length] readonly attribute unsigned long numberOfItems;
 
     [RaisesException] void clear();
     [RaisesException] SVGTransform initialize(SVGTransform item);
-    [RaisesException] SVGTransform getItem(unsigned long index);
+    [RaisesException] getter SVGTransform getItem(unsigned long index);
+    [RaisesException] setter SVGTransform (unsigned long index, SVGTransform value);
     [RaisesException] SVGTransform insertItemBefore(SVGTransform item, unsigned long index);
     [RaisesException] SVGTransform replaceItem(SVGTransform item, unsigned long index);
     [RaisesException] SVGTransform removeItem(unsigned long index);
@@ -41,4 +45,3 @@
 
     [RaisesException] SVGTransform consolidate();
 };
-
diff --git a/Source/core/svg/SVGTransformListTearOff.cpp b/Source/core/svg/SVGTransformListTearOff.cpp
new file mode 100644
index 0000000..0def913
--- /dev/null
+++ b/Source/core/svg/SVGTransformListTearOff.cpp
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGTransformListTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+#include "core/svg/SVGSVGElement.h"
+
+namespace WebCore {
+
+SVGTransformListTearOff::SVGTransformListTearOff(PassRefPtr<SVGTransformList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = nullQName())
+    : NewSVGListPropertyTearOffHelper<SVGTransformListTearOff, SVGTransformList>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+    ScriptWrappable::init(this);
+}
+
+SVGTransformListTearOff::~SVGTransformListTearOff()
+{
+}
+
+PassRefPtr<SVGTransformTearOff> SVGTransformListTearOff::createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff> matrix) const
+{
+    return SVGSVGElement::createSVGTransformFromMatrix(matrix);
+}
+
+PassRefPtr<SVGTransformTearOff> SVGTransformListTearOff::consolidate(ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return nullptr;
+    }
+
+    return createItemTearOff(target()->consolidate());
+}
+
+}
diff --git a/Source/core/svg/SVGTransformListTearOff.h b/Source/core/svg/SVGTransformListTearOff.h
new file mode 100644
index 0000000..5e723b2
--- /dev/null
+++ b/Source/core/svg/SVGTransformListTearOff.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGTransformListTearOff_h
+#define SVGTransformListTearOff_h
+
+#include "core/svg/SVGTransformList.h"
+#include "core/svg/SVGTransformTearOff.h"
+#include "core/svg/properties/NewSVGListPropertyTearOffHelper.h"
+
+namespace WebCore {
+
+class SVGTransformListTearOff FINAL :
+    public NewSVGListPropertyTearOffHelper<SVGTransformListTearOff, SVGTransformList>,
+    public ScriptWrappable {
+public:
+    static PassRefPtr<SVGTransformListTearOff> create(PassRefPtr<SVGTransformList> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = nullQName())
+    {
+        return adoptRef(new SVGTransformListTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+    }
+
+    virtual ~SVGTransformListTearOff();
+
+    PassRefPtr<SVGTransformTearOff> createSVGTransformFromMatrix(PassRefPtr<SVGMatrixTearOff>) const;
+    PassRefPtr<SVGTransformTearOff> consolidate(ExceptionState&);
+
+private:
+    SVGTransformListTearOff(PassRefPtr<SVGTransformList>, SVGElement*, PropertyIsAnimValType, const QualifiedName&);
+};
+
+} // namespace WebCore
+
+#endif // SVGTransformListTearOff_h_
diff --git a/Source/core/svg/SVGTransformTearOff.cpp b/Source/core/svg/SVGTransformTearOff.cpp
new file mode 100644
index 0000000..c13631a
--- /dev/null
+++ b/Source/core/svg/SVGTransformTearOff.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/svg/SVGTransformTearOff.h"
+
+#include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
+
+namespace WebCore {
+
+SVGTransformTearOff::SVGTransformTearOff(PassRefPtr<SVGTransform> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+    : NewSVGPropertyTearOff<SVGTransform>(target, contextElement, propertyIsAnimVal, attributeName)
+{
+    ScriptWrappable::init(this);
+}
+
+SVGTransformTearOff::~SVGTransformTearOff()
+{
+}
+
+SVGMatrixTearOff* SVGTransformTearOff::matrix()
+{
+    if (!m_matrixTearoff) {
+        m_matrixTearoff = SVGMatrixTearOff::create(this);
+    }
+
+    return m_matrixTearoff.get();
+}
+
+void SVGTransformTearOff::setMatrix(PassRefPtr<SVGMatrixTearOff> matrix, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setMatrix(matrix->value());
+    commitChange();
+}
+
+void SVGTransformTearOff::setTranslate(float tx, float ty, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setTranslate(tx, ty);
+    commitChange();
+}
+
+void SVGTransformTearOff::setScale(float sx, float sy, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setScale(sx, sy);
+    commitChange();
+}
+
+void SVGTransformTearOff::setRotate(float angle, float cx, float cy, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setRotate(angle, cx, cy);
+    commitChange();
+}
+
+void SVGTransformTearOff::setSkewX(float x, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setSkewX(x);
+    commitChange();
+}
+
+void SVGTransformTearOff::setSkewY(float y, ExceptionState& exceptionState)
+{
+    if (isImmutable()) {
+        exceptionState.throwDOMException(NoModificationAllowedError, "The attribute is read-only.");
+        return;
+    }
+
+    target()->setSkewY(y);
+    commitChange();
+}
+
+}
diff --git a/Source/core/svg/SVGTransformTearOff.h b/Source/core/svg/SVGTransformTearOff.h
new file mode 100644
index 0000000..9ea0ba1
--- /dev/null
+++ b/Source/core/svg/SVGTransformTearOff.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SVGTransformTearOff_h
+#define SVGTransformTearOff_h
+
+#include "bindings/v8/ScriptWrappable.h"
+#include "core/svg/SVGMatrixTearOff.h"
+#include "core/svg/SVGTransform.h"
+#include "core/svg/properties/NewSVGPropertyTearOff.h"
+
+namespace WebCore {
+
+class SVGMatrix;
+
+class SVGTransformTearOff FINAL : public NewSVGPropertyTearOff<SVGTransform>, public ScriptWrappable {
+public:
+    enum SVGTransformType {
+        SVG_TRANSFORM_UNKNOWN = WebCore::SVG_TRANSFORM_UNKNOWN,
+        SVG_TRANSFORM_MATRIX = WebCore::SVG_TRANSFORM_MATRIX,
+        SVG_TRANSFORM_TRANSLATE = WebCore::SVG_TRANSFORM_TRANSLATE,
+        SVG_TRANSFORM_SCALE = WebCore::SVG_TRANSFORM_SCALE,
+        SVG_TRANSFORM_ROTATE = WebCore::SVG_TRANSFORM_ROTATE,
+        SVG_TRANSFORM_SKEWX = WebCore::SVG_TRANSFORM_SKEWX,
+        SVG_TRANSFORM_SKEWY = WebCore::SVG_TRANSFORM_SKEWY,
+    };
+
+    static PassRefPtr<SVGTransformTearOff> create(PassRefPtr<SVGTransform> target, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName = nullQName())
+    {
+        return adoptRef(new SVGTransformTearOff(target, contextElement, propertyIsAnimVal, attributeName));
+    }
+
+    virtual ~SVGTransformTearOff();
+
+    unsigned short transformType() { return target()->transformType(); }
+    SVGMatrixTearOff* matrix();
+    float angle() { return target()->angle(); }
+
+    void setMatrix(PassRefPtr<SVGMatrixTearOff>, ExceptionState&);
+    void setTranslate(float tx, float ty, ExceptionState&);
+    void setScale(float sx, float sy, ExceptionState&);
+    void setRotate(float angle, float cx, float cy, ExceptionState&);
+    void setSkewX(float, ExceptionState&);
+    void setSkewY(float, ExceptionState&);
+
+private:
+    SVGTransformTearOff(PassRefPtr<SVGTransform>, SVGElement* contextElement, PropertyIsAnimValType, const QualifiedName& attributeName);
+
+    RefPtr<SVGMatrixTearOff> m_matrixTearoff;
+};
+
+} // namespace WebCore
+
+#endif // SVGTransformTearOff_h_
diff --git a/Source/core/svg/SVGURIReference.h b/Source/core/svg/SVGURIReference.h
index 93d4d07..c31946d 100644
--- a/Source/core/svg/SVGURIReference.h
+++ b/Source/core/svg/SVGURIReference.h
@@ -51,7 +51,7 @@
     }
 
     // SVGURIReference JS API.
-    static SVGAnimatedString* href(SVGURIReference* object) { return object->href(); }
+    static SVGAnimatedString* href(SVGURIReference& object) { return object.href(); }
 
     SVGAnimatedString* href() const { return m_href.get(); }
     const String& hrefString() const { return m_href->currentValue()->value(); }
diff --git a/Source/core/html/HTMLImportStateResolver.h b/Source/core/svg/SVGUnitTypes.cpp
similarity index 72%
copy from Source/core/html/HTMLImportStateResolver.h
copy to Source/core/svg/SVGUnitTypes.cpp
index 417680c..1b29d40 100644
--- a/Source/core/html/HTMLImportStateResolver.h
+++ b/Source/core/svg/SVGUnitTypes.cpp
@@ -28,34 +28,20 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef HTMLImportStateResolver_h
-#define HTMLImportStateResolver_h
-
-#include "core/html/HTMLImportState.h"
+#include "config.h"
+#include "core/svg/SVGUnitTypes.h"
 
 namespace WebCore {
 
-class HTMLImport;
-
-class HTMLImportStateResolver {
-public:
-    explicit HTMLImportStateResolver(HTMLImport* import)
-        : m_import(import)
-    { }
-
-    HTMLImportState resolve() const;
-
-private:
-    static bool isBlockingFollowers(HTMLImport*);
-
-    bool shouldBlockDocumentCreation() const;
-    bool shouldBlockScriptExecution() const;
-    bool isActive() const;
-
-    HTMLImport* m_import;
-};
-
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGUnitTypes::SVGUnitType>()
+{
+    DEFINE_STATIC_LOCAL(SVGEnumerationStringEntries, entries, ());
+    if (entries.isEmpty()) {
+        entries.append(std::make_pair(SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN, emptyString()));
+        entries.append(std::make_pair(SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE, "userSpaceOnUse"));
+        entries.append(std::make_pair(SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX, "objectBoundingBox"));
+    }
+    return entries;
 }
 
-#endif // HTMLImportStateResolver_h
-
+}
diff --git a/Source/core/svg/SVGUnitTypes.h b/Source/core/svg/SVGUnitTypes.h
index 3920519..c87ad03 100644
--- a/Source/core/svg/SVGUnitTypes.h
+++ b/Source/core/svg/SVGUnitTypes.h
@@ -20,7 +20,7 @@
 #ifndef SVGUnitTypes_h
 #define SVGUnitTypes_h
 
-#include "core/svg/properties/SVGPropertyTraits.h"
+#include "core/svg/SVGEnumeration.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
@@ -36,35 +36,7 @@
 private:
     SVGUnitTypes() { }
 };
-
-template<>
-struct SVGPropertyTraits<SVGUnitTypes::SVGUnitType> {
-    static unsigned highestEnumValue() { return SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; }
-
-    static String toString(SVGUnitTypes::SVGUnitType type)
-    {
-        switch (type) {
-        case SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN:
-            return emptyString();
-        case SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE:
-            return "userSpaceOnUse";
-        case SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX:
-            return "objectBoundingBox";
-        }
-
-        ASSERT_NOT_REACHED();
-        return emptyString();
-    }
-
-    static SVGUnitTypes::SVGUnitType fromString(const String& value)
-    {
-        if (value == "userSpaceOnUse")
-            return SVGUnitTypes::SVG_UNIT_TYPE_USERSPACEONUSE;
-        if (value == "objectBoundingBox")
-            return SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
-        return SVGUnitTypes::SVG_UNIT_TYPE_UNKNOWN;
-    }
-};
+template<> const SVGEnumerationStringEntries& getStaticStringEntries<SVGUnitTypes::SVGUnitType>();
 
 }
 
diff --git a/Source/core/svg/SVGUnitTypes.idl b/Source/core/svg/SVGUnitTypes.idl
index 5f5ec2e..95c2a49 100644
--- a/Source/core/svg/SVGUnitTypes.idl
+++ b/Source/core/svg/SVGUnitTypes.idl
@@ -23,7 +23,9 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGUnitTypes {
+[
+    DependentLifetime,
+] interface SVGUnitTypes {
     // Unit Types
     const unsigned short SVG_UNIT_TYPE_UNKNOWN           = 0;
     const unsigned short SVG_UNIT_TYPE_USERSPACEONUSE    = 1;
diff --git a/Source/core/svg/SVGUseElement.cpp b/Source/core/svg/SVGUseElement.cpp
index 5f27308..6135db1 100644
--- a/Source/core/svg/SVGUseElement.cpp
+++ b/Source/core/svg/SVGUseElement.cpp
@@ -51,12 +51,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGUseElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGGraphicsElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGUseElement::SVGUseElement(Document& document, bool wasInsertedByParser)
     : SVGGraphicsElement(SVGNames::useTag, document)
     , SVGURIReference(this)
@@ -76,7 +70,6 @@
     addToPropertyMap(m_y);
     addToPropertyMap(m_width);
     addToPropertyMap(m_height);
-    registerAnimatedPropertiesForSVGUseElement();
 }
 
 PassRefPtr<SVGUseElement> SVGUseElement::create(Document& document, bool wasInsertedByParser)
@@ -250,10 +243,8 @@
     SVGElement* element = targetInstance->correspondingElement();
     ASSERT(element);
 
-    if (element->hasTagName(SVGNames::useTag)) {
-        if (toSVGUseElement(element)->resourceIsStillLoading())
-            return;
-    }
+    if (isSVGUseElement(*element) && toSVGUseElement(*element).resourceIsStillLoading())
+        return;
 
     SVGElement* shadowTreeElement = targetInstance->shadowTreeElement();
     ASSERT(shadowTreeElement);
@@ -368,13 +359,13 @@
 
     if (m_targetElementInstance) {
         m_targetElementInstance->detach();
-        m_targetElementInstance = 0;
+        m_targetElementInstance = nullptr;
     }
 
     m_needsShadowTreeRecreation = false;
     document().unscheduleUseShadowTreeUpdate(*this);
 
-    document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+    document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
 }
 
 void SVGUseElement::buildPendingResource()
@@ -395,7 +386,7 @@
         if (id.isEmpty())
             return;
 
-        referencedDocument()->accessSVGExtensions()->addPendingResource(id, this);
+        referencedDocument()->accessSVGExtensions().addPendingResource(id, this);
         ASSERT(hasPendingResources());
         return;
     }
@@ -512,15 +503,15 @@
     return new RenderSVGTransformableContainer(this);
 }
 
-static bool isDirectReference(const Node* node)
+static bool isDirectReference(const Node& node)
 {
-    return node->hasTagName(SVGNames::pathTag)
-           || node->hasTagName(SVGNames::rectTag)
-           || node->hasTagName(SVGNames::circleTag)
-           || node->hasTagName(SVGNames::ellipseTag)
-           || node->hasTagName(SVGNames::polygonTag)
-           || node->hasTagName(SVGNames::polylineTag)
-           || node->hasTagName(SVGNames::textTag);
+    return isSVGPathElement(node)
+        || isSVGRectElement(node)
+        || isSVGCircleElement(node)
+        || isSVGEllipseElement(node)
+        || isSVGPolygonElement(node)
+        || isSVGPolylineElement(node)
+        || isSVGTextElement(node);
 }
 
 void SVGUseElement::toClipPath(Path& path)
@@ -532,9 +523,9 @@
         return;
 
     if (n->isSVGElement() && toSVGElement(n)->isSVGGraphicsElement()) {
-        if (!isDirectReference(n)) {
+        if (!isDirectReference(*n)) {
             // Spec: Indirect references are an error (14.3.5)
-            document().accessSVGExtensions()->reportError("Not allowed to use indirect reference in <clip-path>");
+            document().accessSVGExtensions().reportError("Not allowed to use indirect reference in <clip-path>");
         } else {
             toSVGGraphicsElement(n)->toClipPath(path);
             // FIXME: Avoid manual resolution of x/y here. Its potentially harmful.
@@ -551,7 +542,7 @@
     if (!n)
         return 0;
 
-    if (n->isSVGElement() && isDirectReference(n))
+    if (n->isSVGElement() && isDirectReference(*n))
         return toSVGElement(n)->renderer();
 
     return 0;
@@ -564,9 +555,9 @@
 
     // Spec: If the referenced object is itself a 'use', or if there are 'use' subelements within the referenced
     // object, the instance tree will contain recursive expansion of the indirect references to form a complete tree.
-    bool targetHasUseTag = target->hasTagName(SVGNames::useTag);
+    bool targetIsUseElement = isSVGUseElement(*target);
     SVGElement* newTarget = 0;
-    if (targetHasUseTag) {
+    if (targetIsUseElement) {
         foundProblem = hasCycleUseReferencing(toSVGUseElement(target), targetInstance, newTarget);
         if (foundProblem)
             return;
@@ -574,7 +565,7 @@
         // We only need to track first degree <use> dependencies. Indirect references are handled
         // as the invalidation bubbles up the dependency chain.
         if (!foundUse) {
-            document().accessSVGExtensions()->addElementReferencingTarget(this, target);
+            document().accessSVGExtensions().addElementReferencingTarget(this, target);
             foundUse = true;
         }
     } else if (isDisallowedElement(target)) {
@@ -609,7 +600,7 @@
             return;
     }
 
-    if (!targetHasUseTag || !newTarget)
+    if (!targetIsUseElement || !newTarget)
         return;
 
     RefPtr<SVGElementInstance> newInstance = SVGElementInstance::create(this, toSVGUseElement(target), newTarget);
@@ -683,6 +674,7 @@
 
 void SVGUseElement::expandUseElementsInShadowTree(Node* element)
 {
+    ASSERT(element);
     // Why expand the <use> elements in the shadow tree here, and not just
     // do this directly in buildShadowTree, if we encounter a <use> element?
     //
@@ -690,7 +682,7 @@
     // contains <use> tags, we'd miss them. So once we're done with settin' up the
     // actual shadow tree (after the special case modification for svg/symbol) we have
     // to walk it completely and expand all <use> elements.
-    if (element->hasTagName(SVGNames::useTag)) {
+    if (isSVGUseElement(*element)) {
         SVGUseElement* use = toSVGUseElement(element);
         ASSERT(!use->resourceIsStillLoading());
 
@@ -742,7 +734,8 @@
 
 void SVGUseElement::expandSymbolElementsInShadowTree(Node* element)
 {
-    if (element->hasTagName(SVGNames::symbolTag)) {
+    ASSERT(element);
+    if (isSVGSymbolElement(*element)) {
         // Spec: The referenced 'symbol' and its contents are deep-cloned into the generated tree,
         // with the exception that the 'symbol' is replaced by an 'svg'. This generated 'svg' will
         // always have explicit values for attributes width and height. If attributes width and/or
@@ -808,11 +801,11 @@
         return;
 
     SVGElement* originalElement = targetInstance->correspondingElement();
-
-    if (originalElement->hasTagName(SVGNames::useTag)) {
+    ASSERT(originalElement);
+    if (isSVGUseElement(*originalElement)) {
         // <use> gets replaced by <g>
         ASSERT(AtomicString(target->nodeName()) == SVGNames::gTag);
-    } else if (originalElement->hasTagName(SVGNames::symbolTag)) {
+    } else if (isSVGSymbolElement(*originalElement)) {
         // <symbol> gets replaced by <svg>
         ASSERT(AtomicString(target->nodeName()) == SVGNames::svgTag);
     } else {
@@ -959,7 +952,7 @@
             if (use->resourceIsStillLoading())
                 return true;
         }
-        if (instance->hasChildNodes())
+        if (instance->hasChildren())
             instanceTreeIsLoading(instance);
     }
     return false;
diff --git a/Source/core/svg/SVGUseElement.h b/Source/core/svg/SVGUseElement.h
index a7a0d5e..a58f7ee 100644
--- a/Source/core/svg/SVGUseElement.h
+++ b/Source/core/svg/SVGUseElement.h
@@ -103,8 +103,6 @@
     RefPtr<SVGAnimatedLength> m_y;
     RefPtr<SVGAnimatedLength> m_width;
     RefPtr<SVGAnimatedLength> m_height;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGUseElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 
     bool resourceIsStillLoading();
     Document* externalDocument() const;
@@ -123,8 +121,6 @@
     Timer<SVGElement> m_svgLoadEventTimer;
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGUseElement, hasTagName(SVGNames::useTag));
-
 }
 
 #endif
diff --git a/Source/core/svg/SVGVKernElement.cpp b/Source/core/svg/SVGVKernElement.cpp
index ff60552..b3bdedb 100644
--- a/Source/core/svg/SVGVKernElement.cpp
+++ b/Source/core/svg/SVGVKernElement.cpp
@@ -41,8 +41,8 @@
 {
     if (rootParent->inDocument()) {
         ContainerNode* fontNode = parentNode();
-        if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
-            toSVGFontElement(fontNode)->invalidateGlyphCache();
+        if (isSVGFontElement(fontNode))
+            toSVGFontElement(*fontNode).invalidateGlyphCache();
     }
 
     return SVGElement::insertedInto(rootParent);
@@ -51,8 +51,8 @@
 void SVGVKernElement::removedFrom(ContainerNode* rootParent)
 {
     ContainerNode* fontNode = parentNode();
-    if (fontNode && fontNode->hasTagName(SVGNames::fontTag))
-        toSVGFontElement(fontNode)->invalidateGlyphCache();
+    if (isSVGFontElement(fontNode))
+        toSVGFontElement(*fontNode).invalidateGlyphCache();
 
     SVGElement::removedFrom(rootParent);
 }
diff --git a/Source/core/svg/SVGVKernElement.h b/Source/core/svg/SVGVKernElement.h
index d431f06..5d839b8 100644
--- a/Source/core/svg/SVGVKernElement.h
+++ b/Source/core/svg/SVGVKernElement.h
@@ -42,8 +42,6 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGVKernElement, hasTagName(SVGNames::vkernTag));
-
 } // namespace WebCore
 
 #endif // ENABLE(SVG_FONTS)
diff --git a/Source/core/svg/SVGViewElement.cpp b/Source/core/svg/SVGViewElement.cpp
index f3dcb44..f1afd74 100644
--- a/Source/core/svg/SVGViewElement.cpp
+++ b/Source/core/svg/SVGViewElement.cpp
@@ -24,12 +24,6 @@
 
 namespace WebCore {
 
-// Animated property definitions
-
-BEGIN_REGISTER_ANIMATED_PROPERTIES(SVGViewElement)
-    REGISTER_PARENT_ANIMATED_PROPERTIES(SVGElement)
-END_REGISTER_ANIMATED_PROPERTIES
-
 inline SVGViewElement::SVGViewElement(Document& document)
     : SVGElement(SVGNames::viewTag, document)
     , SVGFitToViewBox(this)
@@ -38,7 +32,6 @@
     ScriptWrappable::init(this);
 
     addToPropertyMap(m_viewTarget);
-    registerAnimatedPropertiesForSVGViewElement();
 }
 
 PassRefPtr<SVGViewElement> SVGViewElement::create(Document& document)
diff --git a/Source/core/svg/SVGViewElement.h b/Source/core/svg/SVGViewElement.h
index 9c44814..2340088 100644
--- a/Source/core/svg/SVGViewElement.h
+++ b/Source/core/svg/SVGViewElement.h
@@ -51,12 +51,8 @@
     virtual bool rendererIsNeeded(const RenderStyle&) OVERRIDE { return false; }
 
     RefPtr<SVGStaticStringList> m_viewTarget;
-    BEGIN_DECLARE_ANIMATED_PROPERTIES(SVGViewElement)
-    END_DECLARE_ANIMATED_PROPERTIES
 };
 
-DEFINE_NODE_TYPE_CASTS(SVGViewElement, hasTagName(SVGNames::viewTag));
-
 } // namespace WebCore
 
 #endif
diff --git a/Source/core/svg/SVGViewSpec.cpp b/Source/core/svg/SVGViewSpec.cpp
index adcea68..77ff930 100644
--- a/Source/core/svg/SVGViewSpec.cpp
+++ b/Source/core/svg/SVGViewSpec.cpp
@@ -27,68 +27,46 @@
 
 namespace WebCore {
 
-// Define custom non-animated property 'transform'.
-const SVGPropertyInfo* SVGViewSpec::transformPropertyInfo()
-{
-    static const SVGPropertyInfo* s_propertyInfo = 0;
-    if (!s_propertyInfo) {
-        s_propertyInfo = new SVGPropertyInfo(AnimatedTransformList,
-                                             PropertyIsReadOnly,
-                                             SVGNames::transformAttr,
-                                             transformIdentifier(),
-                                             0,
-                                             0);
-    }
-    return s_propertyInfo;
-}
-
 SVGViewSpec::SVGViewSpec(SVGSVGElement* contextElement)
-    // Note: We make |viewBox| and |preserveAspectRatio|'s contextElement the target element of SVGViewSpec.
+    // Note: addToPropertyMap is not needed, as SVGViewSpec do not correspond to an element.
+    // Note: We make tear-offs' contextElement the target element of SVGViewSpec.
     // This contextElement will be only used for keeping this alive from the tearoff.
     // SVGSVGElement holds a strong-ref to this SVGViewSpec, so this is kept alive as:
     // AnimatedProperty tearoff -(contextElement)-> SVGSVGElement -(RefPtr)-> SVGViewSpec.
-    : SVGFitToViewBox(contextElement, PropertyMapPolicySkip) // Note: addToPropertyMap is not needed, as SVGViewSpec do not correspond to an element.
+    : SVGFitToViewBox(contextElement, PropertyMapPolicySkip)
     , m_contextElement(contextElement)
+    , m_transform(SVGAnimatedTransformList::create(contextElement, SVGNames::transformAttr, SVGTransformList::create()))
 {
     ASSERT(m_contextElement);
     ScriptWrappable::init(this);
 
     viewBox()->setReadOnly();
     preserveAspectRatio()->setReadOnly();
-}
-
-const AtomicString& SVGViewSpec::transformIdentifier()
-{
-    DEFINE_STATIC_LOCAL(AtomicString, s_identifier, ("SVGViewSpecTransformAttribute", AtomicString::ConstructFromLiteral));
-    return s_identifier;
+    m_transform->setReadOnly();
+    // Note: addToPropertyMap is not needed, as SVGViewSpec do not correspond to an element.
 }
 
 String SVGViewSpec::preserveAspectRatioString() const
 {
+    if (!preserveAspectRatio())
+        return String();
+
     return preserveAspectRatio()->baseValue()->valueAsString();
 }
 
-void SVGViewSpec::setTransformString(const String& transform)
-{
-    if (!m_contextElement)
-        return;
-
-    SVGTransformList newList;
-    newList.parse(transform);
-
-    if (SVGAnimatedProperty* wrapper = SVGAnimatedProperty::lookupWrapper<SVGElement, SVGAnimatedTransformList>(m_contextElement, transformPropertyInfo()))
-        static_cast<SVGAnimatedTransformList*>(wrapper)->detachListWrappers(newList.size());
-
-    m_transform = newList;
-}
-
 String SVGViewSpec::transformString() const
 {
-    return SVGPropertyTraits<SVGTransformList>::toString(m_transform);
+    if (!m_transform)
+        return String();
+
+    return m_transform->baseValue()->valueAsString();
 }
 
 String SVGViewSpec::viewBoxString() const
 {
+    if (!viewBox())
+        return String();
+
     return viewBox()->currentValue()->valueAsString();
 }
 
@@ -102,23 +80,9 @@
     return toSVGElement(element);
 }
 
-SVGTransformListPropertyTearOff* SVGViewSpec::transform()
-{
-    if (!m_contextElement)
-        return 0;
-    // Return the animVal here, as its readonly by default - which is exactly what we want here.
-    return static_cast<SVGTransformListPropertyTearOff*>(static_pointer_cast<SVGAnimatedTransformList>(lookupOrCreateTransformWrapper(this))->animVal());
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGViewSpec::lookupOrCreateTransformWrapper(SVGViewSpec* ownerType)
-{
-    ASSERT(ownerType);
-    ASSERT(ownerType->contextElement());
-    return SVGAnimatedProperty::lookupOrCreateWrapper<SVGElement, SVGAnimatedTransformList, SVGTransformList>(ownerType->contextElement(), transformPropertyInfo(), ownerType->m_transform);
-}
-
 void SVGViewSpec::detachContextElement()
 {
+    m_transform = nullptr;
     clearViewBox();
     clearPreserveAspectRatio();
     m_contextElement = 0;
@@ -127,7 +91,7 @@
 void SVGViewSpec::reset()
 {
     resetZoomAndPan();
-    m_transform.clear();
+    m_transform->baseValue()->clear();
     updateViewBox(FloatRect());
     ASSERT(preserveAspectRatio());
     preserveAspectRatio()->baseValue()->setAlign(SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_XMIDYMID);
@@ -176,7 +140,7 @@
                     ptr++;
                 if (ptr >= end)
                     return false;
-                setViewTargetString(String(viewTargetStart, ptr - viewTargetStart));
+                m_viewTargetString = String(viewTargetStart, ptr - viewTargetStart);
                 ptr++;
             } else
                 return false;
@@ -208,7 +172,7 @@
             if (ptr >= end || *ptr != '(')
                 return false;
             ptr++;
-            parseTransformAttribute(m_transform, ptr, end, DoNotClearList);
+            m_transform->baseValue()->parse(ptr, end);
             if (ptr >= end || *ptr != ')')
                 return false;
             ptr++;
diff --git a/Source/core/svg/SVGViewSpec.h b/Source/core/svg/SVGViewSpec.h
index a3e9473..8bf6309 100644
--- a/Source/core/svg/SVGViewSpec.h
+++ b/Source/core/svg/SVGViewSpec.h
@@ -23,14 +23,11 @@
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/svg/SVGFitToViewBox.h"
 #include "core/svg/SVGSVGElement.h"
-#include "core/svg/SVGTransformList.h"
 #include "core/svg/SVGZoomAndPan.h"
 #include "wtf/WeakPtr.h"
 
 namespace WebCore {
 
-class SVGTransformListPropertyTearOff;
-
 class SVGViewSpec FINAL : public RefCounted<SVGViewSpec>, public ScriptWrappable, public SVGZoomAndPan, public SVGFitToViewBox {
 public:
     using RefCounted<SVGViewSpec>::ref;
@@ -49,34 +46,23 @@
 
     String preserveAspectRatioString() const;
 
-    void setTransformString(const String&);
     String transformString() const;
-
-    void setViewTargetString(const String& string) { m_viewTargetString = string; }
     String viewTargetString() const { return m_viewTargetString; }
 
-    SVGElement* contextElement() const { return m_contextElement; }
     void detachContextElement();
 
-    // Custom non-animated 'transform' property.
-    SVGTransformListPropertyTearOff* transform();
-    SVGTransformList transformBaseValue() const { return m_transform; }
+    SVGTransformList* transform() { return m_transform ? m_transform->baseValue() : 0; }
+    PassRefPtr<SVGTransformListTearOff> transformFromJavascript() { return m_transform ? m_transform->baseVal() : 0; }
 
 private:
     explicit SVGViewSpec(SVGSVGElement*);
 
-    static const SVGPropertyInfo* transformPropertyInfo();
-
-    static const AtomicString& transformIdentifier();
-
-    static PassRefPtr<SVGAnimatedProperty> lookupOrCreateTransformWrapper(SVGViewSpec* contextElement);
-
     template<typename CharType>
     bool parseViewSpecInternal(const CharType* ptr, const CharType* end);
 
     // FIXME(oilpan): This is back-ptr to be cleared from contextElement.
     SVGSVGElement* m_contextElement;
-    SVGTransformList m_transform;
+    RefPtr<SVGAnimatedTransformList> m_transform;
     String m_viewTargetString;
 };
 
diff --git a/Source/core/svg/SVGViewSpec.idl b/Source/core/svg/SVGViewSpec.idl
index f5bb3a4..d174ba4 100644
--- a/Source/core/svg/SVGViewSpec.idl
+++ b/Source/core/svg/SVGViewSpec.idl
@@ -23,8 +23,10 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGViewSpec {
-      readonly attribute SVGTransformList transform;
+[
+    DependentLifetime,
+] interface SVGViewSpec {
+      [ImplementedAs=transformFromJavascript] readonly attribute SVGTransformList transform;
       readonly attribute SVGElement viewTarget;
       readonly attribute DOMString viewBoxString;
       readonly attribute DOMString preserveAspectRatioString;
diff --git a/Source/core/svg/SVGZoomAndPan.cpp b/Source/core/svg/SVGZoomAndPan.cpp
index 714d043..d6bbb1f 100644
--- a/Source/core/svg/SVGZoomAndPan.cpp
+++ b/Source/core/svg/SVGZoomAndPan.cpp
@@ -24,6 +24,7 @@
 
 #include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
+#include "core/dom/ExceptionCode.h"
 #include "core/svg/SVGParserUtilities.h"
 
 namespace WebCore {
@@ -75,7 +76,7 @@
     return parseZoomAndPanInternal(start, end, m_zoomAndPan);
 }
 
-void SVGZoomAndPan::setZoomAndPan(SVGViewSpec*, unsigned short, ExceptionState& exceptionState)
+void SVGZoomAndPan::setZoomAndPan(SVGViewSpec&, unsigned short, ExceptionState& exceptionState)
 {
     // SVGViewSpec and all of its content is read-only.
     exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly());
diff --git a/Source/core/svg/SVGZoomAndPan.h b/Source/core/svg/SVGZoomAndPan.h
index 5b5c69c..12ddd0b 100644
--- a/Source/core/svg/SVGZoomAndPan.h
+++ b/Source/core/svg/SVGZoomAndPan.h
@@ -79,9 +79,9 @@
     }
 
     // SVGZoomAndPan JS API.
-    static SVGZoomAndPanType zoomAndPan(SVGZoomAndPan* object) { return object->m_zoomAndPan; }
-    static void setZoomAndPan(SVGZoomAndPan* object, unsigned short value, ExceptionState&) { object->setZoomAndPan(value); }
-    static void setZoomAndPan(SVGViewSpec*, unsigned short, ExceptionState&);
+    static SVGZoomAndPanType zoomAndPan(SVGZoomAndPan& object) { return object.m_zoomAndPan; }
+    static void setZoomAndPan(SVGZoomAndPan& object, unsigned short value, ExceptionState&) { object.setZoomAndPan(value); }
+    static void setZoomAndPan(SVGViewSpec&, unsigned short, ExceptionState&);
 
     void setZoomAndPan(unsigned short value) { m_zoomAndPan = parseFromNumber(value); }
     SVGZoomAndPanType zoomAndPan() const { return m_zoomAndPan; }
diff --git a/Source/core/svg/SVGZoomEvent.cpp b/Source/core/svg/SVGZoomEvent.cpp
index a65cca3..5cb2474 100644
--- a/Source/core/svg/SVGZoomEvent.cpp
+++ b/Source/core/svg/SVGZoomEvent.cpp
@@ -81,4 +81,9 @@
     return EventNames::SVGZoomEvent;
 }
 
+void SVGZoomEvent::trace(Visitor* visitor)
+{
+    UIEvent::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/svg/SVGZoomEvent.h b/Source/core/svg/SVGZoomEvent.h
index c6aaa5c..266f985 100644
--- a/Source/core/svg/SVGZoomEvent.h
+++ b/Source/core/svg/SVGZoomEvent.h
@@ -47,6 +47,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     SVGZoomEvent();
 
diff --git a/Source/core/svg/SVGZoomEvent.idl b/Source/core/svg/SVGZoomEvent.idl
index bb7e2ac..719739b 100644
--- a/Source/core/svg/SVGZoomEvent.idl
+++ b/Source/core/svg/SVGZoomEvent.idl
@@ -23,11 +23,12 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-interface SVGZoomEvent : UIEvent {
+[
+    DependentLifetime,
+] interface SVGZoomEvent : UIEvent {
     readonly attribute SVGRect zoomRectScreen;
     readonly attribute float previousScale;
     readonly attribute SVGPoint previousTranslate;
     readonly attribute float newScale;
     readonly attribute SVGPoint newTranslate;
 };
-
diff --git a/Source/core/svg/animation/SMILTimeContainer.cpp b/Source/core/svg/animation/SMILTimeContainer.cpp
index c41555d..6cd7a4c 100644
--- a/Source/core/svg/animation/SMILTimeContainer.cpp
+++ b/Source/core/svg/animation/SMILTimeContainer.cpp
@@ -26,25 +26,39 @@
 #include "config.h"
 #include "core/svg/animation/SMILTimeContainer.h"
 
+#include "core/animation/AnimationClock.h"
+#include "core/animation/DocumentTimeline.h"
 #include "core/dom/ElementTraversal.h"
+#include "core/frame/FrameView.h"
 #include "core/svg/SVGSVGElement.h"
 #include "core/svg/animation/SVGSMILElement.h"
-#include "wtf/CurrentTime.h"
 
 using namespace std;
 
 namespace WebCore {
 
-static const double animationFrameDelay = 0.025;
+static const double initialFrameDelay = 0.025;
 
-SMILTimeContainer::SMILTimeContainer(SVGSVGElement* owner)
+// Every entry-point that calls updateAnimations() should instantiate a
+// DiscardScope to prevent deletion of the ownerElement (and hence itself.)
+class DiscardScope {
+public:
+    explicit DiscardScope(SVGSVGElement& timeContainerOwner) : m_discardScopeElement(&timeContainerOwner) { }
+
+private:
+    RefPtr<SVGSVGElement> m_discardScopeElement;
+};
+
+SMILTimeContainer::SMILTimeContainer(SVGSVGElement& owner)
     : m_beginTime(0)
     , m_pauseTime(0)
     , m_resumeTime(0)
     , m_accumulatedActiveTime(0)
     , m_presetStartTime(0)
+    , m_frameSchedulingState(Idle)
     , m_documentOrderIndexesDirty(false)
-    , m_timer(this, &SMILTimeContainer::timerFired)
+    , m_animationClock(AnimationClock::create())
+    , m_wakeupTimer(this, &SMILTimeContainer::wakeupTimerFired)
     , m_ownerSVGElement(owner)
 #ifndef NDEBUG
     , m_preventScheduledAnimationsChanges(false)
@@ -55,7 +69,7 @@
 SMILTimeContainer::~SMILTimeContainer()
 {
     cancelAnimationFrame();
-    ASSERT(!m_timer.isActive());
+    ASSERT(!m_wakeupTimer.isActive());
 #ifndef NDEBUG
     ASSERT(!m_preventScheduledAnimationsChanges);
 #endif
@@ -99,11 +113,26 @@
     scheduled->remove(idx);
 }
 
+bool SMILTimeContainer::hasAnimations() const
+{
+    return !m_scheduledAnimations.isEmpty();
+}
+
+bool SMILTimeContainer::hasPendingSynchronization() const
+{
+    return m_frameSchedulingState == SynchronizeAnimations && m_wakeupTimer.isActive() && !m_wakeupTimer.nextFireInterval();
+}
+
 void SMILTimeContainer::notifyIntervalsChanged()
 {
+    if (!isStarted())
+        return;
     // Schedule updateAnimations() to be called asynchronously so multiple intervals
     // can change with updateAnimations() only called once at the end.
-    scheduleAnimationFrame();
+    if (hasPendingSynchronization())
+        return;
+    cancelAnimationFrame();
+    scheduleWakeUp(0, SynchronizeAnimations);
 }
 
 SMILTime SMILTimeContainer::elapsed() const
@@ -135,12 +164,25 @@
     // If 'm_presetStartTime' is set, the timeline was modified via setElapsed() before the document began.
     // In this case pass on 'seekToTime=true' to updateAnimations().
     m_beginTime = now - m_presetStartTime;
-    updateAnimations(SMILTime(m_presetStartTime), m_presetStartTime ? true : false);
+    DiscardScope discardScope(m_ownerSVGElement);
+    SMILTime earliestFireTime = updateAnimations(SMILTime(m_presetStartTime), m_presetStartTime ? true : false);
     m_presetStartTime = 0;
 
     if (m_pauseTime) {
         m_pauseTime = now;
-        cancelAnimationFrame();
+        // If updateAnimations() caused new syncbase instance to be generated,
+        // we don't want to cancel those. Excepting that, no frame should've
+        // been scheduled at this point.
+        ASSERT(m_frameSchedulingState == Idle || m_frameSchedulingState == SynchronizeAnimations);
+    } else if (!hasPendingSynchronization()) {
+        ASSERT(isTimelineRunning());
+        // If the timeline is running, and there's pending animation updates,
+        // always perform the first update after the timeline was started using
+        // the wake-up mechanism.
+        if (earliestFireTime.isFinite()) {
+            SMILTime delay = earliestFireTime - elapsed();
+            scheduleWakeUp(std::max(initialFrameDelay, delay.value()), SynchronizeAnimations);
+        }
     }
 }
 
@@ -162,7 +204,7 @@
     m_resumeTime = currentTime();
 
     m_pauseTime = 0;
-    scheduleAnimationFrame();
+    scheduleWakeUp(0, SynchronizeAnimations);
 }
 
 void SMILTimeContainer::setElapsed(SMILTime time)
@@ -173,8 +215,7 @@
         return;
     }
 
-    if (m_beginTime)
-        cancelAnimationFrame();
+    cancelAnimationFrame();
 
     double now = currentTime();
     m_beginTime = now - time.value();
@@ -200,7 +241,8 @@
     m_preventScheduledAnimationsChanges = false;
 #endif
 
-    updateAnimations(time, true);
+    DiscardScope discardScope(m_ownerSVGElement);
+    updateAnimationsAndScheduleFrameIfNeeded(time, true);
 }
 
 bool SMILTimeContainer::isTimelineRunning() const
@@ -210,42 +252,49 @@
 
 void SMILTimeContainer::scheduleAnimationFrame(SMILTime fireTime)
 {
-    if (!isTimelineRunning())
-        return;
+    ASSERT(isTimelineRunning() && fireTime.isFinite());
+    ASSERT(!m_wakeupTimer.isActive());
 
-    if (!fireTime.isFinite())
-        return;
-
-    SMILTime delay = max(fireTime - elapsed(), SMILTime(animationFrameDelay));
-    m_timer.startOneShot(delay.value());
-}
-
-void SMILTimeContainer::scheduleAnimationFrame()
-{
-    if (!isTimelineRunning())
-        return;
-
-    m_timer.startOneShot(0);
+    SMILTime delay = fireTime - elapsed();
+    if (delay.value() < DocumentTimeline::s_minimumDelay) {
+        serviceOnNextFrame();
+    } else {
+        scheduleWakeUp(delay.value() - DocumentTimeline::s_minimumDelay, FutureAnimationFrame);
+    }
 }
 
 void SMILTimeContainer::cancelAnimationFrame()
 {
-    m_timer.stop();
+    m_frameSchedulingState = Idle;
+    m_wakeupTimer.stop();
 }
 
-void SMILTimeContainer::timerFired(Timer<SMILTimeContainer>*)
+void SMILTimeContainer::scheduleWakeUp(double delayTime, FrameSchedulingState frameSchedulingState)
 {
-    ASSERT(isTimelineRunning());
-    updateAnimations(elapsed());
+    ASSERT(frameSchedulingState == SynchronizeAnimations || frameSchedulingState == FutureAnimationFrame);
+    m_wakeupTimer.startOneShot(delayTime, FROM_HERE);
+    m_frameSchedulingState = frameSchedulingState;
+}
+
+void SMILTimeContainer::wakeupTimerFired(Timer<SMILTimeContainer>*)
+{
+    ASSERT(m_frameSchedulingState == SynchronizeAnimations || m_frameSchedulingState == FutureAnimationFrame);
+    if (m_frameSchedulingState == FutureAnimationFrame) {
+        ASSERT(isTimelineRunning());
+        m_frameSchedulingState = Idle;
+        serviceOnNextFrame();
+    } else {
+        m_frameSchedulingState = Idle;
+        DiscardScope discardScope(m_ownerSVGElement);
+        updateAnimationsAndScheduleFrameIfNeeded(elapsed());
+    }
 }
 
 void SMILTimeContainer::updateDocumentOrderIndexes()
 {
     unsigned timingElementCount = 0;
-    for (Element* element = m_ownerSVGElement; element; element = ElementTraversal::next(*element, m_ownerSVGElement)) {
-        if (isSVGSMILElement(*element))
-            toSVGSMILElement(element)->setDocumentOrderIndex(timingElementCount++);
-    }
+    for (SVGSMILElement* element = Traversal<SVGSMILElement>::firstWithin(m_ownerSVGElement); element; element = Traversal<SVGSMILElement>::next(*element, &m_ownerSVGElement))
+        element->setDocumentOrderIndex(timingElementCount++);
     m_documentOrderIndexesDirty = false;
 }
 
@@ -266,7 +315,60 @@
     SMILTime m_elapsed;
 };
 
-void SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
+Document& SMILTimeContainer::document() const
+{
+    return m_ownerSVGElement.document();
+}
+
+AnimationClock& SMILTimeContainer::animationClock() const
+{
+    ASSERT(m_animationClock);
+    return *m_animationClock;
+}
+
+double SMILTimeContainer::currentTime() const
+{
+    return animationClock().currentTime();
+}
+
+void SMILTimeContainer::serviceOnNextFrame()
+{
+    if (document().view()) {
+        document().view()->scheduleAnimation();
+        m_frameSchedulingState = AnimationFrame;
+    }
+}
+
+void SMILTimeContainer::serviceAnimations(double monotonicAnimationStartTime)
+{
+    if (m_frameSchedulingState != AnimationFrame)
+        return;
+
+    m_frameSchedulingState = Idle;
+    animationClock().updateTime(monotonicAnimationStartTime);
+    DiscardScope discardScope(m_ownerSVGElement);
+    updateAnimationsAndScheduleFrameIfNeeded(elapsed());
+    animationClock().unfreeze();
+}
+
+void SMILTimeContainer::updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapsed, bool seekToTime)
+{
+    SMILTime earliestFireTime = updateAnimations(elapsed, seekToTime);
+    // If updateAnimations() ended up triggering a synchronization (most likely
+    // via syncbases), then give that priority.
+    if (hasPendingSynchronization())
+        return;
+
+    if (!isTimelineRunning())
+        return;
+
+    if (!earliestFireTime.isFinite())
+        return;
+
+    scheduleAnimationFrame(earliestFireTime);
+}
+
+SMILTime SMILTimeContainer::updateAnimations(SMILTime elapsed, bool seekToTime)
 {
     SMILTime earliestFireTime = SMILTime::unresolved();
 
@@ -326,8 +428,7 @@
 #ifndef NDEBUG
         m_preventScheduledAnimationsChanges = false;
 #endif
-        scheduleAnimationFrame(earliestFireTime);
-        return;
+        return earliestFireTime;
     }
 
     // Apply results to target elements.
@@ -338,8 +439,6 @@
     m_preventScheduledAnimationsChanges = false;
 #endif
 
-    scheduleAnimationFrame(earliestFireTime);
-
     for (unsigned i = 0; i < animationsToApplySize; ++i) {
         if (animationsToApply[i]->inDocument() && animationsToApply[i]->isSVGDiscardElement()) {
             RefPtr<SVGSMILElement> animDiscard = animationsToApply[i];
@@ -355,6 +454,7 @@
             }
         }
     }
+    return earliestFireTime;
 }
 
 }
diff --git a/Source/core/svg/animation/SMILTimeContainer.h b/Source/core/svg/animation/SMILTimeContainer.h
index bff4ae9..e551808 100644
--- a/Source/core/svg/animation/SMILTimeContainer.h
+++ b/Source/core/svg/animation/SMILTimeContainer.h
@@ -38,13 +38,15 @@
 
 namespace WebCore {
 
+class AnimationClock;
+class Document;
 class SVGElement;
 class SVGSMILElement;
 class SVGSVGElement;
 
 class SMILTimeContainer : public RefCounted<SMILTimeContainer>  {
 public:
-    static PassRefPtr<SMILTimeContainer> create(SVGSVGElement* owner) { return adoptRef(new SMILTimeContainer(owner)); }
+    static PassRefPtr<SMILTimeContainer> create(SVGSVGElement& owner) { return adoptRef(new SMILTimeContainer(owner)); }
     ~SMILTimeContainer();
 
     void schedule(SVGSMILElement*, SVGElement*, const QualifiedName&);
@@ -61,37 +63,60 @@
     void resume();
     void setElapsed(SMILTime);
 
+    void serviceAnimations(double monotonicAnimationStartTime);
+    bool hasAnimations() const;
+
     void setDocumentOrderIndexesDirty() { m_documentOrderIndexesDirty = true; }
 
 private:
-    SMILTimeContainer(SVGSVGElement* owner);
+    SMILTimeContainer(SVGSVGElement& owner);
+
+    enum FrameSchedulingState {
+        // No frame scheduled.
+        Idle,
+        // Scheduled a wakeup to update the animation values.
+        SynchronizeAnimations,
+        // Scheduled a wakeup to trigger an animation frame.
+        FutureAnimationFrame,
+        // Scheduled a animation frame for continuous update.
+        AnimationFrame
+    };
 
     bool isTimelineRunning() const;
     void scheduleAnimationFrame(SMILTime fireTime);
-    void scheduleAnimationFrame();
     void cancelAnimationFrame();
-    void timerFired(Timer<SMILTimeContainer>*);
-    void updateAnimations(SMILTime elapsed, bool seekToTime = false);
+    void wakeupTimerFired(Timer<SMILTimeContainer>*);
+    void updateAnimationsAndScheduleFrameIfNeeded(SMILTime elapsed, bool seekToTime = false);
+    SMILTime updateAnimations(SMILTime elapsed, bool seekToTime = false);
+    void serviceOnNextFrame();
+    void scheduleWakeUp(double delayTime, FrameSchedulingState);
+    bool hasPendingSynchronization() const;
 
     void updateDocumentOrderIndexes();
     double lastResumeTime() const { return m_resumeTime ? m_resumeTime : m_beginTime; }
 
+    Document& document() const;
+    AnimationClock& animationClock() const;
+    double currentTime() const;
+
     double m_beginTime;
     double m_pauseTime;
     double m_resumeTime;
     double m_accumulatedActiveTime;
     double m_presetStartTime;
 
+    FrameSchedulingState m_frameSchedulingState;
     bool m_documentOrderIndexesDirty;
 
-    Timer<SMILTimeContainer> m_timer;
+    OwnPtr<AnimationClock> m_animationClock;
+    Timer<SMILTimeContainer> m_wakeupTimer;
 
     typedef pair<SVGElement*, QualifiedName> ElementAttributePair;
     typedef Vector<SVGSMILElement*> AnimationsVector;
     typedef HashMap<ElementAttributePair, OwnPtr<AnimationsVector> > GroupedAnimationsMap;
     GroupedAnimationsMap m_scheduledAnimations;
 
-    SVGSVGElement* m_ownerSVGElement;
+    SVGSVGElement& m_ownerSVGElement;
 
 #ifndef NDEBUG
     bool m_preventScheduledAnimationsChanges;
diff --git a/Source/core/svg/animation/SVGSMILElement.cpp b/Source/core/svg/animation/SVGSMILElement.cpp
index 20ac8cd..1142df3 100644
--- a/Source/core/svg/animation/SVGSMILElement.cpp
+++ b/Source/core/svg/animation/SVGSMILElement.cpp
@@ -34,6 +34,7 @@
 #include "core/events/EventListener.h"
 #include "core/events/EventSender.h"
 #include "core/svg/SVGDocumentExtensions.h"
+#include "core/svg/SVGElementInstance.h"
 #include "core/svg/SVGSVGElement.h"
 #include "core/svg/SVGURIReference.h"
 #include "core/svg/animation/SMILTimeContainer.h"
@@ -196,7 +197,7 @@
 
 void SVGSMILElement::clearResourceAndEventBaseReferences()
 {
-    document().accessSVGExtensions()->removeAllTargetReferencesForElement(this);
+    document().accessSVGExtensions().removeAllTargetReferencesForElement(this);
 }
 
 void SVGSMILElement::clearConditions()
@@ -233,17 +234,17 @@
 
     if (!svgTarget) {
         // Do not register as pending if we are already pending this resource.
-        if (document().accessSVGExtensions()->isElementPendingResource(this, id))
+        if (document().accessSVGExtensions().isElementPendingResource(this, id))
             return;
 
         if (!id.isEmpty()) {
-            document().accessSVGExtensions()->addPendingResource(id, this);
+            document().accessSVGExtensions().addPendingResource(id, this);
             ASSERT(hasPendingResources());
         }
     } else {
         // Register us with the target in the dependencies map. Any change of hrefElement
         // that leads to relayout/repainting now informs us, so we can react to it.
-        document().accessSVGExtensions()->addElementReferencingTarget(this, svgTarget);
+        document().accessSVGExtensions().addElementReferencingTarget(this, svgTarget);
     }
     connectEventBaseConditions();
 }
@@ -332,7 +333,7 @@
         setTargetElement(0);
         setAttributeName(anyQName());
         animationAttributeChanged();
-        m_timeContainer = 0;
+        m_timeContainer = nullptr;
     }
 
     SVGElement::removedFrom(rootParent);
@@ -587,7 +588,7 @@
             ASSERT(!condition.m_baseID.isEmpty());
             condition.m_syncbase = treeScope().getElementById(AtomicString(condition.m_baseID));
             if (!condition.m_syncbase || !isSVGSMILElement(*condition.m_syncbase)) {
-                condition.m_syncbase = 0;
+                condition.m_syncbase = nullptr;
                 continue;
             }
             toSVGSMILElement(condition.m_syncbase.get())->addSyncBaseDependent(this);
@@ -605,7 +606,7 @@
         if (condition.m_type == Condition::Syncbase) {
             if (condition.m_syncbase)
                 toSVGSMILElement(condition.m_syncbase.get())->removeSyncBaseDependent(this);
-            condition.m_syncbase = 0;
+            condition.m_syncbase = nullptr;
         }
     }
 }
@@ -619,14 +620,14 @@
             ASSERT(!condition.m_syncbase);
             SVGElement* eventBase = eventBaseFor(condition);
             if (!eventBase) {
-                if (!condition.m_baseID.isEmpty() && !document().accessSVGExtensions()->isElementPendingResource(this, AtomicString(condition.m_baseID)))
-                    document().accessSVGExtensions()->addPendingResource(AtomicString(condition.m_baseID), this);
+                if (!condition.m_baseID.isEmpty() && !document().accessSVGExtensions().isElementPendingResource(this, AtomicString(condition.m_baseID)))
+                    document().accessSVGExtensions().addPendingResource(AtomicString(condition.m_baseID), this);
                 continue;
             }
             ASSERT(!condition.m_eventListener);
             condition.m_eventListener = ConditionEventListener::create(this, &condition);
             eventBase->addEventListener(AtomicString(condition.m_name), condition.m_eventListener, false);
-            document().accessSVGExtensions()->addElementReferencingTarget(this, eventBase);
+            document().accessSVGExtensions().addElementReferencingTarget(this, eventBase);
         }
     }
 }
@@ -648,7 +649,7 @@
             if (eventBase)
                 eventBase->removeEventListener(AtomicString(condition.m_name), condition.m_eventListener.get(), false);
             condition.m_eventListener->disconnectAnimation();
-            condition.m_eventListener = 0;
+            condition.m_eventListener = nullptr;
         }
     }
 }
@@ -1020,7 +1021,7 @@
     }
 
     if (elapsed >= m_intervalEnd) {
-        if (resolveNextInterval())
+        if (resolveNextInterval() && elapsed >= m_intervalBegin)
             return DidRestartInterval;
     }
     return DidNotRestartInterval;
@@ -1098,7 +1099,7 @@
     if (m_activeState == Active) {
         // If duration is indefinite the value does not actually change over time. Same is true for <set>.
         SMILTime simpleDuration = this->simpleDuration();
-        if (simpleDuration.isIndefinite() || hasTagName(SVGNames::setTag)) {
+        if (simpleDuration.isIndefinite() || isSVGSetElement(*this)) {
             SMILTime repeatingDurationEnd = m_intervalBegin + repeatingDuration();
             // We are supposed to do freeze semantics when repeating ends, even if the element is still active.
             // Take care that we get a timer callback at that point.
@@ -1197,7 +1198,7 @@
     if ((oldActiveState == Active && m_activeState != Active) || restartedInterval == DidRestartInterval) {
         smilEndEventSender().dispatchEventSoon(this);
         endedActiveInterval();
-        if (restartedInterval == DidNotRestartInterval && m_activeState != Frozen && this == resultElement)
+        if (!animationIsContributing && this == resultElement)
             clearAnimatedType(m_targetElement);
     }
 
diff --git a/Source/core/svg/animation/SVGSMILElement.h b/Source/core/svg/animation/SVGSMILElement.h
index d66d599..4e67f6c 100644
--- a/Source/core/svg/animation/SVGSMILElement.h
+++ b/Source/core/svg/animation/SVGSMILElement.h
@@ -252,7 +252,7 @@
         || node.hasTagName(SVGNames::animateTransformTag) || node.hasTagName((SVGNames::discardTag));
 }
 
-DEFINE_NODE_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement);
+DEFINE_ELEMENT_TYPE_CASTS_WITH_FUNCTION(SVGSMILElement);
 
 }
 
diff --git a/Source/core/svg/graphics/SVGImage.cpp b/Source/core/svg/graphics/SVGImage.cpp
index 3299c72..5011268 100644
--- a/Source/core/svg/graphics/SVGImage.cpp
+++ b/Source/core/svg/graphics/SVGImage.cpp
@@ -29,19 +29,21 @@
 
 #include "core/svg/graphics/SVGImage.h"
 
+#include "core/animation/DocumentTimeline.h"
 #include "core/dom/NodeTraversal.h"
 #include "core/dom/shadow/ComposedTreeWalker.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/page/Chrome.h"
-#include "core/frame/Frame.h"
-#include "core/frame/FrameView.h"
-#include "core/frame/Settings.h"
 #include "core/rendering/style/RenderStyle.h"
 #include "core/rendering/svg/RenderSVGRoot.h"
 #include "core/svg/SVGDocument.h"
 #include "core/svg/SVGFEImageElement.h"
 #include "core/svg/SVGImageElement.h"
 #include "core/svg/SVGSVGElement.h"
+#include "core/svg/animation/SMILTimeContainer.h"
 #include "core/svg/graphics/SVGImageChromeClient.h"
 #include "platform/LengthFunctions.h"
 #include "platform/geometry/IntRect.h"
@@ -85,7 +87,7 @@
     if (!m_page)
         return true;
 
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
 
     RELEASE_ASSERT(frame->document()->loadEventFinished());
 
@@ -97,13 +99,13 @@
     // single-origin since these can leak cross-origin information.
     ComposedTreeWalker walker(rootElement);
     while (Node* node = walker.get()) {
-        if (node->hasTagName(SVGNames::foreignObjectTag))
+        if (isSVGForeignObjectElement(*node))
             return false;
-        if (node->hasTagName(SVGNames::imageTag)) {
-            if (!toSVGImageElement(node)->currentFrameHasSingleSecurityOrigin())
+        if (isSVGImageElement(*node)) {
+            if (!toSVGImageElement(*node).currentFrameHasSingleSecurityOrigin())
                 return false;
-        } else if (node->hasTagName(SVGNames::feImageTag)) {
-            if (!toSVGFEImageElement(node)->currentFrameHasSingleSecurityOrigin())
+        } else if (isSVGFEImageElement(*node)) {
+            if (!toSVGFEImageElement(*node).currentFrameHasSingleSecurityOrigin())
                 return false;
         }
         walker.next();
@@ -119,17 +121,17 @@
     if (!m_page || !usesContainerSize())
         return;
 
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return;
-    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
-    if (!renderer)
-        return;
 
     FrameView* view = frameView();
     view->resize(this->containerSize());
 
+    RenderSVGRoot* renderer = toRenderSVGRoot(rootElement->renderer());
+    if (!renderer)
+        return;
     renderer->setContainerSize(size);
 }
 
@@ -137,7 +139,7 @@
 {
     if (!m_page)
         return IntSize();
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return IntSize();
@@ -193,11 +195,11 @@
 PassRefPtr<NativeImageSkia> SVGImage::nativeImageForCurrentFrame()
 {
     if (!m_page)
-        return 0;
+        return nullptr;
 
     OwnPtr<ImageBuffer> buffer = ImageBuffer::create(size());
     if (!buffer)
-        return 0;
+        return nullptr;
 
     drawForContainer(buffer->context(), size(), 1, rect(), rect(), CompositeSourceOver, blink::WebBlendModeNormal);
 
@@ -247,9 +249,12 @@
     context->clip(enclosingIntRect(dstRect));
 
     bool compositingRequiresTransparencyLayer = compositeOp != CompositeSourceOver || blendMode != blink::WebBlendModeNormal;
-    if (compositingRequiresTransparencyLayer) {
-        context->beginTransparencyLayer(1);
-        context->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal);
+    float opacity = context->getNormalizedAlpha() / 255.f;
+    bool requiresTransparencyLayer = compositingRequiresTransparencyLayer || opacity < 1;
+    if (requiresTransparencyLayer) {
+        context->beginTransparencyLayer(opacity);
+        if (compositingRequiresTransparencyLayer)
+            context->setCompositeOperation(CompositeSourceOver, blink::WebBlendModeNormal);
     }
 
     FloatSize scale(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height());
@@ -270,7 +275,7 @@
 
     view->paint(context, enclosingIntRect(srcRect));
 
-    if (compositingRequiresTransparencyLayer)
+    if (requiresTransparencyLayer)
         context->endLayer();
 
     stateSaver.restore();
@@ -283,7 +288,7 @@
 {
     if (!m_page)
         return 0;
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return 0;
@@ -302,7 +307,7 @@
 {
     if (!m_page)
         return false;
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return false;
@@ -313,7 +318,7 @@
 {
     if (!m_page)
         return false;
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return false;
@@ -324,7 +329,7 @@
 {
     if (!m_page)
         return;
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return;
@@ -344,7 +349,7 @@
 {
     if (!m_page)
         return;
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return;
@@ -356,7 +361,7 @@
 {
     if (!m_page)
         return;
-    Frame* frame = m_page->mainFrame();
+    LocalFrame* frame = m_page->mainFrame();
     SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
     if (!rootElement)
         return;
@@ -368,6 +373,17 @@
     stopAnimation();
 }
 
+bool SVGImage::hasAnimations() const
+{
+    if (!m_page)
+        return false;
+    LocalFrame* frame = m_page->mainFrame();
+    SVGSVGElement* rootElement = toSVGDocument(frame->document())->rootElement();
+    if (!rootElement)
+        return false;
+    return rootElement->timeContainer()->hasAnimations() || frame->document()->timeline().hasPendingUpdates();
+}
+
 bool SVGImage::dataChanged(bool allDataReceived)
 {
     TRACE_EVENT0("webkit", "SVGImage::dataChanged");
@@ -390,13 +406,12 @@
         // This will become an issue when SVGImage will be able to load other
         // SVGImage objects, but we're safe now, because SVGImage can only be
         // loaded by a top-level document.
-        m_page = adoptPtr(new Page(pageClients));
-        m_page->settings().setMediaEnabled(false);
-        m_page->settings().setScriptEnabled(false);
-        m_page->settings().setPluginsEnabled(false);
-        m_page->settings().setAcceleratedCompositingEnabled(false);
+        OwnPtr<Page> page = adoptPtr(new Page(pageClients));
+        page->settings().setScriptEnabled(false);
+        page->settings().setPluginsEnabled(false);
+        page->settings().setAcceleratedCompositingEnabled(false);
 
-        RefPtr<Frame> frame = Frame::create(FrameInit::create(0, &m_page->frameHost(), dummyFrameLoaderClient));
+        RefPtr<LocalFrame> frame = LocalFrame::create(dummyFrameLoaderClient, &page->frameHost(), 0);
         frame->setView(FrameView::create(frame.get()));
         frame->init();
         FrameLoader& loader = frame->loader();
@@ -406,6 +421,8 @@
         frame->view()->setCanHaveScrollbars(false); // SVG Images will always synthesize a viewBox, if it's not available, and thus never see scrollbars.
         frame->view()->setTransparent(true); // SVG Images are transparent.
 
+        m_page = page.release();
+
         loader.load(FrameLoadRequest(0, blankURL(), SubstituteData(data(), "image/svg+xml", "UTF-8", KURL(), ForceSynchronousLoad)));
         // Set the intrinsic size before a container size is available.
         m_intrinsicSize = containerSize();
diff --git a/Source/core/svg/graphics/SVGImage.h b/Source/core/svg/graphics/SVGImage.h
index 14cbf4f..b1ea908 100644
--- a/Source/core/svg/graphics/SVGImage.h
+++ b/Source/core/svg/graphics/SVGImage.h
@@ -67,6 +67,9 @@
     // Returns the SVG image document's frame.
     FrameView* frameView() const;
 
+    // Does the SVG image/document contain any animations?
+    bool hasAnimations() const;
+
 private:
     friend class AXRenderObject;
     friend class SVGImageChromeClient;
diff --git a/Source/core/svg/graphics/SVGImageChromeClient.cpp b/Source/core/svg/graphics/SVGImageChromeClient.cpp
index 51ddd37..ccf890a 100644
--- a/Source/core/svg/graphics/SVGImageChromeClient.cpp
+++ b/Source/core/svg/graphics/SVGImageChromeClient.cpp
@@ -32,9 +32,12 @@
 #include "core/frame/FrameView.h"
 #include "core/svg/graphics/SVGImage.h"
 #include "platform/graphics/ImageObserver.h"
+#include "wtf/CurrentTime.h"
 
 namespace WebCore {
 
+static const double animationFrameDelay = 0.025;
+
 SVGImageChromeClient::SVGImageChromeClient(SVGImage* image)
     : m_image(image)
     , m_animationTimer(this, &SVGImageChromeClient::animationTimerFired)
@@ -67,15 +70,22 @@
     // approach.
     if (m_animationTimer.isActive())
         return;
-    m_animationTimer.startOneShot(0);
+    // Schedule the 'animation' ASAP if the image does not contain any
+    // animations, but prefer a fixed, jittery, frame-delay if there're any
+    // animations. Checking for pending/active animations could be more
+    // stringent.
+    double fireTime = m_image->hasAnimations() ? animationFrameDelay : 0;
+    m_animationTimer.startOneShot(fireTime, FROM_HERE);
 }
 
 void SVGImageChromeClient::animationTimerFired(Timer<SVGImageChromeClient>*)
 {
     // In principle, we should call requestAnimationFrame callbacks here, but
     // we know there aren't any because script is forbidden inside SVGImages.
-    if (m_image)
-        m_image->frameView()->layout();
+    if (m_image) {
+        m_image->frameView()->page()->animator().serviceScriptedAnimations(currentTime());
+        m_image->frameView()->updateLayoutAndStyleForPainting();
+    }
 }
 
 }
diff --git a/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp b/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
index fec8012..788ac5b 100644
--- a/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
+++ b/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp
@@ -80,7 +80,7 @@
 
 void SVGFilterBuilder::clearEffects()
 {
-    m_lastEffect = 0;
+    m_lastEffect = nullptr;
     m_namedEffects.clear();
     m_effectReferences.clear();
     m_effectRenderer.clear();
diff --git a/Source/core/svg/properties/NewSVGAnimatedProperty.cpp b/Source/core/svg/properties/NewSVGAnimatedProperty.cpp
index 707c982..2ef17e1 100644
--- a/Source/core/svg/properties/NewSVGAnimatedProperty.cpp
+++ b/Source/core/svg/properties/NewSVGAnimatedProperty.cpp
@@ -60,16 +60,6 @@
     m_isAnimating = true;
 }
 
-void NewSVGAnimatedPropertyBase::animValWillChange()
-{
-    ASSERT(isAnimating());
-}
-
-void NewSVGAnimatedPropertyBase::animValDidChange()
-{
-    ASSERT(isAnimating());
-}
-
 void NewSVGAnimatedPropertyBase::animationEnded()
 {
     ASSERT(isAnimating());
diff --git a/Source/core/svg/properties/NewSVGAnimatedProperty.h b/Source/core/svg/properties/NewSVGAnimatedProperty.h
index 25db5c9..b68dee9 100644
--- a/Source/core/svg/properties/NewSVGAnimatedProperty.h
+++ b/Source/core/svg/properties/NewSVGAnimatedProperty.h
@@ -55,8 +55,6 @@
     virtual PassRefPtr<NewSVGPropertyBase> createAnimatedValue() = 0;
     virtual void setAnimatedValue(PassRefPtr<NewSVGPropertyBase>) = 0;
     virtual void animationEnded();
-    virtual void animValWillChange();
-    virtual void animValDidChange();
 
     virtual bool needsSynchronizeAttribute() = 0;
     virtual void synchronizeAttribute();
diff --git a/Source/core/svg/properties/NewSVGListPropertyHelper.h b/Source/core/svg/properties/NewSVGListPropertyHelper.h
index 0192e34..67646b5 100644
--- a/Source/core/svg/properties/NewSVGListPropertyHelper.h
+++ b/Source/core/svg/properties/NewSVGListPropertyHelper.h
@@ -98,6 +98,11 @@
         return ConstIterator(m_values.begin());
     }
 
+    ConstIterator lastAppended() const
+    {
+        return ConstIterator(m_values.begin() + m_values.size() - 1);
+    }
+
     ConstIterator end() const
     {
         return ConstIterator(m_values.end());
@@ -120,12 +125,12 @@
 
     bool isEmpty() const
     {
-        return !numberOfItems();
+        return !length();
     }
 
     // SVGList*Property DOM spec:
 
-    size_t numberOfItems() const
+    size_t length() const
     {
         return m_values.size();
     }
@@ -152,22 +157,22 @@
     static PassRefPtr<Derived> toDerived(PassRefPtr<NewSVGPropertyBase> passBase)
     {
         if (!passBase)
-            return 0;
+            return nullptr;
 
         RefPtr<NewSVGPropertyBase> base = passBase;
         ASSERT(base->type() == Derived::classType());
-        return static_pointer_cast<Derived>(base.release());
+        return static_pointer_cast<Derived>(base);
     }
 };
 
 template<typename Derived, typename ItemProperty>
 bool NewSVGListPropertyHelper<Derived, ItemProperty>::operator==(const Derived& other) const
 {
-    if (numberOfItems() != other.numberOfItems())
+    if (length() != other.length())
         return false;
 
-    size_t length = numberOfItems();
-    for (size_t i = 0; i < length; ++i) {
+    size_t size = length();
+    for (size_t i = 0; i < size; ++i) {
         if (*at(i) != *other.at(i))
             return false;
     }
@@ -207,7 +212,7 @@
 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::getItem(size_t index, ExceptionState& exceptionState)
 {
     if (!checkIndexBound(index, exceptionState))
-        return 0;
+        return nullptr;
 
     ASSERT(index < m_values.size());
     ASSERT(m_values.at(index)->ownerList() == this);
@@ -217,7 +222,7 @@
 template<typename Derived, typename ItemProperty>
 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::insertItemBefore(PassRefPtr<ItemProperty> passNewItem, size_t index)
 {
-    // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
+    // Spec: If the index is greater than or equal to length, then the new item is appended to the end of the list.
     if (index > m_values.size())
         index = m_values.size();
 
@@ -242,7 +247,7 @@
 {
     if (index >= m_values.size()) {
         exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, m_values.size()));
-        return 0;
+        return nullptr;
     }
     ASSERT(m_values.at(index)->ownerList() == this);
     RefPtr<ItemPropertyType> oldItem = m_values.at(index);
@@ -269,7 +274,7 @@
 PassRefPtr<ItemProperty> NewSVGListPropertyHelper<Derived, ItemProperty>::replaceItem(PassRefPtr<ItemProperty> passNewItem, size_t index, ExceptionState& exceptionState)
 {
     if (!checkIndexBound(index, exceptionState))
-        return 0;
+        return nullptr;
 
     RefPtr<ItemPropertyType> newItem = passNewItem;
 
@@ -283,7 +288,7 @@
     if (m_values.isEmpty()) {
         // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace.
         exceptionState.throwDOMException(IndexSizeError, String::format("Failed to replace the provided item at index %zu.", index));
-        return 0;
+        return nullptr;
     }
 
     // Update the value at the desired position 'index'.
diff --git a/Source/core/svg/properties/NewSVGListPropertyTearOffHelper.h b/Source/core/svg/properties/NewSVGListPropertyTearOffHelper.h
index b5ec8ca..1cdc50c 100644
--- a/Source/core/svg/properties/NewSVGListPropertyTearOffHelper.h
+++ b/Source/core/svg/properties/NewSVGListPropertyTearOffHelper.h
@@ -34,22 +34,56 @@
 #include "bindings/v8/ExceptionState.h"
 #include "core/svg/properties/NewSVGPropertyTearOff.h"
 #include "wtf/HashMap.h"
+#include "wtf/TypeTraits.h"
 
 namespace WebCore {
 
+template<typename ItemProperty>
+class ListItemPropertyTraits {
+public:
+    typedef ItemProperty ItemPropertyType;
+    typedef typename ItemPropertyType::TearOffType ItemTearOffType;
+
+    static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem)
+    {
+        RefPtr<ItemTearOffType> newItem = passNewItem;
+
+        // |newItem| is immutable, OR
+        // |newItem| belongs to a SVGElement, but it does not belong to an animated list
+        // (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)")
+        if (newItem->isImmutable()
+            || (newItem->contextElement() && !newItem->target()->ownerList())) {
+            // We have to copy the incoming |newItem|,
+            // Otherwise we'll end up having two tearoffs that operate on the same SVGProperty. Consider the example above:
+            // SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object
+            // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would
+            // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that.
+            return newItem->target()->clone();
+        }
+
+        return newItem->target();
+    }
+
+    static PassRefPtr<ItemTearOffType> createTearOff(PassRefPtr<ItemPropertyType> value, SVGElement* contextElement, PropertyIsAnimValType propertyIsAnimVal, const QualifiedName& attributeName)
+    {
+        return ItemTearOffType::create(value, contextElement, propertyIsAnimVal, attributeName);
+    }
+};
+
 template<typename Derived, typename ListProperty>
 class NewSVGListPropertyTearOffHelper : public NewSVGPropertyTearOff<ListProperty> {
 public:
     typedef ListProperty ListPropertyType;
     typedef typename ListPropertyType::ItemPropertyType ItemPropertyType;
     typedef typename ItemPropertyType::TearOffType ItemTearOffType;
+    typedef ListItemPropertyTraits<ItemPropertyType> ItemTraits;
 
     // SVG*List DOM interface:
 
     // WebIDL requires "unsigned long" type instead of size_t.
-    unsigned long numberOfItems()
+    unsigned long length()
     {
-        return toDerived()->target()->numberOfItems();
+        return toDerived()->target()->length();
     }
 
     void clear(ExceptionState& exceptionState)
@@ -68,15 +102,15 @@
 
         if (toDerived()->isImmutable()) {
             exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
-            return 0;
+            return nullptr;
         }
 
         if (!item) {
             exceptionState.throwTypeError("Lists must be initialized with a valid item.");
-            return 0;
+            return nullptr;
         }
 
-        RefPtr<ItemPropertyType> value = toDerived()->target()->initialize(cloneTargetIfNeeded(item));
+        RefPtr<ItemPropertyType> value = toDerived()->target()->initialize(getValueForInsertionFromTearOff(item));
         toDerived()->commitChange();
 
         return createItemTearOff(value.release());
@@ -94,15 +128,15 @@
 
         if (toDerived()->isImmutable()) {
             exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
-            return 0;
+            return nullptr;
         }
 
         if (!item) {
             exceptionState.throwTypeError("An invalid item cannot be inserted to a list.");
-            return 0;
+            return nullptr;
         }
 
-        RefPtr<ItemPropertyType> value = toDerived()->target()->insertItemBefore(cloneTargetIfNeeded(item), index);
+        RefPtr<ItemPropertyType> value = toDerived()->target()->insertItemBefore(getValueForInsertionFromTearOff(item), index);
         toDerived()->commitChange();
 
         return createItemTearOff(value.release());
@@ -114,20 +148,26 @@
 
         if (toDerived()->isImmutable()) {
             exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
-            return 0;
+            return nullptr;
         }
 
         if (!item) {
             exceptionState.throwTypeError("An invalid item cannot be replaced with an existing list item.");
-            return 0;
+            return nullptr;
         }
 
-        RefPtr<ItemPropertyType> value = toDerived()->target()->replaceItem(cloneTargetIfNeeded(item), index, exceptionState);
+        RefPtr<ItemPropertyType> value = toDerived()->target()->replaceItem(getValueForInsertionFromTearOff(item), index, exceptionState);
         toDerived()->commitChange();
 
         return createItemTearOff(value.release());
     }
 
+    bool anonymousIndexedSetter(unsigned index, PassRefPtr<ItemTearOffType> passItem, ExceptionState& exceptionState)
+    {
+        replaceItem(passItem, index, exceptionState);
+        return true;
+    }
+
     PassRefPtr<ItemTearOffType> removeItem(unsigned long index, ExceptionState& exceptionState)
     {
         RefPtr<ItemPropertyType> value = toDerived()->target()->removeItem(index, exceptionState);
@@ -142,15 +182,15 @@
 
         if (toDerived()->isImmutable()) {
             exceptionState.throwDOMException(NoModificationAllowedError, "The object is read-only.");
-            return 0;
+            return nullptr;
         }
 
         if (!item) {
             exceptionState.throwTypeError("An invalid item cannot be appended to a list.");
-            return 0;
+            return nullptr;
         }
 
-        RefPtr<ItemPropertyType> value = toDerived()->target()->appendItem(cloneTargetIfNeeded(item));
+        RefPtr<ItemPropertyType> value = toDerived()->target()->appendItem(getValueForInsertionFromTearOff(item));
         toDerived()->commitChange();
 
         return createItemTearOff(value.release());
@@ -162,32 +202,17 @@
     {
     }
 
-    PassRefPtr<ItemPropertyType> cloneTargetIfNeeded(PassRefPtr<ItemTearOffType> passNewItem)
+    static PassRefPtr<ItemPropertyType> getValueForInsertionFromTearOff(PassRefPtr<ItemTearOffType> passNewItem)
     {
-        RefPtr<ItemTearOffType> newItem = passNewItem;
-
-        // |newItem| is immutable, OR
-        // |newItem| belongs to a SVGElement, but it does not belong to an animated list
-        // (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)")
-        if (newItem->isImmutable()
-            || (newItem->contextElement() && !newItem->target()->ownerList())) {
-            // We have to copy the incoming |newItem|, as we're not allowed to insert this tear off as is into our wrapper cache.
-            // Otherwise we'll end up having two tearoffs that operate on the same SVGProperty. Consider the example above:
-            // SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object
-            // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would
-            // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that.
-            return newItem->target()->clone();
-        }
-
-        return newItem->target();
+        return ItemTraits::getValueForInsertionFromTearOff(passNewItem);
     }
 
     PassRefPtr<ItemTearOffType> createItemTearOff(PassRefPtr<ItemPropertyType> value)
     {
         if (!value)
-            return 0;
+            return nullptr;
 
-        return ItemTearOffType::create(value, toDerived()->contextElement(), toDerived()->propertyIsAnimVal(), toDerived()->attributeName());
+        return ItemTraits::createTearOff(value, toDerived()->contextElement(), toDerived()->propertyIsAnimVal(), toDerived()->attributeName());
     }
 
 private:
diff --git a/Source/core/svg/properties/NewSVGProperty.h b/Source/core/svg/properties/NewSVGProperty.h
index 5767e94..197a562 100644
--- a/Source/core/svg/properties/NewSVGProperty.h
+++ b/Source/core/svg/properties/NewSVGProperty.h
@@ -35,6 +35,7 @@
 #include "wtf/Noncopyable.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
+#include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
diff --git a/Source/core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h b/Source/core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h
deleted file mode 100644
index dd90980..0000000
--- a/Source/core/svg/properties/SVGAnimatedEnumerationPropertyTearOff.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedEnumerationPropertyTearOff_h
-#define SVGAnimatedEnumerationPropertyTearOff_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/svg/properties/SVGAnimatedStaticPropertyTearOff.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-
-namespace WebCore {
-
-template<typename EnumType>
-class SVGAnimatedEnumerationPropertyTearOff : public SVGAnimatedStaticPropertyTearOff<unsigned> {
-public:
-    virtual void setBaseVal(const unsigned& property, ExceptionState& exceptionState)
-    {
-        // All SVG enumeration values, that are allowed to be set via SVG DOM start with 1, 0 corresponds to unknown and is not settable through SVG DOM.
-        if (!property) {
-            exceptionState.throwTypeError("The enumeration value provided is 0, which is not settable.");
-            return;
-        }
-
-        if (property > SVGPropertyTraits<EnumType>::highestEnumValue()) {
-            exceptionState.throwTypeError("The enumeration value provided (" + String::number(property) + ") is larger than the largest allowed value (" + String::number(SVGPropertyTraits<EnumType>::highestEnumValue()) + ").");
-            return;
-        }
-        SVGAnimatedStaticPropertyTearOff<unsigned>::setBaseVal(property, exceptionState);
-    }
-
-    static PassRefPtr<SVGAnimatedEnumerationPropertyTearOff<EnumType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, EnumType& property)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new SVGAnimatedEnumerationPropertyTearOff<EnumType>(contextElement, attributeName, animatedPropertyType, reinterpret_cast<unsigned&>(property)));
-    }
-
-    EnumType& currentAnimatedValue()
-    {
-        unsigned& animatedValue = SVGAnimatedStaticPropertyTearOff<unsigned>::currentAnimatedValue();
-        ASSERT(animatedValue <= SVGPropertyTraits<EnumType>::highestEnumValue());
-        return reinterpret_cast<EnumType&>(animatedValue);
-    }
-
-private:
-    SVGAnimatedEnumerationPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, unsigned& property)
-        : SVGAnimatedStaticPropertyTearOff<unsigned>(contextElement, attributeName, animatedPropertyType, property)
-    {
-    }
-};
-
-}
-
-#endif // SVGAnimatedEnumerationPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGAnimatedListPropertyTearOff.h b/Source/core/svg/properties/SVGAnimatedListPropertyTearOff.h
deleted file mode 100644
index bebcc5a..0000000
--- a/Source/core/svg/properties/SVGAnimatedListPropertyTearOff.h
+++ /dev/null
@@ -1,191 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedListPropertyTearOff_h
-#define SVGAnimatedListPropertyTearOff_h
-
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "core/svg/properties/SVGListPropertyTearOff.h"
-#include "core/svg/properties/SVGStaticListPropertyTearOff.h"
-
-namespace WebCore {
-
-template<typename PropertyType>
-class SVGPropertyTearOff;
-
-template<typename PropertyType>
-class SVGAnimatedListPropertyTearOff : public SVGAnimatedProperty {
-public:
-    typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
-    typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
-    typedef Vector<RefPtr<ListItemTearOff> > ListWrapperCache;
-    typedef SVGListProperty<PropertyType> ListProperty;
-    typedef SVGListPropertyTearOff<PropertyType> ListPropertyTearOff;
-    typedef PropertyType ContentType;
-
-    virtual ~SVGAnimatedListPropertyTearOff()
-    {
-        if (m_baseVal)
-            static_cast<ListPropertyTearOff*>(m_baseVal.get())->clearAnimatedProperty();
-        if (m_animVal)
-            static_cast<ListPropertyTearOff*>(m_animVal.get())->clearAnimatedProperty();
-    }
-
-    virtual ListProperty* baseVal()
-    {
-        if (!m_baseVal)
-            m_baseVal = ListPropertyTearOff::create(this, BaseValRole, m_values, m_wrappers);
-        return static_cast<ListProperty*>(m_baseVal.get());
-    }
-
-    virtual ListProperty* animVal()
-    {
-        if (!m_animVal)
-            m_animVal = ListPropertyTearOff::create(this, AnimValRole, m_values, m_wrappers);
-        return static_cast<ListProperty*>(m_animVal.get());
-    }
-
-    virtual bool isAnimatedListTearOff() const { return true; }
-
-    int findItem(SVGProperty* property) const
-    {
-        // This should ever be called for our baseVal, as animVal can't modify the list.
-        // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method.
-        typedef SVGPropertyTearOff<typename SVGPropertyTraits<PropertyType>::ListItemType> ListItemTearOff;
-        return static_cast<ListPropertyTearOff*>(m_baseVal.get())->findItem(static_cast<ListItemTearOff*>(property));
-    }
-
-    void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
-    {
-        // This should ever be called for our baseVal, as animVal can't modify the list.
-        // It's safe to cast to ListPropertyTearOff here as all classes inheriting from us supply their own removeItemFromList() method.
-        static_cast<ListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers);
-    }
-
-    void detachListWrappers(unsigned newListSize)
-    {
-        ListProperty::detachListWrappersAndResize(&m_wrappers, newListSize);
-    }
-
-    PropertyType& currentAnimatedValue()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-        return static_cast<ListProperty*>(m_animVal.get())->values();
-    }
-
-    const PropertyType& currentBaseValue() const
-    {
-        return m_values;
-    }
-
-    void animationStarted(PropertyType* newAnimVal, bool shouldOwnValues = false)
-    {
-        ASSERT(!m_isAnimating);
-        ASSERT(newAnimVal);
-        ASSERT(m_values.size() == m_wrappers.size());
-        ASSERT(m_animatedWrappers.isEmpty());
-
-        // Switch to new passed in value type & new wrappers list. The new wrappers list must be created for the new value.
-        if (!newAnimVal->isEmpty())
-            m_animatedWrappers.fill(0, newAnimVal->size());
-
-        ListProperty* animVal = static_cast<ListProperty*>(this->animVal());
-        animVal->setValuesAndWrappers(newAnimVal, &m_animatedWrappers, shouldOwnValues);
-        ASSERT(animVal->values().size() == animVal->wrappers().size());
-        ASSERT(animVal->wrappers().size() == m_animatedWrappers.size());
-        m_isAnimating = true;
-    }
-
-    void animationEnded()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-        ASSERT(contextElement());
-        ASSERT(m_values.size() == m_wrappers.size());
-
-        ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get());
-        ASSERT(animVal->values().size() == animVal->wrappers().size());
-        ASSERT(animVal->wrappers().size() == m_animatedWrappers.size());
-
-        animVal->setValuesAndWrappers(&m_values, &m_wrappers, false);
-        ASSERT(animVal->values().size() == animVal->wrappers().size());
-        ASSERT(animVal->wrappers().size() == m_wrappers.size());
-
-        m_animatedWrappers.clear();
-        m_isAnimating = false;
-    }
-
-    void synchronizeWrappersIfNeeded()
-    {
-        // Eventually the wrapper list needs synchronization because any SVGAnimateLengthList::calculateAnimatedValue() call may
-        // mutate the length of our values() list, and thus the wrapper() cache needs synchronization, to have the same size.
-        // Also existing wrappers which point directly at elements in the existing SVGLengthList have to be detached (so a copy
-        // of them is created, so existing animVal variables in JS are kept-alive). If we'd detach them later the underlying
-        // SVGLengthList was already mutated, and our list item wrapper tear offs would point nowhere. Assertions would fire.
-        ListProperty* animVal = static_cast<ListProperty*>(m_animVal.get());
-        animVal->detachListWrappers(animVal->values().size());
-
-        ASSERT(animVal->values().size() == animVal->wrappers().size());
-        ASSERT(animVal->wrappers().size() == m_animatedWrappers.size());
-    }
-
-    void animValWillChange()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-        ASSERT(m_values.size() == m_wrappers.size());
-        synchronizeWrappersIfNeeded();
-    }
-
-    void animValDidChange()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-        ASSERT(m_values.size() == m_wrappers.size());
-        synchronizeWrappersIfNeeded();
-    }
-
-    static PassRefPtr<SVGAnimatedListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& values)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new SVGAnimatedListPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, values));
-    }
-
-protected:
-    SVGAnimatedListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& values)
-        : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType)
-        , m_values(values)
-    {
-        if (!values.isEmpty())
-            m_wrappers.fill(0, values.size());
-    }
-
-    PropertyType& m_values;
-
-    ListWrapperCache m_wrappers;
-    ListWrapperCache m_animatedWrappers;
-
-    RefPtr<SVGProperty> m_baseVal;
-    RefPtr<SVGProperty> m_animVal;
-};
-
-}
-
-#endif // SVGAnimatedListPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h b/Source/core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h
deleted file mode 100644
index fb1f47c..0000000
--- a/Source/core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010, 2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPathSegListPropertyTearOff_h
-#define SVGAnimatedPathSegListPropertyTearOff_h
-
-#include "core/svg/SVGPathByteStream.h"
-#include "core/svg/SVGPathElement.h"
-#include "core/svg/SVGPathSegList.h"
-#include "core/svg/SVGPathUtilities.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
-#include "core/svg/properties/SVGPathSegListPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGAnimatedPathSegListPropertyTearOff FINAL : public SVGAnimatedListPropertyTearOff<SVGPathSegList> {
-public:
-    virtual SVGListProperty<SVGPathSegList>* baseVal() OVERRIDE
-    {
-        if (!m_baseVal)
-            m_baseVal = SVGPathSegListPropertyTearOff::create(this, BaseValRole, PathSegUnalteredRole, m_values, m_wrappers);
-        return static_cast<SVGListProperty<SVGPathSegList>*>(m_baseVal.get());
-    }
-
-    virtual SVGListProperty<SVGPathSegList>* animVal() OVERRIDE
-    {
-        if (!m_animVal)
-            m_animVal = SVGPathSegListPropertyTearOff::create(this, AnimValRole, PathSegUnalteredRole, m_values, m_wrappers);
-        return static_cast<SVGListProperty<SVGPathSegList>*>(m_animVal.get());
-    }
-
-    int findItem(const RefPtr<SVGPathSeg>& segment) const
-    {
-        // This should ever be called for our baseVal, as animVal can't modify the list.
-        ASSERT(m_baseVal);
-        return static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->findItem(segment);
-    }
-
-    void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
-    {
-        // This should ever be called for our baseVal, as animVal can't modify the list.
-        ASSERT(m_baseVal);
-        static_cast<SVGPathSegListPropertyTearOff*>(m_baseVal.get())->removeItemFromList(itemIndex, shouldSynchronizeWrappers);
-    }
-
-    static PassRefPtr<SVGAnimatedPathSegListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegList& values)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new SVGAnimatedPathSegListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values));
-    }
-
-    using SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationStarted;
-    void animationStarted(SVGPathByteStream* byteStream, const SVGPathSegList* baseValue)
-    {
-        ASSERT(byteStream);
-        ASSERT(baseValue);
-        ASSERT(!m_animatedPathByteStream);
-        m_animatedPathByteStream = byteStream;
-
-        // Pass shouldOwnValues=true, as the SVGPathSegList lifetime is solely managed by its tear off class.
-        SVGPathSegList* copy = new SVGPathSegList(*baseValue);
-        SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationStarted(copy, true);
-    }
-
-    void animationEnded()
-    {
-        ASSERT(m_animatedPathByteStream);
-        m_animatedPathByteStream = 0;
-        SVGAnimatedListPropertyTearOff<SVGPathSegList>::animationEnded();
-    }
-
-    void animValDidChange()
-    {
-        ASSERT(m_animatedPathByteStream);
-        SVGPathElement* pathElement = toSVGPathElement(contextElement());
-
-        // If the animVal is observed from JS, we have to update it on each animation step.
-        // This is an expensive operation and only done, if someone actually observes the animatedPathSegList() while an animation is running.
-        if (pathElement->isAnimValObserved()) {
-            SVGPathSegList& animatedList = currentAnimatedValue();
-            animatedList.clear();
-            buildSVGPathSegListFromByteStream(m_animatedPathByteStream, pathElement, animatedList, UnalteredParsing);
-        }
-
-        SVGAnimatedListPropertyTearOff<SVGPathSegList>::animValDidChange();
-    }
-
-    SVGPathByteStream* animatedPathByteStream() const { return m_animatedPathByteStream; }
-
-private:
-    SVGAnimatedPathSegListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGPathSegList& values)
-        : SVGAnimatedListPropertyTearOff<SVGPathSegList>(contextElement, attributeName, animatedPropertyType, values)
-        , m_animatedPathByteStream(0)
-    {
-    }
-
-    SVGPathByteStream* m_animatedPathByteStream;
-};
-
-}
-
-#endif // SVGAnimatedPathSegListPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGAnimatedProperty.cpp b/Source/core/svg/properties/SVGAnimatedProperty.cpp
deleted file mode 100644
index b1e1e78..0000000
--- a/Source/core/svg/properties/SVGAnimatedProperty.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-
-#include "core/svg/SVGElement.h"
-
-namespace WebCore {
-
-SVGAnimatedProperty::SVGAnimatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType)
-    : m_contextElement(contextElement)
-    , m_attributeName(attributeName)
-    , m_animatedPropertyType(animatedPropertyType)
-    , m_isAnimating(false)
-    , m_isReadOnly(false)
-{
-    contextElement->setContextElement();
-}
-
-SVGAnimatedProperty::~SVGAnimatedProperty()
-{
-    // Assure that animationEnded() was called, if animationStarted() was called before.
-    ASSERT(!m_isAnimating);
-}
-
-void SVGAnimatedProperty::detachAnimatedPropertiesForElement(SVGElement* element)
-{
-    // Remove wrappers from cache.
-    Cache* cache = animatedPropertyCache();
-
-    Vector<SVGAnimatedPropertyDescription> keysToRemove;
-
-    const Cache::const_iterator end = cache->end();
-    for (Cache::const_iterator it = cache->begin(); it != end; ++it) {
-        if (it->key.m_element == element) {
-            it->value->resetContextElement();
-            keysToRemove.append(it->key);
-        }
-    }
-
-    for (Vector<SVGAnimatedPropertyDescription>::const_iterator it = keysToRemove.begin(); it != keysToRemove.end(); ++it) {
-        // http://crbug.com/333156 :
-        // There are cases where detachAnimatedPropertiesForElement is called recursively from ~SVGAnimatedProperty.
-        // This below protect makes this function safe by deferring the recursive call until we finish touching the HashMap.
-        RefPtr<SVGAnimatedProperty> protect = cache->get(*it);
-        cache->remove(*it);
-    }
-}
-
-void SVGAnimatedProperty::commitChange()
-{
-    ASSERT(m_contextElement);
-    ASSERT_WITH_SECURITY_IMPLICATION(!m_contextElement->m_deletionHasBegun);
-    m_contextElement->invalidateSVGAttributes();
-    m_contextElement->svgAttributeChanged(m_attributeName);
-}
-
-SVGAnimatedProperty::Cache* SVGAnimatedProperty::animatedPropertyCache()
-{
-    static Cache* s_cache = new Cache;
-    return s_cache;
-}
-
-} // namespace WebCore
diff --git a/Source/core/svg/properties/SVGAnimatedProperty.h b/Source/core/svg/properties/SVGAnimatedProperty.h
deleted file mode 100644
index eb0ba54..0000000
--- a/Source/core/svg/properties/SVGAnimatedProperty.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2013 Samsung Electronics. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedProperty_h
-#define SVGAnimatedProperty_h
-
-#include "core/svg/properties/SVGAnimatedPropertyDescription.h"
-#include "core/svg/properties/SVGPropertyInfo.h"
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-class SVGElement;
-
-class SVGAnimatedProperty : public RefCounted<SVGAnimatedProperty> {
-public:
-    SVGElement* contextElement() const { return m_contextElement; }
-    void resetContextElement() { m_contextElement = 0; }
-    const QualifiedName& attributeName() const { return m_attributeName; }
-    AnimatedPropertyType animatedPropertyType() const { return m_animatedPropertyType; }
-    bool isAnimating() const { return m_isAnimating; }
-    bool isReadOnly() const { return m_isReadOnly; }
-    void setIsReadOnly() { m_isReadOnly = true; }
-
-    void commitChange();
-
-    virtual bool isAnimatedListTearOff() const { return false; }
-
-    // Caching facilities.
-    typedef HashMap<SVGAnimatedPropertyDescription, RefPtr<SVGAnimatedProperty>, SVGAnimatedPropertyDescriptionHash, SVGAnimatedPropertyDescriptionHashTraits> Cache;
-
-    virtual ~SVGAnimatedProperty();
-
-    template<typename OwnerType, typename TearOffType, typename PropertyType>
-    static PassRefPtr<TearOffType> lookupOrCreateWrapper(OwnerType* element, const SVGPropertyInfo* info, PropertyType& property)
-    {
-        ASSERT(info);
-        SVGAnimatedPropertyDescription key(element, info->propertyIdentifier);
-        RefPtr<SVGAnimatedProperty> wrapper = animatedPropertyCache()->get(key);
-        if (!wrapper) {
-            wrapper = TearOffType::create(element, info->attributeName, info->animatedPropertyType, property);
-            if (info->animatedPropertyState == PropertyIsReadOnly)
-                wrapper->setIsReadOnly();
-            animatedPropertyCache()->set(key, wrapper);
-        }
-        return static_pointer_cast<TearOffType>(wrapper);
-    }
-
-    template<typename OwnerType, typename TearOffType>
-    static TearOffType* lookupWrapper(OwnerType* element, const SVGPropertyInfo* info)
-    {
-        ASSERT(info);
-        SVGAnimatedPropertyDescription key(element, info->propertyIdentifier);
-        return static_cast<TearOffType*>(animatedPropertyCache()->get(key));
-    }
-
-    template<typename OwnerType, typename TearOffType>
-    static TearOffType* lookupWrapper(const OwnerType* element, const SVGPropertyInfo* info)
-    {
-        return lookupWrapper<OwnerType, TearOffType>(const_cast<OwnerType*>(element), info);
-    }
-
-    static void detachAnimatedPropertiesForElement(SVGElement*);
-
-protected:
-    SVGAnimatedProperty(SVGElement*, const QualifiedName&, AnimatedPropertyType);
-
-private:
-    static Cache* animatedPropertyCache();
-
-    SVGElement* m_contextElement;
-    const QualifiedName& m_attributeName;
-    AnimatedPropertyType m_animatedPropertyType;
-
-protected:
-    bool m_isAnimating;
-    bool m_isReadOnly;
-};
-
-}
-
-#endif // SVGAnimatedProperty_h
diff --git a/Source/core/svg/properties/SVGAnimatedPropertyDescription.h b/Source/core/svg/properties/SVGAnimatedPropertyDescription.h
deleted file mode 100644
index 55f1a8f..0000000
--- a/Source/core/svg/properties/SVGAnimatedPropertyDescription.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPropertyDescription_h
-#define SVGAnimatedPropertyDescription_h
-
-#include "wtf/HashMap.h"
-#include "wtf/HashTableDeletedValueType.h"
-#include "wtf/text/AtomicString.h"
-
-namespace WebCore {
-
-class SVGElement;
-
-struct SVGAnimatedPropertyDescription {
-    // Empty value
-    SVGAnimatedPropertyDescription()
-        : m_element(0)
-        , m_attributeName(0)
-    {
-    }
-
-    // Deleted value
-    SVGAnimatedPropertyDescription(WTF::HashTableDeletedValueType)
-        : m_element(reinterpret_cast<SVGElement*>(-1))
-    {
-    }
-
-    bool isHashTableDeletedValue() const
-    {
-        return m_element == reinterpret_cast<SVGElement*>(-1);
-    }
-
-    SVGAnimatedPropertyDescription(SVGElement* element, const AtomicString& attributeName)
-        : m_element(element)
-        , m_attributeName(attributeName.impl())
-    {
-        ASSERT(m_element);
-        ASSERT(m_attributeName);
-    }
-
-    bool operator==(const SVGAnimatedPropertyDescription& other) const
-    {
-        return m_element == other.m_element && m_attributeName == other.m_attributeName;
-    }
-
-    SVGElement* m_element;
-    StringImpl* m_attributeName;
-};
-
-struct SVGAnimatedPropertyDescriptionHash {
-    static unsigned hash(const SVGAnimatedPropertyDescription& key)
-    {
-        return StringHasher::hashMemory<sizeof(SVGAnimatedPropertyDescription)>(&key);
-    }
-
-    static bool equal(const SVGAnimatedPropertyDescription& a, const SVGAnimatedPropertyDescription& b)
-    {
-        return a == b;
-    }
-
-    static const bool safeToCompareToEmptyOrDeleted = true;
-};
-
-struct SVGAnimatedPropertyDescriptionHashTraits : WTF::SimpleClassHashTraits<SVGAnimatedPropertyDescription> { };
-
-}
-
-#endif // SVGAnimatedPropertyDescription_h
diff --git a/Source/core/svg/properties/SVGAnimatedPropertyMacros.h b/Source/core/svg/properties/SVGAnimatedPropertyMacros.h
deleted file mode 100644
index b6658a8..0000000
--- a/Source/core/svg/properties/SVGAnimatedPropertyMacros.h
+++ /dev/null
@@ -1,199 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
- * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPropertyMacros_h
-#define SVGAnimatedPropertyMacros_h
-
-#include "core/dom/Element.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "core/svg/properties/SVGAttributeToPropertyMap.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-#include "wtf/StdLibExtras.h"
-
-namespace WebCore {
-
-// SVGSynchronizableAnimatedProperty implementation
-template<typename PropertyType>
-struct SVGSynchronizableAnimatedProperty {
-    SVGSynchronizableAnimatedProperty()
-        : value(SVGPropertyTraits<PropertyType>::initialValue())
-        , shouldSynchronize(false)
-    {
-    }
-
-    template<typename ConstructorParameter1>
-    SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1)
-        : value(value1)
-        , shouldSynchronize(false)
-    {
-    }
-
-    template<typename ConstructorParameter1, typename ConstructorParameter2>
-    SVGSynchronizableAnimatedProperty(const ConstructorParameter1& value1, const ConstructorParameter2& value2)
-        : value(value1, value2)
-        , shouldSynchronize(false)
-    {
-    }
-
-    void synchronize(Element* ownerElement, const QualifiedName& attrName, const AtomicString& value)
-    {
-        ownerElement->setSynchronizedLazyAttribute(attrName, value);
-    }
-
-    PropertyType value;
-    bool shouldSynchronize : 1;
-};
-
-// Property registration helpers
-#define BEGIN_REGISTER_ANIMATED_PROPERTIES(OwnerType) \
-SVGAttributeToPropertyMap& OwnerType::attributeToPropertyMap() \
-{ \
-    DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, s_attributeToPropertyMap, ()); \
-    return s_attributeToPropertyMap; \
-} \
-\
-SVGAttributeToPropertyMap& OwnerType::localAttributeToPropertyMap() const \
-{ \
-    return attributeToPropertyMap(); \
-} \
-\
-void OwnerType::registerAnimatedPropertiesFor##OwnerType() \
-{ \
-    OwnerType::m_cleanupAnimatedPropertiesCaller.setOwner(this); \
-    SVGAttributeToPropertyMap& map = OwnerType::attributeToPropertyMap(); \
-    if (!map.isEmpty()) \
-        return; \
-    typedef OwnerType UseOwnerType;
-
-#define REGISTER_LOCAL_ANIMATED_PROPERTY(LowerProperty) \
-     map.addProperty(UseOwnerType::LowerProperty##PropertyInfo());
-
-#define REGISTER_PARENT_ANIMATED_PROPERTIES(ClassName) \
-     map.addProperties(ClassName::attributeToPropertyMap()); \
-
-#define END_REGISTER_ANIMATED_PROPERTIES }
-
-// Property definition helpers (used in SVG*.cpp files)
-#define DEFINE_ANIMATED_PROPERTY(AnimatedPropertyTypeEnum, OwnerType, DOMAttribute, SVGDOMAttributeIdentifier, UpperProperty, LowerProperty, TearOffType, PropertyType) \
-const SVGPropertyInfo* OwnerType::LowerProperty##PropertyInfo() { \
-    DEFINE_STATIC_LOCAL(const SVGPropertyInfo, s_propertyInfo, \
-                        (AnimatedPropertyTypeEnum, \
-                         PropertyIsReadWrite, \
-                         DOMAttribute, \
-                         SVGDOMAttributeIdentifier, \
-                         &OwnerType::synchronize##UpperProperty, \
-                         &OwnerType::lookupOrCreate##UpperProperty##Wrapper)); \
-    return &s_propertyInfo; \
-} \
-bool OwnerType::LowerProperty##Specified() const \
-{ \
-    if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \
-        if (wrapper->isAnimating()) \
-            return true; \
-    } \
-    return hasAttribute(SVGDOMAttributeIdentifier); \
-} \
-PropertyType& OwnerType::LowerProperty##CurrentValue() const \
-{ \
-    if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) { \
-        if (wrapper->isAnimating()) \
-            return wrapper->currentAnimatedValue(); \
-    } \
-    return m_##LowerProperty.value; \
-} \
-\
-PropertyType& OwnerType::LowerProperty##BaseValue() const \
-{ \
-    return m_##LowerProperty.value; \
-} \
-\
-void OwnerType::set##UpperProperty##BaseValue(const PropertyType& type) \
-{ \
-    m_##LowerProperty.value = type; \
-} \
-\
-PassRefPtr<TearOffType> OwnerType::LowerProperty() \
-{ \
-    m_##LowerProperty.shouldSynchronize = true; \
-    return static_pointer_cast<TearOffType>(lookupOrCreate##UpperProperty##Wrapper(this)); \
-} \
-\
-void OwnerType::synchronize##UpperProperty() \
-{ \
-    if (!m_##LowerProperty.shouldSynchronize) \
-        return; \
-    AtomicString value(SVGPropertyTraits<PropertyType>::toString(m_##LowerProperty.value)); \
-    m_##LowerProperty.synchronize(this, LowerProperty##PropertyInfo()->attributeName, value); \
-} \
-\
-PassRefPtr<SVGAnimatedProperty> OwnerType::lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType) \
-{ \
-    ASSERT(maskedOwnerType); \
-    UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
-    return SVGAnimatedProperty::lookupOrCreateWrapper<UseOwnerType, TearOffType, PropertyType>(ownerType, LowerProperty##PropertyInfo(), ownerType->m_##LowerProperty.value); \
-} \
-\
-void OwnerType::synchronize##UpperProperty(SVGElement* maskedOwnerType) \
-{ \
-    ASSERT(maskedOwnerType); \
-    UseOwnerType* ownerType = static_cast<UseOwnerType*>(maskedOwnerType); \
-    ownerType->synchronize##UpperProperty(); \
-}
-
-// Property declaration helpers (used in SVG*.h files)
-#define BEGIN_DECLARE_ANIMATED_PROPERTIES(OwnerType) \
-public: \
-    static SVGAttributeToPropertyMap& attributeToPropertyMap(); \
-    virtual SVGAttributeToPropertyMap& localAttributeToPropertyMap() const; \
-    void registerAnimatedPropertiesFor##OwnerType(); \
-    typedef OwnerType UseOwnerType;
-
-#define DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
-public: \
-    static const SVGPropertyInfo* LowerProperty##PropertyInfo(); \
-    bool LowerProperty##Specified() const; \
-    PropertyType& LowerProperty##CurrentValue() const; \
-    PropertyType& LowerProperty##BaseValue() const; \
-    void set##UpperProperty##BaseValue(const PropertyType& type); \
-    PassRefPtr<TearOffType> LowerProperty(); \
-\
-private: \
-    void synchronize##UpperProperty(); \
-    static PassRefPtr<SVGAnimatedProperty> lookupOrCreate##UpperProperty##Wrapper(SVGElement* maskedOwnerType); \
-    static void synchronize##UpperProperty(SVGElement* maskedOwnerType); \
-\
-    mutable SVGSynchronizableAnimatedProperty<PropertyType> m_##LowerProperty;
-
-#define END_DECLARE_ANIMATED_PROPERTIES \
-    CleanUpAnimatedPropertiesCaller m_cleanupAnimatedPropertiesCaller;
-
-// List specific definition/declaration helpers
-#define DECLARE_ANIMATED_LIST_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
-DECLARE_ANIMATED_PROPERTY(TearOffType, PropertyType, UpperProperty, LowerProperty) \
-void detachAnimated##UpperProperty##ListWrappers(unsigned newListSize) \
-{ \
-    if (TearOffType* wrapper = SVGAnimatedProperty::lookupWrapper<UseOwnerType, TearOffType>(this, LowerProperty##PropertyInfo())) \
-        wrapper->detachListWrappers(newListSize); \
-}
-
-}
-
-#endif // SVGAnimatedPropertyMacros_h
diff --git a/Source/core/svg/properties/SVGAnimatedPropertyTearOff.h b/Source/core/svg/properties/SVGAnimatedPropertyTearOff.h
deleted file mode 100644
index 2216274..0000000
--- a/Source/core/svg/properties/SVGAnimatedPropertyTearOff.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedPropertyTearOff_h
-#define SVGAnimatedPropertyTearOff_h
-
-#include "bindings/v8/ScriptWrappable.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "core/svg/properties/SVGPropertyTearOff.h"
-
-namespace WebCore {
-
-template<typename PropertyType>
-class SVGAnimatedPropertyTearOff FINAL : public SVGAnimatedProperty, public ScriptWrappable {
-public:
-    typedef SVGPropertyTearOff<PropertyType> PropertyTearOff;
-    typedef PropertyType ContentType;
-
-    virtual ~SVGAnimatedPropertyTearOff()
-    {
-        if (m_baseVal) {
-            ASSERT(m_baseVal->animatedProperty() == this);
-            m_baseVal->setAnimatedProperty(0);
-        }
-        if (m_animVal) {
-            ASSERT(m_animVal->animatedProperty() == this);
-            m_animVal->setAnimatedProperty(0);
-        }
-    }
-
-    PropertyTearOff* baseVal()
-    {
-        if (!m_baseVal)
-            m_baseVal = PropertyTearOff::create(this, BaseValRole, m_property);
-        return m_baseVal.get();
-    }
-
-    PropertyTearOff* animVal()
-    {
-        if (!m_animVal)
-            m_animVal = PropertyTearOff::create(this, AnimValRole, m_property);
-        return m_animVal.get();
-    }
-
-    static PassRefPtr<SVGAnimatedPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new SVGAnimatedPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property));
-    }
-
-    PropertyType& currentAnimatedValue()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-        return m_animVal->propertyReference();
-    }
-
-    const PropertyType& currentBaseValue() const
-    {
-        return m_property;
-    }
-
-    void animationStarted(PropertyType* newAnimVal)
-    {
-        ASSERT(!m_isAnimating);
-        ASSERT(newAnimVal);
-        animVal()->setValue(*newAnimVal);
-        m_isAnimating = true;
-    }
-
-    void animationEnded()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-        m_animVal->setValue(m_property);
-        m_isAnimating = false;
-    }
-
-    void animValWillChange()
-    {
-        // no-op for non list types.
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-    }
-
-    void animValDidChange()
-    {
-        // no-op for non list types.
-        ASSERT(m_isAnimating);
-        ASSERT(m_animVal);
-    }
-
-private:
-    SVGAnimatedPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
-        : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType)
-        , m_property(property)
-    {
-        ScriptWrappable::init(this);
-    }
-
-    PropertyType& m_property;
-    RefPtr<PropertyTearOff> m_baseVal;
-    RefPtr<PropertyTearOff> m_animVal;
-};
-
-}
-
-#endif // SVGAnimatedPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGAnimatedStaticPropertyTearOff.h b/Source/core/svg/properties/SVGAnimatedStaticPropertyTearOff.h
deleted file mode 100644
index fb3e610..0000000
--- a/Source/core/svg/properties/SVGAnimatedStaticPropertyTearOff.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedStaticPropertyTearOff_h
-#define SVGAnimatedStaticPropertyTearOff_h
-
-#include "core/svg/properties/SVGAnimatedProperty.h"
-
-namespace WebCore {
-
-class ExceptionState;
-
-template<typename PropertyType>
-class SVGAnimatedStaticPropertyTearOff : public SVGAnimatedProperty {
-public:
-    typedef PropertyType ContentType;
-
-    PropertyType& baseVal()
-    {
-        return m_property;
-    }
-
-    PropertyType& animVal()
-    {
-        if (m_animatedProperty)
-            return *m_animatedProperty;
-        return m_property;
-    }
-
-    virtual void setBaseVal(const PropertyType& property, ExceptionState&)
-    {
-        m_property = property;
-        commitChange();
-    }
-
-    static PassRefPtr<SVGAnimatedStaticPropertyTearOff<PropertyType> > create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new SVGAnimatedStaticPropertyTearOff<PropertyType>(contextElement, attributeName, animatedPropertyType, property));
-    }
-
-    PropertyType& currentAnimatedValue()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animatedProperty);
-        return *m_animatedProperty;
-    }
-
-    const PropertyType& currentBaseValue() const
-    {
-        return m_property;
-    }
-
-    void animationStarted(PropertyType* newAnimVal)
-    {
-        ASSERT(!m_isAnimating);
-        ASSERT(!m_animatedProperty);
-        ASSERT(newAnimVal);
-        m_animatedProperty = newAnimVal;
-        m_isAnimating = true;
-    }
-
-    void animationEnded()
-    {
-        ASSERT(m_isAnimating);
-        ASSERT(m_animatedProperty);
-        m_animatedProperty = 0;
-        m_isAnimating = false;
-    }
-
-    void animValWillChange()
-    {
-        // no-op for non list types.
-        ASSERT(m_isAnimating);
-        ASSERT(m_animatedProperty);
-    }
-
-    void animValDidChange()
-    {
-        // no-op for non list types.
-        ASSERT(m_isAnimating);
-        ASSERT(m_animatedProperty);
-    }
-
-protected:
-    SVGAnimatedStaticPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, PropertyType& property)
-        : SVGAnimatedProperty(contextElement, attributeName, animatedPropertyType)
-        , m_property(property)
-        , m_animatedProperty(0)
-    {
-    }
-
-private:
-    PropertyType& m_property;
-    PropertyType* m_animatedProperty;
-};
-
-}
-
-#endif // SVGAnimatedStaticPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h b/Source/core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h
deleted file mode 100644
index daa7e6e..0000000
--- a/Source/core/svg/properties/SVGAnimatedTransformListPropertyTearOff.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAnimatedTransformListPropertyTearOff_h
-#define SVGAnimatedTransformListPropertyTearOff_h
-
-#include "core/svg/SVGTransformList.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
-#include "core/svg/properties/SVGTransformListPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGAnimatedTransformListPropertyTearOff : public SVGAnimatedListPropertyTearOff<SVGTransformList> {
-public:
-    virtual SVGListPropertyTearOff<SVGTransformList>* baseVal() OVERRIDE
-    {
-        if (!m_baseVal)
-            m_baseVal = SVGTransformListPropertyTearOff::create(this, BaseValRole, m_values, m_wrappers);
-        return static_cast<SVGListPropertyTearOff<SVGTransformList>*>(m_baseVal.get());
-    }
-
-    virtual SVGListPropertyTearOff<SVGTransformList>* animVal() OVERRIDE
-    {
-        if (!m_animVal)
-            m_animVal = SVGTransformListPropertyTearOff::create(this, AnimValRole, m_values, m_wrappers);
-        return static_cast<SVGListPropertyTearOff<SVGTransformList>*>(m_animVal.get());
-    }
-
-    static PassRefPtr<SVGAnimatedTransformListPropertyTearOff> create(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformList& values)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new SVGAnimatedTransformListPropertyTearOff(contextElement, attributeName, animatedPropertyType, values));
-    }
-
-private:
-    SVGAnimatedTransformListPropertyTearOff(SVGElement* contextElement, const QualifiedName& attributeName, AnimatedPropertyType animatedPropertyType, SVGTransformList& values)
-        : SVGAnimatedListPropertyTearOff<SVGTransformList>(contextElement, attributeName, animatedPropertyType, values)
-    {
-    }
-};
-
-}
-
-#endif // SVGAnimatedTransformListPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp b/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp
deleted file mode 100644
index a483d41..0000000
--- a/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-
-#include "core/svg/properties/SVGAttributeToPropertyMap.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "wtf/PassOwnPtr.h"
-
-namespace WebCore {
-
-void SVGAttributeToPropertyMap::addProperties(const SVGAttributeToPropertyMap& map)
-{
-    AttributeToPropertiesMap::const_iterator end = map.m_map.end();
-    for (AttributeToPropertiesMap::const_iterator it = map.m_map.begin(); it != end; ++it) {
-        const PropertiesVector* mapVector = it->value.get();
-        ASSERT(mapVector);
-
-        if (!mapVector->isEmpty()) {
-            const SVGPropertyInfo* firstProperty = mapVector->first();
-            ASSERT(firstProperty);
-            const QualifiedName& attributeName = firstProperty->attributeName;
-
-            // All of the properties in mapVector are guaranteed to have the same attribute name.
-            // Add them to our properties vector for that attribute name, reserving capacity up
-            // front.
-            PropertiesVector* vector = getOrCreatePropertiesVector(attributeName);
-            ASSERT(vector);
-            vector->reserveCapacity(vector->size() + mapVector->size());
-            const PropertiesVector::const_iterator mapVectorEnd = mapVector->end();
-            for (PropertiesVector::const_iterator mapVectorIt = mapVector->begin(); mapVectorIt != mapVectorEnd; ++mapVectorIt) {
-                ASSERT(*mapVectorIt);
-                ASSERT(attributeName == (*mapVectorIt)->attributeName);
-                vector->append(*mapVectorIt);
-            }
-        }
-    }
-}
-
-void SVGAttributeToPropertyMap::addProperty(const SVGPropertyInfo* info)
-{
-    ASSERT(info);
-    PropertiesVector* vector = getOrCreatePropertiesVector(info->attributeName);
-    ASSERT(vector);
-    vector->append(info);
-}
-
-void SVGAttributeToPropertyMap::animatedPropertiesForAttribute(SVGElement* ownerType, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty> >& properties)
-{
-    ASSERT(ownerType);
-    PropertiesVector* vector = m_map.get(attributeName);
-    if (!vector)
-        return;
-
-    properties.reserveCapacity(properties.size() + vector->size());
-    const PropertiesVector::iterator vectorEnd = vector->end();
-    for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
-        properties.append(animatedProperty(ownerType, attributeName, *vectorIt));
-}
-
-void SVGAttributeToPropertyMap::animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>& propertyTypes)
-{
-    PropertiesVector* vector = m_map.get(attributeName);
-    if (!vector)
-        return;
-
-    propertyTypes.reserveCapacity(propertyTypes.size() + vector->size());
-    const PropertiesVector::iterator vectorEnd = vector->end();
-    for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
-        propertyTypes.append((*vectorIt)->animatedPropertyType);
-}
-
-void SVGAttributeToPropertyMap::synchronizeProperties(SVGElement* contextElement)
-{
-    ASSERT(contextElement);
-    const AttributeToPropertiesMap::iterator end = m_map.end();
-    for (AttributeToPropertiesMap::iterator it = m_map.begin(); it != end; ++it) {
-        PropertiesVector* vector = it->value.get();
-        ASSERT(vector);
-
-        const PropertiesVector::iterator vectorEnd = vector->end();
-        for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
-            synchronizeProperty(contextElement, it->key, *vectorIt);
-    }
-}
-
-bool SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName)
-{
-    ASSERT(contextElement);
-    PropertiesVector* vector = m_map.get(attributeName);
-    if (!vector)
-        return false;
-
-    const PropertiesVector::iterator vectorEnd = vector->end();
-    for (PropertiesVector::iterator vectorIt = vector->begin(); vectorIt != vectorEnd; ++vectorIt)
-        synchronizeProperty(contextElement, attributeName, *vectorIt);
-
-    return true;
-}
-
-SVGAttributeToPropertyMap::PropertiesVector* SVGAttributeToPropertyMap::getOrCreatePropertiesVector(const QualifiedName& attributeName)
-{
-    ASSERT(attributeName != anyQName());
-    AttributeToPropertiesMap::AddResult addResult = m_map.add(attributeName, PassOwnPtr<PropertiesVector>());
-    PropertiesVector* vector = addResult.storedValue->value.get();
-    if (addResult.isNewEntry) {
-        ASSERT(!vector);
-        vector = (addResult.storedValue->value = adoptPtr(new PropertiesVector)).get();
-    }
-    ASSERT(vector);
-    ASSERT(addResult.storedValue->value.get() == vector);
-    return vector;
-}
-
-void SVGAttributeToPropertyMap::synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info)
-{
-    ASSERT(info);
-    ASSERT_UNUSED(attributeName, attributeName == info->attributeName);
-    ASSERT(info->synchronizeProperty);
-    (*info->synchronizeProperty)(contextElement);
-}
-
-PassRefPtr<SVGAnimatedProperty> SVGAttributeToPropertyMap::animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo* info)
-{
-    ASSERT(info);
-    ASSERT_UNUSED(attributeName, attributeName == info->attributeName);
-    ASSERT(info->lookupOrCreateWrapperForAnimatedProperty);
-    return (*info->lookupOrCreateWrapperForAnimatedProperty)(contextElement);
-}
-
-}
diff --git a/Source/core/svg/properties/SVGAttributeToPropertyMap.h b/Source/core/svg/properties/SVGAttributeToPropertyMap.h
deleted file mode 100644
index d2e04cf..0000000
--- a/Source/core/svg/properties/SVGAttributeToPropertyMap.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2011. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGAttributeToPropertyMap_h
-#define SVGAttributeToPropertyMap_h
-
-#include "core/svg/properties/SVGPropertyInfo.h"
-#include "wtf/HashMap.h"
-
-namespace WebCore {
-
-class SVGAnimatedProperty;
-class SVGElement;
-
-class SVGAttributeToPropertyMap {
-private:
-    typedef Vector<const SVGPropertyInfo*> PropertiesVector;
-    typedef HashMap<QualifiedName, OwnPtr<PropertiesVector> > AttributeToPropertiesMap;
-
-public:
-    bool isEmpty() const { return m_map.isEmpty(); }
-
-    void addProperties(const SVGAttributeToPropertyMap&);
-    void addProperty(const SVGPropertyInfo*);
-
-    // FIXME: To match WebKit coding style either these functions should have return values instead of out parameters,
-    // or the word "get" should be added as a prefix to their names.
-    void animatedPropertiesForAttribute(SVGElement* contextElement, const QualifiedName& attributeName, Vector<RefPtr<SVGAnimatedProperty> >&);
-    void animatedPropertyTypeForAttribute(const QualifiedName& attributeName, Vector<AnimatedPropertyType>&);
-
-    void synchronizeProperties(SVGElement* contextElement);
-    bool synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName);
-
-private:
-    PropertiesVector* getOrCreatePropertiesVector(const QualifiedName&);
-    void synchronizeProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*);
-    PassRefPtr<SVGAnimatedProperty> animatedProperty(SVGElement* contextElement, const QualifiedName& attributeName, const SVGPropertyInfo*);
-
-    AttributeToPropertiesMap m_map;
-};
-
-}
-
-#endif
diff --git a/Source/core/svg/properties/SVGListProperty.h b/Source/core/svg/properties/SVGListProperty.h
deleted file mode 100644
index 49d1217..0000000
--- a/Source/core/svg/properties/SVGListProperty.h
+++ /dev/null
@@ -1,483 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGListProperty_h
-#define SVGListProperty_h
-
-#include "bindings/v8/ExceptionMessages.h"
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/svg/properties/SVGPropertyTearOff.h"
-#include "core/svg/properties/SVGPropertyTraits.h"
-
-namespace WebCore {
-
-enum ListModification {
-    ListModificationUnknown = 0,
-    ListModificationInsert = 1,
-    ListModificationReplace = 2,
-    ListModificationRemove = 3,
-    ListModificationAppend = 4
-};
-
-template<typename PropertyType>
-class SVGAnimatedListPropertyTearOff;
-
-template<typename PropertyType>
-class SVGListProperty : public SVGProperty {
-public:
-    typedef SVGListProperty<PropertyType> Self;
-
-    typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
-    typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
-    typedef PassRefPtr<ListItemTearOff> PassListItemTearOff;
-    typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff;
-    typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache;
-
-    bool canAlterList(ExceptionState& exceptionState) const
-    {
-        if (m_role == AnimValRole) {
-            exceptionState.throwDOMException(NoModificationAllowedError, ExceptionMessages::readOnly("the property is an animation value"));
-            return false;
-        }
-
-        return true;
-    }
-
-    static void detachListWrappersAndResize(ListWrapperCache* wrappers, unsigned newListSize = 0)
-    {
-        // See SVGPropertyTearOff::detachWrapper() for an explanation about what's happening here.
-        ASSERT(wrappers);
-        unsigned size = wrappers->size();
-        for (unsigned i = 0; i < size; ++i) {
-            if (ListItemTearOff* item = wrappers->at(i).get())
-                item->detachWrapper();
-        }
-
-        // Reinitialize the wrapper cache to be equal to the new values size, after the XML DOM changed the list.
-        if (newListSize)
-            wrappers->fill(0, newListSize);
-        else
-            wrappers->clear();
-    }
-
-    void detachListWrappers(unsigned newListSize)
-    {
-        detachListWrappersAndResize(m_wrappers, newListSize);
-    }
-
-    void setValuesAndWrappers(PropertyType* values, ListWrapperCache* wrappers, bool shouldOwnValues)
-    {
-        // This is only used for animVal support, to switch the underlying values & wrappers
-        // to the current animated values, once animation for a list starts.
-        ASSERT(m_values);
-        ASSERT(m_wrappers);
-        ASSERT(m_role == AnimValRole);
-        if (m_ownsValues)
-            delete m_values;
-        m_values = values;
-        m_ownsValues = shouldOwnValues;
-        m_wrappers = wrappers;
-        ASSERT(m_values->size() == m_wrappers->size());
-    }
-
-    // SVGList::clear()
-    void clearValues(ExceptionState& exceptionState)
-    {
-        if (!canAlterList(exceptionState))
-            return;
-
-        m_values->clear();
-        commitChange();
-    }
-
-    void clearValuesAndWrappers(ExceptionState& exceptionState)
-    {
-        if (!canAlterList(exceptionState))
-            return;
-
-        detachListWrappers(0);
-        m_values->clear();
-        commitChange();
-    }
-
-    // SVGList::numberOfItems()
-    unsigned numberOfItems() const
-    {
-        return m_values->size();
-    }
-
-    // SVGList::initialize()
-    ListItemType initializeValues(const ListItemType& newItem, ExceptionState& exceptionState)
-    {
-        if (!canAlterList(exceptionState))
-            return ListItemType();
-
-        // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list.
-        processIncomingListItemValue(newItem, 0);
-
-        // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter.
-        m_values->clear();
-        m_values->append(newItem);
-
-        commitChange();
-        return newItem;
-    }
-
-    PassListItemTearOff initializeValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
-    {
-        ASSERT(m_wrappers);
-        if (!canAlterList(exceptionState))
-            return 0;
-
-        // Not specified, but FF/Opera do it this way, and it's just sane.
-        if (!passNewItem) {
-            exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-            return 0;
-        }
-
-        RefPtr<ListItemTearOff> newItem = passNewItem;
-        ASSERT(m_values->size() == m_wrappers->size());
-
-        // Spec: If the inserted item is already in a list, it is removed from its previous list before it is inserted into this list.
-        processIncomingListItemWrapper(newItem, 0);
-
-        // Spec: Clears all existing current items from the list and re-initializes the list to hold the single item specified by the parameter.
-        detachListWrappers(0);
-        m_values->clear();
-
-        m_values->append(newItem->propertyReference());
-        m_wrappers->append(newItem);
-
-        commitChange();
-        return newItem.release();
-    }
-
-    // SVGList::getItem()
-    bool canGetItem(unsigned index, ExceptionState& exceptionState)
-    {
-        if (index >= m_values->size()) {
-            exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, m_values->size()));
-            return false;
-        }
-
-        return true;
-    }
-
-    ListItemType getItemValues(unsigned index, ExceptionState& exceptionState)
-    {
-        if (!canGetItem(index, exceptionState))
-            return ListItemType();
-
-        // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy.
-        return m_values->at(index);
-    }
-
-    PassListItemTearOff getItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionState& exceptionState)
-    {
-        ASSERT(m_wrappers);
-        if (!canGetItem(index, exceptionState))
-            return 0;
-
-        // Spec: Returns the specified item from the list. The returned item is the item itself and not a copy.
-        // Any changes made to the item are immediately reflected in the list.
-        ASSERT(m_values->size() == m_wrappers->size());
-        RefPtr<ListItemTearOff> wrapper = m_wrappers->at(index);
-        if (!wrapper) {
-            // Create new wrapper, which is allowed to directly modify the item in the list, w/o copying and cache the wrapper in our map.
-            // It is also associated with our animated property, so it can notify the SVG Element which holds the SVGAnimated*List
-            // that it has been modified (and thus can call svgAttributeChanged(associatedAttributeName)).
-            wrapper = ListItemTearOff::create(animatedList, UndefinedRole, m_values->at(index));
-            m_wrappers->at(index) = wrapper;
-        }
-
-        return wrapper.release();
-    }
-
-    // SVGList::insertItemBefore()
-    ListItemType insertItemBeforeValues(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
-    {
-        if (!canAlterList(exceptionState))
-            return ListItemType();
-
-        // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
-        if (index > m_values->size())
-            index = m_values->size();
-
-        // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-        if (!processIncomingListItemValue(newItem, &index)) {
-            // Inserting the item before itself is a no-op.
-            return newItem;
-        }
-
-        // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be
-        // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list.
-        m_values->insert(index, newItem);
-
-        commitChange();
-        return newItem;
-    }
-
-    PassListItemTearOff insertItemBeforeValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
-    {
-        ASSERT(m_wrappers);
-        if (!canAlterList(exceptionState))
-            return 0;
-
-        // Not specified, but FF/Opera do it this way, and it's just sane.
-        if (!passNewItem) {
-            exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-            return 0;
-        }
-
-        // Spec: If the index is greater than or equal to numberOfItems, then the new item is appended to the end of the list.
-        if (index > m_values->size())
-             index = m_values->size();
-
-        RefPtr<ListItemTearOff> newItem = passNewItem;
-        ASSERT(m_values->size() == m_wrappers->size());
-
-        // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-        if (!processIncomingListItemWrapper(newItem, &index))
-            return newItem.release();
-
-        // Spec: Inserts a new item into the list at the specified position. The index of the item before which the new item is to be
-        // inserted. The first item is number 0. If the index is equal to 0, then the new item is inserted at the front of the list.
-        m_values->insert(index, newItem->propertyReference());
-
-        // Store new wrapper at position 'index', change its underlying value, so mutations of newItem, directly affect the item in the list.
-        m_wrappers->insert(index, newItem);
-
-        commitChange();
-        return newItem.release();
-    }
-
-    // SVGList::replaceItem()
-    bool canReplaceItem(unsigned index, ExceptionState& exceptionState)
-    {
-        if (!canAlterList(exceptionState))
-            return false;
-
-        if (index >= m_values->size()) {
-            exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, m_values->size()));
-            return false;
-        }
-
-        return true;
-    }
-
-    ListItemType replaceItemValues(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
-    {
-        if (!canReplaceItem(index, exceptionState))
-            return ListItemType();
-
-        // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-        // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item.
-        if (!processIncomingListItemValue(newItem, &index)) {
-            // Replacing the item with itself is a no-op.
-            return newItem;
-        }
-
-        if (m_values->isEmpty()) {
-            // 'newItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace.
-            exceptionState.throwDOMException(IndexSizeError, "The new item lived in this list, and has been removed.");
-            return ListItemType();
-        }
-
-        // Update the value at the desired position 'index'.
-        m_values->at(index) = newItem;
-
-        commitChange();
-        return newItem;
-    }
-
-    PassListItemTearOff replaceItemValuesAndWrappers(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
-    {
-        ASSERT(m_wrappers);
-        if (!canReplaceItem(index, exceptionState))
-            return 0;
-
-        // Not specified, but FF/Opera do it this way, and it's just sane.
-        if (!passNewItem) {
-            exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-            return 0;
-        }
-
-        ASSERT(m_values->size() == m_wrappers->size());
-        RefPtr<ListItemTearOff> newItem = passNewItem;
-
-        // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-        // Spec: If the item is already in this list, note that the index of the item to replace is before the removal of the item.
-        if (!processIncomingListItemWrapper(newItem, &index))
-            return newItem.release();
-
-        if (m_values->isEmpty()) {
-            ASSERT(m_wrappers->isEmpty());
-            // 'passNewItem' already lived in our list, we removed it, and now we're empty, which means there's nothing to replace.
-            exceptionState.throwDOMException(IndexSizeError, "The new item lived in this list, and has been removed.");
-            return 0;
-        }
-
-        // Detach the existing wrapper.
-        RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index);
-        if (oldItem)
-            oldItem->detachWrapper();
-
-        // Update the value and the wrapper at the desired position 'index'.
-        m_values->at(index) = newItem->propertyReference();
-        m_wrappers->at(index) = newItem;
-
-        commitChange();
-        return newItem.release();
-    }
-
-    // SVGList::removeItem()
-    bool canRemoveItem(unsigned index, ExceptionState& exceptionState)
-    {
-        if (!canAlterList(exceptionState))
-            return false;
-
-        if (index >= m_values->size()) {
-            exceptionState.throwDOMException(IndexSizeError, ExceptionMessages::indexExceedsMaximumBound("index", index, m_values->size()));
-            return false;
-        }
-
-        return true;
-    }
-
-    ListItemType removeItemValues(unsigned index, ExceptionState& exceptionState)
-    {
-        if (!canRemoveItem(index, exceptionState))
-            return ListItemType();
-
-        ListItemType oldItem = m_values->at(index);
-        m_values->remove(index);
-
-        commitChange();
-        return oldItem;
-    }
-
-    PassListItemTearOff removeItemValuesAndWrappers(AnimatedListPropertyTearOff* animatedList, unsigned index, ExceptionState& exceptionState)
-    {
-        ASSERT(m_wrappers);
-        if (!canRemoveItem(index, exceptionState))
-            return 0;
-
-        ASSERT(m_values->size() == m_wrappers->size());
-
-        // Detach the existing wrapper.
-        RefPtr<ListItemTearOff> oldItem = m_wrappers->at(index);
-        if (!oldItem)
-            oldItem = ListItemTearOff::create(animatedList, UndefinedRole, m_values->at(index));
-
-        oldItem->detachWrapper();
-        m_wrappers->remove(index);
-        m_values->remove(index);
-
-        commitChange();
-        return oldItem.release();
-    }
-
-    // SVGList::appendItem()
-    ListItemType appendItemValues(const ListItemType& newItem, ExceptionState& exceptionState)
-    {
-        if (!canAlterList(exceptionState))
-            return ListItemType();
-
-        // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-        processIncomingListItemValue(newItem, 0);
-
-        // Append the value at the end of the list.
-        m_values->append(newItem);
-
-        commitChange(ListModificationAppend);
-        return newItem;
-    }
-
-    PassListItemTearOff appendItemValuesAndWrappers(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
-    {
-        ASSERT(m_wrappers);
-        if (!canAlterList(exceptionState))
-            return 0;
-
-        // Not specified, but FF/Opera do it this way, and it's just sane.
-        if (!passNewItem) {
-            exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-            return 0;
-        }
-
-        RefPtr<ListItemTearOff> newItem = passNewItem;
-        ASSERT(m_values->size() == m_wrappers->size());
-
-        // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-        processIncomingListItemWrapper(newItem, 0);
-
-        // Append the value and wrapper at the end of the list.
-        m_values->append(newItem->propertyReference());
-        m_wrappers->append(newItem);
-
-        commitChange(ListModificationAppend);
-        return newItem.release();
-    }
-
-    PropertyType& values()
-    {
-        ASSERT(m_values);
-        return *m_values;
-    }
-
-    ListWrapperCache& wrappers() const
-    {
-        ASSERT(m_wrappers);
-        return *m_wrappers;
-    }
-
-protected:
-    SVGListProperty(SVGPropertyRole role, PropertyType& values, ListWrapperCache* wrappers)
-        : m_role(role)
-        , m_ownsValues(false)
-        , m_values(&values)
-        , m_wrappers(wrappers)
-    {
-    }
-
-    virtual ~SVGListProperty()
-    {
-        if (m_ownsValues)
-            delete m_values;
-    }
-
-    virtual void commitChange() = 0;
-    virtual void commitChange(ListModification)
-    {
-        commitChange();
-    }
-
-    virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) = 0;
-    virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify) = 0;
-
-    SVGPropertyRole m_role;
-    bool m_ownsValues;
-    PropertyType* m_values;
-    ListWrapperCache* m_wrappers;
-};
-
-}
-
-#endif // SVGListProperty_h
diff --git a/Source/core/svg/properties/SVGListPropertyTearOff.h b/Source/core/svg/properties/SVGListPropertyTearOff.h
deleted file mode 100644
index 48af096..0000000
--- a/Source/core/svg/properties/SVGListPropertyTearOff.h
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGListPropertyTearOff_h
-#define SVGListPropertyTearOff_h
-
-#include "core/svg/properties/SVGListProperty.h"
-
-namespace WebCore {
-
-class ExceptionState;
-
-template<typename PropertyType>
-class SVGListPropertyTearOff : public SVGListProperty<PropertyType> {
-public:
-    typedef SVGListProperty<PropertyType> Base;
-    typedef SVGListPropertyTearOff<PropertyType> Self;
-
-    typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
-    typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
-    typedef PassRefPtr<ListItemTearOff> PassListItemTearOff;
-    typedef SVGAnimatedListPropertyTearOff<PropertyType> AnimatedListPropertyTearOff;
-    typedef typename SVGAnimatedListPropertyTearOff<PropertyType>::ListWrapperCache ListWrapperCache;
-
-    using Base::m_role;
-    using Base::m_values;
-    using Base::m_wrappers;
-
-    static PassRefPtr<Self> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers)
-    {
-        ASSERT(animatedProperty);
-        return adoptRef(new Self(animatedProperty, role, values, wrappers));
-    }
-
-    int findItem(ListItemTearOff* item) const
-    {
-        ASSERT(m_values);
-        ASSERT(m_wrappers);
-
-        unsigned size = m_wrappers->size();
-        ASSERT(size == m_values->size());
-        for (size_t i = 0; i < size; ++i) {
-            if (item == m_wrappers->at(i))
-                return i;
-        }
-
-        return -1;
-    }
-
-    void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
-    {
-        ASSERT(m_values);
-        ASSERT(m_wrappers);
-        ASSERT(m_values->size() == m_wrappers->size());
-        ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_wrappers->size());
-
-        RefPtr<ListItemTearOff>& item = m_wrappers->at(itemIndex);
-        item->detachWrapper();
-        m_wrappers->remove(itemIndex);
-        m_values->remove(itemIndex);
-
-        if (shouldSynchronizeWrappers)
-            commitChange();
-    }
-
-    // SVGList API
-    void clear(ExceptionState& exceptionState)
-    {
-        Base::clearValuesAndWrappers(exceptionState);
-    }
-
-    PassListItemTearOff initialize(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
-    {
-        return Base::initializeValuesAndWrappers(passNewItem, exceptionState);
-    }
-
-    PassListItemTearOff getItem(unsigned index, ExceptionState& exceptionState)
-    {
-        ASSERT(m_animatedProperty);
-        return Base::getItemValuesAndWrappers(m_animatedProperty, index, exceptionState);
-    }
-
-    PassListItemTearOff insertItemBefore(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
-    {
-        return Base::insertItemBeforeValuesAndWrappers(passNewItem, index, exceptionState);
-    }
-
-    PassListItemTearOff replaceItem(PassListItemTearOff passNewItem, unsigned index, ExceptionState& exceptionState)
-    {
-        return Base::replaceItemValuesAndWrappers(passNewItem, index, exceptionState);
-    }
-
-    PassListItemTearOff removeItem(unsigned index, ExceptionState& exceptionState)
-    {
-        ASSERT(m_animatedProperty);
-        return Base::removeItemValuesAndWrappers(m_animatedProperty, index, exceptionState);
-    }
-
-    PassListItemTearOff appendItem(PassListItemTearOff passNewItem, ExceptionState& exceptionState)
-    {
-        return Base::appendItemValuesAndWrappers(passNewItem, exceptionState);
-    }
-
-    SVGElement* contextElement() const
-    {
-        ASSERT(m_animatedProperty);
-        return m_animatedProperty->contextElement();
-    }
-
-    void clearAnimatedProperty()
-    {
-        ASSERT(m_animatedProperty);
-        m_animatedProperty = 0;
-    }
-
-protected:
-    SVGListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, PropertyType& values, ListWrapperCache& wrappers)
-        : SVGListProperty<PropertyType>(role, values, &wrappers)
-        , m_animatedProperty(animatedProperty)
-    {
-        ASSERT(m_animatedProperty);
-    }
-
-    virtual void commitChange()
-    {
-        ASSERT(m_values);
-        ASSERT(m_wrappers);
-        ASSERT(m_animatedProperty);
-
-        // Update existing wrappers, as the index in the values list has changed.
-        unsigned size = m_wrappers->size();
-        ASSERT(size == m_values->size());
-        for (unsigned i = 0; i < size; ++i) {
-            ListItemTearOff* item = m_wrappers->at(i).get();
-            if (!item)
-                continue;
-            item->setAnimatedProperty(m_animatedProperty);
-            item->setValue(m_values->at(i));
-        }
-
-        m_animatedProperty->commitChange();
-    }
-
-    virtual bool processIncomingListItemValue(const ListItemType&, unsigned*)
-    {
-        ASSERT_NOT_REACHED();
-        return true;
-    }
-
-    virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>& newItem, unsigned* indexToModify)
-    {
-        SVGAnimatedProperty* animatedPropertyOfItem = newItem->animatedProperty();
-
-        // newItem has been created manually, it doesn't belong to any SVGElement.
-        // (for example: "textElement.x.baseVal.appendItem(svgsvgElement.createSVGLength())")
-        if (!animatedPropertyOfItem)
-            return true;
-
-        // newItem belongs to a SVGElement, but its associated SVGAnimatedProperty is not an animated list tear off.
-        // (for example: "textElement.x.baseVal.appendItem(rectElement.width.baseVal)")
-        if (!animatedPropertyOfItem->isAnimatedListTearOff()) {
-            // We have to copy the incoming newItem, as we're not allowed to insert this tear off as is into our wrapper cache.
-            // Otherwhise we'll end up having two SVGAnimatedPropertys that operate on the same SVGPropertyTearOff. Consider the example above:
-            // SVGRectElements SVGAnimatedLength 'width' property baseVal points to the same tear off object
-            // that's inserted into SVGTextElements SVGAnimatedLengthList 'x'. textElement.x.baseVal.getItem(0).value += 150 would
-            // mutate the rectElement width _and_ the textElement x list. That's obviously wrong, take care of that.
-            newItem = ListItemTearOff::create(newItem->propertyReference());
-            return true;
-        }
-
-        // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-        // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal.
-        ASSERT(m_animatedProperty);
-        bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty;
-        AnimatedListPropertyTearOff* propertyTearOff = static_cast<AnimatedListPropertyTearOff*>(animatedPropertyOfItem);
-        int indexToRemove = propertyTearOff->findItem(newItem.get());
-        ASSERT(indexToRemove != -1);
-
-        // Do not remove newItem if already in this list at the target index.
-        if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify)
-            return false;
-
-        propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList);
-
-        if (!indexToModify)
-            return true;
-
-        // If the item lived in our list, adjust the insertion index.
-        if (!livesInOtherList) {
-            unsigned& index = *indexToModify;
-            // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item.
-            if (static_cast<unsigned>(indexToRemove) < index)
-                --index;
-        }
-
-        return true;
-    }
-
-    // Back pointer to the animated property that created us
-    // For example (text.x.baseVal): m_animatedProperty points to the 'x' SVGAnimatedLengthList object
-    AnimatedListPropertyTearOff* m_animatedProperty;
-};
-
-}
-
-#endif // SVGListPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGMatrixTearOff.h b/Source/core/svg/properties/SVGMatrixTearOff.h
deleted file mode 100644
index 42675fd..0000000
--- a/Source/core/svg/properties/SVGMatrixTearOff.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGMatrixTearOff_h
-#define SVGMatrixTearOff_h
-
-#include "core/svg/SVGTransform.h"
-#include "core/svg/properties/SVGPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGMatrixTearOff FINAL : public SVGPropertyTearOff<SVGMatrix> {
-public:
-    // Used for child types (baseVal/animVal) of a SVGAnimated* property (for example: SVGAnimatedLength::baseVal()).
-    // Also used for list tear offs (for example: text.x.baseVal.getItem(0)).
-    static PassRefPtr<SVGMatrixTearOff> create(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, SVGMatrix& value)
-    {
-        ASSERT(animatedProperty);
-        return adoptRef(new SVGMatrixTearOff(animatedProperty, role, value));
-    }
-
-    // Used for non-animated POD types (for example: SVGSVGElement::createSVGLength()).
-    static PassRefPtr<SVGMatrixTearOff> create(const SVGMatrix& initialValue)
-    {
-        return adoptRef(new SVGMatrixTearOff(initialValue));
-    }
-
-    // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute
-    // and that contain a parent type that's exposed to the bindings via a SVGStaticPropertyTearOff object
-    // (for example: SVGTransform::matrix).
-    static PassRefPtr<SVGMatrixTearOff> create(SVGPropertyTearOff<SVGTransform>* parent, SVGMatrix& value)
-    {
-        ASSERT(parent);
-        RefPtr<SVGMatrixTearOff> result = adoptRef(new SVGMatrixTearOff(parent, value));
-        parent->addChild(result->m_weakFactory.createWeakPtr());
-        return result.release();
-    }
-
-    virtual void commitChange() OVERRIDE
-    {
-        if (m_parent) {
-            // This is a tear-off from a SVGPropertyTearOff<SVGTransform>.
-            m_parent->propertyReference().updateSVGMatrix();
-            m_parent->commitChange();
-        } else {
-            // This is either a detached tear-off or a reference tear-off from a AnimatedProperty.
-            SVGPropertyTearOff<SVGMatrix>::commitChange();
-        }
-    }
-
-    // SVGMatrixTearOff can be a child tear-off of a SVGTransform tear-off,
-    // which means that |m_value| may be pointing inside |m_value| of the other tear-off.
-    // This method is called from the parent SVGTransform tear-off when |m_parent->m_value| is updated,
-    // so that |this->m_value| would point to valid location.
-    virtual void setValueForMatrixIfNeeded(SVGTransform* transform) OVERRIDE
-    {
-        setValue(transform->svgMatrix());
-    }
-
-    SVGPropertyTearOff<SVGTransform>* parent() { return m_parent; }
-
-private:
-    SVGMatrixTearOff(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, SVGMatrix& value)
-        : SVGPropertyTearOff<SVGMatrix>(animatedProperty, role, value)
-        , m_parent(0)
-        , m_weakFactory(this)
-    {
-    }
-
-    SVGMatrixTearOff(const SVGMatrix& initialValue)
-        : SVGPropertyTearOff<SVGMatrix>(initialValue)
-        , m_parent(0)
-        , m_weakFactory(this)
-    {
-    }
-
-    SVGMatrixTearOff(SVGPropertyTearOff<SVGTransform>* parent, SVGMatrix& value)
-        : SVGPropertyTearOff<SVGMatrix>(0, UndefinedRole, value)
-        , m_parent(parent)
-        , m_weakFactory(this)
-    {
-    }
-
-    // m_parent is kept alive from V8 wrapper.
-    SVGPropertyTearOff<SVGTransform>* m_parent;
-
-    WeakPtrFactory<SVGPropertyTearOffBase > m_weakFactory;
-};
-
-}
-
-#endif // SVGMatrixTearOff_h
diff --git a/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp b/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
deleted file mode 100644
index 58c0720..0000000
--- a/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#include "config.h"
-#include "core/svg/properties/SVGPathSegListPropertyTearOff.h"
-
-#include "SVGNames.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/svg/SVGPathElement.h"
-#include "core/svg/SVGPathSegWithContext.h"
-#include "core/svg/properties/SVGAnimatedPathSegListPropertyTearOff.h"
-
-namespace WebCore {
-
-void SVGPathSegListPropertyTearOff::clearContextAndRoles()
-{
-    ASSERT(m_values);
-    unsigned size = m_values->size();
-    for (unsigned i = 0; i < size; ++i) {
-        ListItemType item = m_values->at(i);
-        static_cast<SVGPathSegWithContext*>(item.get())->setContextAndRole(0, PathSegUndefinedRole);
-    }
-}
-
-void SVGPathSegListPropertyTearOff::clear(ExceptionState& exceptionState)
-{
-    ASSERT(m_values);
-    if (m_values->isEmpty())
-        return;
-
-    clearContextAndRoles();
-    SVGPathSegListPropertyTearOff::Base::clearValues(exceptionState);
-}
-
-SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::getItem(unsigned index, ExceptionState& exceptionState)
-{
-    ListItemType returnedItem = Base::getItemValues(index, exceptionState);
-    if (returnedItem) {
-        ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->contextElement() == contextElement());
-        ASSERT(static_cast<SVGPathSegWithContext*>(returnedItem.get())->role() == m_pathSegRole);
-    }
-    return returnedItem.release();
-}
-
-SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::replaceItem(PassListItemType passNewItem, unsigned index, ExceptionState& exceptionState)
-{
-    // Not specified, but FF/Opera do it this way, and it's just sane.
-    if (!passNewItem) {
-        exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-        return 0;
-    }
-
-    if (index < m_values->size()) {
-        ListItemType replacedItem = m_values->at(index);
-        ASSERT(replacedItem);
-        static_cast<SVGPathSegWithContext*>(replacedItem.get())->setContextAndRole(0, PathSegUndefinedRole);
-    }
-
-    ListItemType newItem = passNewItem;
-    return Base::replaceItemValues(newItem, index, exceptionState);
-}
-
-SVGPathSegListPropertyTearOff::PassListItemType SVGPathSegListPropertyTearOff::removeItem(unsigned index, ExceptionState& exceptionState)
-{
-    SVGPathSegListPropertyTearOff::ListItemType removedItem = SVGPathSegListPropertyTearOff::Base::removeItemValues(index, exceptionState);
-    if (removedItem)
-        static_cast<SVGPathSegWithContext*>(removedItem.get())->setContextAndRole(0, PathSegUndefinedRole);
-    return removedItem.release();
-}
-
-SVGPathElement* SVGPathSegListPropertyTearOff::contextElement() const
-{
-    SVGElement* contextElement = m_animatedProperty->contextElement();
-    ASSERT(contextElement);
-    return toSVGPathElement(contextElement);
-}
-
-bool SVGPathSegListPropertyTearOff::processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify)
-{
-    SVGPathSegWithContext* newItemWithContext = static_cast<SVGPathSegWithContext*>(newItem.get());
-    SVGAnimatedProperty* animatedPropertyOfItem = newItemWithContext->animatedProperty();
-
-    // Alter the role, after calling animatedProperty(), as that may influence the returned animated property.
-    newItemWithContext->setContextAndRole(contextElement(), m_pathSegRole);
-
-    if (!animatedPropertyOfItem)
-        return true;
-
-    // newItem belongs to a SVGPathElement, but its associated SVGAnimatedProperty is not an animated list tear off.
-    // (for example: "pathElement.pathSegList.appendItem(pathElement.createSVGPathSegClosepath())")
-    if (!animatedPropertyOfItem->isAnimatedListTearOff())
-        return true;
-
-    // Spec: If newItem is already in a list, it is removed from its previous list before it is inserted into this list.
-    // 'newItem' is already living in another list. If it's not our list, synchronize the other lists wrappers after the removal.
-    bool livesInOtherList = animatedPropertyOfItem != m_animatedProperty;
-    SVGAnimatedPathSegListPropertyTearOff* propertyTearOff = static_cast<SVGAnimatedPathSegListPropertyTearOff*>(animatedPropertyOfItem);
-    int indexToRemove = propertyTearOff->findItem(newItem.get());
-    ASSERT(indexToRemove != -1);
-
-    // Do not remove newItem if already in this list at the target index.
-    if (!livesInOtherList && indexToModify && static_cast<unsigned>(indexToRemove) == *indexToModify)
-        return false;
-
-    propertyTearOff->removeItemFromList(indexToRemove, livesInOtherList);
-
-    if (!indexToModify)
-        return true;
-
-    // If the item lived in our list, adjust the insertion index.
-    if (!livesInOtherList) {
-        unsigned& index = *indexToModify;
-        // Spec: If the item is already in this list, note that the index of the item to (replace|insert before) is before the removal of the item.
-        if (static_cast<unsigned>(indexToRemove) < index)
-            --index;
-    }
-
-    return true;
-}
-
-}
diff --git a/Source/core/svg/properties/SVGPathSegListPropertyTearOff.h b/Source/core/svg/properties/SVGPathSegListPropertyTearOff.h
deleted file mode 100644
index abec416..0000000
--- a/Source/core/svg/properties/SVGPathSegListPropertyTearOff.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGPathSegListPropertyTearOff_h
-#define SVGPathSegListPropertyTearOff_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/svg/SVGPathSegList.h"
-#include "core/svg/properties/SVGAnimatedListPropertyTearOff.h"
-
-namespace WebCore {
-
-class SVGPathElement;
-
-class SVGPathSegListPropertyTearOff FINAL : public SVGListProperty<SVGPathSegList> {
-public:
-    typedef SVGListProperty<SVGPathSegList> Base;
-    typedef SVGAnimatedListPropertyTearOff<SVGPathSegList> AnimatedListPropertyTearOff;
-    typedef SVGPropertyTraits<SVGPathSegList>::ListItemType ListItemType;
-    typedef PassRefPtr<SVGPathSeg> PassListItemType;
-
-    static PassRefPtr<SVGPathSegListPropertyTearOff> create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers)
-    {
-        ASSERT(animatedProperty);
-        return adoptRef(new SVGPathSegListPropertyTearOff(animatedProperty, role, pathSegRole, values, wrappers));
-    }
-
-    SVGPathElement* contextElement() const;
-    SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty; }
-
-    int findItem(const ListItemType& item) const
-    {
-        ASSERT(m_values);
-
-        unsigned size = m_values->size();
-        for (size_t i = 0; i < size; ++i) {
-            if (item == m_values->at(i))
-                return i;
-        }
-
-        return -1;
-    }
-
-    void removeItemFromList(size_t itemIndex, bool shouldSynchronizeWrappers)
-    {
-        ASSERT(m_values);
-        ASSERT_WITH_SECURITY_IMPLICATION(itemIndex < m_values->size());
-
-        m_values->remove(itemIndex);
-
-        if (shouldSynchronizeWrappers)
-            commitChange();
-    }
-
-    // SVGList API
-    void clear(ExceptionState&);
-
-    PassListItemType initialize(PassListItemType passNewItem, ExceptionState& exceptionState)
-    {
-        // Not specified, but FF/Opera do it this way, and it's just sane.
-        if (!passNewItem) {
-            exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-            return 0;
-        }
-
-        clearContextAndRoles();
-        ListItemType newItem = passNewItem;
-        return Base::initializeValues(newItem, exceptionState);
-    }
-
-    PassListItemType getItem(unsigned index, ExceptionState&);
-
-    PassListItemType insertItemBefore(PassListItemType passNewItem, unsigned index, ExceptionState& exceptionState)
-    {
-        // Not specified, but FF/Opera do it this way, and it's just sane.
-        if (!passNewItem) {
-            exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-            return 0;
-        }
-
-        ListItemType newItem = passNewItem;
-        return Base::insertItemBeforeValues(newItem, index, exceptionState);
-    }
-
-    PassListItemType replaceItem(PassListItemType, unsigned index, ExceptionState&);
-
-    PassListItemType removeItem(unsigned index, ExceptionState&);
-
-    PassListItemType appendItem(PassListItemType passNewItem, ExceptionState& exceptionState)
-    {
-        // Not specified, but FF/Opera do it this way, and it's just sane.
-        if (!passNewItem) {
-            exceptionState.throwTypeError("The PassListItemType provided is invalid.");
-            return 0;
-        }
-
-        ListItemType newItem = passNewItem;
-        return Base::appendItemValues(newItem, exceptionState);
-    }
-
-private:
-    SVGPathSegListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGPathSegRole pathSegRole, SVGPathSegList& values, ListWrapperCache& wrappers)
-        : SVGListProperty<SVGPathSegList>(role, values, &wrappers)
-        , m_animatedProperty(animatedProperty)
-        , m_pathSegRole(pathSegRole)
-    {
-    }
-
-    void clearContextAndRoles();
-
-    using Base::m_role;
-
-    virtual void commitChange() OVERRIDE
-    {
-        ASSERT(m_values);
-        m_values->commitChange(m_animatedProperty->contextElement(), ListModificationUnknown);
-    }
-
-    virtual void commitChange(ListModification listModification) OVERRIDE
-    {
-        ASSERT(m_values);
-        m_values->commitChange(m_animatedProperty->contextElement(), listModification);
-    }
-
-    virtual bool processIncomingListItemValue(const ListItemType& newItem, unsigned* indexToModify) OVERRIDE;
-    virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*) OVERRIDE
-    {
-        ASSERT_NOT_REACHED();
-        return true;
-    }
-
-private:
-    AnimatedListPropertyTearOff* m_animatedProperty;
-    SVGPathSegRole m_pathSegRole;
-};
-
-}
-
-#endif // SVGListPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGProperty.h b/Source/core/svg/properties/SVGProperty.h
deleted file mode 100644
index ebb454c..0000000
--- a/Source/core/svg/properties/SVGProperty.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGProperty_h
-#define SVGProperty_h
-
-#include "wtf/RefCounted.h"
-
-namespace WebCore {
-
-enum SVGPropertyRole {
-    UndefinedRole,
-    BaseValRole,
-    AnimValRole
-};
-
-class SVGProperty : public RefCounted<SVGProperty> {
-public:
-    virtual ~SVGProperty() { }
-
-    virtual void commitChange() = 0;
-};
-
-}
-
-#endif // SVGProperty_h
diff --git a/Source/core/svg/properties/SVGPropertyInfo.h b/Source/core/svg/properties/SVGPropertyInfo.h
index 598bc39..46cf3ad 100644
--- a/Source/core/svg/properties/SVGPropertyInfo.h
+++ b/Source/core/svg/properties/SVGPropertyInfo.h
@@ -20,19 +20,8 @@
 #ifndef SVGPropertyInfo_h
 #define SVGPropertyInfo_h
 
-#include "core/dom/QualifiedName.h"
-#include "wtf/PassRefPtr.h"
-
 namespace WebCore {
 
-class SVGAnimatedProperty;
-class SVGElement;
-
-enum AnimatedPropertyState {
-    PropertyIsReadWrite,
-    PropertyIsReadOnly
-};
-
 enum AnimatedPropertyType {
     AnimatedAngle,
     AnimatedBoolean,
@@ -52,36 +41,11 @@
     AnimatedRect,
     AnimatedString,
     AnimatedStringList,
+    AnimatedTransform,
     AnimatedTransformList,
     AnimatedUnknown
 };
 
-struct SVGPropertyInfo {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    typedef void (*SynchronizeProperty)(SVGElement*);
-    typedef PassRefPtr<SVGAnimatedProperty> (*LookupOrCreateWrapperForAnimatedProperty)(SVGElement*);
-
-    SVGPropertyInfo(AnimatedPropertyType newType, AnimatedPropertyState newState, const QualifiedName& newAttributeName,
-                    const AtomicString& newPropertyIdentifier, SynchronizeProperty newSynchronizeProperty,
-                    LookupOrCreateWrapperForAnimatedProperty newLookupOrCreateWrapperForAnimatedProperty)
-        : animatedPropertyType(newType)
-        , animatedPropertyState(newState)
-        , attributeName(newAttributeName)
-        , propertyIdentifier(newPropertyIdentifier)
-        , synchronizeProperty(newSynchronizeProperty)
-        , lookupOrCreateWrapperForAnimatedProperty(newLookupOrCreateWrapperForAnimatedProperty)
-    {
-    }
-
-    AnimatedPropertyType animatedPropertyType;
-    AnimatedPropertyState animatedPropertyState;
-    const QualifiedName& attributeName;
-    const AtomicString& propertyIdentifier;
-    SynchronizeProperty synchronizeProperty;
-    LookupOrCreateWrapperForAnimatedProperty lookupOrCreateWrapperForAnimatedProperty;
-};
-
 }
 
 #endif // SVGPropertyInfo_h
diff --git a/Source/core/svg/properties/SVGPropertyTearOff.h b/Source/core/svg/properties/SVGPropertyTearOff.h
deleted file mode 100644
index 8d5609a..0000000
--- a/Source/core/svg/properties/SVGPropertyTearOff.h
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGPropertyTearOff_h
-#define SVGPropertyTearOff_h
-
-#include "core/svg/SVGElement.h"
-#include "core/svg/properties/SVGAnimatedProperty.h"
-#include "core/svg/properties/SVGProperty.h"
-#include "wtf/WeakPtr.h"
-
-namespace WebCore {
-
-class SVGTransform;
-
-class SVGPropertyTearOffBase : public SVGProperty {
-public:
-    virtual void setValueForMatrixIfNeeded(SVGTransform*) { }
-
-    virtual void detachWrapper() = 0;
-};
-
-template<typename PropertyType>
-class SVGPropertyTearOff : public SVGPropertyTearOffBase {
-public:
-    typedef SVGPropertyTearOff<PropertyType> Self;
-
-    // Used for child types (baseVal/animVal) of a SVGAnimated* property (for example: SVGAnimatedLength::baseVal()).
-    // Also used for list tear offs (for example: text.x.baseVal.getItem(0)).
-    static PassRefPtr<Self> create(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, PropertyType& value)
-    {
-        ASSERT(animatedProperty);
-        return adoptRef(new Self(animatedProperty, role, value));
-    }
-
-    // Used for non-animated POD types (for example: SVGSVGElement::createSVGLength()).
-    static PassRefPtr<Self> create(const PropertyType& initialValue)
-    {
-        return adoptRef(new Self(initialValue));
-    }
-
-    PropertyType& propertyReference() { return *m_value; }
-    SVGAnimatedProperty* animatedProperty() const { return m_animatedProperty; }
-
-    void setValue(PropertyType& value)
-    {
-        if (m_valueIsCopy) {
-            detachChildren();
-            delete m_value;
-        }
-
-        updateChildrenTearOffs(&value);
-
-        m_valueIsCopy = false;
-        m_value = &value;
-    }
-
-    void setAnimatedProperty(SVGAnimatedProperty* animatedProperty)
-    {
-        m_animatedProperty = animatedProperty;
-
-        if (m_animatedProperty)
-            m_contextElement = m_animatedProperty->contextElement();
-    }
-
-    SVGElement* contextElement() const
-    {
-        if (!m_animatedProperty || m_valueIsCopy)
-            return 0;
-        ASSERT(m_contextElement);
-        return m_contextElement;
-    }
-
-    void addChild(WeakPtr<SVGPropertyTearOffBase> child)
-    {
-        m_childTearOffs.append(child);
-    }
-
-    virtual void detachWrapper() OVERRIDE
-    {
-        if (m_valueIsCopy)
-            return;
-
-        detachChildren();
-
-        // Switch from a live value, to a non-live value.
-        // For example: <text x="50"/>
-        // var item = text.x.baseVal.getItem(0);
-        // text.setAttribute("x", "100");
-        // item.value still has to report '50' and it has to be possible to modify 'item'
-        // w/o changing the "new item" (with x=100) in the text element.
-        // Whenever the XML DOM modifies the "x" attribute, all existing wrappers are detached, using this function.
-        m_value = new PropertyType(*m_value);
-        m_valueIsCopy = true;
-        m_animatedProperty = 0;
-    }
-
-    virtual void commitChange()
-    {
-        if (!m_animatedProperty || m_valueIsCopy)
-            return;
-        m_animatedProperty->commitChange();
-    }
-
-    bool isReadOnly() const
-    {
-        if (m_role == AnimValRole)
-            return true;
-        if (m_animatedProperty && m_animatedProperty->isReadOnly())
-            return true;
-        return false;
-    }
-
-protected:
-    SVGPropertyTearOff(SVGAnimatedProperty* animatedProperty, SVGPropertyRole role, PropertyType& value)
-        : m_animatedProperty(animatedProperty)
-        , m_role(role)
-        , m_value(&value)
-        , m_valueIsCopy(false)
-    {
-        // Using operator & is completely fine, as SVGAnimatedProperty owns this reference,
-        // and we're guaranteed to live as long as SVGAnimatedProperty does.
-
-        if (m_animatedProperty)
-            m_contextElement = m_animatedProperty->contextElement();
-    }
-
-    SVGPropertyTearOff(const PropertyType& initialValue)
-        : m_animatedProperty(0)
-        , m_role(UndefinedRole)
-        , m_value(new PropertyType(initialValue))
-        , m_valueIsCopy(true)
-    {
-    }
-
-    virtual ~SVGPropertyTearOff()
-    {
-        if (m_valueIsCopy)
-            delete m_value;
-    }
-
-    void detachChildren()
-    {
-        for (Vector<WeakPtr<SVGPropertyTearOffBase> >::iterator iter = m_childTearOffs.begin(); iter != m_childTearOffs.end(); iter++) {
-            if (iter->get())
-                iter->get()->detachWrapper();
-        }
-        m_childTearOffs.clear();
-    }
-
-    // Update m_value of children tear-offs.
-    // Currently only SVGTransform has child tear-offs.
-    void updateChildrenTearOffs(SVGTransform* transform)
-    {
-        for (Vector<WeakPtr<SVGPropertyTearOffBase> >::iterator iter = m_childTearOffs.begin(); iter != m_childTearOffs.end(); iter++) {
-            if (iter->get())
-                iter->get()->setValueForMatrixIfNeeded(transform);
-        }
-    }
-
-    void updateChildrenTearOffs(void*)
-    {
-        // Tear-offs for other types do not have child tear-offs.
-    }
-
-    SVGElement* m_contextElement;
-    SVGAnimatedProperty* m_animatedProperty;
-    SVGPropertyRole m_role;
-    PropertyType* m_value;
-    Vector<WeakPtr<SVGPropertyTearOffBase> > m_childTearOffs;
-    bool m_valueIsCopy : 1;
-};
-
-}
-
-#endif // SVGPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGPropertyTraits.h b/Source/core/svg/properties/SVGPropertyTraits.h
deleted file mode 100644
index a905f8a..0000000
--- a/Source/core/svg/properties/SVGPropertyTraits.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2004, 2005, 2006, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGPropertyTraits_h
-#define SVGPropertyTraits_h
-
-#include "wtf/text/WTFString.h"
-
-namespace WebCore {
-
-template<typename PropertyType>
-struct SVGPropertyTraits { };
-
-template<>
-struct SVGPropertyTraits<bool> {
-    static bool initialValue() { return false; }
-    static String toString(bool type) { return type ? "true" : "false"; }
-};
-
-template<>
-struct SVGPropertyTraits<unsigned> {
-    static unsigned initialValue() { return 0; }
-    static String toString(unsigned type) { return String::number(type); }
-};
-
-template<>
-struct SVGPropertyTraits<int> {
-    static int initialValue() { return 0; }
-    static String toString(int type) { return String::number(type); }
-};
-
-template<>
-struct SVGPropertyTraits<float> {
-    static float initialValue() { return 0; }
-    static String toString(float type) { return String::number(type); }
-};
-
-template<>
-struct SVGPropertyTraits<String> {
-    static String initialValue() { return String(); }
-    static String toString(const String& type) { return type; }
-};
-
-}
-
-#endif
diff --git a/Source/core/svg/properties/SVGStaticListPropertyTearOff.h b/Source/core/svg/properties/SVGStaticListPropertyTearOff.h
deleted file mode 100644
index aee312d..0000000
--- a/Source/core/svg/properties/SVGStaticListPropertyTearOff.h
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGStaticListPropertyTearOff_h
-#define SVGStaticListPropertyTearOff_h
-
-#include "core/svg/properties/SVGListProperty.h"
-
-namespace WebCore {
-
-class ExceptionState;
-
-template<typename PropertyType>
-class SVGStaticListPropertyTearOff : public SVGListProperty<PropertyType> {
-public:
-    typedef SVGListProperty<PropertyType> Base;
-
-    typedef typename SVGPropertyTraits<PropertyType>::ListItemType ListItemType;
-    typedef SVGPropertyTearOff<ListItemType> ListItemTearOff;
-
-    using Base::m_role;
-    using Base::m_values;
-
-    static PassRefPtr<SVGStaticListPropertyTearOff<PropertyType> > create(SVGElement* contextElement, PropertyType& values)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new SVGStaticListPropertyTearOff<PropertyType>(contextElement, values));
-    }
-
-    SVGElement* contextElement() const { return m_contextElement; }
-
-    // SVGList API
-    void clear(ExceptionState& exceptionState)
-    {
-        Base::clearValues(exceptionState);
-    }
-
-    ListItemType initialize(const ListItemType& newItem, ExceptionState& exceptionState)
-    {
-        return Base::initializeValues(newItem, exceptionState);
-    }
-
-    ListItemType getItem(unsigned index, ExceptionState& exceptionState)
-    {
-        return Base::getItemValues(index, exceptionState);
-    }
-
-    ListItemType insertItemBefore(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
-    {
-        return Base::insertItemBeforeValues(newItem, index, exceptionState);
-    }
-
-    ListItemType replaceItem(const ListItemType& newItem, unsigned index, ExceptionState& exceptionState)
-    {
-        return Base::replaceItemValues(newItem, index, exceptionState);
-    }
-
-    ListItemType removeItem(unsigned index, ExceptionState& exceptionState)
-    {
-        return Base::removeItemValues(index, exceptionState);
-    }
-
-    ListItemType appendItem(const ListItemType& newItem, ExceptionState& exceptionState)
-    {
-        return Base::appendItemValues(newItem, exceptionState);
-    }
-
-private:
-    SVGStaticListPropertyTearOff(SVGElement* contextElement, PropertyType& values)
-        : SVGListProperty<PropertyType>(UndefinedRole, values, 0)
-        , m_contextElement(contextElement)
-    {
-        m_contextElement->setContextElement();
-    }
-
-    virtual void commitChange()
-    {
-        ASSERT(m_values);
-        ASSERT(m_contextElement);
-        m_values->commitChange(m_contextElement);
-    }
-
-    virtual bool processIncomingListItemValue(const ListItemType&, unsigned*)
-    {
-        // no-op for static lists
-        return true;
-    }
-
-    virtual bool processIncomingListItemWrapper(RefPtr<ListItemTearOff>&, unsigned*)
-    {
-        ASSERT_NOT_REACHED();
-        return true;
-    }
-
-private:
-    SVGElement* m_contextElement;
-};
-
-}
-
-#endif // SVGStaticListPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGStaticPropertyTearOff.h b/Source/core/svg/properties/SVGStaticPropertyTearOff.h
deleted file mode 100644
index bc6bddd..0000000
--- a/Source/core/svg/properties/SVGStaticPropertyTearOff.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGStaticPropertyTearOff_h
-#define SVGStaticPropertyTearOff_h
-
-#include "core/svg/properties/SVGPropertyTearOff.h"
-
-namespace WebCore {
-
-#if COMPILER(MSVC)
-// UpdateMethod is 12 bytes. We have to pack to a size greater than or equal to that to avoid an
-// alignment warning (C4121). 16 is the next-largest size allowed for packing, so we use that.
-#pragma pack(push, 16)
-#endif
-template<typename ContextElement, typename PropertyType>
-class SVGStaticPropertyTearOff FINAL : public SVGPropertyTearOff<PropertyType> {
-public:
-    typedef SVGStaticPropertyTearOff<ContextElement, PropertyType> Self;
-    typedef void (ContextElement::*UpdateMethod)();
-
-    // Used for non-animated POD types that are not associated with a SVGAnimatedProperty object, nor with a XML DOM attribute
-    // (for example: SVGSVGElement::currentTranslate).
-    static PassRefPtr<Self> create(ContextElement* contextElement, PropertyType& value, UpdateMethod update)
-    {
-        ASSERT(contextElement);
-        return adoptRef(new Self(contextElement, value, update));
-    }
-
-    virtual void commitChange() OVERRIDE { (m_contextElement.get()->*m_update)(); }
-
-private:
-    SVGStaticPropertyTearOff(ContextElement* contextElement, PropertyType& value, UpdateMethod update)
-        : SVGPropertyTearOff<PropertyType>(0, UndefinedRole, value)
-        , m_update(update)
-        , m_contextElement(contextElement)
-    {
-        m_contextElement->setContextElement();
-    }
-
-    UpdateMethod m_update;
-    RefPtr<ContextElement> m_contextElement;
-};
-#if COMPILER(MSVC)
-#pragma pack(pop)
-#endif
-
-}
-
-#endif // SVGStaticPropertyTearOff_h
diff --git a/Source/core/svg/properties/SVGTransformListPropertyTearOff.h b/Source/core/svg/properties/SVGTransformListPropertyTearOff.h
deleted file mode 100644
index 3b7d6da..0000000
--- a/Source/core/svg/properties/SVGTransformListPropertyTearOff.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#ifndef SVGTransformListPropertyTearOff_h
-#define SVGTransformListPropertyTearOff_h
-
-#include "bindings/v8/ExceptionState.h"
-#include "core/dom/ExceptionCode.h"
-#include "core/svg/SVGTransformList.h"
-#include "core/svg/properties/SVGListPropertyTearOff.h"
-
-namespace WebCore {
-
-// SVGTransformList contains two additional methods, that can be exposed to the bindings.
-class SVGTransformListPropertyTearOff : public SVGListPropertyTearOff<SVGTransformList> {
-public:
-    typedef SVGAnimatedListPropertyTearOff<SVGTransformList> AnimatedListPropertyTearOff;
-    typedef SVGAnimatedListPropertyTearOff<SVGTransformList>::ListWrapperCache ListWrapperCache;
-
-    static PassRefPtr<SVGListPropertyTearOff<SVGTransformList> > create(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGTransformList& values, ListWrapperCache& wrappers)
-    {
-        ASSERT(animatedProperty);
-        return adoptRef(new SVGTransformListPropertyTearOff(animatedProperty, role, values, wrappers));
-    }
-
-    PassRefPtr<SVGPropertyTearOff<SVGTransform> > createSVGTransformFromMatrix(SVGPropertyTearOff<SVGMatrix>* matrix)
-    {
-        ASSERT(m_values);
-        return SVGPropertyTearOff<SVGTransform>::create(m_values->createSVGTransformFromMatrix(matrix->propertyReference()));
-    }
-
-    PassRefPtr<SVGPropertyTearOff<SVGTransform> > consolidate(ExceptionState& exceptionState)
-    {
-        ASSERT(m_values);
-        ASSERT(m_wrappers);
-        if (!canAlterList(exceptionState))
-            return 0;
-
-        ASSERT(m_values->size() == m_wrappers->size());
-
-        // Spec: If the list was empty, then a value of null is returned.
-        if (m_values->isEmpty())
-            return 0;
-
-        detachListWrappers(0);
-        RefPtr<SVGPropertyTearOff<SVGTransform> > wrapper = SVGPropertyTearOff<SVGTransform>::create(m_values->consolidate());
-        m_wrappers->append(wrapper);
-
-        ASSERT(m_values->size() == m_wrappers->size());
-        return wrapper.release();
-    }
-
-private:
-    SVGTransformListPropertyTearOff(AnimatedListPropertyTearOff* animatedProperty, SVGPropertyRole role, SVGTransformList& values, ListWrapperCache& wrappers)
-        : SVGListPropertyTearOff<SVGTransformList>(animatedProperty, role, values, wrappers)
-    {
-    }
-};
-
-}
-
-#endif // SVGListPropertyTearOff_h
diff --git a/Source/core/testing/DummyPageHolder.cpp b/Source/core/testing/DummyPageHolder.cpp
index 424e07d..e7e3989 100644
--- a/Source/core/testing/DummyPageHolder.cpp
+++ b/Source/core/testing/DummyPageHolder.cpp
@@ -32,8 +32,8 @@
 #include "core/testing/DummyPageHolder.h"
 
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
 #include "wtf/Assertions.h"
 
 namespace WebCore {
@@ -54,7 +54,7 @@
 
     m_page = adoptPtr(new Page(m_pageClients));
 
-    m_frame = Frame::create(FrameInit::create(0, &m_page->frameHost(), &m_frameLoaderClient));
+    m_frame = LocalFrame::create(&m_frameLoaderClient, &m_page->frameHost(), 0);
     m_frame->setView(FrameView::create(m_frame.get(), initialViewSize));
     m_frame->init();
 }
@@ -71,7 +71,7 @@
     return *m_page;
 }
 
-Frame& DummyPageHolder::frame() const
+LocalFrame& DummyPageHolder::frame() const
 {
     return *m_frame;
 }
diff --git a/Source/core/testing/DummyPageHolder.h b/Source/core/testing/DummyPageHolder.h
index d80f4dc..ab09c2f 100644
--- a/Source/core/testing/DummyPageHolder.h
+++ b/Source/core/testing/DummyPageHolder.h
@@ -42,18 +42,18 @@
 namespace WebCore {
 
 class Document;
-class Frame;
+class LocalFrame;
 class FrameView;
 class IntSize;
 
-// Creates a dummy Page, Frame, and FrameView whose clients are all no-op.
+// Creates a dummy Page, LocalFrame, and FrameView whose clients are all no-op.
 //
 // This class can be used when you write unit tests for components which do not work correctly without renderers.
 // To make sure the renderers are created, you need to call |frameView().layout()| after you add nodes into
 // |document()|.
 //
-// Since DummyPageHolder stores empty clients in it, it must outlive the Page, Frame, FrameView and any other objects
-// created by it. DummyPageHolder's destructor ensures this condition by checking remaining references to the Frame.
+// Since DummyPageHolder stores empty clients in it, it must outlive the Page, LocalFrame, FrameView and any other objects
+// created by it. DummyPageHolder's destructor ensures this condition by checking remaining references to the LocalFrame.
 
 class DummyPageHolder {
     WTF_MAKE_NONCOPYABLE(DummyPageHolder);
@@ -63,7 +63,7 @@
     ~DummyPageHolder();
 
     Page& page() const;
-    Frame& frame() const;
+    LocalFrame& frame() const;
     FrameView& frameView() const;
     Document& document() const;
 
@@ -71,7 +71,7 @@
     explicit DummyPageHolder(const IntSize& initialViewSize);
 
     OwnPtr<Page> m_page;
-    RefPtr<Frame> m_frame;
+    RefPtr<LocalFrame> m_frame;
 
     Page::PageClients m_pageClients;
     EmptyChromeClient m_chromeClient;
diff --git a/Source/core/testing/GCObservation.h b/Source/core/testing/GCObservation.h
index 469656a..093bdbf 100644
--- a/Source/core/testing/GCObservation.h
+++ b/Source/core/testing/GCObservation.h
@@ -32,15 +32,19 @@
 #define GCObservation_h
 
 #include "bindings/v8/ScopedPersistent.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include <v8.h>
 
 namespace WebCore {
 
-class GCObservation : public RefCounted<GCObservation> {
+class GCObservation : public RefCountedWillBeGarbageCollectedFinalized<GCObservation> {
 public:
-    static PassRefPtr<GCObservation> create(v8::Handle<v8::Value> observedValue) { return adoptRef(new GCObservation(observedValue)); }
+    static PassRefPtrWillBeRawPtr<GCObservation> create(v8::Handle<v8::Value> observedValue)
+    {
+        return adoptRefWillBeNoop(new GCObservation(observedValue));
+    }
     ~GCObservation() { }
 
     // Caution: It is only feasible to determine whether an object was
@@ -50,6 +54,8 @@
     bool wasCollected() const { return m_collected; }
     void setWasCollected();
 
+    void trace(Visitor*) { }
+
 private:
     explicit GCObservation(v8::Handle<v8::Value>);
 
diff --git a/Source/core/testing/GCObservation.idl b/Source/core/testing/GCObservation.idl
index aaed5c2..feb1069 100644
--- a/Source/core/testing/GCObservation.idl
+++ b/Source/core/testing/GCObservation.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface GCObservation {
     // Technically, this is true if the object was "near death"; the
diff --git a/Source/core/testing/InspectorFrontendClientLocal.h b/Source/core/testing/InspectorFrontendClientLocal.h
index 4fa3580..bd789fe 100644
--- a/Source/core/testing/InspectorFrontendClientLocal.h
+++ b/Source/core/testing/InspectorFrontendClientLocal.h
@@ -38,7 +38,7 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class InspectorController;
 class InspectorBackendMessageQueue;
 class InspectorFrontendHost;
diff --git a/Source/core/testing/InternalProfilers.h b/Source/core/testing/InternalProfilers.h
index f948cff..d90c777 100644
--- a/Source/core/testing/InternalProfilers.h
+++ b/Source/core/testing/InternalProfilers.h
@@ -31,22 +31,26 @@
 #ifndef InternalProfilers_h
 #define InternalProfilers_h
 
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-
-
-class InternalProfilers : public RefCounted<InternalProfilers> {
+class InternalProfilers : public RefCountedWillBeGarbageCollected<InternalProfilers> {
 public:
-    static PassRefPtr<InternalProfilers> create() { return adoptRef(new InternalProfilers()); }
+    static PassRefPtrWillBeRawPtr<InternalProfilers> create()
+    {
+        return adoptRefWillBeNoop(new InternalProfilers());
+    }
 
     void startHeapProfiling(const String& prefix);
     void stopHeapProfiling();
     void dumpHeapProfiling(const String& reason);
     String getHeapProfile();
+
+    void trace(Visitor*) { }
 };
 
 } // namespace WebCore
diff --git a/Source/core/testing/InternalProfilers.idl b/Source/core/testing/InternalProfilers.idl
index 5ad4863..f8c93f4 100644
--- a/Source/core/testing/InternalProfilers.idl
+++ b/Source/core/testing/InternalProfilers.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface InternalProfilers {
     void startHeapProfiling(DOMString prefix);
diff --git a/Source/core/testing/InternalSettings.cpp b/Source/core/testing/InternalSettings.cpp
index 12b3953..0d9dbef 100644
--- a/Source/core/testing/InternalSettings.cpp
+++ b/Source/core/testing/InternalSettings.cpp
@@ -113,7 +113,7 @@
 // Instead, we manually make InternalSettings supplement Page.
 class InternalSettingsWrapper : public Supplement<Page> {
 public:
-    explicit InternalSettingsWrapper(Page* page)
+    explicit InternalSettingsWrapper(Page& page)
         : m_internalSettings(InternalSettings::create(page)) { }
     virtual ~InternalSettingsWrapper() { m_internalSettings->hostDestroyed(); }
 #if !ASSERT_DISABLED
@@ -122,7 +122,7 @@
     InternalSettings* internalSettings() const { return m_internalSettings.get(); }
 
 private:
-    RefPtr<InternalSettings> m_internalSettings;
+    RefPtrWillBePersistent<InternalSettings> m_internalSettings;
 };
 
 const char* InternalSettings::supplementName()
@@ -130,7 +130,7 @@
     return "InternalSettings";
 }
 
-InternalSettings* InternalSettings::from(Page* page)
+InternalSettings* InternalSettings::from(Page& page)
 {
     if (!Supplement<Page>::from(page, supplementName()))
         Supplement<Page>::provideTo(page, supplementName(), adoptPtr(new InternalSettingsWrapper(page)));
@@ -141,10 +141,10 @@
 {
 }
 
-InternalSettings::InternalSettings(Page* page)
-    : InternalSettingsGenerated(page)
-    , m_page(page)
-    , m_backup(&page->settings())
+InternalSettings::InternalSettings(Page& page)
+    : InternalSettingsGenerated(&page)
+    , m_page(&page)
+    , m_backup(&page.settings())
 {
 }
 
diff --git a/Source/core/testing/InternalSettings.h b/Source/core/testing/InternalSettings.h
index 587d44d..005ffb8 100644
--- a/Source/core/testing/InternalSettings.h
+++ b/Source/core/testing/InternalSettings.h
@@ -29,6 +29,7 @@
 
 #include "InternalSettingsGenerated.h"
 #include "core/editing/EditingBehaviorTypes.h"
+#include "heap/Handle.h"
 #include "platform/geometry/IntSize.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -38,7 +39,7 @@
 
 class Document;
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class Page;
 class Settings;
 
@@ -72,11 +73,11 @@
         bool m_originalPasswordGenerationDecorationEnabled;
     };
 
-    static PassRefPtr<InternalSettings> create(Page* page)
+    static PassRefPtrWillBeRawPtr<InternalSettings> create(Page& page)
     {
-        return adoptRef(new InternalSettings(page));
+        return adoptRefWillBeNoop(new InternalSettings(page));
     }
-    static InternalSettings* from(Page*);
+    static InternalSettings* from(Page&);
     void hostDestroyed() { m_page = 0; }
 
     virtual ~InternalSettings();
@@ -121,8 +122,10 @@
     void setStyleScopedEnabled(bool);
     void setExperimentalContentSecurityPolicyFeaturesEnabled(bool);
 
+    virtual void trace(Visitor* visitor) OVERRIDE { InternalSettingsGenerated::trace(visitor); }
+
 private:
-    explicit InternalSettings(Page*);
+    explicit InternalSettings(Page&);
 
     Settings* settings() const;
     Page* page() const { return m_page; }
diff --git a/Source/core/testing/InternalSettings.idl b/Source/core/testing/InternalSettings.idl
index 69686ce..7ae46cc 100644
--- a/Source/core/testing/InternalSettings.idl
+++ b/Source/core/testing/InternalSettings.idl
@@ -24,6 +24,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface InternalSettings : InternalSettingsGenerated {
     // All methods which access Page::settings() can raise an exception
diff --git a/Source/core/testing/Internals.cpp b/Source/core/testing/Internals.cpp
index 6061954..35e8ee2 100644
--- a/Source/core/testing/Internals.cpp
+++ b/Source/core/testing/Internals.cpp
@@ -28,7 +28,6 @@
 #include "Internals.h"
 
 #include <v8.h>
-#include "HTMLNames.h"
 #include "InspectorFrontendClientLocal.h"
 #include "InternalProfilers.h"
 #include "InternalRuntimeFlags.h"
@@ -39,6 +38,7 @@
 #include "MockPagePopupDriver.h"
 #include "RuntimeEnabledFeatures.h"
 #include "TypeConversions.h"
+#include "bindings/v8/ExceptionMessages.h"
 #include "bindings/v8/ExceptionState.h"
 #include "bindings/v8/ScriptFunction.h"
 #include "bindings/v8/ScriptPromise.h"
@@ -73,18 +73,24 @@
 #include "core/editing/PlainTextRange.h"
 #include "core/editing/SpellCheckRequester.h"
 #include "core/editing/SpellChecker.h"
+#include "core/editing/SurroundingText.h"
 #include "core/editing/TextIterator.h"
 #include "core/fetch/MemoryCache.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/frame/DOMPoint.h"
-#include "core/frame/Frame.h"
+#include "core/frame/DOMWindow.h"
+#include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/Settings.h"
+#include "core/html/HTMLContentElement.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLMediaElement.h"
 #include "core/html/HTMLSelectElement.h"
 #include "core/html/HTMLTextAreaElement.h"
 #include "core/html/forms/FormController.h"
-#include "core/html/shadow/HTMLContentElement.h"
+#include "core/html/shadow/ShadowElementNames.h"
+#include "core/html/shadow/TextControlInnerElements.h"
 #include "core/inspector/InspectorClient.h"
 #include "core/inspector/InspectorConsoleAgent.h"
 #include "core/inspector/InspectorController.h"
@@ -97,20 +103,17 @@
 #include "core/loader/HistoryItem.h"
 #include "core/page/Chrome.h"
 #include "core/page/ChromeClient.h"
-#include "core/frame/DOMWindow.h"
 #include "core/page/EventHandler.h"
-#include "core/frame/FrameView.h"
 #include "core/page/Page.h"
 #include "core/page/PagePopupController.h"
 #include "core/page/PrintContext.h"
-#include "core/frame/Settings.h"
-#include "core/rendering/CompositedLayerMapping.h"
 #include "core/rendering/RenderLayer.h"
-#include "core/rendering/RenderLayerCompositor.h"
 #include "core/rendering/RenderMenuList.h"
 #include "core/rendering/RenderObject.h"
 #include "core/rendering/RenderTreeAsText.h"
 #include "core/rendering/RenderView.h"
+#include "core/rendering/compositing/CompositedLayerMapping.h"
+#include "core/rendering/compositing/RenderLayerCompositor.h"
 #include "core/testing/GCObservation.h"
 #include "core/workers/WorkerThread.h"
 #include "platform/ColorChooser.h"
@@ -134,6 +137,7 @@
 
 namespace WebCore {
 
+// FIXME: oilpan: These will be removed soon.
 static MockPagePopupDriver* s_pagePopupDriver = 0;
 
 using namespace HTMLNames;
@@ -142,7 +146,8 @@
 public:
     explicit InspectorFrontendChannelDummy(Page*);
     virtual ~InspectorFrontendChannelDummy() { }
-    virtual bool sendMessageToFrontend(const String& message) OVERRIDE;
+    virtual void sendMessageToFrontend(PassRefPtr<JSONObject> message) OVERRIDE;
+    virtual void flush() OVERRIDE { }
 
 private:
     Page* m_frontendPage;
@@ -153,9 +158,9 @@
 {
 }
 
-bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
+void InspectorFrontendChannelDummy::sendMessageToFrontend(PassRefPtr<JSONObject> message)
 {
-    return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
+    InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message->toJSONString());
 }
 
 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
@@ -183,9 +188,9 @@
 
 const char* Internals::internalsId = "internals";
 
-PassRefPtr<Internals> Internals::create(Document* document)
+PassRefPtrWillBeRawPtr<Internals> Internals::create(Document* document)
 {
-    return adoptRef(new Internals(document));
+    return adoptRefWillBeNoop(new Internals(document));
 }
 
 Internals::~Internals()
@@ -226,7 +231,7 @@
     return toDocument(executionContext());
 }
 
-Frame* Internals::frame() const
+LocalFrame* Internals::frame() const
 {
     if (!contextDocument())
         return 0;
@@ -241,7 +246,7 @@
     Page* page = document->page();
     if (!page)
         return 0;
-    return InternalSettings::from(page);
+    return InternalSettings::from(*page);
 }
 
 InternalRuntimeFlags* Internals::runtimeFlags() const
@@ -269,13 +274,13 @@
     return String(buf);
 }
 
-PassRefPtr<GCObservation> Internals::observeGC(ScriptValue scriptValue)
+PassRefPtrWillBeRawPtr<GCObservation> Internals::observeGC(ScriptValue scriptValue)
 {
     v8::Handle<v8::Value> observedValue = scriptValue.v8Value();
     ASSERT(!observedValue.IsEmpty());
     if (observedValue->IsNull() || observedValue->IsUndefined()) {
         V8ThrowException::throwTypeError("value to observe is null or undefined", v8::Isolate::GetCurrent());
-        return 0;
+        return nullptr;
     }
 
     return GCObservation::create(observedValue);
@@ -296,7 +301,7 @@
 
 unsigned Internals::needsLayoutCount(ExceptionState& exceptionState) const
 {
-    Frame* contextFrame = frame();
+    LocalFrame* contextFrame = frame();
     if (!contextFrame) {
         exceptionState.throwDOMException(InvalidAccessError, "No context frame is available.");
         return 0;
@@ -360,7 +365,7 @@
 bool Internals::isSharingStyle(Element* element1, Element* element2, ExceptionState& exceptionState) const
 {
     if (!element1 || !element2) {
-        exceptionState.throwDOMException(InvalidAccessError, String::format("The %s element provided is invalid.", element1 ? "second" : "first"));
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(element1 ? 2 : 1, "Element"));
         return false;
     }
     return element1->renderStyle() == element2->renderStyle();
@@ -373,13 +378,13 @@
         return false;
     }
 
-    return insertionPoint->hasTagName(contentTag) && toHTMLContentElement(insertionPoint)->isSelectValid();
+    return isHTMLContentElement(*insertionPoint) && toHTMLContentElement(*insertionPoint).isSelectValid();
 }
 
 Node* Internals::treeScopeRootNode(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
 
@@ -389,7 +394,7 @@
 Node* Internals::parentTreeScope(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
     const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
@@ -456,7 +461,7 @@
 unsigned short Internals::compareTreeScopePosition(const Node* node1, const Node* node2, ExceptionState& exceptionState) const
 {
     if (!node1 || !node2) {
-        exceptionState.throwDOMException(InvalidAccessError, String::format("The %s node provided is invalid.", node1 ? "second" : "first"));
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(node1 ? 2 : 1, "Node"));
         return 0;
     }
     const TreeScope* treeScope1 = node1->isDocumentNode() ? static_cast<const TreeScope*>(toDocument(node1)) :
@@ -472,23 +477,21 @@
 
 unsigned Internals::numberOfActiveAnimations() const
 {
-    Frame* contextFrame = frame();
+    LocalFrame* contextFrame = frame();
     Document* document = contextFrame->document();
-    return document->timeline()->numberOfActiveAnimationsForTesting() + document->transitionTimeline()->numberOfActiveAnimationsForTesting();
+    return document->timeline().numberOfActiveAnimationsForTesting() + document->transitionTimeline().numberOfActiveAnimationsForTesting();
 }
 
 void Internals::pauseAnimations(double pauseTime, ExceptionState& exceptionState)
 {
     if (pauseTime < 0) {
-        exceptionState.throwDOMException(InvalidAccessError, "The pauseTime provided is negative.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("pauseTime", pauseTime, 0.0));
         return;
     }
 
-    // https://code.google.com/p/chromium/issues/detail?id=343760
-    DisableCompositingQueryAsserts disabler;
-
-    frame()->document()->timeline()->pauseAnimationsForTesting(pauseTime);
-    frame()->document()->transitionTimeline()->pauseAnimationsForTesting(pauseTime);
+    frame()->view()->updateLayoutAndStyleForPainting();
+    frame()->document()->timeline().pauseAnimationsForTesting(pauseTime);
+    frame()->document()->transitionTimeline().pauseAnimationsForTesting(pauseTime);
 }
 
 bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionState& exceptionState) const
@@ -496,7 +499,7 @@
     if (root && root->isShadowRoot())
         return toShadowRoot(root)->containsShadowElements();
 
-    exceptionState.throwDOMException(InvalidAccessError, "The root node provided is invalid.");
+    exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
     return 0;
 }
 
@@ -505,14 +508,14 @@
     if (root && root->isShadowRoot())
         return toShadowRoot(root)->containsContentElements();
 
-    exceptionState.throwDOMException(InvalidAccessError, "The root node provided is invalid.");
+    exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
     return 0;
 }
 
 size_t Internals::countElementShadow(const Node* root, ExceptionState& exceptionState) const
 {
     if (!root || !root->isShadowRoot()) {
-        exceptionState.throwDOMException(InvalidAccessError, "The root node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
     return toShadowRoot(root)->childShadowRootCount();
@@ -521,7 +524,7 @@
 Node* Internals::nextSiblingByWalker(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
     ComposedTreeWalker walker(node);
@@ -532,7 +535,7 @@
 Node* Internals::firstChildByWalker(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
     ComposedTreeWalker walker(node);
@@ -543,7 +546,7 @@
 Node* Internals::lastChildByWalker(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
     ComposedTreeWalker walker(node);
@@ -554,7 +557,7 @@
 Node* Internals::nextNodeByWalker(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
     ComposedTreeWalker walker(node);
@@ -565,7 +568,7 @@
 Node* Internals::previousNodeByWalker(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
     ComposedTreeWalker walker(node);
@@ -576,7 +579,7 @@
 String Internals::elementRenderTreeAsText(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return String();
     }
 
@@ -594,15 +597,15 @@
     if (scope && (scope->isElementNode() || scope->isShadowRoot()))
         return scope->numberOfScopedHTMLStyleChildren();
 
-    exceptionState.throwDOMException(InvalidAccessError, "The scope provided is invalid.");
+    exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
     return 0;
 }
 
 PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionState& exceptionState) const
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
+        return nullptr;
     }
 
     bool allowVisitedStyle = true;
@@ -619,7 +622,7 @@
 ShadowRoot* Internals::youngestShadowRoot(Element* host, ExceptionState& exceptionState)
 {
     if (!host) {
-        exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return 0;
     }
 
@@ -631,7 +634,7 @@
 ShadowRoot* Internals::oldestShadowRoot(Element* host, ExceptionState& exceptionState)
 {
     if (!host) {
-        exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return 0;
     }
 
@@ -671,7 +674,7 @@
 const AtomicString& Internals::shadowPseudoId(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return nullAtom;
     }
 
@@ -681,7 +684,7 @@
 void Internals::setShadowPseudoId(Element* element, const AtomicString& id, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return;
     }
 
@@ -700,12 +703,13 @@
 
 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
 {
-    if (!element->hasTagName(inputTag))
+    ASSERT(element);
+    if (!isHTMLInputElement(*element))
         return;
     Color color;
     if (!color.setFromString(colorValue))
         return;
-    toHTMLInputElement(element)->selectColorInColorChooser(color);
+    toHTMLInputElement(*element).selectColorInColorChooser(color);
 }
 
 bool Internals::hasAutofocusRequest(Document* document)
@@ -755,7 +759,7 @@
     page->chrome().client().setPagePopupDriver(s_pagePopupDriver);
 }
 
-PassRefPtr<PagePopupController> Internals::pagePopupController()
+PassRefPtrWillBeRawPtr<PagePopupController> Internals::pagePopupController()
 {
     return s_pagePopupDriver ? s_pagePopupDriver->pagePopupController() : 0;
 }
@@ -785,7 +789,7 @@
 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return ClientRect::create();
     }
 
@@ -811,7 +815,7 @@
 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
 
@@ -821,19 +825,19 @@
         return 0;
     }
 
-    return node->document().markers()->markersFor(node, markerTypes).size();
+    return node->document().markers().markersFor(node, markerTypes).size();
 }
 
 unsigned Internals::activeMarkerCountForNode(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
 
     // Only TextMatch markers can be active.
     DocumentMarker::MarkerType markerType = DocumentMarker::TextMatch;
-    Vector<DocumentMarker*> markers = node->document().markers()->markersFor(node, markerType);
+    Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerType);
 
     unsigned activeMarkerCount = 0;
     for (Vector<DocumentMarker*>::iterator iter = markers.begin(); iter != markers.end(); ++iter) {
@@ -847,7 +851,7 @@
 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return 0;
     }
 
@@ -857,7 +861,7 @@
         return 0;
     }
 
-    Vector<DocumentMarker*> markers = node->document().markers()->markersFor(node, markerTypes);
+    Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
     if (markers.size() <= index)
         return 0;
     return markers[index];
@@ -867,7 +871,7 @@
 {
     DocumentMarker* marker = markerAt(node, markerType, index, exceptionState);
     if (!marker)
-        return 0;
+        return nullptr;
     return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
 }
 
@@ -882,17 +886,17 @@
 void Internals::addTextMatchMarker(const Range* range, bool isActive)
 {
     range->ownerDocument().updateLayoutIgnorePendingStylesheets();
-    range->ownerDocument().markers()->addTextMatchMarker(range, isActive);
+    range->ownerDocument().markers().addTextMatchMarker(range, isActive);
 }
 
 void Internals::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(InvalidAccessError, "The node provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
         return;
     }
 
-    node->document().markers()->setMarkersActive(node, startOffset, endOffset, active);
+    node->document().markers().setMarkersActive(node, startOffset, endOffset, active);
 }
 
 void Internals::setMarkedTextMatchesAreHighlighted(Document* document, bool highlight, ExceptionState&)
@@ -964,15 +968,15 @@
 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionState& exceptionState)
 {
     if (!textField) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return false;
     }
 
-    if (textField->hasTagName(inputTag))
-        return toHTMLInputElement(textField)->lastChangeWasUserEdit();
+    if (isHTMLInputElement(*textField))
+        return toHTMLInputElement(*textField).lastChangeWasUserEdit();
 
-    if (textField->hasTagName(textareaTag))
-        return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
+    if (isHTMLTextAreaElement(*textField))
+        return toHTMLTextAreaElement(*textField).lastChangeWasUserEdit();
 
     exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a TEXTAREA.");
     return false;
@@ -981,12 +985,12 @@
 bool Internals::elementShouldAutoComplete(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return false;
     }
 
-    if (element->hasTagName(inputTag))
-        return toHTMLInputElement(element)->shouldAutocomplete();
+    if (isHTMLInputElement(*element))
+        return toHTMLInputElement(*element).shouldAutocomplete();
 
     exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not an INPUT.");
     return false;
@@ -995,7 +999,7 @@
 String Internals::suggestedValue(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return String();
     }
 
@@ -1005,18 +1009,18 @@
     }
 
     String suggestedValue;
-    if (element->hasTagName(inputTag))
-        suggestedValue = toHTMLInputElement(element)->suggestedValue();
+    if (isHTMLInputElement(*element))
+        suggestedValue = toHTMLInputElement(*element).suggestedValue();
 
-    if (element->hasTagName(textareaTag))
-        suggestedValue = toHTMLTextAreaElement(element)->suggestedValue();
+    if (isHTMLTextAreaElement(*element))
+        suggestedValue = toHTMLTextAreaElement(*element).suggestedValue();
     return suggestedValue;
 }
 
 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return;
     }
 
@@ -1025,26 +1029,26 @@
         return;
     }
 
-    if (element->hasTagName(inputTag))
-        toHTMLInputElement(element)->setSuggestedValue(value);
+    if (isHTMLInputElement(*element))
+        toHTMLInputElement(*element).setSuggestedValue(value);
 
-    if (element->hasTagName(textareaTag))
-        toHTMLTextAreaElement(element)->setSuggestedValue(value);
+    if (isHTMLTextAreaElement(*element))
+        toHTMLTextAreaElement(*element).setSuggestedValue(value);
 }
 
 void Internals::setEditingValue(Element* element, const String& value, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return;
     }
 
-    if (!element->hasTagName(inputTag)) {
+    if (!isHTMLInputElement(*element)) {
         exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not an INPUT.");
         return;
     }
 
-    toHTMLInputElement(element)->setEditingValue(value);
+    toHTMLInputElement(*element).setEditingValue(value);
 }
 
 void Internals::setAutofilled(Element* element, bool enabled, ExceptionState& exceptionState)
@@ -1059,7 +1063,7 @@
 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionState& exceptionState)
 {
     if (!element || !element->document().view()) {
-        exceptionState.throwDOMException(InvalidNodeTypeError, element ? "No view can be obtained from the provided element's document." : "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidNodeTypeError, element ? "No view can be obtained from the provided element's document." : ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return;
     }
     FrameView* frameView = element->document().view();
@@ -1069,8 +1073,8 @@
 PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionState& exceptionState)
 {
     if (!scope) {
-        exceptionState.throwDOMException(InvalidAccessError, "The scope element provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+        return nullptr;
     }
 
     // TextIterator depends on Layout information, make sure layout it up to date.
@@ -1082,7 +1086,7 @@
 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
 {
     if (!scope || !range) {
-        exceptionState.throwDOMException(InvalidAccessError, scope ? "The Range provided is invalid." : "The scope element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(scope ? 2 : 1, scope ? "Range" : "Element"));
         return 0;
     }
 
@@ -1095,7 +1099,7 @@
 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
 {
     if (!scope || !range) {
-        exceptionState.throwDOMException(InvalidAccessError, scope ? "The Range provided is invalid." : "The scope element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(scope ? 2 : 1, scope ? "Range" : "Element"));
         return 0;
     }
 
@@ -1108,7 +1112,7 @@
 String Internals::rangeAsText(const Range* range, ExceptionState& exceptionState)
 {
     if (!range) {
-        exceptionState.throwDOMException(InvalidAccessError, "The Range provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Range"));
         return String();
     }
 
@@ -1119,7 +1123,7 @@
 {
     if (!document || !document->frame()) {
         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
-        return 0;
+        return nullptr;
     }
 
     document->updateLayout();
@@ -1134,7 +1138,7 @@
     if (foundNode)
         return DOMPoint::create(adjustedPoint.x(), adjustedPoint.y());
 
-    return 0;
+    return nullptr;
 }
 
 Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
@@ -1159,7 +1163,7 @@
 {
     if (!document || !document->frame()) {
         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
-        return 0;
+        return nullptr;
     }
 
     document->updateLayout();
@@ -1199,7 +1203,7 @@
 {
     if (!document || !document->frame()) {
         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
-        return 0;
+        return nullptr;
     }
 
     document->updateLayout();
@@ -1213,7 +1217,7 @@
     if (foundNode)
         return ClientRect::create(zoomableArea);
 
-    return 0;
+    return nullptr;
 }
 
 
@@ -1256,6 +1260,16 @@
     WebCore::overrideUserPreferredLanguages(atomicLanguages);
 }
 
+unsigned Internals::activeDOMObjectCount(Document* document, ExceptionState& exceptionState)
+{
+    if (!document) {
+        exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
+        return 0;
+    }
+
+    return document->activeDOMObjectCount();
+}
+
 unsigned Internals::wheelEventHandlerCount(Document* document, ExceptionState& exceptionState)
 {
     if (!document) {
@@ -1263,7 +1277,7 @@
         return 0;
     }
 
-    return WheelController::from(document)->wheelEventHandlerCount();
+    return WheelController::from(*document)->wheelEventHandlerCount();
 }
 
 unsigned Internals::touchEventHandlerCount(Document* document, ExceptionState& exceptionState)
@@ -1385,30 +1399,30 @@
         accumulateLayerRectList(compositor, graphicsLayer->children()[i], rects);
 }
 
-PassRefPtr<LayerRectList> Internals::touchEventTargetLayerRects(Document* document, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<LayerRectList> Internals::touchEventTargetLayerRects(Document* document, ExceptionState& exceptionState)
 {
     if (!document || !document->view() || !document->page() || document != contextDocument()) {
         exceptionState.throwDOMException(InvalidAccessError, "The document provided is invalid.");
-        return 0;
+        return nullptr;
     }
 
     // Do any pending layout and compositing update (which may call touchEventTargetRectsChange) to ensure this
     // really takes any previous changes into account.
     forceCompositingUpdate(document, exceptionState);
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     if (RenderView* view = document->renderView()) {
         if (RenderLayerCompositor* compositor = view->compositor()) {
             if (GraphicsLayer* rootLayer = compositor->rootGraphicsLayer()) {
-                RefPtr<LayerRectList> rects = LayerRectList::create();
+                RefPtrWillBeRawPtr<LayerRectList> rects = LayerRectList::create();
                 accumulateLayerRectList(compositor, rootLayer, rects.get());
                 return rects;
             }
         }
     }
 
-    return 0;
+    return nullptr;
 }
 
 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
@@ -1416,15 +1430,15 @@
 {
     if (!document || !document->frame() || !document->frame()->view()) {
         exceptionState.throwDOMException(InvalidAccessError, "No view can be obtained from the provided document.");
-        return 0;
+        return nullptr;
     }
 
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
     FrameView* frameView = document->view();
     RenderView* renderView = document->renderView();
 
     if (!renderView)
-        return 0;
+        return nullptr;
 
     float zoomFactor = frame->pageZoomFactor();
     LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
@@ -1441,7 +1455,7 @@
 
     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
     if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
-        return 0;
+        return nullptr;
 
     Vector<RefPtr<Node> > matches;
 
@@ -1604,11 +1618,11 @@
 unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionState&)
 {
     unsigned count = 0;
-    Frame* frame = document->frame();
+    LocalFrame* frame = document->frame();
     if (frame->view()->scrollableAreas())
         count += frame->view()->scrollableAreas()->size();
 
-    for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
+    for (LocalFrame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
         if (child->view() && child->view()->scrollableAreas())
             count += child->view()->scrollableAreas()->size();
     }
@@ -1633,14 +1647,15 @@
 
 String Internals::elementLayerTreeAsText(Element* element, ExceptionState& exceptionState) const
 {
+    DisableCompositingQueryAsserts disabler;
     return elementLayerTreeAsText(element, 0, exceptionState);
 }
 
 static PassRefPtr<NodeList> paintOrderList(Element* element, ExceptionState& exceptionState, RenderLayerStackingNode::PaintOrderListType type)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+        return nullptr;
     }
 
     element->document().updateLayout();
@@ -1648,13 +1663,13 @@
     RenderObject* renderer = element->renderer();
     if (!renderer || !renderer->isBox()) {
         exceptionState.throwDOMException(InvalidAccessError, renderer ? "The provided element's renderer is not a box." : "The provided element has no renderer.");
-        return 0;
+        return nullptr;
     }
 
     RenderLayer* layer = toRenderBox(renderer)->layer();
     if (!layer) {
         exceptionState.throwDOMException(InvalidAccessError, "No render layer can be obtained from the provided element.");
-        return 0;
+        return nullptr;
     }
 
     Vector<RefPtr<Node> > nodes;
@@ -1705,7 +1720,7 @@
 bool Internals::isUnclippedDescendant(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return 0;
     }
 
@@ -1729,7 +1744,7 @@
 bool Internals::needsCompositedScrolling(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return 0;
     }
 
@@ -1763,7 +1778,7 @@
 String Internals::elementLayerTreeAsText(Element* element, unsigned flags, ExceptionState& exceptionState) const
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return String();
     }
 
@@ -1789,7 +1804,7 @@
 static RenderLayer* getRenderLayerForElement(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return 0;
     }
 
@@ -1811,7 +1826,7 @@
 void Internals::setNeedsCompositedScrolling(Element* element, unsigned needsCompositedScrolling, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return;
     }
 
@@ -1834,8 +1849,8 @@
 PassRefPtr<ClientRectList> Internals::repaintRects(Element* element, ExceptionState& exceptionState) const
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
-        return 0;
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
+        return nullptr;
     }
 
     if (RenderLayer* layer = getRenderLayerForElement(element, exceptionState)) {
@@ -1850,7 +1865,7 @@
     }
 
     exceptionState.throwDOMException(InvalidAccessError, "The provided element is not composited.");
-    return 0;
+    return nullptr;
 }
 
 String Internals::scrollingStateTreeAsText(Document* document, ExceptionState& exceptionState) const
@@ -1882,12 +1897,12 @@
 {
     if (!document || !document->frame()) {
         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
-        return 0;
+        return nullptr;
     }
 
     Page* page = document->page();
     if (!page)
-        return 0;
+        return nullptr;
 
     return page->nonFastScrollableRects(document->frame());
 }
@@ -2004,28 +2019,28 @@
 {
     if (!document)
         return;
-    FullscreenElementStack::from(document)->webkitWillEnterFullScreenForElement(element);
+    FullscreenElementStack::from(*document).webkitWillEnterFullScreenForElement(element);
 }
 
 void Internals::webkitDidEnterFullScreenForElement(Document* document, Element* element)
 {
     if (!document)
         return;
-    FullscreenElementStack::from(document)->webkitDidEnterFullScreenForElement(element);
+    FullscreenElementStack::from(*document).webkitDidEnterFullScreenForElement(element);
 }
 
 void Internals::webkitWillExitFullScreenForElement(Document* document, Element* element)
 {
     if (!document)
         return;
-    FullscreenElementStack::from(document)->webkitWillExitFullScreenForElement(element);
+    FullscreenElementStack::from(*document).webkitWillExitFullScreenForElement(element);
 }
 
 void Internals::webkitDidExitFullScreenForElement(Document* document, Element* element)
 {
     if (!document)
         return;
-    FullscreenElementStack::from(document)->webkitDidExitFullScreenForElement(element);
+    FullscreenElementStack::from(*document).webkitDidExitFullScreenForElement(element);
 }
 
 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
@@ -2038,19 +2053,19 @@
     SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
 }
 
-PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
+PassRefPtrWillBeRawPtr<MallocStatistics> Internals::mallocStatistics() const
 {
     return MallocStatistics::create();
 }
 
-PassRefPtr<TypeConversions> Internals::typeConversions() const
+PassRefPtrWillBeRawPtr<TypeConversions> Internals::typeConversions() const
 {
     return TypeConversions::create();
 }
 
 Vector<String> Internals::getReferencedFilePaths() const
 {
-    frame()->loader().saveDocumentAndScrollState();
+    frame()->loader().saveDocumentState();
     return FormController::getReferencedFilePaths(frame()->loader().currentItem()->documentState());
 }
 
@@ -2088,10 +2103,10 @@
         document = contextDocument();
     } else if (node->isDocumentNode()) {
         document = toDocument(node);
-    } else if (node->hasTagName(HTMLNames::iframeTag)) {
-        document = toHTMLIFrameElement(node)->contentDocument();
+    } else if (isHTMLIFrameElement(*node)) {
+        document = toHTMLIFrameElement(*node).contentDocument();
     } else {
-        exceptionState.throwDOMException(TypeError, "The node provided is neither a document nor an IFrame.");
+        exceptionState.throwTypeError("The node provided is neither a document nor an IFrame.");
         return;
     }
     document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
@@ -2235,7 +2250,7 @@
     Document* document = contextDocument();
     if (!document || !document->frame()) {
         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "No context document can be obtained.");
-        return 0;
+        return nullptr;
     }
 
     return ClientRect::create(document->frame()->selection().bounds());
@@ -2244,7 +2259,7 @@
 String Internals::markerTextForListItem(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return String();
     }
     return WebCore::markerTextForListItem(element);
@@ -2253,7 +2268,7 @@
 String Internals::getImageSourceURL(Element* element, ExceptionState& exceptionState)
 {
     if (!element) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return String();
     }
     return element->imageSourceURL();
@@ -2271,12 +2286,13 @@
 
 bool Internals::isSelectPopupVisible(Node* node)
 {
-    if (!node->hasTagName(HTMLNames::selectTag))
+    ASSERT(node);
+    if (!isHTMLSelectElement(*node))
         return false;
 
-    HTMLSelectElement* select = toHTMLSelectElement(node);
+    HTMLSelectElement& select = toHTMLSelectElement(*node);
 
-    RenderObject* renderer = select->renderer();
+    RenderObject* renderer = select.renderer();
     if (!renderer->isMenuList())
         return false;
 
@@ -2329,12 +2345,12 @@
 
 void Internals::setShouldRevealPassword(Element* element, bool reveal, ExceptionState& exceptionState)
 {
-    if (!element || !element->hasTagName(inputTag)) {
-        exceptionState.throwDOMException(InvalidAccessError, "The element provided is invalid.");
+    if (!isHTMLInputElement(element)) {
+        exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
         return;
     }
 
-    return toHTMLInputElement(element)->setShouldRevealPassword(reveal);
+    return toHTMLInputElement(*element).setShouldRevealPassword(reveal);
 }
 
 namespace {
@@ -2370,4 +2386,35 @@
     return promise.then(AddOneFunction::create(context));
 }
 
+void Internals::trace(Visitor* visitor)
+{
+    visitor->trace(m_runtimeFlags);
+    visitor->trace(m_profilers);
+}
+
+void Internals::startSpeechInput(Element* element)
+{
+#if ENABLE(INPUT_SPEECH)
+    HTMLInputElement* input = toHTMLInputElement(element);
+    if (!input->isSpeechEnabled())
+        return;
+
+    InputFieldSpeechButtonElement* speechButton = toInputFieldSpeechButtonElement(input->userAgentShadowRoot()->getElementById(ShadowElementNames::speechButton()));
+    if (speechButton)
+        speechButton->startSpeechInput();
+#endif
+}
+
+void Internals::setValueForUser(Element* element, const String& value)
+{
+    toHTMLInputElement(element)->setValueForUser(value);
+}
+
+String Internals::textSurroundingNode(Node* node, int x, int y, unsigned long maxLength)
+{
+    blink::WebPoint point(x, y);
+    SurroundingText surroundingText(VisiblePosition(node->renderer()->positionForPoint(static_cast<IntPoint>(point))), maxLength);
+    return surroundingText.content();
+}
+
 }
diff --git a/Source/core/testing/Internals.h b/Source/core/testing/Internals.h
index cadc681..3865517 100644
--- a/Source/core/testing/Internals.h
+++ b/Source/core/testing/Internals.h
@@ -34,6 +34,7 @@
 #include "core/dom/ContextLifecycleObserver.h"
 #include "core/dom/NodeList.h"
 #include "core/page/scrolling/ScrollingCoordinator.h"
+#include "heap/Handle.h"
 #include "wtf/ArrayBuffer.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -50,7 +51,7 @@
 class DocumentMarker;
 class Element;
 class ExceptionState;
-class Frame;
+class LocalFrame;
 class GCObservation;
 class InspectorFrontendChannelDummy;
 class InternalProfilers;
@@ -67,10 +68,9 @@
 class ShadowRoot;
 class TypeConversions;
 
-class Internals FINAL : public RefCounted<Internals>
-    , public ContextLifecycleObserver {
+class Internals FINAL : public RefCountedWillBeGarbageCollectedFinalized<Internals>, public ContextLifecycleObserver {
 public:
-    static PassRefPtr<Internals> create(Document*);
+    static PassRefPtrWillBeRawPtr<Internals> create(Document*);
     virtual ~Internals();
 
     static void resetToConsistentState(Page*);
@@ -79,7 +79,7 @@
 
     String address(Node*);
 
-    PassRefPtr<GCObservation> observeGC(ScriptValue);
+    PassRefPtrWillBeRawPtr<GCObservation> observeGC(ScriptValue);
 
     bool isPreloaded(const String& url);
     bool isLoadingFromMemoryCache(const String& url);
@@ -136,7 +136,7 @@
     Vector<String> formControlStateOfHistoryItem(ExceptionState&);
     void setFormControlStateOfHistoryItem(const Vector<String>&, ExceptionState&);
     void setEnableMockPagePopup(bool, ExceptionState&);
-    PassRefPtr<PagePopupController> pagePopupController();
+    PassRefPtrWillBeRawPtr<PagePopupController> pagePopupController();
 
     PassRefPtr<ClientRect> unscaledViewportRect(ExceptionState&);
 
@@ -182,9 +182,10 @@
     Vector<AtomicString> userPreferredLanguages() const;
     void setUserPreferredLanguages(const Vector<String>&);
 
+    unsigned activeDOMObjectCount(Document*, ExceptionState&);
     unsigned wheelEventHandlerCount(Document*, ExceptionState&);
     unsigned touchEventHandlerCount(Document*, ExceptionState&);
-    PassRefPtr<LayerRectList> touchEventTargetLayerRects(Document*, ExceptionState&);
+    PassRefPtrWillBeRawPtr<LayerRectList> touchEventTargetLayerRects(Document*, ExceptionState&);
 
     // This is used to test rect based hit testing like what's done on touch screens.
     PassRefPtr<NodeList> nodesFromRect(Document*, int x, int y, unsigned topPadding, unsigned rightPadding,
@@ -270,8 +271,8 @@
     void registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme);
     void removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme);
 
-    PassRefPtr<MallocStatistics> mallocStatistics() const;
-    PassRefPtr<TypeConversions> typeConversions() const;
+    PassRefPtrWillBeRawPtr<MallocStatistics> mallocStatistics() const;
+    PassRefPtrWillBeRawPtr<TypeConversions> typeConversions() const;
 
     Vector<String> getReferencedFilePaths() const;
 
@@ -311,18 +312,25 @@
 
     ScriptPromise addOneToPromise(ExecutionContext*, ScriptPromise);
 
+    void trace(Visitor*);
+
+    void startSpeechInput(Element*);
+    void setValueForUser(Element*, const String&);
+
+    String textSurroundingNode(Node*, int x, int y, unsigned long maxLength);
+
 private:
     explicit Internals(Document*);
     Document* contextDocument() const;
-    Frame* frame() const;
+    LocalFrame* frame() const;
     Vector<String> iconURLs(Document*, int iconTypesMask) const;
     PassRefPtr<ClientRectList> annotatedRegions(Document*, bool draggable, ExceptionState&);
 
     DocumentMarker* markerAt(Node*, const String& markerType, unsigned index, ExceptionState&);
     RefPtr<DOMWindow> m_frontendWindow;
     OwnPtr<InspectorFrontendChannelDummy> m_frontendChannel;
-    RefPtr<InternalRuntimeFlags> m_runtimeFlags;
-    RefPtr<InternalProfilers> m_profilers;
+    RefPtrWillBeMember<InternalRuntimeFlags> m_runtimeFlags;
+    RefPtrWillBeMember<InternalProfilers> m_profilers;
 };
 
 } // namespace WebCore
diff --git a/Source/core/testing/Internals.idl b/Source/core/testing/Internals.idl
index 082be3d..b3da863 100644
--- a/Source/core/testing/Internals.idl
+++ b/Source/core/testing/Internals.idl
@@ -25,6 +25,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     DoNotCheckConstants,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface Internals {
@@ -139,6 +140,7 @@
     sequence<DOMString> userPreferredLanguages();
     void setUserPreferredLanguages(sequence<DOMString> languages);
 
+    [RaisesException] unsigned long activeDOMObjectCount(Document document);
     [RaisesException] unsigned long wheelEventHandlerCount(Document document);
     [RaisesException] unsigned long touchEventHandlerCount(Document document);
     [RaisesException] LayerRectList touchEventTargetLayerRects(Document document);
@@ -277,4 +279,9 @@
     [RaisesException] void setShouldRevealPassword(Element element, boolean reveal);
 
     [CallWith=ExecutionContext] Promise addOneToPromise(Promise promise);
+
+    void startSpeechInput(Element element);
+    void setValueForUser(Element element, DOMString value);
+
+    DOMString textSurroundingNode(Node node, long x, long y, unsigned long maxLength);
 };
diff --git a/Source/core/testing/LayerRect.h b/Source/core/testing/LayerRect.h
index 4827fee..559dfd9 100644
--- a/Source/core/testing/LayerRect.h
+++ b/Source/core/testing/LayerRect.h
@@ -33,6 +33,7 @@
 
 #include "core/dom/ClientRect.h"
 
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -42,17 +43,19 @@
 
 class Node;
 
-class LayerRect : public RefCounted<LayerRect> {
+class LayerRect : public RefCountedWillBeGarbageCollectedFinalized<LayerRect> {
 public:
-    static PassRefPtr<LayerRect> create(PassRefPtr<Node> node, const String& layerType, PassRefPtr<ClientRect> rect)
+    static PassRefPtrWillBeRawPtr<LayerRect> create(PassRefPtr<Node> node, const String& layerType, PassRefPtr<ClientRect> rect)
     {
-        return adoptRef(new LayerRect(node, layerType, rect));
+        return adoptRefWillBeNoop(new LayerRect(node, layerType, rect));
     }
 
     Node* layerRootNode() const { return m_layerRootNode.get(); }
     String layerType() const { return m_layerType; }
     ClientRect* layerRelativeRect() const { return m_rect.get(); }
 
+    void trace(Visitor*) { }
+
 private:
     LayerRect(PassRefPtr<Node> node, const String& layerName, PassRefPtr<ClientRect> rect)
         : m_layerRootNode(node)
diff --git a/Source/core/testing/LayerRect.idl b/Source/core/testing/LayerRect.idl
index 7cc2f5b..2b116d1 100644
--- a/Source/core/testing/LayerRect.idl
+++ b/Source/core/testing/LayerRect.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface LayerRect {
     readonly attribute Node layerRootNode;
diff --git a/Source/core/testing/LayerRectList.cpp b/Source/core/testing/LayerRectList.cpp
index 4e8b991..9cb79c1 100644
--- a/Source/core/testing/LayerRectList.cpp
+++ b/Source/core/testing/LayerRectList.cpp
@@ -41,9 +41,7 @@
 {
 }
 
-LayerRectList::~LayerRectList()
-{
-}
+DEFINE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(LayerRectList)
 
 unsigned LayerRectList::length() const
 {
@@ -63,4 +61,9 @@
     m_list.append(LayerRect::create(layerRootNode, layerType, layerRelativeRect));
 }
 
+void LayerRectList::trace(Visitor* visitor)
+{
+    visitor->trace(m_list);
+}
+
 } // namespace WebCore
diff --git a/Source/core/testing/LayerRectList.h b/Source/core/testing/LayerRectList.h
index ec1582b..f87c5de 100644
--- a/Source/core/testing/LayerRectList.h
+++ b/Source/core/testing/LayerRectList.h
@@ -44,19 +44,24 @@
 class LayerRect;
 class Node;
 
-class LayerRectList : public RefCounted<LayerRectList> {
+class LayerRectList : public RefCountedWillBeGarbageCollected<LayerRectList> {
+    DECLARE_EMPTY_DESTRUCTOR_WILL_BE_REMOVED(LayerRectList);
 public:
-    static PassRefPtr<LayerRectList> create() { return adoptRef(new LayerRectList); }
-    ~LayerRectList();
+    static PassRefPtrWillBeRawPtr<LayerRectList> create()
+    {
+        return adoptRefWillBeNoop(new LayerRectList);
+    }
 
     unsigned length() const;
     LayerRect* item(unsigned index);
     void append(PassRefPtr<Node> layerRootNode, const String& layerName, PassRefPtr<ClientRect> layerRelativeRect);
 
+    void trace(Visitor*);
+
 private:
     LayerRectList();
 
-    Vector<RefPtr<LayerRect> > m_list;
+    WillBeHeapVector<RefPtrWillBeMember<LayerRect> > m_list;
 };
 
 } // namespace WebCore
diff --git a/Source/core/testing/LayerRectList.idl b/Source/core/testing/LayerRectList.idl
index 03e63c5..2e789a5 100644
--- a/Source/core/testing/LayerRectList.idl
+++ b/Source/core/testing/LayerRectList.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface LayerRectList {
     readonly attribute unsigned long length;
diff --git a/Source/core/testing/MallocStatistics.h b/Source/core/testing/MallocStatistics.h
index bc4da85..a3e36af 100644
--- a/Source/core/testing/MallocStatistics.h
+++ b/Source/core/testing/MallocStatistics.h
@@ -26,20 +26,26 @@
 #ifndef MallocStatistics_h
 #define MallocStatistics_h
 
+#include "heap/Handle.h"
 #include "wtf/FastMalloc.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-class MallocStatistics : public RefCounted<MallocStatistics> {
+class MallocStatistics : public RefCountedWillBeGarbageCollected<MallocStatistics> {
 public:
-    static PassRefPtr<MallocStatistics> create() { return adoptRef(new MallocStatistics()); }
+    static PassRefPtrWillBeRawPtr<MallocStatistics> create()
+    {
+        return adoptRefWillBeNoop(new MallocStatistics());
+    }
 
     size_t reservedVMBytes() const { return m_stats.reservedVMBytes; }
     size_t committedVMBytes() const { return m_stats.committedVMBytes; }
     size_t freeListBytes() const { return m_stats.freeListBytes; }
 
+    void trace(Visitor*) { }
+
 private:
     MallocStatistics()
     {
diff --git a/Source/core/testing/MallocStatistics.idl b/Source/core/testing/MallocStatistics.idl
index 663fabb..fbe5ac5 100644
--- a/Source/core/testing/MallocStatistics.idl
+++ b/Source/core/testing/MallocStatistics.idl
@@ -24,6 +24,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface MallocStatistics {
     readonly attribute unsigned long reservedVMBytes;
diff --git a/Source/core/testing/MockPagePopupDriver.cpp b/Source/core/testing/MockPagePopupDriver.cpp
index e0a789e..433372a 100644
--- a/Source/core/testing/MockPagePopupDriver.cpp
+++ b/Source/core/testing/MockPagePopupDriver.cpp
@@ -29,10 +29,10 @@
 #include "CSSPropertyNames.h"
 #include "CSSValueKeywords.h"
 #include "bindings/v8/ExceptionStatePlaceholder.h"
+#include "core/frame/LocalFrame.h"
 #include "core/html/HTMLIFrameElement.h"
 #include "core/loader/FrameLoadRequest.h"
 #include "core/loader/FrameLoader.h"
-#include "core/frame/Frame.h"
 #include "core/page/PagePopup.h"
 #include "core/page/PagePopupController.h"
 #include "platform/Timer.h"
@@ -41,12 +41,12 @@
 
 class MockPagePopup : public PagePopup, public RefCounted<MockPagePopup> {
 public:
-    static PassRefPtr<MockPagePopup> create(PagePopupClient*, const IntRect& originBoundsInRootView, Frame*);
+    static PassRefPtr<MockPagePopup> create(PagePopupClient*, const IntRect& originBoundsInRootView, LocalFrame*);
     virtual ~MockPagePopup();
     void closeLater();
 
 private:
-    MockPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView, Frame*);
+    MockPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView, LocalFrame*);
     void close(Timer<MockPagePopup>*);
 
     PagePopupClient* m_popupClient;
@@ -54,7 +54,7 @@
     Timer<MockPagePopup> m_closeTimer;
 };
 
-inline MockPagePopup::MockPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView, Frame* mainFrame)
+inline MockPagePopup::MockPagePopup(PagePopupClient* client, const IntRect& originBoundsInRootView, LocalFrame* mainFrame)
     : m_popupClient(client)
     , m_closeTimer(this, &MockPagePopup::close)
 {
@@ -74,7 +74,7 @@
     m_iframe->contentFrame()->loader().load(FrameLoadRequest(0, blankURL(), SubstituteData(data, "text/html", "UTF-8", KURL(), ForceSynchronousLoad)));
 }
 
-PassRefPtr<MockPagePopup> MockPagePopup::create(PagePopupClient* client, const IntRect& originBoundsInRootView, Frame* mainFrame)
+PassRefPtr<MockPagePopup> MockPagePopup::create(PagePopupClient* client, const IntRect& originBoundsInRootView, LocalFrame* mainFrame)
 {
     return adoptRef(new MockPagePopup(client, originBoundsInRootView, mainFrame));
 }
@@ -86,7 +86,7 @@
     m_popupClient = 0;
     // This can be called in detach(), and we should not change DOM structure
     // during detach().
-    m_closeTimer.startOneShot(0);
+    m_closeTimer.startOneShot(0, FROM_HERE);
 }
 
 void MockPagePopup::close(Timer<MockPagePopup>*)
@@ -100,12 +100,12 @@
         m_iframe->parentNode()->removeChild(m_iframe.get());
 }
 
-inline MockPagePopupDriver::MockPagePopupDriver(Frame* mainFrame)
+inline MockPagePopupDriver::MockPagePopupDriver(LocalFrame* mainFrame)
     : m_mainFrame(mainFrame)
 {
 }
 
-PassOwnPtr<MockPagePopupDriver> MockPagePopupDriver::create(Frame* mainFrame)
+PassOwnPtr<MockPagePopupDriver> MockPagePopupDriver::create(LocalFrame* mainFrame)
 {
     return adoptPtr(new MockPagePopupDriver(mainFrame));
 }
diff --git a/Source/core/testing/MockPagePopupDriver.h b/Source/core/testing/MockPagePopupDriver.h
index b69b553..c6e1c5a 100644
--- a/Source/core/testing/MockPagePopupDriver.h
+++ b/Source/core/testing/MockPagePopupDriver.h
@@ -28,11 +28,12 @@
 
 #include "core/page/PagePopupClient.h"
 #include "core/page/PagePopupDriver.h"
+#include "heap/Handle.h"
 #include "wtf/RefPtr.h"
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class IntRect;
 class MockPagePopup;
 class PagePopup;
@@ -40,20 +41,20 @@
 
 class MockPagePopupDriver FINAL : public PagePopupDriver {
 public:
-    static PassOwnPtr<MockPagePopupDriver> create(Frame* mainFrame);
+    static PassOwnPtr<MockPagePopupDriver> create(LocalFrame* mainFrame);
     virtual ~MockPagePopupDriver();
     PagePopupController* pagePopupController() { return m_pagePopupController.get(); }
 
 private:
-    MockPagePopupDriver(Frame* mainFrame);
+    MockPagePopupDriver(LocalFrame* mainFrame);
 
     // PagePopupDriver functions:
     virtual PagePopup* openPagePopup(PagePopupClient*, const IntRect& originBoundsInRootView) OVERRIDE;
     virtual void closePagePopup(PagePopup*) OVERRIDE;
 
     RefPtr<MockPagePopup> m_mockPagePopup;
-    Frame* m_mainFrame;
-    RefPtr<PagePopupController> m_pagePopupController;
+    LocalFrame* m_mainFrame;
+    RefPtrWillBePersistent<PagePopupController> m_pagePopupController;
 };
 
 }
diff --git a/Source/core/testing/TypeConversions.h b/Source/core/testing/TypeConversions.h
index 9a2625d..eff9fe3 100644
--- a/Source/core/testing/TypeConversions.h
+++ b/Source/core/testing/TypeConversions.h
@@ -32,9 +32,12 @@
 
 namespace WebCore {
 
-class TypeConversions : public RefCounted<TypeConversions> {
+class TypeConversions : public RefCountedWillBeGarbageCollected<TypeConversions> {
 public:
-    static PassRefPtr<TypeConversions> create() { return adoptRef(new TypeConversions()); }
+    static PassRefPtrWillBeRawPtr<TypeConversions> create()
+    {
+        return adoptRefWillBeNoop(new TypeConversions());
+    }
 
     long testLong() { return m_long; }
     void setTestLong(long value) { m_long = value; }
@@ -56,6 +59,8 @@
     uint16_t testUnsignedShort() { return m_unsignedShort; }
     void setTestUnsignedShort(uint16_t value) { m_unsignedShort = value; }
 
+    void trace(Visitor*) { }
+
 private:
     TypeConversions()
     {
diff --git a/Source/core/testing/TypeConversions.idl b/Source/core/testing/TypeConversions.idl
index b87b984..83d63c6 100644
--- a/Source/core/testing/TypeConversions.idl
+++ b/Source/core/testing/TypeConversions.idl
@@ -24,6 +24,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject,  // testing interfaces do not appear on global objects
 ] interface TypeConversions {
     attribute long testLong;
diff --git a/Source/core/testing/v8/WebCoreTestSupport.cpp b/Source/core/testing/v8/WebCoreTestSupport.cpp
index 45e2e70..e0553ab 100644
--- a/Source/core/testing/v8/WebCoreTestSupport.cpp
+++ b/Source/core/testing/v8/WebCoreTestSupport.cpp
@@ -31,7 +31,7 @@
 #include "V8Internals.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExecutionContext.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 #include <v8.h>
 
@@ -59,8 +59,9 @@
 
     ExecutionContext* scriptContext = currentExecutionContext(context->GetIsolate());
     Page* page = toDocument(scriptContext)->frame()->page();
+    ASSERT(page);
     Internals::resetToConsistentState(page);
-    InternalSettings::from(page)->resetToConsistentState();
+    InternalSettings::from(*page)->resetToConsistentState();
 }
 
 }
diff --git a/Source/core/testing/v8/WebCoreTestSupport.h b/Source/core/testing/v8/WebCoreTestSupport.h
index 1ff2d76..558ee35 100644
--- a/Source/core/testing/v8/WebCoreTestSupport.h
+++ b/Source/core/testing/v8/WebCoreTestSupport.h
@@ -32,7 +32,7 @@
 }
 
 namespace WebCore {
-class Frame;
+class LocalFrame;
 class PagePopupController;
 }
 
diff --git a/Source/core/timing/MemoryInfo.cpp b/Source/core/timing/MemoryInfo.cpp
index 3bb0821..945e284 100644
--- a/Source/core/timing/MemoryInfo.cpp
+++ b/Source/core/timing/MemoryInfo.cpp
@@ -32,7 +32,7 @@
 #include "core/timing/MemoryInfo.h"
 
 #include <limits>
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/Settings.h"
 #include "wtf/CurrentTime.h"
 #include "wtf/MainThread.h"
@@ -40,7 +40,6 @@
 
 namespace WebCore {
 
-
 class HeapSizeCache {
     WTF_MAKE_NONCOPYABLE(HeapSizeCache); WTF_MAKE_FAST_ALLOCATED;
 public:
@@ -132,7 +131,7 @@
 }
 
 
-MemoryInfo::MemoryInfo(Frame* frame)
+MemoryInfo::MemoryInfo(LocalFrame* frame)
 {
     ScriptWrappable::init(this);
     if (!frame || !frame->settings())
diff --git a/Source/core/timing/MemoryInfo.h b/Source/core/timing/MemoryInfo.h
index 59629a4..6009f5f 100644
--- a/Source/core/timing/MemoryInfo.h
+++ b/Source/core/timing/MemoryInfo.h
@@ -33,23 +33,29 @@
 
 #include "bindings/v8/ScriptGCEvent.h"
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 
-class MemoryInfo : public RefCounted<MemoryInfo>, public ScriptWrappable {
+class MemoryInfo : public RefCountedWillBeGarbageCollectedFinalized<MemoryInfo>, public ScriptWrappable {
 public:
-    static PassRefPtr<MemoryInfo> create(Frame* frame) { return adoptRef(new MemoryInfo(frame)); }
+    static PassRefPtrWillBeRawPtr<MemoryInfo> create(LocalFrame* frame)
+    {
+        return adoptRefWillBeNoop(new MemoryInfo(frame));
+    }
 
     size_t totalJSHeapSize() const { return m_info.totalJSHeapSize; }
     size_t usedJSHeapSize() const { return m_info.usedJSHeapSize; }
     size_t jsHeapSizeLimit() const { return m_info.jsHeapSizeLimit; }
 
+    void trace(Visitor*) { }
+
 private:
-    explicit MemoryInfo(Frame*);
+    explicit MemoryInfo(LocalFrame*);
 
     HeapInfo m_info;
 };
diff --git a/Source/core/timing/MemoryInfo.idl b/Source/core/timing/MemoryInfo.idl
index 30ac718..552f175 100644
--- a/Source/core/timing/MemoryInfo.idl
+++ b/Source/core/timing/MemoryInfo.idl
@@ -29,6 +29,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject
 ] interface MemoryInfo {
 
diff --git a/Source/core/timing/Performance.cpp b/Source/core/timing/Performance.cpp
index e441579..f3decc4 100644
--- a/Source/core/timing/Performance.cpp
+++ b/Source/core/timing/Performance.cpp
@@ -33,6 +33,7 @@
 #include "core/timing/Performance.h"
 
 #include "core/dom/Document.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/timing/ResourceTimingInfo.h"
 #include "core/timing/PerformanceResourceTiming.h"
@@ -40,19 +41,16 @@
 #include "platform/weborigin/SecurityOrigin.h"
 #include "wtf/CurrentTime.h"
 
-#include "core/frame/Frame.h"
-
 namespace WebCore {
 
 static const size_t defaultResourceTimingBufferSize = 150;
 
-Performance::Performance(Frame* frame)
+Performance::Performance(LocalFrame* frame)
     : DOMWindowProperty(frame)
     , m_resourceTimingBufferSize(defaultResourceTimingBufferSize)
-    , m_referenceTime(frame->document()->loader()->timing()->referenceMonotonicTime())
-    , m_userTiming(0)
+    , m_referenceTime(frame->host() ? frame->document()->loader()->timing()->referenceMonotonicTime() : 0.0)
+    , m_userTiming(nullptr)
 {
-    ASSERT(m_referenceTime);
     ScriptWrappable::init(this);
 }
 
@@ -72,7 +70,7 @@
     return frame()->document();
 }
 
-PassRefPtr<MemoryInfo> Performance::memory() const
+PassRefPtrWillBeRawPtr<MemoryInfo> Performance::memory() const
 {
     return MemoryInfo::create(m_frame);
 }
@@ -93,54 +91,54 @@
     return m_timing.get();
 }
 
-Vector<RefPtr<PerformanceEntry> > Performance::getEntries() const
+PerformanceEntryVector Performance::getEntries() const
 {
-    Vector<RefPtr<PerformanceEntry> > entries;
+    PerformanceEntryVector entries;
 
-    entries.append(m_resourceTimingBuffer);
+    entries.appendVector(m_resourceTimingBuffer);
 
     if (m_userTiming) {
-        entries.append(m_userTiming->getMarks());
-        entries.append(m_userTiming->getMeasures());
+        entries.appendVector(m_userTiming->getMarks());
+        entries.appendVector(m_userTiming->getMeasures());
     }
 
     std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompareLessThan);
     return entries;
 }
 
-Vector<RefPtr<PerformanceEntry> > Performance::getEntriesByType(const String& entryType)
+PerformanceEntryVector Performance::getEntriesByType(const String& entryType)
 {
-    Vector<RefPtr<PerformanceEntry> > entries;
+    PerformanceEntryVector entries;
 
     if (equalIgnoringCase(entryType, "resource"))
-        for (Vector<RefPtr<PerformanceEntry> >::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
+        for (PerformanceEntryVector::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
             entries.append(*resource);
 
     if (m_userTiming) {
         if (equalIgnoringCase(entryType, "mark"))
-            entries.append(m_userTiming->getMarks());
+            entries.appendVector(m_userTiming->getMarks());
         else if (equalIgnoringCase(entryType, "measure"))
-            entries.append(m_userTiming->getMeasures());
+            entries.appendVector(m_userTiming->getMeasures());
     }
 
     std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompareLessThan);
     return entries;
 }
 
-Vector<RefPtr<PerformanceEntry> > Performance::getEntriesByName(const String& name, const String& entryType)
+PerformanceEntryVector Performance::getEntriesByName(const String& name, const String& entryType)
 {
-    Vector<RefPtr<PerformanceEntry> > entries;
+    PerformanceEntryVector entries;
 
     if (entryType.isNull() || equalIgnoringCase(entryType, "resource"))
-        for (Vector<RefPtr<PerformanceEntry> >::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
+        for (PerformanceEntryVector::const_iterator resource = m_resourceTimingBuffer.begin(); resource != m_resourceTimingBuffer.end(); ++resource)
             if ((*resource)->name() == name)
                 entries.append(*resource);
 
     if (m_userTiming) {
         if (entryType.isNull() || equalIgnoringCase(entryType, "mark"))
-            entries.append(m_userTiming->getMarks(name));
+            entries.appendVector(m_userTiming->getMarks(name));
         if (entryType.isNull() || equalIgnoringCase(entryType, "measure"))
-            entries.append(m_userTiming->getMeasures(name));
+            entries.appendVector(m_userTiming->getMeasures(name));
     }
 
     std::sort(entries.begin(), entries.end(), PerformanceEntry::startTimeCompareLessThan);
@@ -208,7 +206,7 @@
     double startTime = info.initialTime();
 
     if (info.redirectChain().isEmpty()) {
-        RefPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, allowTimingDetails);
+        RefPtrWillBeRawPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, allowTimingDetails);
         addResourceTimingBuffer(entry);
         return;
     }
@@ -227,11 +225,11 @@
     ASSERT(lastRedirectTiming);
     double lastRedirectEndTime = lastRedirectTiming->receiveHeadersEnd;
 
-    RefPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails);
+    RefPtrWillBeRawPtr<PerformanceEntry> entry = PerformanceResourceTiming::create(info, initiatorDocument, startTime, lastRedirectEndTime, allowTimingDetails, allowRedirectDetails);
     addResourceTimingBuffer(entry);
 }
 
-void Performance::addResourceTimingBuffer(PassRefPtr<PerformanceEntry> entry)
+void Performance::addResourceTimingBuffer(PassRefPtrWillBeRawPtr<PerformanceEntry> entry)
 {
     m_resourceTimingBuffer.append(entry);
 
@@ -277,4 +275,12 @@
     return 1000.0 * (monotonicallyIncreasingTime() - m_referenceTime);
 }
 
+void Performance::trace(Visitor* visitor)
+{
+    visitor->trace(m_navigation);
+    visitor->trace(m_timing);
+    visitor->trace(m_resourceTimingBuffer);
+    visitor->trace(m_userTiming);
+}
+
 } // namespace WebCore
diff --git a/Source/core/timing/Performance.h b/Source/core/timing/Performance.h
index 65111a6..a351919 100644
--- a/Source/core/timing/Performance.h
+++ b/Source/core/timing/Performance.h
@@ -39,6 +39,7 @@
 #include "core/timing/PerformanceEntry.h"
 #include "core/timing/PerformanceNavigation.h"
 #include "core/timing/PerformanceTiming.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -53,23 +54,28 @@
 class ResourceTimingInfo;
 class UserTiming;
 
-class Performance FINAL : public ScriptWrappable, public RefCounted<Performance>, public DOMWindowProperty, public EventTargetWithInlineData {
-    REFCOUNTED_EVENT_TARGET(Performance);
+typedef WillBeHeapVector<RefPtrWillBeMember<PerformanceEntry> > PerformanceEntryVector;
+
+class Performance FINAL : public RefCountedWillBeRefCountedGarbageCollected<Performance>, public ScriptWrappable, public DOMWindowProperty, public EventTargetWithInlineData {
+    DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<Performance>);
 public:
-    static PassRefPtr<Performance> create(Frame* frame) { return adoptRef(new Performance(frame)); }
+    static PassRefPtrWillBeRawPtr<Performance> create(LocalFrame* frame)
+    {
+        return adoptRefWillBeRefCountedGarbageCollected(new Performance(frame));
+    }
     virtual ~Performance();
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
     virtual ExecutionContext* executionContext() const OVERRIDE;
 
-    PassRefPtr<MemoryInfo> memory() const;
+    PassRefPtrWillBeRawPtr<MemoryInfo> memory() const;
     PerformanceNavigation* navigation() const;
     PerformanceTiming* timing() const;
     double now() const;
 
-    Vector<RefPtr<PerformanceEntry> > getEntries() const;
-    Vector<RefPtr<PerformanceEntry> > getEntriesByType(const String& entryType);
-    Vector<RefPtr<PerformanceEntry> > getEntriesByName(const String& name, const String& entryType);
+    PerformanceEntryVector getEntries() const;
+    PerformanceEntryVector getEntriesByType(const String& entryType);
+    PerformanceEntryVector getEntriesByName(const String& name, const String& entryType);
 
     void webkitClearResourceTimings();
     void webkitSetResourceTimingBufferSize(unsigned int);
@@ -84,20 +90,22 @@
     void measure(const String& measureName, const String& startMark, const String& endMark, ExceptionState&);
     void clearMeasures(const String& measureName);
 
+    void trace(Visitor*);
+
 private:
-    explicit Performance(Frame*);
+    explicit Performance(LocalFrame*);
 
     bool isResourceTimingBufferFull();
-    void addResourceTimingBuffer(PassRefPtr<PerformanceEntry>);
+    void addResourceTimingBuffer(PassRefPtrWillBeRawPtr<PerformanceEntry>);
 
-    mutable RefPtr<PerformanceNavigation> m_navigation;
-    mutable RefPtr<PerformanceTiming> m_timing;
+    mutable RefPtrWillBeMember<PerformanceNavigation> m_navigation;
+    mutable RefPtrWillBeMember<PerformanceTiming> m_timing;
 
-    Vector<RefPtr<PerformanceEntry> > m_resourceTimingBuffer;
+    PerformanceEntryVector m_resourceTimingBuffer;
     unsigned m_resourceTimingBufferSize;
     double m_referenceTime;
 
-    RefPtr<UserTiming> m_userTiming;
+    RefPtrWillBeMember<UserTiming> m_userTiming;
 };
 
 }
diff --git a/Source/core/timing/Performance.idl b/Source/core/timing/Performance.idl
index 762f6b0..00593ec 100644
--- a/Source/core/timing/Performance.idl
+++ b/Source/core/timing/Performance.idl
@@ -30,7 +30,9 @@
  */
 
 // See: http://www.w3.org/TR/navigation-timing/
-interface Performance : EventTarget {
+[
+    WillBeGarbageCollected
+] interface Performance : EventTarget {
     readonly attribute PerformanceNavigation navigation;
     readonly attribute PerformanceTiming timing;
     readonly attribute MemoryInfo memory;
diff --git a/Source/core/timing/PerformanceEntry.h b/Source/core/timing/PerformanceEntry.h
index 1f19b43..828d21f 100644
--- a/Source/core/timing/PerformanceEntry.h
+++ b/Source/core/timing/PerformanceEntry.h
@@ -33,13 +33,14 @@
 #define PerformanceEntry_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
 
-class PerformanceEntry : public RefCounted<PerformanceEntry>, public ScriptWrappable {
+class PerformanceEntry : public RefCountedWillBeGarbageCollectedFinalized<PerformanceEntry>, public ScriptWrappable {
 public:
     virtual ~PerformanceEntry();
 
@@ -52,11 +53,13 @@
     virtual bool isMark() { return false; }
     virtual bool isMeasure() { return false; }
 
-    static bool startTimeCompareLessThan(PassRefPtr<PerformanceEntry> a, PassRefPtr<PerformanceEntry> b)
+    static bool startTimeCompareLessThan(PassRefPtrWillBeRawPtr<PerformanceEntry> a, PassRefPtrWillBeRawPtr<PerformanceEntry> b)
     {
         return a->startTime() < b->startTime();
     }
 
+    virtual void trace(Visitor*) { }
+
 protected:
     PerformanceEntry(const String& name, const String& entryType, double startTime, double finishTime);
 
diff --git a/Source/core/timing/PerformanceEntry.idl b/Source/core/timing/PerformanceEntry.idl
index 2f5771f..06d8222 100644
--- a/Source/core/timing/PerformanceEntry.idl
+++ b/Source/core/timing/PerformanceEntry.idl
@@ -30,6 +30,7 @@
 
 // See: https://dvcs.w3.org/hg/webperf/raw-file/tip/specs/PerformanceTimeline/Overview.html
 [
+    WillBeGarbageCollected,
     Custom=Wrap,
 ] interface PerformanceEntry {
     readonly attribute DOMString name;
diff --git a/Source/core/timing/PerformanceMark.h b/Source/core/timing/PerformanceMark.h
index 8e8b589..a1142c9 100644
--- a/Source/core/timing/PerformanceMark.h
+++ b/Source/core/timing/PerformanceMark.h
@@ -27,6 +27,7 @@
 #define PerformanceMark_h
 
 #include "core/timing/PerformanceEntry.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/text/WTFString.h"
 
@@ -34,10 +35,18 @@
 
 class PerformanceMark FINAL : public PerformanceEntry {
 public:
-    static PassRefPtr<PerformanceMark> create(const String& name, double startTime) { return adoptRef(new PerformanceMark(name, startTime)); }
+    static PassRefPtrWillBeRawPtr<PerformanceMark> create(const String& name, double startTime)
+    {
+        return adoptRefWillBeNoop(new PerformanceMark(name, startTime));
+    }
 
     virtual bool isMark() OVERRIDE { return true; }
 
+    virtual void trace(Visitor* visitor) OVERRIDE
+    {
+        PerformanceEntry::trace(visitor);
+    }
+
 private:
     PerformanceMark(const String& name, double startTime) : PerformanceEntry(name, "mark", startTime, startTime)
     {
diff --git a/Source/core/timing/PerformanceMeasure.h b/Source/core/timing/PerformanceMeasure.h
index acab8e5..00d39e8 100644
--- a/Source/core/timing/PerformanceMeasure.h
+++ b/Source/core/timing/PerformanceMeasure.h
@@ -27,6 +27,7 @@
 #define PerformanceMeasure_h
 
 #include "core/timing/PerformanceEntry.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/text/WTFString.h"
 
@@ -34,10 +35,18 @@
 
 class PerformanceMeasure FINAL : public PerformanceEntry {
 public:
-    static PassRefPtr<PerformanceMeasure> create(const String& name, double startTime, double endTime) { return adoptRef(new PerformanceMeasure(name, startTime, endTime)); }
+    static PassRefPtrWillBeRawPtr<PerformanceMeasure> create(const String& name, double startTime, double endTime)
+    {
+        return adoptRefWillBeNoop(new PerformanceMeasure(name, startTime, endTime));
+    }
 
     virtual bool isMeasure() OVERRIDE { return true; }
 
+    virtual void trace(Visitor* visitor)
+    {
+        PerformanceEntry::trace(visitor);
+    }
+
 private:
     PerformanceMeasure(const String& name, double startTime, double endTime) : PerformanceEntry(name, "measure", startTime, endTime)
     {
diff --git a/Source/core/timing/PerformanceNavigation.cpp b/Source/core/timing/PerformanceNavigation.cpp
index 7e94d75..4683fd7 100644
--- a/Source/core/timing/PerformanceNavigation.cpp
+++ b/Source/core/timing/PerformanceNavigation.cpp
@@ -31,13 +31,13 @@
 #include "config.h"
 #include "core/timing/PerformanceNavigation.h"
 
+#include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoaderTypes.h"
-#include "core/frame/Frame.h"
 
 namespace WebCore {
 
-PerformanceNavigation::PerformanceNavigation(Frame* frame)
+PerformanceNavigation::PerformanceNavigation(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
diff --git a/Source/core/timing/PerformanceNavigation.h b/Source/core/timing/PerformanceNavigation.h
index c635942..0507cbb 100644
--- a/Source/core/timing/PerformanceNavigation.h
+++ b/Source/core/timing/PerformanceNavigation.h
@@ -33,16 +33,20 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/frame/DOMWindowProperty.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 
-class PerformanceNavigation FINAL : public RefCounted<PerformanceNavigation>, public ScriptWrappable, public DOMWindowProperty {
+class PerformanceNavigation FINAL : public RefCountedWillBeGarbageCollectedFinalized<PerformanceNavigation>, public ScriptWrappable, public DOMWindowProperty {
 public:
-    static PassRefPtr<PerformanceNavigation> create(Frame* frame) { return adoptRef(new PerformanceNavigation(frame)); }
+    static PassRefPtrWillBeRawPtr<PerformanceNavigation> create(LocalFrame* frame)
+    {
+        return adoptRefWillBeNoop(new PerformanceNavigation(frame));
+    }
 
     enum PerformanceNavigationType {
         TYPE_NAVIGATE,
@@ -54,8 +58,10 @@
     unsigned short type() const;
     unsigned short redirectCount() const;
 
+    void trace(Visitor*) { }
+
 private:
-    explicit PerformanceNavigation(Frame*);
+    explicit PerformanceNavigation(LocalFrame*);
 };
 
 }
diff --git a/Source/core/timing/PerformanceNavigation.idl b/Source/core/timing/PerformanceNavigation.idl
index cde7a72..ea485ab 100644
--- a/Source/core/timing/PerformanceNavigation.idl
+++ b/Source/core/timing/PerformanceNavigation.idl
@@ -29,7 +29,9 @@
  */
 
 // See: http://www.w3.org/TR/navigation-timing/
-interface PerformanceNavigation {
+[
+    WillBeGarbageCollected
+] interface PerformanceNavigation {
     const unsigned short TYPE_NAVIGATE = 0;
     const unsigned short TYPE_RELOAD = 1;
     const unsigned short TYPE_BACK_FORWARD = 2;
diff --git a/Source/core/timing/PerformanceResourceTiming.h b/Source/core/timing/PerformanceResourceTiming.h
index fd286f3..2260f14 100644
--- a/Source/core/timing/PerformanceResourceTiming.h
+++ b/Source/core/timing/PerformanceResourceTiming.h
@@ -33,6 +33,7 @@
 #define PerformanceResourceTiming_h
 
 #include "core/timing/PerformanceEntry.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
 
@@ -47,14 +48,14 @@
 
 class PerformanceResourceTiming FINAL : public PerformanceEntry {
 public:
-    static PassRefPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool m_allowTimingDetails, bool m_allowRedirectDetails)
+    static PassRefPtrWillBeRawPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool m_allowTimingDetails, bool m_allowRedirectDetails)
     {
-        return adoptRef(new PerformanceResourceTiming(info, requestingDocument, startTime, lastRedirectEndTime, m_allowTimingDetails, m_allowRedirectDetails));
+        return adoptRefWillBeNoop(new PerformanceResourceTiming(info, requestingDocument, startTime, lastRedirectEndTime, m_allowTimingDetails, m_allowRedirectDetails));
     }
 
-    static PassRefPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, bool m_allowTimingDetails)
+    static PassRefPtrWillBeRawPtr<PerformanceResourceTiming> create(const ResourceTimingInfo& info, Document* requestingDocument, double startTime, bool m_allowTimingDetails)
     {
-        return adoptRef(new PerformanceResourceTiming(info, requestingDocument, startTime, 0.0, m_allowTimingDetails, false));
+        return adoptRefWillBeNoop(new PerformanceResourceTiming(info, requestingDocument, startTime, 0.0, m_allowTimingDetails, false));
     }
 
     AtomicString initiatorType() const;
@@ -73,6 +74,11 @@
 
     virtual bool isResource() OVERRIDE { return true; }
 
+    virtual void trace(Visitor* visitor)
+    {
+        PerformanceEntry::trace(visitor);
+    }
+
 private:
     PerformanceResourceTiming(const ResourceTimingInfo&, Document* requestingDocument, double startTime, double lastRedirectEndTime, bool m_allowTimingDetails, bool m_allowRedirectDetails);
     virtual ~PerformanceResourceTiming();
diff --git a/Source/core/timing/PerformanceTiming.cpp b/Source/core/timing/PerformanceTiming.cpp
index 6312694..38ef305 100644
--- a/Source/core/timing/PerformanceTiming.cpp
+++ b/Source/core/timing/PerformanceTiming.cpp
@@ -33,7 +33,7 @@
 
 #include "core/dom/Document.h"
 #include "core/dom/DocumentTiming.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/loader/DocumentLoadTiming.h"
 #include "core/loader/DocumentLoader.h"
 #include "core/loader/FrameLoader.h"
@@ -48,7 +48,7 @@
     return static_cast<unsigned long long>(seconds * 1000.0);
 }
 
-PerformanceTiming::PerformanceTiming(Frame* frame)
+PerformanceTiming::PerformanceTiming(LocalFrame* frame)
     : DOMWindowProperty(frame)
 {
     ScriptWrappable::init(this);
@@ -324,7 +324,7 @@
     if (!document)
         return 0;
 
-    return document->timing();
+    return &document->timing();
 }
 
 DocumentLoadTiming* PerformanceTiming::documentLoadTiming() const
diff --git a/Source/core/timing/PerformanceTiming.h b/Source/core/timing/PerformanceTiming.h
index 640b47e..618d682 100644
--- a/Source/core/timing/PerformanceTiming.h
+++ b/Source/core/timing/PerformanceTiming.h
@@ -33,6 +33,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/frame/DOMWindowProperty.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 
@@ -41,12 +42,15 @@
 class DocumentLoadTiming;
 class DocumentLoader;
 struct DocumentTiming;
-class Frame;
+class LocalFrame;
 class ResourceLoadTiming;
 
-class PerformanceTiming FINAL : public RefCounted<PerformanceTiming>, public ScriptWrappable, public DOMWindowProperty {
+class PerformanceTiming FINAL : public RefCountedWillBeGarbageCollectedFinalized<PerformanceTiming>, public ScriptWrappable, public DOMWindowProperty {
 public:
-    static PassRefPtr<PerformanceTiming> create(Frame* frame) { return adoptRef(new PerformanceTiming(frame)); }
+    static PassRefPtrWillBeRawPtr<PerformanceTiming> create(LocalFrame* frame)
+    {
+        return adoptRefWillBeNoop(new PerformanceTiming(frame));
+    }
 
     unsigned long long navigationStart() const;
     unsigned long long unloadEventStart() const;
@@ -70,8 +74,10 @@
     unsigned long long loadEventStart() const;
     unsigned long long loadEventEnd() const;
 
+    void trace(Visitor*) { }
+
 private:
-    explicit PerformanceTiming(Frame*);
+    explicit PerformanceTiming(LocalFrame*);
 
     const DocumentTiming* documentTiming() const;
     DocumentLoader* documentLoader() const;
diff --git a/Source/core/timing/PerformanceTiming.idl b/Source/core/timing/PerformanceTiming.idl
index 160e5cc..3178e42 100644
--- a/Source/core/timing/PerformanceTiming.idl
+++ b/Source/core/timing/PerformanceTiming.idl
@@ -29,7 +29,9 @@
  */
 
 // See: http://dev.w3.org/2006/webapi/WebTiming/
-interface PerformanceTiming {
+[
+    WillBeGarbageCollected
+] interface PerformanceTiming {
     readonly attribute unsigned long long navigationStart;
     readonly attribute unsigned long long unloadEventStart;
     readonly attribute unsigned long long unloadEventEnd;
diff --git a/Source/core/timing/PerformanceUserTiming.cpp b/Source/core/timing/PerformanceUserTiming.cpp
index f1f7836..853c6d6 100644
--- a/Source/core/timing/PerformanceUserTiming.cpp
+++ b/Source/core/timing/PerformanceUserTiming.cpp
@@ -74,16 +74,16 @@
 {
 }
 
-static void insertPerformanceEntry(PerformanceEntryMap& performanceEntryMap, PassRefPtr<PerformanceEntry> performanceEntry)
+static void insertPerformanceEntry(PerformanceEntryMap& performanceEntryMap, PassRefPtrWillBeRawPtr<PerformanceEntry> performanceEntry)
 {
-    RefPtr<PerformanceEntry> entry = performanceEntry;
+    RefPtrWillBeRawPtr<PerformanceEntry> entry = performanceEntry;
     PerformanceEntryMap::iterator it = performanceEntryMap.find(entry->name());
     if (it != performanceEntryMap.end())
         it->value.append(entry);
     else {
-        Vector<RefPtr<PerformanceEntry> > v(1);
-        v[0] = entry;
-        performanceEntryMap.set(entry->name(), v);
+        PerformanceEntryVector vector(1);
+        vector[0] = entry;
+        performanceEntryMap.set(entry->name(), vector);
     }
 }
 
@@ -164,45 +164,52 @@
     clearPeformanceEntries(m_measuresMap, measureName);
 }
 
-static Vector<RefPtr<PerformanceEntry> > convertToEntrySequence(const PerformanceEntryMap& performanceEntryMap)
+static PerformanceEntryVector convertToEntrySequence(const PerformanceEntryMap& performanceEntryMap)
 {
-    Vector<RefPtr<PerformanceEntry> > entries;
+    PerformanceEntryVector entries;
 
     for (PerformanceEntryMap::const_iterator it = performanceEntryMap.begin(); it != performanceEntryMap.end(); ++it)
-        entries.append(it->value);
+        entries.appendVector(it->value);
 
     return entries;
 }
 
-static Vector<RefPtr<PerformanceEntry> > getEntrySequenceByName(const PerformanceEntryMap& performanceEntryMap, const String& name)
+static PerformanceEntryVector getEntrySequenceByName(const PerformanceEntryMap& performanceEntryMap, const String& name)
 {
-    Vector<RefPtr<PerformanceEntry> > entries;
+    PerformanceEntryVector entries;
 
     PerformanceEntryMap::const_iterator it = performanceEntryMap.find(name);
     if (it != performanceEntryMap.end())
-        entries.append(it->value);
+        entries.appendVector(it->value);
 
     return entries;
 }
 
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMarks() const
+PerformanceEntryVector UserTiming::getMarks() const
 {
     return convertToEntrySequence(m_marksMap);
 }
 
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMarks(const String& name) const
+PerformanceEntryVector UserTiming::getMarks(const String& name) const
 {
     return getEntrySequenceByName(m_marksMap, name);
 }
 
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMeasures() const
+PerformanceEntryVector UserTiming::getMeasures() const
 {
     return convertToEntrySequence(m_measuresMap);
 }
 
-Vector<RefPtr<PerformanceEntry> > UserTiming::getMeasures(const String& name) const
+PerformanceEntryVector UserTiming::getMeasures(const String& name) const
 {
     return getEntrySequenceByName(m_measuresMap, name);
 }
 
+void UserTiming::trace(Visitor* visitor)
+{
+    visitor->trace(m_performance);
+    visitor->trace(m_marksMap);
+    visitor->trace(m_measuresMap);
+}
+
 } // namespace WebCore
diff --git a/Source/core/timing/PerformanceUserTiming.h b/Source/core/timing/PerformanceUserTiming.h
index c12d6cf..ff45d5c 100644
--- a/Source/core/timing/PerformanceUserTiming.h
+++ b/Source/core/timing/PerformanceUserTiming.h
@@ -26,7 +26,9 @@
 #ifndef PerformanceUserTiming_h
 #define PerformanceUserTiming_h
 
+#include "core/timing/Performance.h"
 #include "core/timing/PerformanceTiming.h"
+#include "heap/Handle.h"
 #include "wtf/HashMap.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -40,11 +42,14 @@
 class PerformanceEntry;
 
 typedef unsigned long long (PerformanceTiming::*NavigationTimingFunction)() const;
-typedef HashMap<String, Vector<RefPtr<PerformanceEntry> > > PerformanceEntryMap;
+typedef WillBeHeapHashMap<String, PerformanceEntryVector> PerformanceEntryMap;
 
-class UserTiming : public RefCounted<UserTiming> {
+class UserTiming : public RefCountedWillBeGarbageCollected<UserTiming> {
 public:
-    static PassRefPtr<UserTiming> create(Performance* performance) { return adoptRef(new UserTiming(performance)); }
+    static PassRefPtrWillBeRawPtr<UserTiming> create(Performance* performance)
+    {
+        return adoptRefWillBeNoop(new UserTiming(performance));
+    }
 
     void mark(const String& markName, ExceptionState&);
     void clearMarks(const String& markName);
@@ -52,17 +57,19 @@
     void measure(const String& measureName, const String& startMark, const String& endMark, ExceptionState&);
     void clearMeasures(const String& measureName);
 
-    Vector<RefPtr<PerformanceEntry> > getMarks() const;
-    Vector<RefPtr<PerformanceEntry> > getMeasures() const;
+    PerformanceEntryVector getMarks() const;
+    PerformanceEntryVector getMeasures() const;
 
-    Vector<RefPtr<PerformanceEntry> > getMarks(const String& name) const;
-    Vector<RefPtr<PerformanceEntry> > getMeasures(const String& name) const;
+    PerformanceEntryVector getMarks(const String& name) const;
+    PerformanceEntryVector getMeasures(const String& name) const;
+
+    void trace(Visitor*);
 
 private:
     explicit UserTiming(Performance*);
 
     double findExistingMarkStartTime(const String& markName, ExceptionState&);
-    Performance* m_performance;
+    RawPtrWillBeMember<Performance> m_performance;
     PerformanceEntryMap m_marksMap;
     PerformanceEntryMap m_measuresMap;
 };
diff --git a/Source/core/timing/ResourceTimingInfo.h b/Source/core/timing/ResourceTimingInfo.h
index a3784a6..ef3f42d 100644
--- a/Source/core/timing/ResourceTimingInfo.h
+++ b/Source/core/timing/ResourceTimingInfo.h
@@ -63,9 +63,9 @@
 
     void clearLoadTimings()
     {
-        m_finalResponse.setResourceLoadTiming(0);
+        m_finalResponse.setResourceLoadTiming(nullptr);
         for (size_t i = 0; i < m_redirectChain.size(); ++i)
-            m_redirectChain[i].setResourceLoadTiming(0);
+            m_redirectChain[i].setResourceLoadTiming(nullptr);
     }
 
 private:
diff --git a/Source/core/webcore_dom.target.darwin-arm.mk b/Source/core/webcore_dom.target.darwin-arm.mk
index 992b695..9a49bcf 100644
--- a/Source/core/webcore_dom.target.darwin-arm.mk
+++ b/Source/core/webcore_dom.target.darwin-arm.mk
@@ -74,13 +74,14 @@
 	third_party/WebKit/Source/core/dom/ElementDataCache.cpp \
 	third_party/WebKit/Source/core/dom/ElementRareData.cpp \
 	third_party/WebKit/Source/core/dom/EmptyNodeList.cpp \
-	third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp \
 	third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp \
 	third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp \
+	third_party/WebKit/Source/core/dom/SiblingRuleHelper.cpp \
 	third_party/WebKit/Source/core/dom/IconURL.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserver.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp \
 	third_party/WebKit/Source/core/dom/LiveNodeList.cpp \
+	third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp \
 	third_party/WebKit/Source/core/dom/MessageChannel.cpp \
 	third_party/WebKit/Source/core/dom/MessagePort.cpp \
 	third_party/WebKit/Source/core/dom/Microtask.cpp \
@@ -96,6 +97,7 @@
 	third_party/WebKit/Source/core/dom/NodeFilter.cpp \
 	third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp \
 	third_party/WebKit/Source/core/dom/NodeIterator.cpp \
+	third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp \
 	third_party/WebKit/Source/core/dom/NodeRareData.cpp \
 	third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp \
 	third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp \
@@ -154,7 +156,6 @@
 	third_party/WebKit/Source/core/dom/Touch.cpp \
 	third_party/WebKit/Source/core/dom/TouchList.cpp \
 	third_party/WebKit/Source/core/dom/TransformSourceLibxslt.cpp \
-	third_party/WebKit/Source/core/dom/Traversal.cpp \
 	third_party/WebKit/Source/core/dom/TreeScope.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp \
@@ -241,6 +242,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -248,9 +250,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -259,12 +261,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -274,8 +273,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -284,6 +288,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -390,6 +395,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -397,9 +403,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -408,12 +414,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -423,8 +426,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -433,6 +441,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -506,9 +515,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -520,7 +531,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -528,6 +538,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -542,7 +553,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_dom.target.darwin-mips.mk b/Source/core/webcore_dom.target.darwin-mips.mk
index 3eeb867..b3c1d94 100644
--- a/Source/core/webcore_dom.target.darwin-mips.mk
+++ b/Source/core/webcore_dom.target.darwin-mips.mk
@@ -74,13 +74,14 @@
 	third_party/WebKit/Source/core/dom/ElementDataCache.cpp \
 	third_party/WebKit/Source/core/dom/ElementRareData.cpp \
 	third_party/WebKit/Source/core/dom/EmptyNodeList.cpp \
-	third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp \
 	third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp \
 	third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp \
+	third_party/WebKit/Source/core/dom/SiblingRuleHelper.cpp \
 	third_party/WebKit/Source/core/dom/IconURL.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserver.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp \
 	third_party/WebKit/Source/core/dom/LiveNodeList.cpp \
+	third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp \
 	third_party/WebKit/Source/core/dom/MessageChannel.cpp \
 	third_party/WebKit/Source/core/dom/MessagePort.cpp \
 	third_party/WebKit/Source/core/dom/Microtask.cpp \
@@ -96,6 +97,7 @@
 	third_party/WebKit/Source/core/dom/NodeFilter.cpp \
 	third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp \
 	third_party/WebKit/Source/core/dom/NodeIterator.cpp \
+	third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp \
 	third_party/WebKit/Source/core/dom/NodeRareData.cpp \
 	third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp \
 	third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp \
@@ -154,7 +156,6 @@
 	third_party/WebKit/Source/core/dom/Touch.cpp \
 	third_party/WebKit/Source/core/dom/TouchList.cpp \
 	third_party/WebKit/Source/core/dom/TransformSourceLibxslt.cpp \
-	third_party/WebKit/Source/core/dom/Traversal.cpp \
 	third_party/WebKit/Source/core/dom/TreeScope.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp \
@@ -240,6 +241,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -247,9 +249,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -258,12 +260,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -273,8 +272,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -283,6 +287,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -388,6 +393,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -395,9 +401,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -406,12 +412,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -421,8 +424,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -431,6 +439,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -504,9 +513,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -516,7 +527,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -524,6 +534,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -536,7 +547,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_dom.target.darwin-x86.mk b/Source/core/webcore_dom.target.darwin-x86.mk
index 78f67d4..696d525 100644
--- a/Source/core/webcore_dom.target.darwin-x86.mk
+++ b/Source/core/webcore_dom.target.darwin-x86.mk
@@ -74,13 +74,14 @@
 	third_party/WebKit/Source/core/dom/ElementDataCache.cpp \
 	third_party/WebKit/Source/core/dom/ElementRareData.cpp \
 	third_party/WebKit/Source/core/dom/EmptyNodeList.cpp \
-	third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp \
 	third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp \
 	third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp \
+	third_party/WebKit/Source/core/dom/SiblingRuleHelper.cpp \
 	third_party/WebKit/Source/core/dom/IconURL.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserver.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp \
 	third_party/WebKit/Source/core/dom/LiveNodeList.cpp \
+	third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp \
 	third_party/WebKit/Source/core/dom/MessageChannel.cpp \
 	third_party/WebKit/Source/core/dom/MessagePort.cpp \
 	third_party/WebKit/Source/core/dom/Microtask.cpp \
@@ -96,6 +97,7 @@
 	third_party/WebKit/Source/core/dom/NodeFilter.cpp \
 	third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp \
 	third_party/WebKit/Source/core/dom/NodeIterator.cpp \
+	third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp \
 	third_party/WebKit/Source/core/dom/NodeRareData.cpp \
 	third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp \
 	third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp \
@@ -154,7 +156,6 @@
 	third_party/WebKit/Source/core/dom/Touch.cpp \
 	third_party/WebKit/Source/core/dom/TouchList.cpp \
 	third_party/WebKit/Source/core/dom/TransformSourceLibxslt.cpp \
-	third_party/WebKit/Source/core/dom/Traversal.cpp \
 	third_party/WebKit/Source/core/dom/TreeScope.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp \
@@ -216,11 +217,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -243,6 +243,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -250,9 +251,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -261,12 +262,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -276,8 +274,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -286,6 +289,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -366,11 +370,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -393,6 +396,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -400,9 +404,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -411,12 +415,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -426,8 +427,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -436,6 +442,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -508,9 +515,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -520,7 +529,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -528,6 +536,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -540,7 +549,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_dom.target.linux-arm.mk b/Source/core/webcore_dom.target.linux-arm.mk
index 992b695..9a49bcf 100644
--- a/Source/core/webcore_dom.target.linux-arm.mk
+++ b/Source/core/webcore_dom.target.linux-arm.mk
@@ -74,13 +74,14 @@
 	third_party/WebKit/Source/core/dom/ElementDataCache.cpp \
 	third_party/WebKit/Source/core/dom/ElementRareData.cpp \
 	third_party/WebKit/Source/core/dom/EmptyNodeList.cpp \
-	third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp \
 	third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp \
 	third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp \
+	third_party/WebKit/Source/core/dom/SiblingRuleHelper.cpp \
 	third_party/WebKit/Source/core/dom/IconURL.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserver.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp \
 	third_party/WebKit/Source/core/dom/LiveNodeList.cpp \
+	third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp \
 	third_party/WebKit/Source/core/dom/MessageChannel.cpp \
 	third_party/WebKit/Source/core/dom/MessagePort.cpp \
 	third_party/WebKit/Source/core/dom/Microtask.cpp \
@@ -96,6 +97,7 @@
 	third_party/WebKit/Source/core/dom/NodeFilter.cpp \
 	third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp \
 	third_party/WebKit/Source/core/dom/NodeIterator.cpp \
+	third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp \
 	third_party/WebKit/Source/core/dom/NodeRareData.cpp \
 	third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp \
 	third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp \
@@ -154,7 +156,6 @@
 	third_party/WebKit/Source/core/dom/Touch.cpp \
 	third_party/WebKit/Source/core/dom/TouchList.cpp \
 	third_party/WebKit/Source/core/dom/TransformSourceLibxslt.cpp \
-	third_party/WebKit/Source/core/dom/Traversal.cpp \
 	third_party/WebKit/Source/core/dom/TreeScope.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp \
@@ -241,6 +242,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -248,9 +250,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -259,12 +261,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -274,8 +273,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -284,6 +288,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -390,6 +395,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -397,9 +403,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -408,12 +414,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -423,8 +426,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -433,6 +441,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -506,9 +515,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -520,7 +531,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -528,6 +538,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -542,7 +553,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_dom.target.linux-mips.mk b/Source/core/webcore_dom.target.linux-mips.mk
index 3eeb867..b3c1d94 100644
--- a/Source/core/webcore_dom.target.linux-mips.mk
+++ b/Source/core/webcore_dom.target.linux-mips.mk
@@ -74,13 +74,14 @@
 	third_party/WebKit/Source/core/dom/ElementDataCache.cpp \
 	third_party/WebKit/Source/core/dom/ElementRareData.cpp \
 	third_party/WebKit/Source/core/dom/EmptyNodeList.cpp \
-	third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp \
 	third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp \
 	third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp \
+	third_party/WebKit/Source/core/dom/SiblingRuleHelper.cpp \
 	third_party/WebKit/Source/core/dom/IconURL.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserver.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp \
 	third_party/WebKit/Source/core/dom/LiveNodeList.cpp \
+	third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp \
 	third_party/WebKit/Source/core/dom/MessageChannel.cpp \
 	third_party/WebKit/Source/core/dom/MessagePort.cpp \
 	third_party/WebKit/Source/core/dom/Microtask.cpp \
@@ -96,6 +97,7 @@
 	third_party/WebKit/Source/core/dom/NodeFilter.cpp \
 	third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp \
 	third_party/WebKit/Source/core/dom/NodeIterator.cpp \
+	third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp \
 	third_party/WebKit/Source/core/dom/NodeRareData.cpp \
 	third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp \
 	third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp \
@@ -154,7 +156,6 @@
 	third_party/WebKit/Source/core/dom/Touch.cpp \
 	third_party/WebKit/Source/core/dom/TouchList.cpp \
 	third_party/WebKit/Source/core/dom/TransformSourceLibxslt.cpp \
-	third_party/WebKit/Source/core/dom/Traversal.cpp \
 	third_party/WebKit/Source/core/dom/TreeScope.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp \
@@ -240,6 +241,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -247,9 +249,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -258,12 +260,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -273,8 +272,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -283,6 +287,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -388,6 +393,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -395,9 +401,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -406,12 +412,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -421,8 +424,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -431,6 +439,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -504,9 +513,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -516,7 +527,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -524,6 +534,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -536,7 +547,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_dom.target.linux-x86.mk b/Source/core/webcore_dom.target.linux-x86.mk
index 78f67d4..696d525 100644
--- a/Source/core/webcore_dom.target.linux-x86.mk
+++ b/Source/core/webcore_dom.target.linux-x86.mk
@@ -74,13 +74,14 @@
 	third_party/WebKit/Source/core/dom/ElementDataCache.cpp \
 	third_party/WebKit/Source/core/dom/ElementRareData.cpp \
 	third_party/WebKit/Source/core/dom/EmptyNodeList.cpp \
-	third_party/WebKit/Source/core/dom/ExecutionContextTask.cpp \
 	third_party/WebKit/Source/core/dom/MainThreadTaskRunner.cpp \
 	third_party/WebKit/Source/core/dom/FullscreenElementStack.cpp \
+	third_party/WebKit/Source/core/dom/SiblingRuleHelper.cpp \
 	third_party/WebKit/Source/core/dom/IconURL.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserver.cpp \
 	third_party/WebKit/Source/core/dom/IdTargetObserverRegistry.cpp \
 	third_party/WebKit/Source/core/dom/LiveNodeList.cpp \
+	third_party/WebKit/Source/core/dom/LiveNodeListBase.cpp \
 	third_party/WebKit/Source/core/dom/MessageChannel.cpp \
 	third_party/WebKit/Source/core/dom/MessagePort.cpp \
 	third_party/WebKit/Source/core/dom/Microtask.cpp \
@@ -96,6 +97,7 @@
 	third_party/WebKit/Source/core/dom/NodeFilter.cpp \
 	third_party/WebKit/Source/core/dom/NodeFilterCondition.cpp \
 	third_party/WebKit/Source/core/dom/NodeIterator.cpp \
+	third_party/WebKit/Source/core/dom/NodeIteratorBase.cpp \
 	third_party/WebKit/Source/core/dom/NodeRareData.cpp \
 	third_party/WebKit/Source/core/dom/RenderTreeBuilder.cpp \
 	third_party/WebKit/Source/core/dom/NodeRenderingTraversal.cpp \
@@ -154,7 +156,6 @@
 	third_party/WebKit/Source/core/dom/Touch.cpp \
 	third_party/WebKit/Source/core/dom/TouchList.cpp \
 	third_party/WebKit/Source/core/dom/TransformSourceLibxslt.cpp \
-	third_party/WebKit/Source/core/dom/Traversal.cpp \
 	third_party/WebKit/Source/core/dom/TreeScope.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeAdopter.cpp \
 	third_party/WebKit/Source/core/dom/TreeScopeStyleSheetCollection.cpp \
@@ -216,11 +217,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -243,6 +243,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -250,9 +251,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -261,12 +262,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -276,8 +274,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -286,6 +289,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -366,11 +370,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -393,6 +396,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -400,9 +404,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -411,12 +415,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -426,8 +427,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -436,6 +442,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -508,9 +515,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -520,7 +529,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -528,6 +536,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -540,7 +549,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_generated.target.darwin-arm.mk b/Source/core/webcore_generated.target.darwin-arm.mk
index ff7a9a2..3000330 100644
--- a/Source/core/webcore_generated.target.darwin-arm.mk
+++ b/Source/core/webcore_generated.target.darwin-arm.mk
@@ -108,6 +108,10 @@
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/HTMLEntityTable.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp
 	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaFeatureNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp
+	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaTypeNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp
+	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/CSSTokenizer.cpp: $(gyp_shared_intermediate_dir)/blink/CSSTokenizer.cpp
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/BisonCSSParser.cpp: $(gyp_shared_intermediate_dir)/blink/BisonCSSParser.cpp
@@ -175,6 +179,8 @@
 	$(gyp_intermediate_dir)/XMLNSNames.cpp \
 	$(gyp_intermediate_dir)/XMLNames.cpp \
 	$(gyp_intermediate_dir)/HTMLEntityTable.cpp \
+	$(gyp_intermediate_dir)/MediaFeatureNames.cpp \
+	$(gyp_intermediate_dir)/MediaTypeNames.cpp \
 	$(gyp_intermediate_dir)/CSSTokenizer.cpp \
 	$(gyp_intermediate_dir)/BisonCSSParser.cpp \
 	$(gyp_intermediate_dir)/HTMLMetaElement.cpp \
@@ -234,13 +240,15 @@
 	third_party/WebKit/Source/bindings/v8/V8Binding.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Callback.cpp \
 	third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp \
+	third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp \
-	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp \
+	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCController.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp \
+	third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Initializer.cpp \
 	third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp \
@@ -254,7 +262,6 @@
 	third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp \
 	third_party/WebKit/Source/bindings/v8/V8StringResource.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp \
-	third_party/WebKit/Source/bindings/v8/V8Utilities.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp \
@@ -270,7 +277,6 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \
@@ -324,7 +330,7 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp \
+	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextBaseCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp \
@@ -372,6 +378,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -379,9 +386,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -390,12 +397,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -405,8 +409,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -415,6 +424,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -526,6 +536,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -533,9 +544,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -544,12 +555,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -559,8 +567,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -569,6 +582,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -647,9 +661,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -661,7 +677,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -669,6 +684,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -683,7 +699,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_generated.target.darwin-mips.mk b/Source/core/webcore_generated.target.darwin-mips.mk
index bf10518..9f6d09b 100644
--- a/Source/core/webcore_generated.target.darwin-mips.mk
+++ b/Source/core/webcore_generated.target.darwin-mips.mk
@@ -108,6 +108,10 @@
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/HTMLEntityTable.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp
 	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaFeatureNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp
+	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaTypeNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp
+	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/CSSTokenizer.cpp: $(gyp_shared_intermediate_dir)/blink/CSSTokenizer.cpp
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/BisonCSSParser.cpp: $(gyp_shared_intermediate_dir)/blink/BisonCSSParser.cpp
@@ -175,6 +179,8 @@
 	$(gyp_intermediate_dir)/XMLNSNames.cpp \
 	$(gyp_intermediate_dir)/XMLNames.cpp \
 	$(gyp_intermediate_dir)/HTMLEntityTable.cpp \
+	$(gyp_intermediate_dir)/MediaFeatureNames.cpp \
+	$(gyp_intermediate_dir)/MediaTypeNames.cpp \
 	$(gyp_intermediate_dir)/CSSTokenizer.cpp \
 	$(gyp_intermediate_dir)/BisonCSSParser.cpp \
 	$(gyp_intermediate_dir)/HTMLMetaElement.cpp \
@@ -234,13 +240,15 @@
 	third_party/WebKit/Source/bindings/v8/V8Binding.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Callback.cpp \
 	third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp \
+	third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp \
-	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp \
+	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCController.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp \
+	third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Initializer.cpp \
 	third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp \
@@ -254,7 +262,6 @@
 	third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp \
 	third_party/WebKit/Source/bindings/v8/V8StringResource.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp \
-	third_party/WebKit/Source/bindings/v8/V8Utilities.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp \
@@ -270,7 +277,6 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \
@@ -324,7 +330,7 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp \
+	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextBaseCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp \
@@ -371,6 +377,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -378,9 +385,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -389,12 +396,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -404,8 +408,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -414,6 +423,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -524,6 +534,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -531,9 +542,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -542,12 +553,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -557,8 +565,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -567,6 +580,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -645,9 +659,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -657,7 +673,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -665,6 +680,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -677,7 +693,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_generated.target.darwin-x86.mk b/Source/core/webcore_generated.target.darwin-x86.mk
index 96b8300..2a41c96 100644
--- a/Source/core/webcore_generated.target.darwin-x86.mk
+++ b/Source/core/webcore_generated.target.darwin-x86.mk
@@ -108,6 +108,10 @@
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/HTMLEntityTable.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp
 	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaFeatureNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp
+	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaTypeNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp
+	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/CSSTokenizer.cpp: $(gyp_shared_intermediate_dir)/blink/CSSTokenizer.cpp
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/BisonCSSParser.cpp: $(gyp_shared_intermediate_dir)/blink/BisonCSSParser.cpp
@@ -175,6 +179,8 @@
 	$(gyp_intermediate_dir)/XMLNSNames.cpp \
 	$(gyp_intermediate_dir)/XMLNames.cpp \
 	$(gyp_intermediate_dir)/HTMLEntityTable.cpp \
+	$(gyp_intermediate_dir)/MediaFeatureNames.cpp \
+	$(gyp_intermediate_dir)/MediaTypeNames.cpp \
 	$(gyp_intermediate_dir)/CSSTokenizer.cpp \
 	$(gyp_intermediate_dir)/BisonCSSParser.cpp \
 	$(gyp_intermediate_dir)/HTMLMetaElement.cpp \
@@ -234,13 +240,15 @@
 	third_party/WebKit/Source/bindings/v8/V8Binding.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Callback.cpp \
 	third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp \
+	third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp \
-	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp \
+	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCController.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp \
+	third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Initializer.cpp \
 	third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp \
@@ -254,7 +262,6 @@
 	third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp \
 	third_party/WebKit/Source/bindings/v8/V8StringResource.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp \
-	third_party/WebKit/Source/bindings/v8/V8Utilities.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp \
@@ -270,7 +277,6 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \
@@ -324,7 +330,7 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp \
+	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextBaseCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp \
@@ -347,11 +353,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -374,6 +379,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -381,9 +387,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -392,12 +398,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -407,8 +410,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -417,6 +425,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -502,11 +511,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -529,6 +537,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -536,9 +545,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -547,12 +556,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -562,8 +568,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -572,6 +583,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -649,9 +661,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -661,7 +675,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -669,6 +682,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -681,7 +695,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_generated.target.linux-arm.mk b/Source/core/webcore_generated.target.linux-arm.mk
index ff7a9a2..3000330 100644
--- a/Source/core/webcore_generated.target.linux-arm.mk
+++ b/Source/core/webcore_generated.target.linux-arm.mk
@@ -108,6 +108,10 @@
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/HTMLEntityTable.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp
 	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaFeatureNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp
+	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaTypeNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp
+	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/CSSTokenizer.cpp: $(gyp_shared_intermediate_dir)/blink/CSSTokenizer.cpp
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/BisonCSSParser.cpp: $(gyp_shared_intermediate_dir)/blink/BisonCSSParser.cpp
@@ -175,6 +179,8 @@
 	$(gyp_intermediate_dir)/XMLNSNames.cpp \
 	$(gyp_intermediate_dir)/XMLNames.cpp \
 	$(gyp_intermediate_dir)/HTMLEntityTable.cpp \
+	$(gyp_intermediate_dir)/MediaFeatureNames.cpp \
+	$(gyp_intermediate_dir)/MediaTypeNames.cpp \
 	$(gyp_intermediate_dir)/CSSTokenizer.cpp \
 	$(gyp_intermediate_dir)/BisonCSSParser.cpp \
 	$(gyp_intermediate_dir)/HTMLMetaElement.cpp \
@@ -234,13 +240,15 @@
 	third_party/WebKit/Source/bindings/v8/V8Binding.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Callback.cpp \
 	third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp \
+	third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp \
-	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp \
+	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCController.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp \
+	third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Initializer.cpp \
 	third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp \
@@ -254,7 +262,6 @@
 	third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp \
 	third_party/WebKit/Source/bindings/v8/V8StringResource.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp \
-	third_party/WebKit/Source/bindings/v8/V8Utilities.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp \
@@ -270,7 +277,6 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \
@@ -324,7 +330,7 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp \
+	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextBaseCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp \
@@ -372,6 +378,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -379,9 +386,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -390,12 +397,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -405,8 +409,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -415,6 +424,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -526,6 +536,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -533,9 +544,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -544,12 +555,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -559,8 +567,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -569,6 +582,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -647,9 +661,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -661,7 +677,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -669,6 +684,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -683,7 +699,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_generated.target.linux-mips.mk b/Source/core/webcore_generated.target.linux-mips.mk
index bf10518..9f6d09b 100644
--- a/Source/core/webcore_generated.target.linux-mips.mk
+++ b/Source/core/webcore_generated.target.linux-mips.mk
@@ -108,6 +108,10 @@
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/HTMLEntityTable.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp
 	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaFeatureNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp
+	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaTypeNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp
+	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/CSSTokenizer.cpp: $(gyp_shared_intermediate_dir)/blink/CSSTokenizer.cpp
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/BisonCSSParser.cpp: $(gyp_shared_intermediate_dir)/blink/BisonCSSParser.cpp
@@ -175,6 +179,8 @@
 	$(gyp_intermediate_dir)/XMLNSNames.cpp \
 	$(gyp_intermediate_dir)/XMLNames.cpp \
 	$(gyp_intermediate_dir)/HTMLEntityTable.cpp \
+	$(gyp_intermediate_dir)/MediaFeatureNames.cpp \
+	$(gyp_intermediate_dir)/MediaTypeNames.cpp \
 	$(gyp_intermediate_dir)/CSSTokenizer.cpp \
 	$(gyp_intermediate_dir)/BisonCSSParser.cpp \
 	$(gyp_intermediate_dir)/HTMLMetaElement.cpp \
@@ -234,13 +240,15 @@
 	third_party/WebKit/Source/bindings/v8/V8Binding.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Callback.cpp \
 	third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp \
+	third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp \
-	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp \
+	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCController.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp \
+	third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Initializer.cpp \
 	third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp \
@@ -254,7 +262,6 @@
 	third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp \
 	third_party/WebKit/Source/bindings/v8/V8StringResource.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp \
-	third_party/WebKit/Source/bindings/v8/V8Utilities.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp \
@@ -270,7 +277,6 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \
@@ -324,7 +330,7 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp \
+	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextBaseCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp \
@@ -371,6 +377,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -378,9 +385,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -389,12 +396,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -404,8 +408,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -414,6 +423,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -524,6 +534,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -531,9 +542,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -542,12 +553,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -557,8 +565,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -567,6 +580,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -645,9 +659,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -657,7 +673,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -665,6 +680,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -677,7 +693,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_generated.target.linux-x86.mk b/Source/core/webcore_generated.target.linux-x86.mk
index 96b8300..2a41c96 100644
--- a/Source/core/webcore_generated.target.linux-x86.mk
+++ b/Source/core/webcore_generated.target.linux-x86.mk
@@ -108,6 +108,10 @@
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/HTMLEntityTable.cpp: $(gyp_shared_intermediate_dir)/blink/HTMLEntityTable.cpp
 	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaFeatureNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaFeatureNames.cpp
+	mkdir -p $(@D); cp $< $@
+$(gyp_intermediate_dir)/MediaTypeNames.cpp: $(gyp_shared_intermediate_dir)/blink/MediaTypeNames.cpp
+	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/CSSTokenizer.cpp: $(gyp_shared_intermediate_dir)/blink/CSSTokenizer.cpp
 	mkdir -p $(@D); cp $< $@
 $(gyp_intermediate_dir)/BisonCSSParser.cpp: $(gyp_shared_intermediate_dir)/blink/BisonCSSParser.cpp
@@ -175,6 +179,8 @@
 	$(gyp_intermediate_dir)/XMLNSNames.cpp \
 	$(gyp_intermediate_dir)/XMLNames.cpp \
 	$(gyp_intermediate_dir)/HTMLEntityTable.cpp \
+	$(gyp_intermediate_dir)/MediaFeatureNames.cpp \
+	$(gyp_intermediate_dir)/MediaTypeNames.cpp \
 	$(gyp_intermediate_dir)/CSSTokenizer.cpp \
 	$(gyp_intermediate_dir)/BisonCSSParser.cpp \
 	$(gyp_intermediate_dir)/HTMLMetaElement.cpp \
@@ -234,13 +240,15 @@
 	third_party/WebKit/Source/bindings/v8/V8Binding.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Callback.cpp \
 	third_party/WebKit/Source/bindings/v8/V8CustomElementLifecycleCallbacks.cpp \
+	third_party/WebKit/Source/bindings/v8/V8DOMActivityLogger.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMConfiguration.cpp \
-	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8DOMWrapper.cpp \
+	third_party/WebKit/Source/bindings/v8/V8ErrorHandler.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8EventListenerList.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCController.cpp \
 	third_party/WebKit/Source/bindings/v8/V8GCForContextDispose.cpp \
+	third_party/WebKit/Source/bindings/v8/V8HiddenValue.cpp \
 	third_party/WebKit/Source/bindings/v8/V8Initializer.cpp \
 	third_party/WebKit/Source/bindings/v8/V8LazyEventListener.cpp \
 	third_party/WebKit/Source/bindings/v8/V8MutationCallback.cpp \
@@ -254,7 +262,6 @@
 	third_party/WebKit/Source/bindings/v8/V8ScriptRunner.cpp \
 	third_party/WebKit/Source/bindings/v8/V8StringResource.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ThrowException.cpp \
-	third_party/WebKit/Source/bindings/v8/V8Utilities.cpp \
 	third_party/WebKit/Source/bindings/v8/V8ValueCache.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WindowShell.cpp \
 	third_party/WebKit/Source/bindings/v8/V8WorkerGlobalScopeEventListener.cpp \
@@ -270,7 +277,6 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSStyleDeclarationCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CSSValueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContext2DCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8CanvasRenderingContextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CryptoCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomEventCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8CustomSQLStatementErrorCallback.cpp \
@@ -324,7 +330,7 @@
 	third_party/WebKit/Source/bindings/v8/custom/V8TextCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TextTrackCueCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8TrackEventCustom.cpp \
-	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextCustom.cpp \
+	third_party/WebKit/Source/bindings/v8/custom/V8WebGLRenderingContextBaseCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WebKitPointCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WindowCustom.cpp \
 	third_party/WebKit/Source/bindings/v8/custom/V8WorkerGlobalScopeCustom.cpp \
@@ -347,11 +353,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -374,6 +379,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -381,9 +387,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -392,12 +398,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -407,8 +410,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -417,6 +425,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -502,11 +511,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -529,6 +537,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -536,9 +545,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -547,12 +556,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -562,8 +568,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -572,6 +583,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -649,9 +661,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -661,7 +675,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -669,6 +682,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -681,7 +695,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_html.target.darwin-arm.mk b/Source/core/webcore_html.target.darwin-arm.mk
index 5d6322c..147d980 100644
--- a/Source/core/webcore_html.target.darwin-arm.mk
+++ b/Source/core/webcore_html.target.darwin-arm.mk
@@ -39,6 +39,7 @@
 	third_party/WebKit/Source/core/html/HTMLButtonElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCollection.cpp \
+	third_party/WebKit/Source/core/html/HTMLContentElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDataListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp \
@@ -66,11 +67,6 @@
 	third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImport.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportsController.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportChild.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportStateResolver.cpp \
 	third_party/WebKit/Source/core/html/HTMLInputElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLLIElement.cpp \
@@ -102,6 +98,7 @@
 	third_party/WebKit/Source/core/html/HTMLRubyElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLScriptElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSelectElement.cpp \
+	third_party/WebKit/Source/core/html/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSourceElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSpanElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLStyleElement.cpp \
@@ -127,7 +124,6 @@
 	third_party/WebKit/Source/core/html/ImageDocument.cpp \
 	third_party/WebKit/Source/core/html/LabelableElement.cpp \
 	third_party/WebKit/Source/core/html/LabelsNodeList.cpp \
-	third_party/WebKit/Source/core/html/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/LinkRelAttribute.cpp \
 	third_party/WebKit/Source/core/html/LinkResource.cpp \
 	third_party/WebKit/Source/core/html/MediaController.cpp \
@@ -180,6 +176,7 @@
 	third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp \
+	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp \
@@ -224,6 +221,12 @@
 	third_party/WebKit/Source/core/html/forms/URLInputType.cpp \
 	third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp \
 	third_party/WebKit/Source/core/html/forms/WeekInputType.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImport.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp \
+	third_party/WebKit/Source/core/html/imports/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp \
 	third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp \
@@ -260,12 +263,9 @@
 	third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DateTimeSymbolicFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControls.cpp \
-	third_party/WebKit/Source/core/html/shadow/MediaControlsAndroid.cpp \
 	third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp \
@@ -329,6 +329,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -336,9 +337,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -347,12 +348,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -362,8 +360,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -372,6 +375,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -478,6 +482,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -485,9 +490,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -496,12 +501,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -511,8 +513,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -521,6 +528,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -594,9 +602,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -608,7 +618,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -616,6 +625,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -630,7 +640,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_html.target.darwin-mips.mk b/Source/core/webcore_html.target.darwin-mips.mk
index 70d3e59..944576f 100644
--- a/Source/core/webcore_html.target.darwin-mips.mk
+++ b/Source/core/webcore_html.target.darwin-mips.mk
@@ -39,6 +39,7 @@
 	third_party/WebKit/Source/core/html/HTMLButtonElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCollection.cpp \
+	third_party/WebKit/Source/core/html/HTMLContentElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDataListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp \
@@ -66,11 +67,6 @@
 	third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImport.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportsController.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportChild.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportStateResolver.cpp \
 	third_party/WebKit/Source/core/html/HTMLInputElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLLIElement.cpp \
@@ -102,6 +98,7 @@
 	third_party/WebKit/Source/core/html/HTMLRubyElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLScriptElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSelectElement.cpp \
+	third_party/WebKit/Source/core/html/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSourceElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSpanElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLStyleElement.cpp \
@@ -127,7 +124,6 @@
 	third_party/WebKit/Source/core/html/ImageDocument.cpp \
 	third_party/WebKit/Source/core/html/LabelableElement.cpp \
 	third_party/WebKit/Source/core/html/LabelsNodeList.cpp \
-	third_party/WebKit/Source/core/html/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/LinkRelAttribute.cpp \
 	third_party/WebKit/Source/core/html/LinkResource.cpp \
 	third_party/WebKit/Source/core/html/MediaController.cpp \
@@ -180,6 +176,7 @@
 	third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp \
+	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp \
@@ -224,6 +221,12 @@
 	third_party/WebKit/Source/core/html/forms/URLInputType.cpp \
 	third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp \
 	third_party/WebKit/Source/core/html/forms/WeekInputType.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImport.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp \
+	third_party/WebKit/Source/core/html/imports/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp \
 	third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp \
@@ -260,12 +263,9 @@
 	third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DateTimeSymbolicFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControls.cpp \
-	third_party/WebKit/Source/core/html/shadow/MediaControlsAndroid.cpp \
 	third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp \
@@ -328,6 +328,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -335,9 +336,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -346,12 +347,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -361,8 +359,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -371,6 +374,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -476,6 +480,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -483,9 +488,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -494,12 +499,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -509,8 +511,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -519,6 +526,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -592,9 +600,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -604,7 +614,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -612,6 +621,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -624,7 +634,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_html.target.darwin-x86.mk b/Source/core/webcore_html.target.darwin-x86.mk
index 6aab4b0..80e6a3d 100644
--- a/Source/core/webcore_html.target.darwin-x86.mk
+++ b/Source/core/webcore_html.target.darwin-x86.mk
@@ -39,6 +39,7 @@
 	third_party/WebKit/Source/core/html/HTMLButtonElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCollection.cpp \
+	third_party/WebKit/Source/core/html/HTMLContentElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDataListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp \
@@ -66,11 +67,6 @@
 	third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImport.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportsController.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportChild.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportStateResolver.cpp \
 	third_party/WebKit/Source/core/html/HTMLInputElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLLIElement.cpp \
@@ -102,6 +98,7 @@
 	third_party/WebKit/Source/core/html/HTMLRubyElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLScriptElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSelectElement.cpp \
+	third_party/WebKit/Source/core/html/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSourceElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSpanElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLStyleElement.cpp \
@@ -127,7 +124,6 @@
 	third_party/WebKit/Source/core/html/ImageDocument.cpp \
 	third_party/WebKit/Source/core/html/LabelableElement.cpp \
 	third_party/WebKit/Source/core/html/LabelsNodeList.cpp \
-	third_party/WebKit/Source/core/html/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/LinkRelAttribute.cpp \
 	third_party/WebKit/Source/core/html/LinkResource.cpp \
 	third_party/WebKit/Source/core/html/MediaController.cpp \
@@ -180,6 +176,7 @@
 	third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp \
+	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp \
@@ -224,6 +221,12 @@
 	third_party/WebKit/Source/core/html/forms/URLInputType.cpp \
 	third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp \
 	third_party/WebKit/Source/core/html/forms/WeekInputType.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImport.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp \
+	third_party/WebKit/Source/core/html/imports/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp \
 	third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp \
@@ -260,12 +263,9 @@
 	third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DateTimeSymbolicFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControls.cpp \
-	third_party/WebKit/Source/core/html/shadow/MediaControlsAndroid.cpp \
 	third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp \
@@ -304,11 +304,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -331,6 +330,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -338,9 +338,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -349,12 +349,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -364,8 +361,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -374,6 +376,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -454,11 +457,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -481,6 +483,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -488,9 +491,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -499,12 +502,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -514,8 +514,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -524,6 +529,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -596,9 +602,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -608,7 +616,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -616,6 +623,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -628,7 +636,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_html.target.linux-arm.mk b/Source/core/webcore_html.target.linux-arm.mk
index 5d6322c..147d980 100644
--- a/Source/core/webcore_html.target.linux-arm.mk
+++ b/Source/core/webcore_html.target.linux-arm.mk
@@ -39,6 +39,7 @@
 	third_party/WebKit/Source/core/html/HTMLButtonElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCollection.cpp \
+	third_party/WebKit/Source/core/html/HTMLContentElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDataListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp \
@@ -66,11 +67,6 @@
 	third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImport.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportsController.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportChild.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportStateResolver.cpp \
 	third_party/WebKit/Source/core/html/HTMLInputElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLLIElement.cpp \
@@ -102,6 +98,7 @@
 	third_party/WebKit/Source/core/html/HTMLRubyElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLScriptElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSelectElement.cpp \
+	third_party/WebKit/Source/core/html/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSourceElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSpanElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLStyleElement.cpp \
@@ -127,7 +124,6 @@
 	third_party/WebKit/Source/core/html/ImageDocument.cpp \
 	third_party/WebKit/Source/core/html/LabelableElement.cpp \
 	third_party/WebKit/Source/core/html/LabelsNodeList.cpp \
-	third_party/WebKit/Source/core/html/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/LinkRelAttribute.cpp \
 	third_party/WebKit/Source/core/html/LinkResource.cpp \
 	third_party/WebKit/Source/core/html/MediaController.cpp \
@@ -180,6 +176,7 @@
 	third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp \
+	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp \
@@ -224,6 +221,12 @@
 	third_party/WebKit/Source/core/html/forms/URLInputType.cpp \
 	third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp \
 	third_party/WebKit/Source/core/html/forms/WeekInputType.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImport.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp \
+	third_party/WebKit/Source/core/html/imports/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp \
 	third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp \
@@ -260,12 +263,9 @@
 	third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DateTimeSymbolicFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControls.cpp \
-	third_party/WebKit/Source/core/html/shadow/MediaControlsAndroid.cpp \
 	third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp \
@@ -329,6 +329,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -336,9 +337,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -347,12 +348,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -362,8 +360,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -372,6 +375,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -478,6 +482,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -485,9 +490,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -496,12 +501,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -511,8 +513,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -521,6 +528,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -594,9 +602,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -608,7 +618,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -616,6 +625,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -630,7 +640,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_html.target.linux-mips.mk b/Source/core/webcore_html.target.linux-mips.mk
index 70d3e59..944576f 100644
--- a/Source/core/webcore_html.target.linux-mips.mk
+++ b/Source/core/webcore_html.target.linux-mips.mk
@@ -39,6 +39,7 @@
 	third_party/WebKit/Source/core/html/HTMLButtonElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCollection.cpp \
+	third_party/WebKit/Source/core/html/HTMLContentElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDataListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp \
@@ -66,11 +67,6 @@
 	third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImport.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportsController.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportChild.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportStateResolver.cpp \
 	third_party/WebKit/Source/core/html/HTMLInputElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLLIElement.cpp \
@@ -102,6 +98,7 @@
 	third_party/WebKit/Source/core/html/HTMLRubyElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLScriptElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSelectElement.cpp \
+	third_party/WebKit/Source/core/html/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSourceElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSpanElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLStyleElement.cpp \
@@ -127,7 +124,6 @@
 	third_party/WebKit/Source/core/html/ImageDocument.cpp \
 	third_party/WebKit/Source/core/html/LabelableElement.cpp \
 	third_party/WebKit/Source/core/html/LabelsNodeList.cpp \
-	third_party/WebKit/Source/core/html/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/LinkRelAttribute.cpp \
 	third_party/WebKit/Source/core/html/LinkResource.cpp \
 	third_party/WebKit/Source/core/html/MediaController.cpp \
@@ -180,6 +176,7 @@
 	third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp \
+	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp \
@@ -224,6 +221,12 @@
 	third_party/WebKit/Source/core/html/forms/URLInputType.cpp \
 	third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp \
 	third_party/WebKit/Source/core/html/forms/WeekInputType.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImport.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp \
+	third_party/WebKit/Source/core/html/imports/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp \
 	third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp \
@@ -260,12 +263,9 @@
 	third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DateTimeSymbolicFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControls.cpp \
-	third_party/WebKit/Source/core/html/shadow/MediaControlsAndroid.cpp \
 	third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp \
@@ -328,6 +328,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -335,9 +336,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -346,12 +347,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -361,8 +359,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -371,6 +374,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -476,6 +480,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -483,9 +488,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -494,12 +499,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -509,8 +511,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -519,6 +526,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -592,9 +600,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -604,7 +614,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -612,6 +621,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -624,7 +634,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_html.target.linux-x86.mk b/Source/core/webcore_html.target.linux-x86.mk
index 6aab4b0..80e6a3d 100644
--- a/Source/core/webcore_html.target.linux-x86.mk
+++ b/Source/core/webcore_html.target.linux-x86.mk
@@ -39,6 +39,7 @@
 	third_party/WebKit/Source/core/html/HTMLButtonElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCanvasElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLCollection.cpp \
+	third_party/WebKit/Source/core/html/HTMLContentElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDataListElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLDetailsElement.cpp \
@@ -66,11 +67,6 @@
 	third_party/WebKit/Source/core/html/HTMLIFrameElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLImageLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImport.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportsController.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportChild.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportLoader.cpp \
-	third_party/WebKit/Source/core/html/HTMLImportStateResolver.cpp \
 	third_party/WebKit/Source/core/html/HTMLInputElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLKeygenElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLLIElement.cpp \
@@ -102,6 +98,7 @@
 	third_party/WebKit/Source/core/html/HTMLRubyElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLScriptElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSelectElement.cpp \
+	third_party/WebKit/Source/core/html/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSourceElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLSpanElement.cpp \
 	third_party/WebKit/Source/core/html/HTMLStyleElement.cpp \
@@ -127,7 +124,6 @@
 	third_party/WebKit/Source/core/html/ImageDocument.cpp \
 	third_party/WebKit/Source/core/html/LabelableElement.cpp \
 	third_party/WebKit/Source/core/html/LabelsNodeList.cpp \
-	third_party/WebKit/Source/core/html/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/LinkRelAttribute.cpp \
 	third_party/WebKit/Source/core/html/LinkResource.cpp \
 	third_party/WebKit/Source/core/html/MediaController.cpp \
@@ -180,6 +176,7 @@
 	third_party/WebKit/Source/core/html/canvas/WebGLProgram.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderbuffer.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContext.cpp \
+	third_party/WebKit/Source/core/html/canvas/WebGLRenderingContextBase.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShader.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLShaderPrecisionFormat.cpp \
 	third_party/WebKit/Source/core/html/canvas/WebGLSharedObject.cpp \
@@ -224,6 +221,12 @@
 	third_party/WebKit/Source/core/html/forms/URLInputType.cpp \
 	third_party/WebKit/Source/core/html/forms/ValidationMessage.cpp \
 	third_party/WebKit/Source/core/html/forms/WeekInputType.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImport.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportsController.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportChild.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportLoader.cpp \
+	third_party/WebKit/Source/core/html/imports/HTMLImportStateResolver.cpp \
+	third_party/WebKit/Source/core/html/imports/LinkImport.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLParser.cpp \
 	third_party/WebKit/Source/core/html/parser/BackgroundHTMLInputStream.cpp \
 	third_party/WebKit/Source/core/html/parser/CSSPreloadScanner.cpp \
@@ -260,12 +263,9 @@
 	third_party/WebKit/Source/core/html/shadow/DateTimeNumericFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DateTimeSymbolicFieldElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/DetailsMarkerControl.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLContentElement.cpp \
-	third_party/WebKit/Source/core/html/shadow/HTMLShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElementTypes.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControlElements.cpp \
 	third_party/WebKit/Source/core/html/shadow/MediaControls.cpp \
-	third_party/WebKit/Source/core/html/shadow/MediaControlsAndroid.cpp \
 	third_party/WebKit/Source/core/html/shadow/MeterShadowElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/PasswordGeneratorButtonElement.cpp \
 	third_party/WebKit/Source/core/html/shadow/ProgressShadowElement.cpp \
@@ -304,11 +304,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -331,6 +330,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -338,9 +338,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -349,12 +349,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -364,8 +361,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -374,6 +376,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -454,11 +457,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -481,6 +483,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -488,9 +491,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -499,12 +502,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -514,8 +514,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -524,6 +529,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -596,9 +602,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -608,7 +616,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -616,6 +623,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -628,7 +636,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_remaining.target.darwin-arm.mk b/Source/core/webcore_remaining.target.darwin-arm.mk
index 32d8a9c..5acc2ee 100644
--- a/Source/core/webcore_remaining.target.darwin-arm.mk
+++ b/Source/core/webcore_remaining.target.darwin-arm.mk
@@ -74,23 +74,28 @@
 	third_party/WebKit/Source/core/animation/AnimatableValue.cpp \
 	third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp \
 	third_party/WebKit/Source/core/animation/Animation.cpp \
+	third_party/WebKit/Source/core/animation/AnimationClock.cpp \
 	third_party/WebKit/Source/core/animation/AnimationStack.cpp \
 	third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp \
 	third_party/WebKit/Source/core/animation/CompositorAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentTimeline.cpp \
-	third_party/WebKit/Source/core/animation/ElementAnimation.cpp \
+	third_party/WebKit/Source/core/animation/EffectInput.cpp \
 	third_party/WebKit/Source/core/animation/InertAnimation.cpp \
+	third_party/WebKit/Source/core/animation/Interpolation.cpp \
+	third_party/WebKit/Source/core/animation/InterpolableValue.cpp \
+	third_party/WebKit/Source/core/animation/InterpolationEffect.cpp \
 	third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp \
-	third_party/WebKit/Source/core/animation/Player.cpp \
+	third_party/WebKit/Source/core/animation/AnimationPlayer.cpp \
 	third_party/WebKit/Source/core/animation/TimedItem.cpp \
 	third_party/WebKit/Source/core/animation/TimedItemTiming.cpp \
+	third_party/WebKit/Source/core/animation/TimingInput.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationDataList.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp \
-	third_party/WebKit/Source/core/animation/css/CSSPropertyAnimation.cpp \
+	third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp \
 	third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp \
 	third_party/WebKit/Source/core/clipboard/Clipboard.cpp \
 	third_party/WebKit/Source/core/clipboard/DataObject.cpp \
@@ -99,6 +104,7 @@
 	third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp \
 	third_party/WebKit/Source/core/clipboard/Pasteboard.cpp \
 	third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp \
+	third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp \
 	third_party/WebKit/Source/core/css/CSSAspectRatioValue.cpp \
 	third_party/WebKit/Source/core/css/CSSBasicShapes.cpp \
@@ -140,6 +146,11 @@
 	third_party/WebKit/Source/core/css/CSSMediaRule.cpp \
 	third_party/WebKit/Source/core/css/CSSOMUtils.cpp \
 	third_party/WebKit/Source/core/css/CSSPageRule.cpp \
+	third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp \
 	third_party/WebKit/Source/core/css/CSSParserMode.cpp \
 	third_party/WebKit/Source/core/css/CSSParserValues.cpp \
 	third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp \
@@ -172,7 +183,7 @@
 	third_party/WebKit/Source/core/css/FontFaceCache.cpp \
 	third_party/WebKit/Source/core/css/FontFaceSet.cpp \
 	third_party/WebKit/Source/core/css/FontSize.cpp \
-	third_party/WebKit/Source/core/css/MediaFeatureNames.cpp \
+	third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/MediaList.cpp \
 	third_party/WebKit/Source/core/css/MediaQuery.cpp \
 	third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp \
@@ -184,11 +195,12 @@
 	third_party/WebKit/Source/core/css/Pair.cpp \
 	third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp \
 	third_party/WebKit/Source/core/css/RGBColor.cpp \
+	third_party/WebKit/Source/core/css/Rect.cpp \
+	third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/RuleFeature.cpp \
 	third_party/WebKit/Source/core/css/RuleSet.cpp \
 	third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp \
 	third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp \
-	third_party/WebKit/Source/core/css/SVGCSSParser.cpp \
 	third_party/WebKit/Source/core/css/SelectorChecker.cpp \
 	third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp \
 	third_party/WebKit/Source/core/css/SelectorFilter.cpp \
@@ -283,7 +295,6 @@
 	third_party/WebKit/Source/core/editing/htmlediting.cpp \
 	third_party/WebKit/Source/core/editing/markup.cpp \
 	third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp \
-	third_party/WebKit/Source/core/fetch/CachedMetadata.cpp \
 	third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp \
 	third_party/WebKit/Source/core/fetch/DocumentResource.cpp \
 	third_party/WebKit/Source/core/fetch/FetchContext.cpp \
@@ -312,8 +323,8 @@
 	third_party/WebKit/Source/core/frame/BarProp.cpp \
 	third_party/WebKit/Source/core/frame/Console.cpp \
 	third_party/WebKit/Source/core/frame/ConsoleBase.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventController.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventDispatcher.cpp \
 	third_party/WebKit/Source/core/frame/DOMTimer.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindow.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp \
@@ -329,15 +340,24 @@
 	third_party/WebKit/Source/core/frame/FrameView.cpp \
 	third_party/WebKit/Source/core/frame/History.cpp \
 	third_party/WebKit/Source/core/frame/ImageBitmap.cpp \
+	third_party/WebKit/Source/core/frame/LocalFrame.cpp \
 	third_party/WebKit/Source/core/frame/Location.cpp \
 	third_party/WebKit/Source/core/frame/Navigator.cpp \
 	third_party/WebKit/Source/core/frame/NavigatorID.cpp \
 	third_party/WebKit/Source/core/frame/PageConsole.cpp \
+	third_party/WebKit/Source/core/frame/PinchViewport.cpp \
+	third_party/WebKit/Source/core/frame/RemoteFrame.cpp \
 	third_party/WebKit/Source/core/frame/Screen.cpp \
 	third_party/WebKit/Source/core/frame/Settings.cpp \
 	third_party/WebKit/Source/core/frame/SettingsDelegate.cpp \
 	third_party/WebKit/Source/core/frame/SuspendableTimer.cpp \
 	third_party/WebKit/Source/core/frame/UseCounter.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSource.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp \
+	third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp \
+	third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp \
+	third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp \
 	third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp \
 	third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp \
@@ -387,6 +407,7 @@
 	third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp \
+	third_party/WebKit/Source/core/inspector/PromiseTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptArguments.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp \
@@ -429,6 +450,7 @@
 	third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp \
 	third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp \
 	third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp \
+	third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp \
 	third_party/WebKit/Source/core/page/AutoscrollController.cpp \
 	third_party/WebKit/Source/core/page/Chrome.cpp \
 	third_party/WebKit/Source/core/page/ContextMenuController.cpp \
@@ -447,8 +469,7 @@
 	third_party/WebKit/Source/core/frame/SmartClip.cpp \
 	third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp \
 	third_party/WebKit/Source/core/page/Page.cpp \
-	third_party/WebKit/Source/core/page/PageGroup.cpp \
-	third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp \
+	third_party/WebKit/Source/core/page/PageAnimator.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleNotifier.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleObserver.cpp \
 	third_party/WebKit/Source/core/page/PagePopupClient.cpp \
@@ -458,6 +479,7 @@
 	third_party/WebKit/Source/core/page/PageVisibilityState.cpp \
 	third_party/WebKit/Source/core/page/PointerLockController.cpp \
 	third_party/WebKit/Source/core/page/PrintContext.cpp \
+	third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp \
 	third_party/WebKit/Source/core/page/SpatialNavigation.cpp \
 	third_party/WebKit/Source/core/page/TouchAdjustment.cpp \
 	third_party/WebKit/Source/core/page/TouchDisambiguation.cpp \
@@ -532,6 +554,7 @@
 	third_party/WebKit/Source/core/xml/XSLTProcessor.cpp \
 	third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp \
 	third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp \
+	third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.cpp
 
@@ -574,6 +597,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -581,9 +605,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -592,12 +616,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -607,8 +628,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -617,6 +643,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -724,6 +751,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -731,9 +759,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -742,12 +770,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -757,8 +782,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -767,6 +797,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -840,9 +871,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -854,7 +887,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -862,6 +894,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -876,7 +909,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_remaining.target.darwin-mips.mk b/Source/core/webcore_remaining.target.darwin-mips.mk
index ef63598..a335096 100644
--- a/Source/core/webcore_remaining.target.darwin-mips.mk
+++ b/Source/core/webcore_remaining.target.darwin-mips.mk
@@ -74,23 +74,28 @@
 	third_party/WebKit/Source/core/animation/AnimatableValue.cpp \
 	third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp \
 	third_party/WebKit/Source/core/animation/Animation.cpp \
+	third_party/WebKit/Source/core/animation/AnimationClock.cpp \
 	third_party/WebKit/Source/core/animation/AnimationStack.cpp \
 	third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp \
 	third_party/WebKit/Source/core/animation/CompositorAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentTimeline.cpp \
-	third_party/WebKit/Source/core/animation/ElementAnimation.cpp \
+	third_party/WebKit/Source/core/animation/EffectInput.cpp \
 	third_party/WebKit/Source/core/animation/InertAnimation.cpp \
+	third_party/WebKit/Source/core/animation/Interpolation.cpp \
+	third_party/WebKit/Source/core/animation/InterpolableValue.cpp \
+	third_party/WebKit/Source/core/animation/InterpolationEffect.cpp \
 	third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp \
-	third_party/WebKit/Source/core/animation/Player.cpp \
+	third_party/WebKit/Source/core/animation/AnimationPlayer.cpp \
 	third_party/WebKit/Source/core/animation/TimedItem.cpp \
 	third_party/WebKit/Source/core/animation/TimedItemTiming.cpp \
+	third_party/WebKit/Source/core/animation/TimingInput.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationDataList.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp \
-	third_party/WebKit/Source/core/animation/css/CSSPropertyAnimation.cpp \
+	third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp \
 	third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp \
 	third_party/WebKit/Source/core/clipboard/Clipboard.cpp \
 	third_party/WebKit/Source/core/clipboard/DataObject.cpp \
@@ -99,6 +104,7 @@
 	third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp \
 	third_party/WebKit/Source/core/clipboard/Pasteboard.cpp \
 	third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp \
+	third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp \
 	third_party/WebKit/Source/core/css/CSSAspectRatioValue.cpp \
 	third_party/WebKit/Source/core/css/CSSBasicShapes.cpp \
@@ -140,6 +146,11 @@
 	third_party/WebKit/Source/core/css/CSSMediaRule.cpp \
 	third_party/WebKit/Source/core/css/CSSOMUtils.cpp \
 	third_party/WebKit/Source/core/css/CSSPageRule.cpp \
+	third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp \
 	third_party/WebKit/Source/core/css/CSSParserMode.cpp \
 	third_party/WebKit/Source/core/css/CSSParserValues.cpp \
 	third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp \
@@ -172,7 +183,7 @@
 	third_party/WebKit/Source/core/css/FontFaceCache.cpp \
 	third_party/WebKit/Source/core/css/FontFaceSet.cpp \
 	third_party/WebKit/Source/core/css/FontSize.cpp \
-	third_party/WebKit/Source/core/css/MediaFeatureNames.cpp \
+	third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/MediaList.cpp \
 	third_party/WebKit/Source/core/css/MediaQuery.cpp \
 	third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp \
@@ -184,11 +195,12 @@
 	third_party/WebKit/Source/core/css/Pair.cpp \
 	third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp \
 	third_party/WebKit/Source/core/css/RGBColor.cpp \
+	third_party/WebKit/Source/core/css/Rect.cpp \
+	third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/RuleFeature.cpp \
 	third_party/WebKit/Source/core/css/RuleSet.cpp \
 	third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp \
 	third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp \
-	third_party/WebKit/Source/core/css/SVGCSSParser.cpp \
 	third_party/WebKit/Source/core/css/SelectorChecker.cpp \
 	third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp \
 	third_party/WebKit/Source/core/css/SelectorFilter.cpp \
@@ -283,7 +295,6 @@
 	third_party/WebKit/Source/core/editing/htmlediting.cpp \
 	third_party/WebKit/Source/core/editing/markup.cpp \
 	third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp \
-	third_party/WebKit/Source/core/fetch/CachedMetadata.cpp \
 	third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp \
 	third_party/WebKit/Source/core/fetch/DocumentResource.cpp \
 	third_party/WebKit/Source/core/fetch/FetchContext.cpp \
@@ -312,8 +323,8 @@
 	third_party/WebKit/Source/core/frame/BarProp.cpp \
 	third_party/WebKit/Source/core/frame/Console.cpp \
 	third_party/WebKit/Source/core/frame/ConsoleBase.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventController.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventDispatcher.cpp \
 	third_party/WebKit/Source/core/frame/DOMTimer.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindow.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp \
@@ -329,15 +340,24 @@
 	third_party/WebKit/Source/core/frame/FrameView.cpp \
 	third_party/WebKit/Source/core/frame/History.cpp \
 	third_party/WebKit/Source/core/frame/ImageBitmap.cpp \
+	third_party/WebKit/Source/core/frame/LocalFrame.cpp \
 	third_party/WebKit/Source/core/frame/Location.cpp \
 	third_party/WebKit/Source/core/frame/Navigator.cpp \
 	third_party/WebKit/Source/core/frame/NavigatorID.cpp \
 	third_party/WebKit/Source/core/frame/PageConsole.cpp \
+	third_party/WebKit/Source/core/frame/PinchViewport.cpp \
+	third_party/WebKit/Source/core/frame/RemoteFrame.cpp \
 	third_party/WebKit/Source/core/frame/Screen.cpp \
 	third_party/WebKit/Source/core/frame/Settings.cpp \
 	third_party/WebKit/Source/core/frame/SettingsDelegate.cpp \
 	third_party/WebKit/Source/core/frame/SuspendableTimer.cpp \
 	third_party/WebKit/Source/core/frame/UseCounter.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSource.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp \
+	third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp \
+	third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp \
+	third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp \
 	third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp \
 	third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp \
@@ -387,6 +407,7 @@
 	third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp \
+	third_party/WebKit/Source/core/inspector/PromiseTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptArguments.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp \
@@ -429,6 +450,7 @@
 	third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp \
 	third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp \
 	third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp \
+	third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp \
 	third_party/WebKit/Source/core/page/AutoscrollController.cpp \
 	third_party/WebKit/Source/core/page/Chrome.cpp \
 	third_party/WebKit/Source/core/page/ContextMenuController.cpp \
@@ -447,8 +469,7 @@
 	third_party/WebKit/Source/core/frame/SmartClip.cpp \
 	third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp \
 	third_party/WebKit/Source/core/page/Page.cpp \
-	third_party/WebKit/Source/core/page/PageGroup.cpp \
-	third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp \
+	third_party/WebKit/Source/core/page/PageAnimator.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleNotifier.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleObserver.cpp \
 	third_party/WebKit/Source/core/page/PagePopupClient.cpp \
@@ -458,6 +479,7 @@
 	third_party/WebKit/Source/core/page/PageVisibilityState.cpp \
 	third_party/WebKit/Source/core/page/PointerLockController.cpp \
 	third_party/WebKit/Source/core/page/PrintContext.cpp \
+	third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp \
 	third_party/WebKit/Source/core/page/SpatialNavigation.cpp \
 	third_party/WebKit/Source/core/page/TouchAdjustment.cpp \
 	third_party/WebKit/Source/core/page/TouchDisambiguation.cpp \
@@ -532,6 +554,7 @@
 	third_party/WebKit/Source/core/xml/XSLTProcessor.cpp \
 	third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp \
 	third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp \
+	third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.cpp
 
@@ -573,6 +596,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -580,9 +604,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -591,12 +615,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -606,8 +627,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -616,6 +642,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -722,6 +749,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -729,9 +757,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -740,12 +768,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -755,8 +780,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -765,6 +795,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -838,9 +869,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -850,7 +883,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -858,6 +890,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -870,7 +903,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_remaining.target.darwin-x86.mk b/Source/core/webcore_remaining.target.darwin-x86.mk
index 101789b..a44acd1 100644
--- a/Source/core/webcore_remaining.target.darwin-x86.mk
+++ b/Source/core/webcore_remaining.target.darwin-x86.mk
@@ -74,23 +74,28 @@
 	third_party/WebKit/Source/core/animation/AnimatableValue.cpp \
 	third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp \
 	third_party/WebKit/Source/core/animation/Animation.cpp \
+	third_party/WebKit/Source/core/animation/AnimationClock.cpp \
 	third_party/WebKit/Source/core/animation/AnimationStack.cpp \
 	third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp \
 	third_party/WebKit/Source/core/animation/CompositorAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentTimeline.cpp \
-	third_party/WebKit/Source/core/animation/ElementAnimation.cpp \
+	third_party/WebKit/Source/core/animation/EffectInput.cpp \
 	third_party/WebKit/Source/core/animation/InertAnimation.cpp \
+	third_party/WebKit/Source/core/animation/Interpolation.cpp \
+	third_party/WebKit/Source/core/animation/InterpolableValue.cpp \
+	third_party/WebKit/Source/core/animation/InterpolationEffect.cpp \
 	third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp \
-	third_party/WebKit/Source/core/animation/Player.cpp \
+	third_party/WebKit/Source/core/animation/AnimationPlayer.cpp \
 	third_party/WebKit/Source/core/animation/TimedItem.cpp \
 	third_party/WebKit/Source/core/animation/TimedItemTiming.cpp \
+	third_party/WebKit/Source/core/animation/TimingInput.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationDataList.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp \
-	third_party/WebKit/Source/core/animation/css/CSSPropertyAnimation.cpp \
+	third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp \
 	third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp \
 	third_party/WebKit/Source/core/clipboard/Clipboard.cpp \
 	third_party/WebKit/Source/core/clipboard/DataObject.cpp \
@@ -99,6 +104,7 @@
 	third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp \
 	third_party/WebKit/Source/core/clipboard/Pasteboard.cpp \
 	third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp \
+	third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp \
 	third_party/WebKit/Source/core/css/CSSAspectRatioValue.cpp \
 	third_party/WebKit/Source/core/css/CSSBasicShapes.cpp \
@@ -140,6 +146,11 @@
 	third_party/WebKit/Source/core/css/CSSMediaRule.cpp \
 	third_party/WebKit/Source/core/css/CSSOMUtils.cpp \
 	third_party/WebKit/Source/core/css/CSSPageRule.cpp \
+	third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp \
 	third_party/WebKit/Source/core/css/CSSParserMode.cpp \
 	third_party/WebKit/Source/core/css/CSSParserValues.cpp \
 	third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp \
@@ -172,7 +183,7 @@
 	third_party/WebKit/Source/core/css/FontFaceCache.cpp \
 	third_party/WebKit/Source/core/css/FontFaceSet.cpp \
 	third_party/WebKit/Source/core/css/FontSize.cpp \
-	third_party/WebKit/Source/core/css/MediaFeatureNames.cpp \
+	third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/MediaList.cpp \
 	third_party/WebKit/Source/core/css/MediaQuery.cpp \
 	third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp \
@@ -184,11 +195,12 @@
 	third_party/WebKit/Source/core/css/Pair.cpp \
 	third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp \
 	third_party/WebKit/Source/core/css/RGBColor.cpp \
+	third_party/WebKit/Source/core/css/Rect.cpp \
+	third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/RuleFeature.cpp \
 	third_party/WebKit/Source/core/css/RuleSet.cpp \
 	third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp \
 	third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp \
-	third_party/WebKit/Source/core/css/SVGCSSParser.cpp \
 	third_party/WebKit/Source/core/css/SelectorChecker.cpp \
 	third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp \
 	third_party/WebKit/Source/core/css/SelectorFilter.cpp \
@@ -283,7 +295,6 @@
 	third_party/WebKit/Source/core/editing/htmlediting.cpp \
 	third_party/WebKit/Source/core/editing/markup.cpp \
 	third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp \
-	third_party/WebKit/Source/core/fetch/CachedMetadata.cpp \
 	third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp \
 	third_party/WebKit/Source/core/fetch/DocumentResource.cpp \
 	third_party/WebKit/Source/core/fetch/FetchContext.cpp \
@@ -312,8 +323,8 @@
 	third_party/WebKit/Source/core/frame/BarProp.cpp \
 	third_party/WebKit/Source/core/frame/Console.cpp \
 	third_party/WebKit/Source/core/frame/ConsoleBase.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventController.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventDispatcher.cpp \
 	third_party/WebKit/Source/core/frame/DOMTimer.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindow.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp \
@@ -329,15 +340,24 @@
 	third_party/WebKit/Source/core/frame/FrameView.cpp \
 	third_party/WebKit/Source/core/frame/History.cpp \
 	third_party/WebKit/Source/core/frame/ImageBitmap.cpp \
+	third_party/WebKit/Source/core/frame/LocalFrame.cpp \
 	third_party/WebKit/Source/core/frame/Location.cpp \
 	third_party/WebKit/Source/core/frame/Navigator.cpp \
 	third_party/WebKit/Source/core/frame/NavigatorID.cpp \
 	third_party/WebKit/Source/core/frame/PageConsole.cpp \
+	third_party/WebKit/Source/core/frame/PinchViewport.cpp \
+	third_party/WebKit/Source/core/frame/RemoteFrame.cpp \
 	third_party/WebKit/Source/core/frame/Screen.cpp \
 	third_party/WebKit/Source/core/frame/Settings.cpp \
 	third_party/WebKit/Source/core/frame/SettingsDelegate.cpp \
 	third_party/WebKit/Source/core/frame/SuspendableTimer.cpp \
 	third_party/WebKit/Source/core/frame/UseCounter.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSource.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp \
+	third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp \
+	third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp \
+	third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp \
 	third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp \
 	third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp \
@@ -387,6 +407,7 @@
 	third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp \
+	third_party/WebKit/Source/core/inspector/PromiseTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptArguments.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp \
@@ -429,6 +450,7 @@
 	third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp \
 	third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp \
 	third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp \
+	third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp \
 	third_party/WebKit/Source/core/page/AutoscrollController.cpp \
 	third_party/WebKit/Source/core/page/Chrome.cpp \
 	third_party/WebKit/Source/core/page/ContextMenuController.cpp \
@@ -447,8 +469,7 @@
 	third_party/WebKit/Source/core/frame/SmartClip.cpp \
 	third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp \
 	third_party/WebKit/Source/core/page/Page.cpp \
-	third_party/WebKit/Source/core/page/PageGroup.cpp \
-	third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp \
+	third_party/WebKit/Source/core/page/PageAnimator.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleNotifier.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleObserver.cpp \
 	third_party/WebKit/Source/core/page/PagePopupClient.cpp \
@@ -458,6 +479,7 @@
 	third_party/WebKit/Source/core/page/PageVisibilityState.cpp \
 	third_party/WebKit/Source/core/page/PointerLockController.cpp \
 	third_party/WebKit/Source/core/page/PrintContext.cpp \
+	third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp \
 	third_party/WebKit/Source/core/page/SpatialNavigation.cpp \
 	third_party/WebKit/Source/core/page/TouchAdjustment.cpp \
 	third_party/WebKit/Source/core/page/TouchDisambiguation.cpp \
@@ -532,6 +554,7 @@
 	third_party/WebKit/Source/core/xml/XSLTProcessor.cpp \
 	third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp \
 	third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp \
+	third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.cpp
 
@@ -549,11 +572,10 @@
 	-pipe \
 	-fPIC \
 	-fno-strict-aliasing \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -576,6 +598,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -583,9 +606,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -594,12 +617,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -609,8 +629,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -619,6 +644,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -700,11 +726,10 @@
 	-pipe \
 	-fPIC \
 	-fno-strict-aliasing \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -727,6 +752,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -734,9 +760,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -745,12 +771,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -760,8 +783,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -770,6 +798,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -842,9 +871,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -854,7 +885,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -862,6 +892,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -874,7 +905,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_remaining.target.linux-arm.mk b/Source/core/webcore_remaining.target.linux-arm.mk
index 32d8a9c..5acc2ee 100644
--- a/Source/core/webcore_remaining.target.linux-arm.mk
+++ b/Source/core/webcore_remaining.target.linux-arm.mk
@@ -74,23 +74,28 @@
 	third_party/WebKit/Source/core/animation/AnimatableValue.cpp \
 	third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp \
 	third_party/WebKit/Source/core/animation/Animation.cpp \
+	third_party/WebKit/Source/core/animation/AnimationClock.cpp \
 	third_party/WebKit/Source/core/animation/AnimationStack.cpp \
 	third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp \
 	third_party/WebKit/Source/core/animation/CompositorAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentTimeline.cpp \
-	third_party/WebKit/Source/core/animation/ElementAnimation.cpp \
+	third_party/WebKit/Source/core/animation/EffectInput.cpp \
 	third_party/WebKit/Source/core/animation/InertAnimation.cpp \
+	third_party/WebKit/Source/core/animation/Interpolation.cpp \
+	third_party/WebKit/Source/core/animation/InterpolableValue.cpp \
+	third_party/WebKit/Source/core/animation/InterpolationEffect.cpp \
 	third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp \
-	third_party/WebKit/Source/core/animation/Player.cpp \
+	third_party/WebKit/Source/core/animation/AnimationPlayer.cpp \
 	third_party/WebKit/Source/core/animation/TimedItem.cpp \
 	third_party/WebKit/Source/core/animation/TimedItemTiming.cpp \
+	third_party/WebKit/Source/core/animation/TimingInput.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationDataList.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp \
-	third_party/WebKit/Source/core/animation/css/CSSPropertyAnimation.cpp \
+	third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp \
 	third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp \
 	third_party/WebKit/Source/core/clipboard/Clipboard.cpp \
 	third_party/WebKit/Source/core/clipboard/DataObject.cpp \
@@ -99,6 +104,7 @@
 	third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp \
 	third_party/WebKit/Source/core/clipboard/Pasteboard.cpp \
 	third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp \
+	third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp \
 	third_party/WebKit/Source/core/css/CSSAspectRatioValue.cpp \
 	third_party/WebKit/Source/core/css/CSSBasicShapes.cpp \
@@ -140,6 +146,11 @@
 	third_party/WebKit/Source/core/css/CSSMediaRule.cpp \
 	third_party/WebKit/Source/core/css/CSSOMUtils.cpp \
 	third_party/WebKit/Source/core/css/CSSPageRule.cpp \
+	third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp \
 	third_party/WebKit/Source/core/css/CSSParserMode.cpp \
 	third_party/WebKit/Source/core/css/CSSParserValues.cpp \
 	third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp \
@@ -172,7 +183,7 @@
 	third_party/WebKit/Source/core/css/FontFaceCache.cpp \
 	third_party/WebKit/Source/core/css/FontFaceSet.cpp \
 	third_party/WebKit/Source/core/css/FontSize.cpp \
-	third_party/WebKit/Source/core/css/MediaFeatureNames.cpp \
+	third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/MediaList.cpp \
 	third_party/WebKit/Source/core/css/MediaQuery.cpp \
 	third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp \
@@ -184,11 +195,12 @@
 	third_party/WebKit/Source/core/css/Pair.cpp \
 	third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp \
 	third_party/WebKit/Source/core/css/RGBColor.cpp \
+	third_party/WebKit/Source/core/css/Rect.cpp \
+	third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/RuleFeature.cpp \
 	third_party/WebKit/Source/core/css/RuleSet.cpp \
 	third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp \
 	third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp \
-	third_party/WebKit/Source/core/css/SVGCSSParser.cpp \
 	third_party/WebKit/Source/core/css/SelectorChecker.cpp \
 	third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp \
 	third_party/WebKit/Source/core/css/SelectorFilter.cpp \
@@ -283,7 +295,6 @@
 	third_party/WebKit/Source/core/editing/htmlediting.cpp \
 	third_party/WebKit/Source/core/editing/markup.cpp \
 	third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp \
-	third_party/WebKit/Source/core/fetch/CachedMetadata.cpp \
 	third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp \
 	third_party/WebKit/Source/core/fetch/DocumentResource.cpp \
 	third_party/WebKit/Source/core/fetch/FetchContext.cpp \
@@ -312,8 +323,8 @@
 	third_party/WebKit/Source/core/frame/BarProp.cpp \
 	third_party/WebKit/Source/core/frame/Console.cpp \
 	third_party/WebKit/Source/core/frame/ConsoleBase.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventController.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventDispatcher.cpp \
 	third_party/WebKit/Source/core/frame/DOMTimer.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindow.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp \
@@ -329,15 +340,24 @@
 	third_party/WebKit/Source/core/frame/FrameView.cpp \
 	third_party/WebKit/Source/core/frame/History.cpp \
 	third_party/WebKit/Source/core/frame/ImageBitmap.cpp \
+	third_party/WebKit/Source/core/frame/LocalFrame.cpp \
 	third_party/WebKit/Source/core/frame/Location.cpp \
 	third_party/WebKit/Source/core/frame/Navigator.cpp \
 	third_party/WebKit/Source/core/frame/NavigatorID.cpp \
 	third_party/WebKit/Source/core/frame/PageConsole.cpp \
+	third_party/WebKit/Source/core/frame/PinchViewport.cpp \
+	third_party/WebKit/Source/core/frame/RemoteFrame.cpp \
 	third_party/WebKit/Source/core/frame/Screen.cpp \
 	third_party/WebKit/Source/core/frame/Settings.cpp \
 	third_party/WebKit/Source/core/frame/SettingsDelegate.cpp \
 	third_party/WebKit/Source/core/frame/SuspendableTimer.cpp \
 	third_party/WebKit/Source/core/frame/UseCounter.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSource.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp \
+	third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp \
+	third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp \
+	third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp \
 	third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp \
 	third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp \
@@ -387,6 +407,7 @@
 	third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp \
+	third_party/WebKit/Source/core/inspector/PromiseTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptArguments.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp \
@@ -429,6 +450,7 @@
 	third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp \
 	third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp \
 	third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp \
+	third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp \
 	third_party/WebKit/Source/core/page/AutoscrollController.cpp \
 	third_party/WebKit/Source/core/page/Chrome.cpp \
 	third_party/WebKit/Source/core/page/ContextMenuController.cpp \
@@ -447,8 +469,7 @@
 	third_party/WebKit/Source/core/frame/SmartClip.cpp \
 	third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp \
 	third_party/WebKit/Source/core/page/Page.cpp \
-	third_party/WebKit/Source/core/page/PageGroup.cpp \
-	third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp \
+	third_party/WebKit/Source/core/page/PageAnimator.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleNotifier.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleObserver.cpp \
 	third_party/WebKit/Source/core/page/PagePopupClient.cpp \
@@ -458,6 +479,7 @@
 	third_party/WebKit/Source/core/page/PageVisibilityState.cpp \
 	third_party/WebKit/Source/core/page/PointerLockController.cpp \
 	third_party/WebKit/Source/core/page/PrintContext.cpp \
+	third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp \
 	third_party/WebKit/Source/core/page/SpatialNavigation.cpp \
 	third_party/WebKit/Source/core/page/TouchAdjustment.cpp \
 	third_party/WebKit/Source/core/page/TouchDisambiguation.cpp \
@@ -532,6 +554,7 @@
 	third_party/WebKit/Source/core/xml/XSLTProcessor.cpp \
 	third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp \
 	third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp \
+	third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.cpp
 
@@ -574,6 +597,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -581,9 +605,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -592,12 +616,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -607,8 +628,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -617,6 +643,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -724,6 +751,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -731,9 +759,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -742,12 +770,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -757,8 +782,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -767,6 +797,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -840,9 +871,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -854,7 +887,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -862,6 +894,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -876,7 +909,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_remaining.target.linux-mips.mk b/Source/core/webcore_remaining.target.linux-mips.mk
index ef63598..a335096 100644
--- a/Source/core/webcore_remaining.target.linux-mips.mk
+++ b/Source/core/webcore_remaining.target.linux-mips.mk
@@ -74,23 +74,28 @@
 	third_party/WebKit/Source/core/animation/AnimatableValue.cpp \
 	third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp \
 	third_party/WebKit/Source/core/animation/Animation.cpp \
+	third_party/WebKit/Source/core/animation/AnimationClock.cpp \
 	third_party/WebKit/Source/core/animation/AnimationStack.cpp \
 	third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp \
 	third_party/WebKit/Source/core/animation/CompositorAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentTimeline.cpp \
-	third_party/WebKit/Source/core/animation/ElementAnimation.cpp \
+	third_party/WebKit/Source/core/animation/EffectInput.cpp \
 	third_party/WebKit/Source/core/animation/InertAnimation.cpp \
+	third_party/WebKit/Source/core/animation/Interpolation.cpp \
+	third_party/WebKit/Source/core/animation/InterpolableValue.cpp \
+	third_party/WebKit/Source/core/animation/InterpolationEffect.cpp \
 	third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp \
-	third_party/WebKit/Source/core/animation/Player.cpp \
+	third_party/WebKit/Source/core/animation/AnimationPlayer.cpp \
 	third_party/WebKit/Source/core/animation/TimedItem.cpp \
 	third_party/WebKit/Source/core/animation/TimedItemTiming.cpp \
+	third_party/WebKit/Source/core/animation/TimingInput.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationDataList.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp \
-	third_party/WebKit/Source/core/animation/css/CSSPropertyAnimation.cpp \
+	third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp \
 	third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp \
 	third_party/WebKit/Source/core/clipboard/Clipboard.cpp \
 	third_party/WebKit/Source/core/clipboard/DataObject.cpp \
@@ -99,6 +104,7 @@
 	third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp \
 	third_party/WebKit/Source/core/clipboard/Pasteboard.cpp \
 	third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp \
+	third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp \
 	third_party/WebKit/Source/core/css/CSSAspectRatioValue.cpp \
 	third_party/WebKit/Source/core/css/CSSBasicShapes.cpp \
@@ -140,6 +146,11 @@
 	third_party/WebKit/Source/core/css/CSSMediaRule.cpp \
 	third_party/WebKit/Source/core/css/CSSOMUtils.cpp \
 	third_party/WebKit/Source/core/css/CSSPageRule.cpp \
+	third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp \
 	third_party/WebKit/Source/core/css/CSSParserMode.cpp \
 	third_party/WebKit/Source/core/css/CSSParserValues.cpp \
 	third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp \
@@ -172,7 +183,7 @@
 	third_party/WebKit/Source/core/css/FontFaceCache.cpp \
 	third_party/WebKit/Source/core/css/FontFaceSet.cpp \
 	third_party/WebKit/Source/core/css/FontSize.cpp \
-	third_party/WebKit/Source/core/css/MediaFeatureNames.cpp \
+	third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/MediaList.cpp \
 	third_party/WebKit/Source/core/css/MediaQuery.cpp \
 	third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp \
@@ -184,11 +195,12 @@
 	third_party/WebKit/Source/core/css/Pair.cpp \
 	third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp \
 	third_party/WebKit/Source/core/css/RGBColor.cpp \
+	third_party/WebKit/Source/core/css/Rect.cpp \
+	third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/RuleFeature.cpp \
 	third_party/WebKit/Source/core/css/RuleSet.cpp \
 	third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp \
 	third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp \
-	third_party/WebKit/Source/core/css/SVGCSSParser.cpp \
 	third_party/WebKit/Source/core/css/SelectorChecker.cpp \
 	third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp \
 	third_party/WebKit/Source/core/css/SelectorFilter.cpp \
@@ -283,7 +295,6 @@
 	third_party/WebKit/Source/core/editing/htmlediting.cpp \
 	third_party/WebKit/Source/core/editing/markup.cpp \
 	third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp \
-	third_party/WebKit/Source/core/fetch/CachedMetadata.cpp \
 	third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp \
 	third_party/WebKit/Source/core/fetch/DocumentResource.cpp \
 	third_party/WebKit/Source/core/fetch/FetchContext.cpp \
@@ -312,8 +323,8 @@
 	third_party/WebKit/Source/core/frame/BarProp.cpp \
 	third_party/WebKit/Source/core/frame/Console.cpp \
 	third_party/WebKit/Source/core/frame/ConsoleBase.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventController.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventDispatcher.cpp \
 	third_party/WebKit/Source/core/frame/DOMTimer.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindow.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp \
@@ -329,15 +340,24 @@
 	third_party/WebKit/Source/core/frame/FrameView.cpp \
 	third_party/WebKit/Source/core/frame/History.cpp \
 	third_party/WebKit/Source/core/frame/ImageBitmap.cpp \
+	third_party/WebKit/Source/core/frame/LocalFrame.cpp \
 	third_party/WebKit/Source/core/frame/Location.cpp \
 	third_party/WebKit/Source/core/frame/Navigator.cpp \
 	third_party/WebKit/Source/core/frame/NavigatorID.cpp \
 	third_party/WebKit/Source/core/frame/PageConsole.cpp \
+	third_party/WebKit/Source/core/frame/PinchViewport.cpp \
+	third_party/WebKit/Source/core/frame/RemoteFrame.cpp \
 	third_party/WebKit/Source/core/frame/Screen.cpp \
 	third_party/WebKit/Source/core/frame/Settings.cpp \
 	third_party/WebKit/Source/core/frame/SettingsDelegate.cpp \
 	third_party/WebKit/Source/core/frame/SuspendableTimer.cpp \
 	third_party/WebKit/Source/core/frame/UseCounter.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSource.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp \
+	third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp \
+	third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp \
+	third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp \
 	third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp \
 	third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp \
@@ -387,6 +407,7 @@
 	third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp \
+	third_party/WebKit/Source/core/inspector/PromiseTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptArguments.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp \
@@ -429,6 +450,7 @@
 	third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp \
 	third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp \
 	third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp \
+	third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp \
 	third_party/WebKit/Source/core/page/AutoscrollController.cpp \
 	third_party/WebKit/Source/core/page/Chrome.cpp \
 	third_party/WebKit/Source/core/page/ContextMenuController.cpp \
@@ -447,8 +469,7 @@
 	third_party/WebKit/Source/core/frame/SmartClip.cpp \
 	third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp \
 	third_party/WebKit/Source/core/page/Page.cpp \
-	third_party/WebKit/Source/core/page/PageGroup.cpp \
-	third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp \
+	third_party/WebKit/Source/core/page/PageAnimator.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleNotifier.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleObserver.cpp \
 	third_party/WebKit/Source/core/page/PagePopupClient.cpp \
@@ -458,6 +479,7 @@
 	third_party/WebKit/Source/core/page/PageVisibilityState.cpp \
 	third_party/WebKit/Source/core/page/PointerLockController.cpp \
 	third_party/WebKit/Source/core/page/PrintContext.cpp \
+	third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp \
 	third_party/WebKit/Source/core/page/SpatialNavigation.cpp \
 	third_party/WebKit/Source/core/page/TouchAdjustment.cpp \
 	third_party/WebKit/Source/core/page/TouchDisambiguation.cpp \
@@ -532,6 +554,7 @@
 	third_party/WebKit/Source/core/xml/XSLTProcessor.cpp \
 	third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp \
 	third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp \
+	third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.cpp
 
@@ -573,6 +596,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -580,9 +604,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -591,12 +615,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -606,8 +627,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -616,6 +642,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -722,6 +749,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -729,9 +757,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -740,12 +768,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -755,8 +780,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -765,6 +795,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -838,9 +869,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -850,7 +883,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -858,6 +890,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -870,7 +903,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_remaining.target.linux-x86.mk b/Source/core/webcore_remaining.target.linux-x86.mk
index 101789b..a44acd1 100644
--- a/Source/core/webcore_remaining.target.linux-x86.mk
+++ b/Source/core/webcore_remaining.target.linux-x86.mk
@@ -74,23 +74,28 @@
 	third_party/WebKit/Source/core/animation/AnimatableValue.cpp \
 	third_party/WebKit/Source/core/animation/AnimatableVisibility.cpp \
 	third_party/WebKit/Source/core/animation/Animation.cpp \
+	third_party/WebKit/Source/core/animation/AnimationClock.cpp \
 	third_party/WebKit/Source/core/animation/AnimationStack.cpp \
 	third_party/WebKit/Source/core/animation/AnimationTranslationUtil.cpp \
 	third_party/WebKit/Source/core/animation/CompositorAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentAnimations.cpp \
 	third_party/WebKit/Source/core/animation/DocumentTimeline.cpp \
-	third_party/WebKit/Source/core/animation/ElementAnimation.cpp \
+	third_party/WebKit/Source/core/animation/EffectInput.cpp \
 	third_party/WebKit/Source/core/animation/InertAnimation.cpp \
+	third_party/WebKit/Source/core/animation/Interpolation.cpp \
+	third_party/WebKit/Source/core/animation/InterpolableValue.cpp \
+	third_party/WebKit/Source/core/animation/InterpolationEffect.cpp \
 	third_party/WebKit/Source/core/animation/KeyframeEffectModel.cpp \
-	third_party/WebKit/Source/core/animation/Player.cpp \
+	third_party/WebKit/Source/core/animation/AnimationPlayer.cpp \
 	third_party/WebKit/Source/core/animation/TimedItem.cpp \
 	third_party/WebKit/Source/core/animation/TimedItemTiming.cpp \
+	third_party/WebKit/Source/core/animation/TimingInput.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimatableValueFactory.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimations.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationData.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSAnimationDataList.cpp \
 	third_party/WebKit/Source/core/animation/css/CSSPendingAnimations.cpp \
-	third_party/WebKit/Source/core/animation/css/CSSPropertyAnimation.cpp \
+	third_party/WebKit/Source/core/animation/css/CSSPropertyEquality.cpp \
 	third_party/WebKit/Source/core/animation/css/TransitionTimeline.cpp \
 	third_party/WebKit/Source/core/clipboard/Clipboard.cpp \
 	third_party/WebKit/Source/core/clipboard/DataObject.cpp \
@@ -99,6 +104,7 @@
 	third_party/WebKit/Source/core/clipboard/DataTransferItemList.cpp \
 	third_party/WebKit/Source/core/clipboard/Pasteboard.cpp \
 	third_party/WebKit/Source/core/css/BasicShapeFunctions.cpp \
+	third_party/WebKit/Source/core/css/BinaryDataFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/CSSArrayFunctionValue.cpp \
 	third_party/WebKit/Source/core/css/CSSAspectRatioValue.cpp \
 	third_party/WebKit/Source/core/css/CSSBasicShapes.cpp \
@@ -140,6 +146,11 @@
 	third_party/WebKit/Source/core/css/CSSMediaRule.cpp \
 	third_party/WebKit/Source/core/css/CSSOMUtils.cpp \
 	third_party/WebKit/Source/core/css/CSSPageRule.cpp \
+	third_party/WebKit/Source/core/css/parser/CSSPropertyParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryTokenizer.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryParser.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryInputStream.cpp \
+	third_party/WebKit/Source/core/css/parser/MediaQueryToken.cpp \
 	third_party/WebKit/Source/core/css/CSSParserMode.cpp \
 	third_party/WebKit/Source/core/css/CSSParserValues.cpp \
 	third_party/WebKit/Source/core/css/CSSPrimitiveValue.cpp \
@@ -172,7 +183,7 @@
 	third_party/WebKit/Source/core/css/FontFaceCache.cpp \
 	third_party/WebKit/Source/core/css/FontFaceSet.cpp \
 	third_party/WebKit/Source/core/css/FontSize.cpp \
-	third_party/WebKit/Source/core/css/MediaFeatureNames.cpp \
+	third_party/WebKit/Source/core/css/LocalFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/MediaList.cpp \
 	third_party/WebKit/Source/core/css/MediaQuery.cpp \
 	third_party/WebKit/Source/core/css/MediaQueryEvaluator.cpp \
@@ -184,11 +195,12 @@
 	third_party/WebKit/Source/core/css/Pair.cpp \
 	third_party/WebKit/Source/core/css/PropertySetCSSStyleDeclaration.cpp \
 	third_party/WebKit/Source/core/css/RGBColor.cpp \
+	third_party/WebKit/Source/core/css/Rect.cpp \
+	third_party/WebKit/Source/core/css/RemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/css/RuleFeature.cpp \
 	third_party/WebKit/Source/core/css/RuleSet.cpp \
 	third_party/WebKit/Source/core/css/RuntimeCSSEnabled.cpp \
 	third_party/WebKit/Source/core/css/SVGCSSComputedStyleDeclaration.cpp \
-	third_party/WebKit/Source/core/css/SVGCSSParser.cpp \
 	third_party/WebKit/Source/core/css/SelectorChecker.cpp \
 	third_party/WebKit/Source/core/css/SelectorCheckerFastPath.cpp \
 	third_party/WebKit/Source/core/css/SelectorFilter.cpp \
@@ -283,7 +295,6 @@
 	third_party/WebKit/Source/core/editing/htmlediting.cpp \
 	third_party/WebKit/Source/core/editing/markup.cpp \
 	third_party/WebKit/Source/core/fetch/CSSStyleSheetResource.cpp \
-	third_party/WebKit/Source/core/fetch/CachedMetadata.cpp \
 	third_party/WebKit/Source/core/fetch/CrossOriginAccessControl.cpp \
 	third_party/WebKit/Source/core/fetch/DocumentResource.cpp \
 	third_party/WebKit/Source/core/fetch/FetchContext.cpp \
@@ -312,8 +323,8 @@
 	third_party/WebKit/Source/core/frame/BarProp.cpp \
 	third_party/WebKit/Source/core/frame/Console.cpp \
 	third_party/WebKit/Source/core/frame/ConsoleBase.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicy.cpp \
-	third_party/WebKit/Source/core/frame/ContentSecurityPolicyResponseHeaders.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventController.cpp \
+	third_party/WebKit/Source/core/frame/DeviceSensorEventDispatcher.cpp \
 	third_party/WebKit/Source/core/frame/DOMTimer.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindow.cpp \
 	third_party/WebKit/Source/core/frame/DOMWindowBase64.cpp \
@@ -329,15 +340,24 @@
 	third_party/WebKit/Source/core/frame/FrameView.cpp \
 	third_party/WebKit/Source/core/frame/History.cpp \
 	third_party/WebKit/Source/core/frame/ImageBitmap.cpp \
+	third_party/WebKit/Source/core/frame/LocalFrame.cpp \
 	third_party/WebKit/Source/core/frame/Location.cpp \
 	third_party/WebKit/Source/core/frame/Navigator.cpp \
 	third_party/WebKit/Source/core/frame/NavigatorID.cpp \
 	third_party/WebKit/Source/core/frame/PageConsole.cpp \
+	third_party/WebKit/Source/core/frame/PinchViewport.cpp \
+	third_party/WebKit/Source/core/frame/RemoteFrame.cpp \
 	third_party/WebKit/Source/core/frame/Screen.cpp \
 	third_party/WebKit/Source/core/frame/Settings.cpp \
 	third_party/WebKit/Source/core/frame/SettingsDelegate.cpp \
 	third_party/WebKit/Source/core/frame/SuspendableTimer.cpp \
 	third_party/WebKit/Source/core/frame/UseCounter.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPDirectiveList.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSource.cpp \
+	third_party/WebKit/Source/core/frame/csp/CSPSourceList.cpp \
+	third_party/WebKit/Source/core/frame/csp/ContentSecurityPolicy.cpp \
+	third_party/WebKit/Source/core/frame/csp/MediaListDirective.cpp \
+	third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp \
 	third_party/WebKit/Source/core/inspector/AsyncCallStackTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ConsoleMessage.cpp \
 	third_party/WebKit/Source/core/inspector/ContentSearchUtils.cpp \
@@ -387,6 +407,7 @@
 	third_party/WebKit/Source/core/inspector/PageConsoleAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageDebuggerAgent.cpp \
 	third_party/WebKit/Source/core/inspector/PageRuntimeAgent.cpp \
+	third_party/WebKit/Source/core/inspector/PromiseTracker.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptArguments.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallFrame.cpp \
 	third_party/WebKit/Source/core/inspector/ScriptCallStack.cpp \
@@ -429,6 +450,7 @@
 	third_party/WebKit/Source/core/loader/WorkerLoaderClientBridgeSyncHelper.cpp \
 	third_party/WebKit/Source/core/loader/WorkerThreadableLoader.cpp \
 	third_party/WebKit/Source/core/loader/appcache/ApplicationCache.cpp \
+	third_party/WebKit/Source/core/loader/appcache/ApplicationCacheHost.cpp \
 	third_party/WebKit/Source/core/page/AutoscrollController.cpp \
 	third_party/WebKit/Source/core/page/Chrome.cpp \
 	third_party/WebKit/Source/core/page/ContextMenuController.cpp \
@@ -447,8 +469,7 @@
 	third_party/WebKit/Source/core/frame/SmartClip.cpp \
 	third_party/WebKit/Source/core/page/NetworkStateNotifier.cpp \
 	third_party/WebKit/Source/core/page/Page.cpp \
-	third_party/WebKit/Source/core/page/PageGroup.cpp \
-	third_party/WebKit/Source/core/page/PageGroupLoadDeferrer.cpp \
+	third_party/WebKit/Source/core/page/PageAnimator.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleNotifier.cpp \
 	third_party/WebKit/Source/core/page/PageLifecycleObserver.cpp \
 	third_party/WebKit/Source/core/page/PagePopupClient.cpp \
@@ -458,6 +479,7 @@
 	third_party/WebKit/Source/core/page/PageVisibilityState.cpp \
 	third_party/WebKit/Source/core/page/PointerLockController.cpp \
 	third_party/WebKit/Source/core/page/PrintContext.cpp \
+	third_party/WebKit/Source/core/page/ScopedPageLoadDeferrer.cpp \
 	third_party/WebKit/Source/core/page/SpatialNavigation.cpp \
 	third_party/WebKit/Source/core/page/TouchAdjustment.cpp \
 	third_party/WebKit/Source/core/page/TouchDisambiguation.cpp \
@@ -532,6 +554,7 @@
 	third_party/WebKit/Source/core/xml/XSLTProcessor.cpp \
 	third_party/WebKit/Source/core/xml/XSLTProcessorLibxslt.cpp \
 	third_party/WebKit/Source/core/xml/XSLTUnicodeSort.cpp \
+	third_party/WebKit/Source/core/xml/parser/SharedBufferReader.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParser.cpp \
 	third_party/WebKit/Source/core/xml/parser/XMLDocumentParserScope.cpp
 
@@ -549,11 +572,10 @@
 	-pipe \
 	-fPIC \
 	-fno-strict-aliasing \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -576,6 +598,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -583,9 +606,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -594,12 +617,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -609,8 +629,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -619,6 +644,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -700,11 +726,10 @@
 	-pipe \
 	-fPIC \
 	-fno-strict-aliasing \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -727,6 +752,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -734,9 +760,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -745,12 +771,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -760,8 +783,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -770,6 +798,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -842,9 +871,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -854,7 +885,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -862,6 +892,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -874,7 +905,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_rendering.target.darwin-arm.mk b/Source/core/webcore_rendering.target.darwin-arm.mk
index af08054..1d161ed 100644
--- a/Source/core/webcore_rendering.target.darwin-arm.mk
+++ b/Source/core/webcore_rendering.target.darwin-arm.mk
@@ -27,7 +27,6 @@
 	third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp \
 	third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp \
 	third_party/WebKit/Source/core/rendering/ClipRect.cpp \
-	third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp \
 	third_party/WebKit/Source/core/rendering/CounterNode.cpp \
 	third_party/WebKit/Source/core/rendering/EllipsisBox.cpp \
 	third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp \
@@ -80,7 +79,6 @@
 	third_party/WebKit/Source/core/rendering/RenderLayer.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp \
-	third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp \
@@ -98,7 +96,6 @@
 	third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMenuList.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMeter.cpp \
-	third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp \
 	third_party/WebKit/Source/core/rendering/RenderObject.cpp \
@@ -147,6 +144,10 @@
 	third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp \
 	third_party/WebKit/Source/core/rendering/TextAutosizer.cpp \
 	third_party/WebKit/Source/core/rendering/break_lines.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineWidth.cpp \
@@ -186,7 +187,8 @@
 	third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleSurroundData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleTransformData.cpp \
-	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
+	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp \
+	third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -226,6 +228,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -233,9 +236,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -244,12 +247,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -259,8 +259,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -269,6 +274,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -375,6 +381,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -382,9 +389,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -393,12 +400,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -408,8 +412,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -418,6 +427,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -491,9 +501,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -505,7 +517,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -513,6 +524,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -527,7 +539,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_rendering.target.darwin-mips.mk b/Source/core/webcore_rendering.target.darwin-mips.mk
index 5dee352..4109803 100644
--- a/Source/core/webcore_rendering.target.darwin-mips.mk
+++ b/Source/core/webcore_rendering.target.darwin-mips.mk
@@ -27,7 +27,6 @@
 	third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp \
 	third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp \
 	third_party/WebKit/Source/core/rendering/ClipRect.cpp \
-	third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp \
 	third_party/WebKit/Source/core/rendering/CounterNode.cpp \
 	third_party/WebKit/Source/core/rendering/EllipsisBox.cpp \
 	third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp \
@@ -80,7 +79,6 @@
 	third_party/WebKit/Source/core/rendering/RenderLayer.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp \
-	third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp \
@@ -98,7 +96,6 @@
 	third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMenuList.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMeter.cpp \
-	third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp \
 	third_party/WebKit/Source/core/rendering/RenderObject.cpp \
@@ -147,6 +144,10 @@
 	third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp \
 	third_party/WebKit/Source/core/rendering/TextAutosizer.cpp \
 	third_party/WebKit/Source/core/rendering/break_lines.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineWidth.cpp \
@@ -186,7 +187,8 @@
 	third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleSurroundData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleTransformData.cpp \
-	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
+	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp \
+	third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -225,6 +227,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -232,9 +235,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -243,12 +246,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -258,8 +258,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -268,6 +273,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -373,6 +379,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -380,9 +387,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -391,12 +398,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -406,8 +410,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -416,6 +425,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -489,9 +499,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -501,7 +513,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -509,6 +520,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -521,7 +533,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_rendering.target.darwin-x86.mk b/Source/core/webcore_rendering.target.darwin-x86.mk
index 4078373..3af5bba 100644
--- a/Source/core/webcore_rendering.target.darwin-x86.mk
+++ b/Source/core/webcore_rendering.target.darwin-x86.mk
@@ -27,7 +27,6 @@
 	third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp \
 	third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp \
 	third_party/WebKit/Source/core/rendering/ClipRect.cpp \
-	third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp \
 	third_party/WebKit/Source/core/rendering/CounterNode.cpp \
 	third_party/WebKit/Source/core/rendering/EllipsisBox.cpp \
 	third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp \
@@ -80,7 +79,6 @@
 	third_party/WebKit/Source/core/rendering/RenderLayer.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp \
-	third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp \
@@ -98,7 +96,6 @@
 	third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMenuList.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMeter.cpp \
-	third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp \
 	third_party/WebKit/Source/core/rendering/RenderObject.cpp \
@@ -147,6 +144,10 @@
 	third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp \
 	third_party/WebKit/Source/core/rendering/TextAutosizer.cpp \
 	third_party/WebKit/Source/core/rendering/break_lines.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineWidth.cpp \
@@ -186,7 +187,8 @@
 	third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleSurroundData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleTransformData.cpp \
-	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
+	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp \
+	third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -202,11 +204,10 @@
 	-pipe \
 	-fPIC \
 	-Wno-uninitialized \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -229,6 +230,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -236,9 +238,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -247,12 +249,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -262,8 +261,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -272,6 +276,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -353,11 +358,10 @@
 	-pipe \
 	-fPIC \
 	-Wno-uninitialized \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -380,6 +384,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -387,9 +392,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -398,12 +403,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -413,8 +415,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -423,6 +430,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -495,9 +503,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -507,7 +517,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -515,6 +524,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -527,7 +537,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_rendering.target.linux-arm.mk b/Source/core/webcore_rendering.target.linux-arm.mk
index af08054..1d161ed 100644
--- a/Source/core/webcore_rendering.target.linux-arm.mk
+++ b/Source/core/webcore_rendering.target.linux-arm.mk
@@ -27,7 +27,6 @@
 	third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp \
 	third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp \
 	third_party/WebKit/Source/core/rendering/ClipRect.cpp \
-	third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp \
 	third_party/WebKit/Source/core/rendering/CounterNode.cpp \
 	third_party/WebKit/Source/core/rendering/EllipsisBox.cpp \
 	third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp \
@@ -80,7 +79,6 @@
 	third_party/WebKit/Source/core/rendering/RenderLayer.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp \
-	third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp \
@@ -98,7 +96,6 @@
 	third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMenuList.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMeter.cpp \
-	third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp \
 	third_party/WebKit/Source/core/rendering/RenderObject.cpp \
@@ -147,6 +144,10 @@
 	third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp \
 	third_party/WebKit/Source/core/rendering/TextAutosizer.cpp \
 	third_party/WebKit/Source/core/rendering/break_lines.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineWidth.cpp \
@@ -186,7 +187,8 @@
 	third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleSurroundData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleTransformData.cpp \
-	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
+	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp \
+	third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -226,6 +228,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -233,9 +236,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -244,12 +247,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -259,8 +259,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -269,6 +274,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -375,6 +381,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -382,9 +389,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -393,12 +400,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -408,8 +412,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -418,6 +427,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -491,9 +501,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -505,7 +517,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -513,6 +524,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -527,7 +539,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_rendering.target.linux-mips.mk b/Source/core/webcore_rendering.target.linux-mips.mk
index 5dee352..4109803 100644
--- a/Source/core/webcore_rendering.target.linux-mips.mk
+++ b/Source/core/webcore_rendering.target.linux-mips.mk
@@ -27,7 +27,6 @@
 	third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp \
 	third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp \
 	third_party/WebKit/Source/core/rendering/ClipRect.cpp \
-	third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp \
 	third_party/WebKit/Source/core/rendering/CounterNode.cpp \
 	third_party/WebKit/Source/core/rendering/EllipsisBox.cpp \
 	third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp \
@@ -80,7 +79,6 @@
 	third_party/WebKit/Source/core/rendering/RenderLayer.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp \
-	third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp \
@@ -98,7 +96,6 @@
 	third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMenuList.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMeter.cpp \
-	third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp \
 	third_party/WebKit/Source/core/rendering/RenderObject.cpp \
@@ -147,6 +144,10 @@
 	third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp \
 	third_party/WebKit/Source/core/rendering/TextAutosizer.cpp \
 	third_party/WebKit/Source/core/rendering/break_lines.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineWidth.cpp \
@@ -186,7 +187,8 @@
 	third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleSurroundData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleTransformData.cpp \
-	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
+	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp \
+	third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -225,6 +227,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -232,9 +235,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -243,12 +246,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -258,8 +258,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -268,6 +273,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -373,6 +379,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -380,9 +387,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -391,12 +398,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -406,8 +410,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -416,6 +425,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -489,9 +499,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -501,7 +513,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -509,6 +520,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -521,7 +533,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_rendering.target.linux-x86.mk b/Source/core/webcore_rendering.target.linux-x86.mk
index 4078373..3af5bba 100644
--- a/Source/core/webcore_rendering.target.linux-x86.mk
+++ b/Source/core/webcore_rendering.target.linux-x86.mk
@@ -27,7 +27,6 @@
 	third_party/WebKit/Source/core/rendering/AbstractInlineTextBox.cpp \
 	third_party/WebKit/Source/core/rendering/AutoTableLayout.cpp \
 	third_party/WebKit/Source/core/rendering/ClipRect.cpp \
-	third_party/WebKit/Source/core/rendering/CompositedLayerMapping.cpp \
 	third_party/WebKit/Source/core/rendering/CounterNode.cpp \
 	third_party/WebKit/Source/core/rendering/EllipsisBox.cpp \
 	third_party/WebKit/Source/core/rendering/FastTextAutosizer.cpp \
@@ -80,7 +79,6 @@
 	third_party/WebKit/Source/core/rendering/RenderLayer.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerBlendInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerClipper.cpp \
-	third_party/WebKit/Source/core/rendering/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerFilterInfo.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerModelObject.cpp \
 	third_party/WebKit/Source/core/rendering/RenderLayerReflectionInfo.cpp \
@@ -98,7 +96,6 @@
 	third_party/WebKit/Source/core/rendering/RenderMediaControls.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMenuList.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMeter.cpp \
-	third_party/WebKit/Source/core/rendering/RenderMultiColumnBlock.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnFlowThread.cpp \
 	third_party/WebKit/Source/core/rendering/RenderMultiColumnSet.cpp \
 	third_party/WebKit/Source/core/rendering/RenderObject.cpp \
@@ -147,6 +144,10 @@
 	third_party/WebKit/Source/core/rendering/SubtreeLayoutScope.cpp \
 	third_party/WebKit/Source/core/rendering/TextAutosizer.cpp \
 	third_party/WebKit/Source/core/rendering/break_lines.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositedLayerMapping.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/CompositingReasonFinder.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/GraphicsLayerUpdater.cpp \
+	third_party/WebKit/Source/core/rendering/compositing/RenderLayerCompositor.cpp \
 	third_party/WebKit/Source/core/rendering/line/BreakingContext.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineBreaker.cpp \
 	third_party/WebKit/Source/core/rendering/line/LineWidth.cpp \
@@ -186,7 +187,8 @@
 	third_party/WebKit/Source/core/rendering/style/StyleRareNonInheritedData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleSurroundData.cpp \
 	third_party/WebKit/Source/core/rendering/style/StyleTransformData.cpp \
-	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp
+	third_party/WebKit/Source/core/rendering/style/StyleVisualData.cpp \
+	third_party/WebKit/Source/core/rendering/style/StyleWillChangeData.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -202,11 +204,10 @@
 	-pipe \
 	-fPIC \
 	-Wno-uninitialized \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -229,6 +230,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -236,9 +238,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -247,12 +249,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -262,8 +261,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -272,6 +276,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -353,11 +358,10 @@
 	-pipe \
 	-fPIC \
 	-Wno-uninitialized \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -380,6 +384,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -387,9 +392,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -398,12 +403,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -413,8 +415,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -423,6 +430,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -495,9 +503,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -507,7 +517,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -515,6 +524,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -527,7 +537,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_svg.target.darwin-arm.mk b/Source/core/webcore_svg.target.darwin-arm.mk
index 73b1426..139c8ea 100644
--- a/Source/core/webcore_svg.target.darwin-arm.mk
+++ b/Source/core/webcore_svg.target.darwin-arm.mk
@@ -85,18 +85,16 @@
 	third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAngle.cpp \
+	third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp \
+	third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp \
@@ -105,7 +103,6 @@
 	third_party/WebKit/Source/core/svg/SVGBoolean.cpp \
 	third_party/WebKit/Source/core/svg/SVGCircleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGColor.cpp \
 	third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGCursorElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDefsElement.cpp \
@@ -113,6 +110,7 @@
 	third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocument.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp \
+	third_party/WebKit/Source/core/svg/SVGEnumeration.cpp \
 	third_party/WebKit/Source/core/svg/SVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstance.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp \
@@ -151,6 +149,7 @@
 	third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp \
@@ -171,11 +170,12 @@
 	third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGLineElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMaskElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp \
@@ -188,6 +188,7 @@
 	third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathParser.cpp \
+	third_party/WebKit/Source/core/svg/SVGPathSeg.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegList.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp \
@@ -208,6 +209,7 @@
 	third_party/WebKit/Source/core/svg/SVGRect.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp \
+	third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGSVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGScriptElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGSetElement.cpp \
@@ -227,9 +229,12 @@
 	third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTitleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransform.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformList.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGURIReference.cpp \
+	third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp \
 	third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGUseElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGVKernElement.cpp \
@@ -248,10 +253,7 @@
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp \
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp \
 	third_party/WebKit/Source/core/svg/properties/NewSVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -291,6 +293,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -298,9 +301,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -309,12 +312,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -324,8 +324,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -334,6 +339,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -440,6 +446,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -447,9 +454,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -458,12 +465,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -473,8 +477,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -483,6 +492,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -556,9 +566,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -570,7 +582,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -578,6 +589,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -592,7 +604,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_svg.target.darwin-mips.mk b/Source/core/webcore_svg.target.darwin-mips.mk
index 86b1983..57675eb 100644
--- a/Source/core/webcore_svg.target.darwin-mips.mk
+++ b/Source/core/webcore_svg.target.darwin-mips.mk
@@ -85,18 +85,16 @@
 	third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAngle.cpp \
+	third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp \
+	third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp \
@@ -105,7 +103,6 @@
 	third_party/WebKit/Source/core/svg/SVGBoolean.cpp \
 	third_party/WebKit/Source/core/svg/SVGCircleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGColor.cpp \
 	third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGCursorElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDefsElement.cpp \
@@ -113,6 +110,7 @@
 	third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocument.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp \
+	third_party/WebKit/Source/core/svg/SVGEnumeration.cpp \
 	third_party/WebKit/Source/core/svg/SVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstance.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp \
@@ -151,6 +149,7 @@
 	third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp \
@@ -171,11 +170,12 @@
 	third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGLineElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMaskElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp \
@@ -188,6 +188,7 @@
 	third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathParser.cpp \
+	third_party/WebKit/Source/core/svg/SVGPathSeg.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegList.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp \
@@ -208,6 +209,7 @@
 	third_party/WebKit/Source/core/svg/SVGRect.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp \
+	third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGSVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGScriptElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGSetElement.cpp \
@@ -227,9 +229,12 @@
 	third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTitleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransform.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformList.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGURIReference.cpp \
+	third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp \
 	third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGUseElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGVKernElement.cpp \
@@ -248,10 +253,7 @@
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp \
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp \
 	third_party/WebKit/Source/core/svg/properties/NewSVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -290,6 +292,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -297,9 +300,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -308,12 +311,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -323,8 +323,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -333,6 +338,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -438,6 +444,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -445,9 +452,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -456,12 +463,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -471,8 +475,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -481,6 +490,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -554,9 +564,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -566,7 +578,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -574,6 +585,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -586,7 +598,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_svg.target.darwin-x86.mk b/Source/core/webcore_svg.target.darwin-x86.mk
index 1d1888f..39a1c8d 100644
--- a/Source/core/webcore_svg.target.darwin-x86.mk
+++ b/Source/core/webcore_svg.target.darwin-x86.mk
@@ -85,18 +85,16 @@
 	third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAngle.cpp \
+	third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp \
+	third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp \
@@ -105,7 +103,6 @@
 	third_party/WebKit/Source/core/svg/SVGBoolean.cpp \
 	third_party/WebKit/Source/core/svg/SVGCircleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGColor.cpp \
 	third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGCursorElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDefsElement.cpp \
@@ -113,6 +110,7 @@
 	third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocument.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp \
+	third_party/WebKit/Source/core/svg/SVGEnumeration.cpp \
 	third_party/WebKit/Source/core/svg/SVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstance.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp \
@@ -151,6 +149,7 @@
 	third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp \
@@ -171,11 +170,12 @@
 	third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGLineElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMaskElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp \
@@ -188,6 +188,7 @@
 	third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathParser.cpp \
+	third_party/WebKit/Source/core/svg/SVGPathSeg.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegList.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp \
@@ -208,6 +209,7 @@
 	third_party/WebKit/Source/core/svg/SVGRect.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp \
+	third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGSVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGScriptElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGSetElement.cpp \
@@ -227,9 +229,12 @@
 	third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTitleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransform.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformList.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGURIReference.cpp \
+	third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp \
 	third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGUseElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGVKernElement.cpp \
@@ -248,10 +253,7 @@
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp \
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp \
 	third_party/WebKit/Source/core/svg/properties/NewSVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -266,11 +268,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -293,6 +294,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -300,9 +302,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -311,12 +313,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -326,8 +325,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -336,6 +340,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -416,11 +421,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -443,6 +447,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -450,9 +455,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -461,12 +466,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -476,8 +478,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -486,6 +493,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -558,9 +566,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -570,7 +580,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -578,6 +587,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -590,7 +600,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_svg.target.linux-arm.mk b/Source/core/webcore_svg.target.linux-arm.mk
index 73b1426..139c8ea 100644
--- a/Source/core/webcore_svg.target.linux-arm.mk
+++ b/Source/core/webcore_svg.target.linux-arm.mk
@@ -85,18 +85,16 @@
 	third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAngle.cpp \
+	third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp \
+	third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp \
@@ -105,7 +103,6 @@
 	third_party/WebKit/Source/core/svg/SVGBoolean.cpp \
 	third_party/WebKit/Source/core/svg/SVGCircleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGColor.cpp \
 	third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGCursorElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDefsElement.cpp \
@@ -113,6 +110,7 @@
 	third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocument.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp \
+	third_party/WebKit/Source/core/svg/SVGEnumeration.cpp \
 	third_party/WebKit/Source/core/svg/SVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstance.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp \
@@ -151,6 +149,7 @@
 	third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp \
@@ -171,11 +170,12 @@
 	third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGLineElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMaskElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp \
@@ -188,6 +188,7 @@
 	third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathParser.cpp \
+	third_party/WebKit/Source/core/svg/SVGPathSeg.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegList.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp \
@@ -208,6 +209,7 @@
 	third_party/WebKit/Source/core/svg/SVGRect.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp \
+	third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGSVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGScriptElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGSetElement.cpp \
@@ -227,9 +229,12 @@
 	third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTitleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransform.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformList.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGURIReference.cpp \
+	third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp \
 	third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGUseElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGVKernElement.cpp \
@@ -248,10 +253,7 @@
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp \
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp \
 	third_party/WebKit/Source/core/svg/properties/NewSVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -291,6 +293,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -298,9 +301,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -309,12 +312,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -324,8 +324,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -334,6 +339,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -440,6 +446,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -447,9 +454,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -458,12 +465,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -473,8 +477,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -483,6 +492,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -556,9 +566,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -570,7 +582,6 @@
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
 	-Wl,--icf=safe \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -578,6 +589,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -592,7 +604,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_svg.target.linux-mips.mk b/Source/core/webcore_svg.target.linux-mips.mk
index 86b1983..57675eb 100644
--- a/Source/core/webcore_svg.target.linux-mips.mk
+++ b/Source/core/webcore_svg.target.linux-mips.mk
@@ -85,18 +85,16 @@
 	third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAngle.cpp \
+	third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp \
+	third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp \
@@ -105,7 +103,6 @@
 	third_party/WebKit/Source/core/svg/SVGBoolean.cpp \
 	third_party/WebKit/Source/core/svg/SVGCircleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGColor.cpp \
 	third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGCursorElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDefsElement.cpp \
@@ -113,6 +110,7 @@
 	third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocument.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp \
+	third_party/WebKit/Source/core/svg/SVGEnumeration.cpp \
 	third_party/WebKit/Source/core/svg/SVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstance.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp \
@@ -151,6 +149,7 @@
 	third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp \
@@ -171,11 +170,12 @@
 	third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGLineElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMaskElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp \
@@ -188,6 +188,7 @@
 	third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathParser.cpp \
+	third_party/WebKit/Source/core/svg/SVGPathSeg.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegList.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp \
@@ -208,6 +209,7 @@
 	third_party/WebKit/Source/core/svg/SVGRect.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp \
+	third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGSVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGScriptElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGSetElement.cpp \
@@ -227,9 +229,12 @@
 	third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTitleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransform.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformList.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGURIReference.cpp \
+	third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp \
 	third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGUseElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGVKernElement.cpp \
@@ -248,10 +253,7 @@
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp \
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp \
 	third_party/WebKit/Source/core/svg/properties/NewSVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -290,6 +292,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -297,9 +300,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -308,12 +311,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -323,8 +323,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -333,6 +338,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -438,6 +444,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -445,9 +452,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -456,12 +463,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -471,8 +475,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -481,6 +490,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -554,9 +564,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -566,7 +578,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -574,6 +585,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -586,7 +598,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/webcore_svg.target.linux-x86.mk b/Source/core/webcore_svg.target.linux-x86.mk
index 1d1888f..39a1c8d 100644
--- a/Source/core/webcore_svg.target.linux-x86.mk
+++ b/Source/core/webcore_svg.target.linux-x86.mk
@@ -85,18 +85,16 @@
 	third_party/WebKit/Source/core/svg/SVGAltGlyphElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAltGlyphItemElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAngle.cpp \
+	third_party/WebKit/Source/core/svg/SVGAngleTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedAngle.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedColor.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedEnumeration.cpp \
+	third_party/WebKit/Source/core/svg/SVGAnimatedEnumerationBase.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedIntegerOptionalInteger.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedLength.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedNewPropertyAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedPath.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedTransformList.cpp \
-	third_party/WebKit/Source/core/svg/SVGAnimatedType.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimatedTypeAnimator.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGAnimateMotionElement.cpp \
@@ -105,7 +103,6 @@
 	third_party/WebKit/Source/core/svg/SVGBoolean.cpp \
 	third_party/WebKit/Source/core/svg/SVGCircleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGClipPathElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGColor.cpp \
 	third_party/WebKit/Source/core/svg/SVGComponentTransferFunctionElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGCursorElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDefsElement.cpp \
@@ -113,6 +110,7 @@
 	third_party/WebKit/Source/core/svg/SVGDiscardElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocument.cpp \
 	third_party/WebKit/Source/core/svg/SVGDocumentExtensions.cpp \
+	third_party/WebKit/Source/core/svg/SVGEnumeration.cpp \
 	third_party/WebKit/Source/core/svg/SVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstance.cpp \
 	third_party/WebKit/Source/core/svg/SVGElementInstanceList.cpp \
@@ -151,6 +149,7 @@
 	third_party/WebKit/Source/core/svg/SVGFontFaceElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceFormatElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceNameElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceSrcElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGFontFaceUriElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGForeignObjectElement.cpp \
@@ -171,11 +170,12 @@
 	third_party/WebKit/Source/core/svg/SVGLengthTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGLineElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGLinearGradientElement.cpp \
-	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMatrixTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGMarkerElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMaskElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMetadataElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGMissingGlyphElement.cpp \
+	third_party/WebKit/Source/core/svg/SVGMPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberOptionalNumber.cpp \
 	third_party/WebKit/Source/core/svg/SVGNumberTearOff.cpp \
@@ -188,6 +188,7 @@
 	third_party/WebKit/Source/core/svg/SVGPathByteStreamSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathParser.cpp \
+	third_party/WebKit/Source/core/svg/SVGPathSeg.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegList.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListBuilder.cpp \
 	third_party/WebKit/Source/core/svg/SVGPathSegListSource.cpp \
@@ -208,6 +209,7 @@
 	third_party/WebKit/Source/core/svg/SVGRect.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGRectTearOff.cpp \
+	third_party/WebKit/Source/core/svg/SVGRemoteFontFaceSource.cpp \
 	third_party/WebKit/Source/core/svg/SVGSVGElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGScriptElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGSetElement.cpp \
@@ -227,9 +229,12 @@
 	third_party/WebKit/Source/core/svg/SVGTextPositioningElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTitleElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransform.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformDistance.cpp \
 	third_party/WebKit/Source/core/svg/SVGTransformList.cpp \
+	third_party/WebKit/Source/core/svg/SVGTransformListTearOff.cpp \
 	third_party/WebKit/Source/core/svg/SVGURIReference.cpp \
+	third_party/WebKit/Source/core/svg/SVGUnitTypes.cpp \
 	third_party/WebKit/Source/core/svg/SVGUnknownElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGUseElement.cpp \
 	third_party/WebKit/Source/core/svg/SVGVKernElement.cpp \
@@ -248,10 +253,7 @@
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilter.cpp \
 	third_party/WebKit/Source/core/svg/graphics/filters/SVGFilterBuilder.cpp \
 	third_party/WebKit/Source/core/svg/properties/NewSVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAnimatedProperty.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGAttributeToPropertyMap.cpp \
-	third_party/WebKit/Source/core/svg/properties/SVGPathSegListPropertyTearOff.cpp
+	third_party/WebKit/Source/core/svg/properties/NewSVGPropertyTearOff.cpp
 
 
 # Flags passed to both C and C++ files.
@@ -266,11 +268,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -293,6 +294,7 @@
 
 MY_DEFS_Debug := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -300,9 +302,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -311,12 +313,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -326,8 +325,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -336,6 +340,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -416,11 +421,10 @@
 	-fvisibility=hidden \
 	-pipe \
 	-fPIC \
-	-m32 \
-	-mmmx \
-	-march=pentium4 \
 	-msse2 \
 	-mfpmath=sse \
+	-mmmx \
+	-m32 \
 	-fuse-ld=gold \
 	-ffunction-sections \
 	-funwind-tables \
@@ -443,6 +447,7 @@
 
 MY_DEFS_Release := \
 	'-DV8_DEPRECATION_WARNINGS' \
+	'-DBLINK_SCALE_FILTERS_AT_RECORD_TIME' \
 	'-D_FILE_OFFSET_BITS=64' \
 	'-DNO_TCMALLOC' \
 	'-DDISABLE_NACL' \
@@ -450,9 +455,9 @@
 	'-DUSE_LIBJPEG_TURBO=1' \
 	'-DUSE_PROPRIETARY_CODECS' \
 	'-DENABLE_CONFIGURATION_POLICY' \
+	'-DENABLE_NEW_GAMEPAD_API=1' \
 	'-DDISCARDABLE_MEMORY_ALWAYS_SUPPORTED_NATIVELY' \
 	'-DSYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE' \
-	'-DUSE_OPENSSL=1' \
 	'-DENABLE_EGLIMAGE=1' \
 	'-DCLD_VERSION=1' \
 	'-DENABLE_PRINTING=1' \
@@ -461,12 +466,9 @@
 	'-DINSIDE_BLINK' \
 	'-DENABLE_CUSTOM_SCHEME_HANDLER=0' \
 	'-DENABLE_SVG_FONTS=1' \
-	'-DENABLE_GDI_FONTS_ON_WINDOWS=0' \
-	'-DENABLE_HARFBUZZ_ON_WINDOWS=1' \
 	'-DWTF_USE_CONCATENATED_IMPULSE_RESPONSES=1' \
 	'-DENABLE_FAST_MOBILE_SCROLLING=1' \
 	'-DENABLE_INPUT_SPEECH=0' \
-	'-DENABLE_LEGACY_NOTIFICATIONS=0' \
 	'-DENABLE_MEDIA_CAPTURE=1' \
 	'-DENABLE_OPENTYPE_VERTICAL=1' \
 	'-DU_USING_ICU_NAMESPACE=0' \
@@ -476,8 +478,13 @@
 	'-DSK_ENABLE_LEGACY_API_ALIASING=1' \
 	'-DSK_ATTR_DEPRECATED=SK_NOTHING_ARG1' \
 	'-DGR_GL_IGNORE_ES3_MSAA=0' \
+	'-DSK_SUPPORT_LEGACY_LAYERRASTERIZER_API=1' \
+	'-DSK_WILL_NEVER_DRAW_PERSPECTIVE_TEXT' \
 	'-DSK_SUPPORT_LEGACY_COMPATIBLEDEVICE_CONFIG=1' \
 	'-DSK_SUPPORT_LEGACY_PUBLICEFFECTCONSTRUCTORS=1' \
+	'-DSK_SUPPORT_LEGACY_GETCLIPTYPE' \
+	'-DSK_SUPPORT_LEGACY_GETTOTALCLIP' \
+	'-DSK_SUPPORT_LEGACY_GETTOPDEVICE' \
 	'-DSK_BUILD_FOR_ANDROID' \
 	'-DSK_USE_POSIX_THREADS' \
 	'-DSK_DEFERRED_CANVAS_USES_FACTORIES=1' \
@@ -486,6 +493,7 @@
 	'-DCHROME_PNG_READ_PACK_SUPPORT' \
 	'-DLIBXML_STATIC' \
 	'-DLIBXSLT_STATIC' \
+	'-DUSE_OPENSSL=1' \
 	'-D__STDC_CONSTANT_MACROS' \
 	'-D__STDC_FORMAT_MACROS' \
 	'-DANDROID' \
@@ -558,9 +566,11 @@
 LOCAL_CFLAGS := $(MY_CFLAGS_$(GYP_CONFIGURATION)) $(MY_DEFS_$(GYP_CONFIGURATION))
 LOCAL_C_INCLUDES := $(GYP_COPIED_SOURCE_ORIGIN_DIRS) $(LOCAL_C_INCLUDES_$(GYP_CONFIGURATION))
 LOCAL_CPPFLAGS := $(LOCAL_CPPFLAGS_$(GYP_CONFIGURATION))
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
 ### Rules for final target.
 
 LOCAL_LDFLAGS_Debug := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -570,7 +580,6 @@
 	-nostdlib \
 	-Wl,--no-undefined \
 	-Wl,--exclude-libs=ALL \
-	-Wl,--fatal-warnings \
 	-Wl,--gc-sections \
 	-Wl,--warn-shared-textrel \
 	-Wl,-O1 \
@@ -578,6 +587,7 @@
 
 
 LOCAL_LDFLAGS_Release := \
+	-Wl,--fatal-warnings \
 	-Wl,-z,now \
 	-Wl,-z,relro \
 	-Wl,-z,noexecstack \
@@ -590,7 +600,6 @@
 	-Wl,-O1 \
 	-Wl,--as-needed \
 	-Wl,--gc-sections \
-	-Wl,--fatal-warnings \
 	-Wl,--warn-shared-textrel
 
 
diff --git a/Source/core/workers/AbstractWorker.cpp b/Source/core/workers/AbstractWorker.cpp
index aa07055..1aba3c2 100644
--- a/Source/core/workers/AbstractWorker.cpp
+++ b/Source/core/workers/AbstractWorker.cpp
@@ -34,7 +34,7 @@
 #include "bindings/v8/ExceptionState.h"
 #include "core/dom/ExceptionCode.h"
 #include "core/dom/ExecutionContext.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
 namespace WebCore {
diff --git a/Source/core/workers/AbstractWorker.h b/Source/core/workers/AbstractWorker.h
index 213d7c9..08d90e3 100644
--- a/Source/core/workers/AbstractWorker.h
+++ b/Source/core/workers/AbstractWorker.h
@@ -36,6 +36,7 @@
 #include "core/events/EventListener.h"
 #include "core/events/EventTarget.h"
 #include "core/events/ThreadLocalEventNames.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -47,8 +48,8 @@
 class KURL;
 class ExecutionContext;
 
-class AbstractWorker : public RefCounted<AbstractWorker>, public EventTargetWithInlineData, public ActiveDOMObject {
-    REFCOUNTED_EVENT_TARGET(AbstractWorker);
+class AbstractWorker : public RefCountedWillBeRefCountedGarbageCollected<AbstractWorker>, public EventTargetWithInlineData, public ActiveDOMObject {
+    DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<AbstractWorker>);
 public:
     // EventTarget APIs
     virtual ExecutionContext* executionContext() const OVERRIDE FINAL { return ActiveDOMObject::executionContext(); }
@@ -58,6 +59,8 @@
     AbstractWorker(ExecutionContext*);
     virtual ~AbstractWorker();
 
+    virtual void trace(Visitor*) { }
+
 protected:
     // Helper function that converts a URL to an absolute URL and checks the result for validity.
     KURL resolveURL(const String& url, ExceptionState&);
diff --git a/Source/core/workers/AbstractWorker.idl b/Source/core/workers/AbstractWorker.idl
index 1b643f7..0076c3a 100644
--- a/Source/core/workers/AbstractWorker.idl
+++ b/Source/core/workers/AbstractWorker.idl
@@ -30,7 +30,8 @@
  */
 
 [
-    NoInterfaceObject
+    NoInterfaceObject,
+    WillBeGarbageCollected
 ] interface AbstractWorker {
     attribute EventHandler onerror;
 };
diff --git a/Source/core/workers/DedicatedWorkerGlobalScope.cpp b/Source/core/workers/DedicatedWorkerGlobalScope.cpp
index 0605c01..8acf5af 100644
--- a/Source/core/workers/DedicatedWorkerGlobalScope.cpp
+++ b/Source/core/workers/DedicatedWorkerGlobalScope.cpp
@@ -41,9 +41,9 @@
 
 namespace WebCore {
 
-PassRefPtr<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(DedicatedWorkerThread* thread, PassOwnPtr<WorkerThreadStartupData> startupData, double timeOrigin)
+PassRefPtrWillBeRawPtr<DedicatedWorkerGlobalScope> DedicatedWorkerGlobalScope::create(DedicatedWorkerThread* thread, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData, double timeOrigin)
 {
-    RefPtr<DedicatedWorkerGlobalScope> context = adoptRef(new DedicatedWorkerGlobalScope(startupData->m_scriptURL, startupData->m_userAgent, thread, timeOrigin, startupData->m_workerClients.release()));
+    RefPtrWillBeRawPtr<DedicatedWorkerGlobalScope> context = adoptRefWillBeRefCountedGarbageCollected(new DedicatedWorkerGlobalScope(startupData->m_scriptURL, startupData->m_userAgent, thread, timeOrigin, startupData->m_workerClients.release()));
     context->applyContentSecurityPolicyFromString(startupData->m_contentSecurityPolicy, startupData->m_contentSecurityPolicyType);
     return context.release();
 }
@@ -83,4 +83,9 @@
     return static_cast<DedicatedWorkerThread*>(Base::thread());
 }
 
+void DedicatedWorkerGlobalScope::trace(Visitor* visitor)
+{
+    WorkerGlobalScope::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/workers/DedicatedWorkerGlobalScope.h b/Source/core/workers/DedicatedWorkerGlobalScope.h
index c689d79..68f4a2e 100644
--- a/Source/core/workers/DedicatedWorkerGlobalScope.h
+++ b/Source/core/workers/DedicatedWorkerGlobalScope.h
@@ -32,18 +32,19 @@
 #define DedicatedWorkerGlobalScope_h
 
 #include "core/dom/MessagePort.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerGlobalScope.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
 class DedicatedWorkerThread;
-struct WorkerThreadStartupData;
+class WorkerThreadStartupData;
 
 class DedicatedWorkerGlobalScope FINAL : public WorkerGlobalScope {
 public:
     typedef WorkerGlobalScope Base;
-    static PassRefPtr<DedicatedWorkerGlobalScope> create(DedicatedWorkerThread*, PassOwnPtr<WorkerThreadStartupData>, double timeOrigin);
+    static PassRefPtrWillBeRawPtr<DedicatedWorkerGlobalScope> create(DedicatedWorkerThread*, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>, double timeOrigin);
     virtual ~DedicatedWorkerGlobalScope();
 
     virtual bool isDedicatedWorkerGlobalScope() const OVERRIDE { return true; }
@@ -60,6 +61,8 @@
 
     DedicatedWorkerThread* thread();
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     DedicatedWorkerGlobalScope(const KURL&, const String& userAgent, DedicatedWorkerThread*, double timeOrigin, PassOwnPtr<WorkerClients>);
 };
diff --git a/Source/core/workers/DedicatedWorkerGlobalScope.idl b/Source/core/workers/DedicatedWorkerGlobalScope.idl
index 1ef0663..dcc182c 100644
--- a/Source/core/workers/DedicatedWorkerGlobalScope.idl
+++ b/Source/core/workers/DedicatedWorkerGlobalScope.idl
@@ -29,7 +29,7 @@
  */
 
 [
-    GlobalContext=DedicatedWorkerGlobalScope,
+    GlobalContext=DedicatedWorkerGlobalScope
 ] interface DedicatedWorkerGlobalScope : WorkerGlobalScope {
     [Custom, RaisesException] void postMessage(any message, optional MessagePort[] messagePorts);
     attribute EventHandler onmessage;
diff --git a/Source/core/workers/DedicatedWorkerThread.cpp b/Source/core/workers/DedicatedWorkerThread.cpp
index 94038c6..82acf46 100644
--- a/Source/core/workers/DedicatedWorkerThread.cpp
+++ b/Source/core/workers/DedicatedWorkerThread.cpp
@@ -38,12 +38,12 @@
 
 namespace WebCore {
 
-PassRefPtr<DedicatedWorkerThread> DedicatedWorkerThread::create(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtr<DedicatedWorkerThread> DedicatedWorkerThread::create(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
 {
     return adoptRef(new DedicatedWorkerThread(workerLoaderProxy, workerObjectProxy, timeOrigin, startupData));
 }
 
-DedicatedWorkerThread::DedicatedWorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtr<WorkerThreadStartupData> startupData)
+DedicatedWorkerThread::DedicatedWorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerObjectProxy& workerObjectProxy, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
     : WorkerThread(workerLoaderProxy, workerObjectProxy, startupData)
     , m_workerObjectProxy(workerObjectProxy)
     , m_timeOrigin(timeOrigin)
@@ -54,7 +54,7 @@
 {
 }
 
-PassRefPtr<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtrWillBeRawPtr<WorkerGlobalScope> DedicatedWorkerThread::createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
 {
     return DedicatedWorkerGlobalScope::create(this, startupData, m_timeOrigin);
 }
diff --git a/Source/core/workers/DedicatedWorkerThread.h b/Source/core/workers/DedicatedWorkerThread.h
index 3ae1871..ade5728 100644
--- a/Source/core/workers/DedicatedWorkerThread.h
+++ b/Source/core/workers/DedicatedWorkerThread.h
@@ -30,26 +30,26 @@
 #ifndef DedicatedWorkerThread_h
 #define DedicatedWorkerThread_h
 
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerThread.h"
 
 namespace WebCore {
 
 class WorkerObjectProxy;
-struct WorkerThreadStartupData;
+class WorkerThreadStartupData;
 
 class DedicatedWorkerThread FINAL : public WorkerThread {
 public:
-    static PassRefPtr<DedicatedWorkerThread> create(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtr<WorkerThreadStartupData>);
+    static PassRefPtr<DedicatedWorkerThread> create(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
     WorkerObjectProxy& workerObjectProxy() const { return m_workerObjectProxy; }
     virtual ~DedicatedWorkerThread();
 
 protected:
-    virtual PassRefPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData>) OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>) OVERRIDE;
     virtual void runEventLoop() OVERRIDE;
 
 private:
-    DedicatedWorkerThread(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtr<WorkerThreadStartupData>);
+    DedicatedWorkerThread(WorkerLoaderProxy&, WorkerObjectProxy&, double timeOrigin, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
 
     WorkerObjectProxy& m_workerObjectProxy;
     double m_timeOrigin;
diff --git a/Source/core/workers/SharedWorker.cpp b/Source/core/workers/SharedWorker.cpp
index 331c8cd..f548e9b 100644
--- a/Source/core/workers/SharedWorker.cpp
+++ b/Source/core/workers/SharedWorker.cpp
@@ -37,7 +37,7 @@
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/MessageChannel.h"
 #include "core/dom/MessagePort.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/UseCounter.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/loader/FrameLoader.h"
@@ -54,14 +54,14 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<SharedWorker> SharedWorker::create(ExecutionContext* context, const String& url, const String& name, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<SharedWorker> SharedWorker::create(ExecutionContext* context, const String& url, const String& name, ExceptionState& exceptionState)
 {
     ASSERT(isMainThread());
     ASSERT_WITH_SECURITY_IMPLICATION(context->isDocument());
 
     UseCounter::count(context, UseCounter::SharedWorkerStart);
 
-    RefPtr<SharedWorker> worker = adoptRef(new SharedWorker(context));
+    RefPtrWillBeRawPtr<SharedWorker> worker = adoptRefWillBeRefCountedGarbageCollected(new SharedWorker(context));
 
     RefPtr<MessageChannel> channel = MessageChannel::create(context);
     worker->m_port = channel->port1();
@@ -74,12 +74,12 @@
     Document* document = toDocument(context);
     if (!document->securityOrigin()->canAccessSharedWorkers()) {
         exceptionState.throwSecurityError("Access to shared workers is denied to origin '" + document->securityOrigin()->toString() + "'.");
-        return 0;
+        return nullptr;
     }
 
     KURL scriptURL = worker->resolveURL(url, exceptionState);
     if (scriptURL.isEmpty())
-        return 0;
+        return nullptr;
 
     if (document->frame()->loader().client()->sharedWorkerRepositoryClient())
         document->frame()->loader().client()->sharedWorkerRepositoryClient()->connect(worker.get(), remotePort.release(), scriptURL, name, exceptionState);
@@ -106,4 +106,9 @@
     unsetPendingActivity(this);
 }
 
+void SharedWorker::trace(Visitor* visitor)
+{
+    AbstractWorker::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/workers/SharedWorker.h b/Source/core/workers/SharedWorker.h
index b19fd41..561695e 100644
--- a/Source/core/workers/SharedWorker.h
+++ b/Source/core/workers/SharedWorker.h
@@ -33,6 +33,7 @@
 #define SharedWorker_h
 
 #include "core/workers/AbstractWorker.h"
+#include "heap/Handle.h"
 #include "platform/Supplementable.h"
 
 namespace WebCore {
@@ -41,7 +42,7 @@
 
 class SharedWorker FINAL : public AbstractWorker, public ScriptWrappable, public Supplementable<SharedWorker> {
 public:
-    static PassRefPtr<SharedWorker> create(ExecutionContext*, const String& url, const String& name, ExceptionState&);
+    static PassRefPtrWillBeRawPtr<SharedWorker> create(ExecutionContext*, const String& url, const String& name, ExceptionState&);
     virtual ~SharedWorker();
 
     MessagePort* port() const { return m_port.get(); }
@@ -53,6 +54,8 @@
     // Allows this SharedWorker + JS wrapper to be garbage collected.
     void unsetPreventGC();
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     explicit SharedWorker(ExecutionContext*);
 
diff --git a/Source/core/workers/SharedWorker.idl b/Source/core/workers/SharedWorker.idl
index b36361e..51efb03 100644
--- a/Source/core/workers/SharedWorker.idl
+++ b/Source/core/workers/SharedWorker.idl
@@ -35,6 +35,7 @@
     ConstructorCallWith=ExecutionContext,
     RaisesException=Constructor,
     RuntimeEnabled=SharedWorker,
+    WillBeGarbageCollected,
 ] interface SharedWorker : EventTarget {
     readonly attribute MessagePort port;
 };
diff --git a/Source/core/workers/SharedWorkerGlobalScope.cpp b/Source/core/workers/SharedWorkerGlobalScope.cpp
index c961699..0367bd0 100644
--- a/Source/core/workers/SharedWorkerGlobalScope.cpp
+++ b/Source/core/workers/SharedWorkerGlobalScope.cpp
@@ -51,9 +51,9 @@
 }
 
 // static
-PassRefPtr<SharedWorkerGlobalScope> SharedWorkerGlobalScope::create(const String& name, SharedWorkerThread* thread, PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtrWillBeRawPtr<SharedWorkerGlobalScope> SharedWorkerGlobalScope::create(const String& name, SharedWorkerThread* thread, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
 {
-    RefPtr<SharedWorkerGlobalScope> context = adoptRef(new SharedWorkerGlobalScope(name, startupData->m_scriptURL, startupData->m_userAgent, thread, startupData->m_workerClients.release()));
+    RefPtrWillBeRawPtr<SharedWorkerGlobalScope> context = adoptRefWillBeRefCountedGarbageCollected(new SharedWorkerGlobalScope(name, startupData->m_scriptURL, startupData->m_userAgent, thread, startupData->m_workerClients.release()));
     context->applyContentSecurityPolicyFromString(startupData->m_contentSecurityPolicy, startupData->m_contentSecurityPolicyType);
     return context.release();
 }
@@ -85,4 +85,9 @@
     addMessageToWorkerConsole(JSMessageSource, ErrorMessageLevel, errorMessage, sourceURL, lineNumber, callStack, 0);
 }
 
+void SharedWorkerGlobalScope::trace(Visitor* visitor)
+{
+    WorkerGlobalScope::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/workers/SharedWorkerGlobalScope.h b/Source/core/workers/SharedWorkerGlobalScope.h
index 8dae3bb..376d524 100644
--- a/Source/core/workers/SharedWorkerGlobalScope.h
+++ b/Source/core/workers/SharedWorkerGlobalScope.h
@@ -31,9 +31,10 @@
 #ifndef SharedWorkerGlobalScope_h
 #define SharedWorkerGlobalScope_h
 
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerGlobalScope.h"
 #include "core/workers/WorkerThreadStartupData.h"
+#include "heap/Handle.h"
 
 namespace WebCore {
 
@@ -43,7 +44,7 @@
     class SharedWorkerGlobalScope FINAL : public WorkerGlobalScope {
     public:
         typedef WorkerGlobalScope Base;
-        static PassRefPtr<SharedWorkerGlobalScope> create(const String& name, SharedWorkerThread*, PassOwnPtr<WorkerThreadStartupData>);
+        static PassRefPtrWillBeRawPtr<SharedWorkerGlobalScope> create(const String& name, SharedWorkerThread*, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
         virtual ~SharedWorkerGlobalScope();
 
         virtual bool isSharedWorkerGlobalScope() const OVERRIDE { return true; }
@@ -57,6 +58,8 @@
 
         SharedWorkerThread* thread();
 
+        virtual void trace(Visitor*) OVERRIDE;
+
     private:
         SharedWorkerGlobalScope(const String& name, const KURL&, const String& userAgent, SharedWorkerThread*, PassOwnPtr<WorkerClients>);
         virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) OVERRIDE;
diff --git a/Source/core/workers/SharedWorkerRepositoryClient.h b/Source/core/workers/SharedWorkerRepositoryClient.h
index 607bc29..a8ebc3b 100644
--- a/Source/core/workers/SharedWorkerRepositoryClient.h
+++ b/Source/core/workers/SharedWorkerRepositoryClient.h
@@ -31,6 +31,7 @@
 #ifndef SharedWorkerRepositoryClient_h
 #define SharedWorkerRepositoryClient_h
 
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/Noncopyable.h"
 
@@ -51,7 +52,7 @@
     SharedWorkerRepositoryClient() { }
     virtual ~SharedWorkerRepositoryClient() { }
 
-    virtual void connect(PassRefPtr<SharedWorker>, PassOwnPtr<blink::WebMessagePortChannel>, const KURL&, const String& name, ExceptionState&)  = 0;
+    virtual void connect(PassRefPtrWillBeRawPtr<SharedWorker>, PassOwnPtr<blink::WebMessagePortChannel>, const KURL&, const String& name, ExceptionState&)  = 0;
 
     virtual void documentDetached(Document*) = 0;
 };
diff --git a/Source/core/workers/SharedWorkerThread.cpp b/Source/core/workers/SharedWorkerThread.cpp
index 117b583..267b26a 100644
--- a/Source/core/workers/SharedWorkerThread.cpp
+++ b/Source/core/workers/SharedWorkerThread.cpp
@@ -37,12 +37,12 @@
 
 namespace WebCore {
 
-PassRefPtr<SharedWorkerThread> SharedWorkerThread::create(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtr<SharedWorkerThread> SharedWorkerThread::create(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
 {
     return adoptRef(new SharedWorkerThread(name, workerLoaderProxy, workerReportingProxy, startupData));
 }
 
-SharedWorkerThread::SharedWorkerThread(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> startupData)
+SharedWorkerThread::SharedWorkerThread(const String& name, WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
     : WorkerThread(workerLoaderProxy, workerReportingProxy, startupData)
     , m_name(name.isolatedCopy())
 {
@@ -52,7 +52,7 @@
 {
 }
 
-PassRefPtr<WorkerGlobalScope> SharedWorkerThread::createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData> startupData)
+PassRefPtrWillBeRawPtr<WorkerGlobalScope> SharedWorkerThread::createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
 {
     return SharedWorkerGlobalScope::create(m_name, this, startupData);
 }
diff --git a/Source/core/workers/SharedWorkerThread.h b/Source/core/workers/SharedWorkerThread.h
index ca1f15e..46cb873 100644
--- a/Source/core/workers/SharedWorkerThread.h
+++ b/Source/core/workers/SharedWorkerThread.h
@@ -30,23 +30,23 @@
 #ifndef SharedWorkerThread_h
 #define SharedWorkerThread_h
 
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerThread.h"
 
 namespace WebCore {
 
-struct WorkerThreadStartupData;
+class WorkerThreadStartupData;
 
 class SharedWorkerThread : public WorkerThread {
 public:
-    static PassRefPtr<SharedWorkerThread> create(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtr<WorkerThreadStartupData>);
+    static PassRefPtr<SharedWorkerThread> create(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
     virtual ~SharedWorkerThread();
 
 protected:
-    virtual PassRefPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData>) OVERRIDE;
+    virtual PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>) OVERRIDE;
 
 private:
-    SharedWorkerThread(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtr<WorkerThreadStartupData>);
+    SharedWorkerThread(const String& name, WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
 
     String m_name;
 };
diff --git a/Source/core/workers/Worker.cpp b/Source/core/workers/Worker.cpp
index f75b7ac..12442f1 100644
--- a/Source/core/workers/Worker.cpp
+++ b/Source/core/workers/Worker.cpp
@@ -50,22 +50,25 @@
     ScriptWrappable::init(this);
 }
 
-PassRefPtr<Worker> Worker::create(ExecutionContext* context, const String& url, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<Worker> Worker::create(ExecutionContext* context, const String& url, ExceptionState& exceptionState)
 {
     ASSERT(isMainThread());
     Document* document = toDocument(context);
     UseCounter::count(context, UseCounter::WorkerStart);
-    ASSERT(document->page());
-    WorkerGlobalScopeProxyProvider* proxyProvider = WorkerGlobalScopeProxyProvider::from(document->page());
+    if (!document->page()) {
+        exceptionState.throwDOMException(InvalidAccessError, "The context provided is invalid.");
+        return nullptr;
+    }
+    WorkerGlobalScopeProxyProvider* proxyProvider = WorkerGlobalScopeProxyProvider::from(*document->page());
     ASSERT(proxyProvider);
 
-    RefPtr<Worker> worker = adoptRef(new Worker(context));
+    RefPtrWillBeRawPtr<Worker> worker = adoptRefWillBeRefCountedGarbageCollected(new Worker(context));
 
     worker->suspendIfNeeded();
 
     KURL scriptURL = worker->resolveURL(url, exceptionState);
     if (scriptURL.isEmpty())
-        return 0;
+        return nullptr;
 
     // The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
     worker->setPendingActivity(worker.get());
@@ -100,7 +103,8 @@
 
 void Worker::terminate()
 {
-    m_contextProxy->terminateWorkerGlobalScope();
+    if (m_contextProxy)
+        m_contextProxy->terminateWorkerGlobalScope();
 }
 
 void Worker::stop()
@@ -134,4 +138,9 @@
     unsetPendingActivity(this);
 }
 
+void Worker::trace(Visitor* visitor)
+{
+    AbstractWorker::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/workers/Worker.h b/Source/core/workers/Worker.h
index 1f1067b..8e8771a 100644
--- a/Source/core/workers/Worker.h
+++ b/Source/core/workers/Worker.h
@@ -34,6 +34,7 @@
 #include "core/events/ThreadLocalEventNames.h"
 #include "core/workers/AbstractWorker.h"
 #include "core/workers/WorkerScriptLoaderClient.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefPtr.h"
@@ -48,7 +49,7 @@
 
 class Worker FINAL : public AbstractWorker, public ScriptWrappable, private WorkerScriptLoaderClient {
 public:
-    static PassRefPtr<Worker> create(ExecutionContext*, const String& url, ExceptionState&);
+    static PassRefPtrWillBeRawPtr<Worker> create(ExecutionContext*, const String& url, ExceptionState&);
     virtual ~Worker();
 
     virtual const AtomicString& interfaceName() const OVERRIDE;
@@ -62,6 +63,8 @@
 
     DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     explicit Worker(ExecutionContext*);
 
diff --git a/Source/core/workers/Worker.idl b/Source/core/workers/Worker.idl
index 5d9f11a..f494473 100644
--- a/Source/core/workers/Worker.idl
+++ b/Source/core/workers/Worker.idl
@@ -30,6 +30,7 @@
     Constructor(DOMString scriptUrl),
     ConstructorCallWith=ExecutionContext,
     RaisesException=Constructor,
+    WillBeGarbageCollected,
 ] interface Worker : EventTarget {
 
     attribute EventHandler onmessage;
diff --git a/Source/core/workers/WorkerConsole.cpp b/Source/core/workers/WorkerConsole.cpp
index f4a819e..1d77add 100644
--- a/Source/core/workers/WorkerConsole.cpp
+++ b/Source/core/workers/WorkerConsole.cpp
@@ -62,6 +62,11 @@
     return m_scope->executionContext();
 }
 
+void WorkerConsole::trace(Visitor* visitor)
+{
+    visitor->trace(m_scope);
+}
+
 // FIXME: add memory getter
 
 } // namespace WebCore
diff --git a/Source/core/workers/WorkerConsole.h b/Source/core/workers/WorkerConsole.h
index a2ef40d..8a644c6 100644
--- a/Source/core/workers/WorkerConsole.h
+++ b/Source/core/workers/WorkerConsole.h
@@ -34,6 +34,7 @@
 #include "core/inspector/ConsoleAPITypes.h"
 #include "core/frame/ConsoleBase.h"
 #include "core/frame/ConsoleTypes.h"
+#include "heap/Handle.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -43,14 +44,19 @@
 
 class ScriptArguments;
 
-class WorkerConsole FINAL : public RefCounted<WorkerConsole>, public ConsoleBase, public ScriptWrappable {
+class WorkerConsole FINAL : public RefCountedWillBeRefCountedGarbageCollected<WorkerConsole>, public ConsoleBase, public ScriptWrappable {
 public:
-    using RefCounted<WorkerConsole>::ref;
-    using RefCounted<WorkerConsole>::deref;
+    using RefCountedWillBeRefCountedGarbageCollected<WorkerConsole>::ref;
+    using RefCountedWillBeRefCountedGarbageCollected<WorkerConsole>::deref;
 
-    static PassRefPtr<WorkerConsole> create(WorkerGlobalScope* scope) { return adoptRef(new WorkerConsole(scope)); }
+    static PassRefPtrWillBeRawPtr<WorkerConsole> create(WorkerGlobalScope* scope)
+    {
+        return adoptRefWillBeRefCountedGarbageCollected(new WorkerConsole(scope));
+    }
     virtual ~WorkerConsole();
 
+    void trace(Visitor*);
+
 protected:
     virtual ExecutionContext* context() OVERRIDE;
     virtual void reportMessageToClient(MessageLevel, const String& message, PassRefPtr<ScriptCallStack>) OVERRIDE;
@@ -61,7 +67,7 @@
     virtual void refConsole() OVERRIDE { ref(); }
     virtual void derefConsole() OVERRIDE { deref(); }
 
-    WorkerGlobalScope* m_scope;
+    RawPtrWillBeMember<WorkerGlobalScope> m_scope;
 };
 
 } // namespace WebCore
diff --git a/Source/core/workers/WorkerConsole.idl b/Source/core/workers/WorkerConsole.idl
index 84e181b..3ed5e4e 100644
--- a/Source/core/workers/WorkerConsole.idl
+++ b/Source/core/workers/WorkerConsole.idl
@@ -27,6 +27,7 @@
  */
 
 [
-    NoInterfaceObject
+    NoInterfaceObject,
+    WillBeGarbageCollected
 ] interface WorkerConsole : ConsoleBase {
 };
diff --git a/Source/core/workers/WorkerGlobalScope.cpp b/Source/core/workers/WorkerGlobalScope.cpp
index e7e302d..1699766 100644
--- a/Source/core/workers/WorkerGlobalScope.cpp
+++ b/Source/core/workers/WorkerGlobalScope.cpp
@@ -51,6 +51,7 @@
 #include "core/workers/WorkerReportingProxy.h"
 #include "core/workers/WorkerScriptLoader.h"
 #include "core/workers/WorkerThread.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
 #include "platform/weborigin/KURL.h"
 #include "platform/weborigin/SecurityOrigin.h"
 
@@ -92,21 +93,15 @@
 
 WorkerGlobalScope::~WorkerGlobalScope()
 {
-    ASSERT(thread()->isCurrentThread());
-
-    // Make sure we have no observers.
-    notifyObserversOfStop();
-
-    // Notify proxy that we are going away. This can free the WorkerThread object, so do not access it after this.
-    thread()->workerReportingProxy().workerGlobalScopeDestroyed();
-
-    setClient(0);
+#if !ENABLE(OILPAN)
+    dispose();
+#endif
 }
 
-void WorkerGlobalScope::applyContentSecurityPolicyFromString(const String& policy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType)
+void WorkerGlobalScope::applyContentSecurityPolicyFromString(const String& policy, ContentSecurityPolicyHeaderType contentSecurityPolicyType)
 {
     setContentSecurityPolicy(ContentSecurityPolicy::create(this));
-    contentSecurityPolicy()->didReceiveHeader(policy, contentSecurityPolicyType, ContentSecurityPolicy::HeaderSourceHTTP);
+    contentSecurityPolicy()->didReceiveHeader(policy, contentSecurityPolicyType, ContentSecurityPolicyHeaderSourceHTTP);
 }
 
 ExecutionContext* WorkerGlobalScope::executionContext() const
@@ -192,6 +187,29 @@
     m_workerInspectorController.clear();
 }
 
+void WorkerGlobalScope::willStopActiveDOMObjects()
+{
+    lifecycleNotifier().notifyWillStopActiveDOMObjects();
+}
+
+void WorkerGlobalScope::dispose()
+{
+    ASSERT(thread()->isCurrentThread());
+
+    // Notify proxy that we are going away. This can free the WorkerThread object, so do not access it after this.
+    thread()->workerReportingProxy().workerGlobalScopeDestroyed();
+
+    clearScript();
+    clearInspector();
+    setClient(0);
+
+    // The thread reference isn't currently cleared, as the execution
+    // context's thread is accessed by GCed lifetime objects when
+    // they're finalized.
+    // FIXME: oilpan: avoid by explicitly removing the WorkerGlobalScope
+    // as an observable context right here.
+}
+
 void WorkerGlobalScope::importScripts(const Vector<String>& urls, ExceptionState& exceptionState)
 {
     ASSERT(contentSecurityPolicy());
@@ -251,7 +269,7 @@
         return;
     }
     thread()->workerReportingProxy().reportConsoleMessage(source, level, message, lineNumber, sourceURL);
-    addMessageToWorkerConsole(source, level, message, sourceURL, lineNumber, 0, state);
+    addMessageToWorkerConsole(source, level, message, sourceURL, lineNumber, nullptr, state);
 }
 
 void WorkerGlobalScope::addMessageToWorkerConsole(MessageSource source, MessageLevel level, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack> callStack, ScriptState* state)
@@ -273,53 +291,6 @@
     return m_script->isExecutionForbidden();
 }
 
-WorkerGlobalScope::Observer::Observer(WorkerGlobalScope* context)
-    : m_context(context)
-{
-    ASSERT(m_context && m_context->isContextThread());
-    m_context->registerObserver(this);
-}
-
-WorkerGlobalScope::Observer::~Observer()
-{
-    if (!m_context)
-        return;
-    ASSERT(m_context->isContextThread());
-    m_context->unregisterObserver(this);
-}
-
-void WorkerGlobalScope::Observer::stopObserving()
-{
-    if (!m_context)
-        return;
-    ASSERT(m_context->isContextThread());
-    m_context->unregisterObserver(this);
-    m_context = 0;
-}
-
-void WorkerGlobalScope::registerObserver(Observer* observer)
-{
-    ASSERT(observer);
-    m_workerObservers.add(observer);
-}
-
-void WorkerGlobalScope::unregisterObserver(Observer* observer)
-{
-    ASSERT(observer);
-    m_workerObservers.remove(observer);
-}
-
-void WorkerGlobalScope::notifyObserversOfStop()
-{
-    HashSet<Observer*>::iterator iter = m_workerObservers.begin();
-    while (iter != m_workerObservers.end()) {
-        WorkerGlobalScope::Observer* observer = *iter;
-        observer->stopObserving();
-        observer->notifyStop();
-        iter = m_workerObservers.begin();
-    }
-}
-
 bool WorkerGlobalScope::idleNotification()
 {
     return script()->idleNotification();
@@ -330,4 +301,14 @@
     return m_eventQueue.get();
 }
 
+void WorkerGlobalScope::trace(Visitor* visitor)
+{
+    visitor->trace(m_console);
+    visitor->trace(m_location);
+    visitor->trace(m_navigator);
+#if ENABLE(OILPAN)
+    HeapSupplementable<WorkerGlobalScope>::trace(visitor);
+#endif
+}
+
 } // namespace WebCore
diff --git a/Source/core/workers/WorkerGlobalScope.h b/Source/core/workers/WorkerGlobalScope.h
index 08fa1ee..915e779 100644
--- a/Source/core/workers/WorkerGlobalScope.h
+++ b/Source/core/workers/WorkerGlobalScope.h
@@ -33,10 +33,11 @@
 #include "core/events/EventListener.h"
 #include "core/events/EventTarget.h"
 #include "core/events/ThreadLocalEventNames.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerConsole.h"
 #include "core/workers/WorkerEventQueue.h"
-#include "core/workers/WorkerSupplementable.h"
+#include "heap/Handle.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
 #include "wtf/Assertions.h"
 #include "wtf/HashMap.h"
 #include "wtf/OwnPtr.h"
@@ -48,7 +49,6 @@
 namespace WebCore {
 
     class Blob;
-    class DOMURL;
     class ExceptionState;
     class ScheduledAction;
     class WorkerClients;
@@ -58,8 +58,9 @@
     class WorkerNavigator;
     class WorkerThread;
 
-    class WorkerGlobalScope : public RefCounted<WorkerGlobalScope>, public ScriptWrappable, public SecurityContext, public ExecutionContext, public ExecutionContextClient, public WorkerSupplementable, public EventTargetWithInlineData {
-        REFCOUNTED_EVENT_TARGET(WorkerGlobalScope);
+    class WorkerGlobalScope : public RefCountedWillBeRefCountedGarbageCollected<WorkerGlobalScope>, public ScriptWrappable, public SecurityContext, public ExecutionContext, public ExecutionContextClient, public WillBeHeapSupplementable<WorkerGlobalScope>, public EventTargetWithInlineData {
+        WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WorkerGlobalScope);
+        DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<WorkerGlobalScope>);
     public:
         virtual ~WorkerGlobalScope();
 
@@ -81,6 +82,9 @@
         void clearScript() { m_script.clear(); }
         void clearInspector();
 
+        void willStopActiveDOMObjects();
+        void dispose();
+
         WorkerThread* thread() const { return m_thread; }
 
         virtual void postTask(PassOwnPtr<ExecutionContextTask>) OVERRIDE FINAL; // Executes the task on context's thread asynchronously.
@@ -115,22 +119,6 @@
 
         bool isClosing() { return m_closing; }
 
-        // An observer interface to be notified when the worker thread is getting stopped.
-        class Observer {
-            WTF_MAKE_NONCOPYABLE(Observer);
-        public:
-            Observer(WorkerGlobalScope*);
-            virtual ~Observer();
-            virtual void notifyStop() = 0;
-            void stopObserving();
-        private:
-            WorkerGlobalScope* m_context;
-        };
-        friend class Observer;
-        void registerObserver(Observer*);
-        void unregisterObserver(Observer*);
-        void notifyObserversOfStop();
-
         bool idleNotification();
 
         double timeOrigin() const { return m_timeOrigin; }
@@ -140,9 +128,11 @@
         using SecurityContext::securityOrigin;
         using SecurityContext::contentSecurityPolicy;
 
+        virtual void trace(Visitor*);
+
     protected:
         WorkerGlobalScope(const KURL&, const String& userAgent, WorkerThread*, double timeOrigin, PassOwnPtr<WorkerClients>);
-        void applyContentSecurityPolicyFromString(const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType);
+        void applyContentSecurityPolicyFromString(const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType);
 
         virtual void logExceptionToConsole(const String& errorMessage, const String& sourceURL, int lineNumber, int columnNumber, PassRefPtr<ScriptCallStack>) OVERRIDE;
         void addMessageToWorkerConsole(MessageSource, MessageLevel, const String& message, const String& sourceURL, unsigned lineNumber, PassRefPtr<ScriptCallStack>, ScriptState*);
@@ -163,19 +153,16 @@
         KURL m_url;
         String m_userAgent;
 
-        mutable RefPtr<WorkerConsole> m_console;
-        mutable RefPtr<WorkerLocation> m_location;
-        mutable RefPtr<WorkerNavigator> m_navigator;
+        mutable RefPtrWillBeMember<WorkerConsole> m_console;
+        mutable RefPtrWillBeMember<WorkerLocation> m_location;
+        mutable RefPtrWillBeMember<WorkerNavigator> m_navigator;
 
         OwnPtr<WorkerScriptController> m_script;
         WorkerThread* m_thread;
 
-        mutable RefPtr<DOMURL> m_domURL;
         OwnPtr<WorkerInspectorController> m_workerInspectorController;
         bool m_closing;
 
-        HashSet<Observer*> m_workerObservers;
-
         OwnPtr<WorkerEventQueue> m_eventQueue;
 
         OwnPtr<WorkerClients> m_workerClients;
diff --git a/Source/core/workers/WorkerGlobalScope.idl b/Source/core/workers/WorkerGlobalScope.idl
index d61d48f..7e5dd62 100644
--- a/Source/core/workers/WorkerGlobalScope.idl
+++ b/Source/core/workers/WorkerGlobalScope.idl
@@ -27,6 +27,7 @@
 [
     Custom=ToV8,
     GlobalContext=WorkerGlobalScope,
+    WillBeGarbageCollected
 ] interface WorkerGlobalScope : EventTarget {
 
     // WorkerGlobalScope
@@ -42,7 +43,7 @@
     [Replaceable] readonly attribute WorkerNavigator navigator;
 
     // Additional constructors
-    attribute URLConstructor webkitURL; // FIXME: deprecate this.
+    [MeasureAs=PrefixedWorkerURL] attribute URLConstructor webkitURL; // FIXME: deprecate this.
 };
 
 WorkerGlobalScope implements ImageBitmapFactories;
diff --git a/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp b/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp
index 3a539df..05bd6f1 100644
--- a/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp
+++ b/Source/core/workers/WorkerGlobalScopeProxyProvider.cpp
@@ -33,7 +33,7 @@
 
 namespace WebCore {
 
-WorkerGlobalScopeProxyProvider* WorkerGlobalScopeProxyProvider::from(Page* page)
+WorkerGlobalScopeProxyProvider* WorkerGlobalScopeProxyProvider::from(Page& page)
 {
     return static_cast<WorkerGlobalScopeProxyProvider*>(Supplement<Page>::from(page, supplementName()));
 }
@@ -43,7 +43,7 @@
     return "WorkerGlobalScopeProxyProvider";
 }
 
-void provideWorkerGlobalScopeProxyProviderTo(Page* page, PassOwnPtr<WorkerGlobalScopeProxyProvider> provider)
+void provideWorkerGlobalScopeProxyProviderTo(Page& page, PassOwnPtr<WorkerGlobalScopeProxyProvider> provider)
 {
     Supplement<Page>::provideTo(page, WorkerGlobalScopeProxyProvider::supplementName(), provider);
 }
diff --git a/Source/core/workers/WorkerGlobalScopeProxyProvider.h b/Source/core/workers/WorkerGlobalScopeProxyProvider.h
index 54b5f47..6265938 100644
--- a/Source/core/workers/WorkerGlobalScopeProxyProvider.h
+++ b/Source/core/workers/WorkerGlobalScopeProxyProvider.h
@@ -50,11 +50,11 @@
 
     virtual WorkerGlobalScopeProxy* createWorkerGlobalScopeProxy(Worker*) = 0;
 
-    static WorkerGlobalScopeProxyProvider* from(Page*);
+    static WorkerGlobalScopeProxyProvider* from(Page&);
     static const char* supplementName();
 };
 
-void provideWorkerGlobalScopeProxyProviderTo(Page*, PassOwnPtr<WorkerGlobalScopeProxyProvider>);
+void provideWorkerGlobalScopeProxyProviderTo(Page&, PassOwnPtr<WorkerGlobalScopeProxyProvider>);
 
 } // namespace WebCore
 
diff --git a/Source/core/workers/WorkerLocation.h b/Source/core/workers/WorkerLocation.h
index 6b5aefb..b36cb88 100644
--- a/Source/core/workers/WorkerLocation.h
+++ b/Source/core/workers/WorkerLocation.h
@@ -29,6 +29,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/dom/DOMURLUtilsReadOnly.h"
+#include "heap/Handle.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -37,11 +38,11 @@
 
 namespace WebCore {
 
-class WorkerLocation FINAL : public RefCounted<WorkerLocation>, public ScriptWrappable, public DOMURLUtilsReadOnly {
+class WorkerLocation FINAL : public RefCountedWillBeGarbageCollectedFinalized<WorkerLocation>, public ScriptWrappable, public DOMURLUtilsReadOnly {
 public:
-    static PassRefPtr<WorkerLocation> create(const KURL& url)
+    static PassRefPtrWillBeRawPtr<WorkerLocation> create(const KURL& url)
     {
-        return adoptRef(new WorkerLocation(url));
+        return adoptRefWillBeNoop(new WorkerLocation(url));
     }
 
     virtual KURL url() const OVERRIDE { return m_url; }
@@ -51,6 +52,8 @@
         return String();
     }
 
+    void trace(Visitor*) { }
+
 private:
     explicit WorkerLocation(const KURL& url) : m_url(url)
     {
diff --git a/Source/core/workers/WorkerLocation.idl b/Source/core/workers/WorkerLocation.idl
index 64ed9e0..6db8c03 100644
--- a/Source/core/workers/WorkerLocation.idl
+++ b/Source/core/workers/WorkerLocation.idl
@@ -27,7 +27,8 @@
  */
 
 [
-    GlobalContext=WorkerGlobalScope
+    GlobalContext=WorkerGlobalScope,
+    WillBeGarbageCollected
 ] interface WorkerLocation {
 };
 
diff --git a/Source/core/workers/WorkerMessagingProxy.cpp b/Source/core/workers/WorkerMessagingProxy.cpp
index 0a15e5d..be37a1c 100644
--- a/Source/core/workers/WorkerMessagingProxy.cpp
+++ b/Source/core/workers/WorkerMessagingProxy.cpp
@@ -33,21 +33,21 @@
 #include "core/dom/Document.h"
 #include "core/events/ErrorEvent.h"
 #include "core/events/MessageEvent.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/DOMWindow.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/inspector/InspectorInstrumentation.h"
 #include "core/inspector/ScriptCallStack.h"
 #include "core/inspector/WorkerDebuggerAgent.h"
 #include "core/inspector/WorkerInspectorController.h"
 #include "core/loader/DocumentLoadTiming.h"
 #include "core/loader/DocumentLoader.h"
-#include "core/page/PageGroup.h"
 #include "core/workers/DedicatedWorkerGlobalScope.h"
 #include "core/workers/DedicatedWorkerThread.h"
 #include "core/workers/Worker.h"
 #include "core/workers/WorkerClients.h"
 #include "core/workers/WorkerObjectProxy.h"
 #include "core/workers/WorkerThreadStartupData.h"
+#include "heap/Handle.h"
 #include "platform/NotImplemented.h"
 #include "wtf/Functional.h"
 #include "wtf/MainThread.h"
@@ -111,7 +111,7 @@
     ASSERT(m_executionContext->isDocument());
     Document* document = toDocument(m_executionContext.get());
 
-    OwnPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode, startMode, document->contentSecurityPolicy()->deprecatedHeader(), document->contentSecurityPolicy()->deprecatedHeaderType(), m_workerClients.release());
+    OwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode, startMode, document->contentSecurityPolicy()->deprecatedHeader(), document->contentSecurityPolicy()->deprecatedHeaderType(), m_workerClients.release());
     double originTime = document->loader() ? document->loader()->timing()->referenceMonotonicTime() : monotonicallyIncreasingTime();
 
     RefPtr<DedicatedWorkerThread> thread = DedicatedWorkerThread::create(*this, *m_workerObjectProxy.get(), originTime, startupData.release());
@@ -169,7 +169,7 @@
     RefPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sourceURL, lineNumber, columnNumber, 0);
     bool errorHandled = !m_workerObject->dispatchEvent(event);
     if (!errorHandled)
-        m_executionContext->reportException(event, 0, NotSharableCrossOrigin);
+        m_executionContext->reportException(event, nullptr, NotSharableCrossOrigin);
 }
 
 void WorkerMessagingProxy::reportConsoleMessage(MessageSource source, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
@@ -224,7 +224,7 @@
         return;
     ASSERT(!m_pageInspector);
     m_pageInspector = pageInspector;
-    m_workerThread->runLoop().postTaskForMode(createCallbackTask(connectToWorkerGlobalScopeInspectorTask, true), WorkerDebuggerAgent::debuggerTaskMode);
+    m_workerThread->runLoop().postDebuggerTask(createCallbackTask(connectToWorkerGlobalScopeInspectorTask, true));
 }
 
 static void disconnectFromWorkerGlobalScopeInspectorTask(ExecutionContext* context, bool)
@@ -237,7 +237,7 @@
     m_pageInspector = 0;
     if (m_askedToTerminate)
         return;
-    m_workerThread->runLoop().postTaskForMode(createCallbackTask(disconnectFromWorkerGlobalScopeInspectorTask, true), WorkerDebuggerAgent::debuggerTaskMode);
+    m_workerThread->runLoop().postDebuggerTask(createCallbackTask(disconnectFromWorkerGlobalScopeInspectorTask, true));
 }
 
 static void dispatchOnInspectorBackendTask(ExecutionContext* context, const String& message)
@@ -249,7 +249,7 @@
 {
     if (m_askedToTerminate)
         return;
-    m_workerThread->runLoop().postTaskForMode(createCallbackTask(dispatchOnInspectorBackendTask, String(message)), WorkerDebuggerAgent::debuggerTaskMode);
+    m_workerThread->runLoop().postDebuggerTask(createCallbackTask(dispatchOnInspectorBackendTask, String(message)));
     WorkerDebuggerAgent::interruptAndDispatchInspectorCommands(m_workerThread.get());
 }
 
@@ -258,7 +258,7 @@
     // This method is always the last to be performed, so the proxy is not needed for communication
     // in either side any more. However, the Worker object may still exist, and it assumes that the proxy exists, too.
     m_askedToTerminate = true;
-    m_workerThread = 0;
+    m_workerThread = nullptr;
 
     InspectorInstrumentation::workerGlobalScopeTerminated(m_executionContext.get(), this);
 
diff --git a/Source/core/workers/WorkerNavigator.cpp b/Source/core/workers/WorkerNavigator.cpp
index 7ad476c..ea364ee 100644
--- a/Source/core/workers/WorkerNavigator.cpp
+++ b/Source/core/workers/WorkerNavigator.cpp
@@ -45,4 +45,11 @@
     return m_userAgent;
 }
 
+void WorkerNavigator::trace(Visitor* visitor)
+{
+#if ENABLE(OILPAN)
+    HeapSupplementable<WorkerNavigator>::trace(visitor);
+#endif
+}
+
 } // namespace WebCore
diff --git a/Source/core/workers/WorkerNavigator.h b/Source/core/workers/WorkerNavigator.h
index 850d706..e7865ad 100644
--- a/Source/core/workers/WorkerNavigator.h
+++ b/Source/core/workers/WorkerNavigator.h
@@ -28,6 +28,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/frame/NavigatorBase.h"
+#include "heap/Handle.h"
 #include "platform/Supplementable.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -35,13 +36,19 @@
 
 namespace WebCore {
 
-class WorkerNavigator FINAL : public RefCounted<WorkerNavigator>, public ScriptWrappable, public NavigatorBase, public Supplementable<WorkerNavigator> {
+class WorkerNavigator FINAL : public RefCountedWillBeGarbageCollectedFinalized<WorkerNavigator>, public ScriptWrappable, public NavigatorBase, public WillBeHeapSupplementable<WorkerNavigator> {
+    WILL_BE_USING_GARBAGE_COLLECTED_MIXIN(WorkerNavigator);
 public:
-    static PassRefPtr<WorkerNavigator> create(const String& userAgent) { return adoptRef(new WorkerNavigator(userAgent)); }
+    static PassRefPtrWillBeRawPtr<WorkerNavigator> create(const String& userAgent)
+    {
+        return adoptRefWillBeNoop(new WorkerNavigator(userAgent));
+    }
     virtual ~WorkerNavigator();
 
     virtual String userAgent() const OVERRIDE;
 
+    void trace(Visitor*);
+
 private:
     explicit WorkerNavigator(const String&);
 
diff --git a/Source/core/workers/WorkerNavigator.idl b/Source/core/workers/WorkerNavigator.idl
index 3debfca..b62d74d 100644
--- a/Source/core/workers/WorkerNavigator.idl
+++ b/Source/core/workers/WorkerNavigator.idl
@@ -27,7 +27,8 @@
  */
 
 [
-    GlobalContext=WorkerGlobalScope
+    GlobalContext=WorkerGlobalScope,
+    WillBeGarbageCollected
 ] interface WorkerNavigator {
 };
 
diff --git a/Source/core/workers/WorkerRunLoop.cpp b/Source/core/workers/WorkerRunLoop.cpp
index f015c82..e17016b 100644
--- a/Source/core/workers/WorkerRunLoop.cpp
+++ b/Source/core/workers/WorkerRunLoop.cpp
@@ -42,35 +42,50 @@
 
 namespace WebCore {
 
-static String defaultMode()
-{
-    return String();
-}
-
-class WorkerRunLoop::Task {
-    WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
+class WorkerRunLoopTask : public blink::WebThread::Task {
+    WTF_MAKE_NONCOPYABLE(WorkerRunLoopTask); WTF_MAKE_FAST_ALLOCATED;
 public:
-    static PassOwnPtr<Task> create(PassOwnPtr<ExecutionContextTask> task, const String& mode)
+    static PassOwnPtr<WorkerRunLoopTask> create(const WorkerRunLoop& runLoop, PassOwnPtr<ExecutionContextTask> task)
     {
-        return adoptPtr(new Task(task, mode));
+        return adoptPtr(new WorkerRunLoopTask(runLoop, task));
     }
-    const String& mode() const { return m_mode; }
-    void performTask(const WorkerRunLoop& runLoop, ExecutionContext* context)
+
+    virtual ~WorkerRunLoopTask() { }
+
+    virtual void run() OVERRIDE
     {
-        WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
-        if ((!workerGlobalScope->isClosing() && !runLoop.terminated()) || m_task->isCleanupTask())
-            m_task->performTask(context);
+        WorkerGlobalScope* workerGlobalScope = m_runLoop.context();
+        if ((!workerGlobalScope->isClosing() && !m_runLoop.terminated()) || m_task->isCleanupTask())
+            m_task->performTask(workerGlobalScope);
     }
 
 private:
-    Task(PassOwnPtr<ExecutionContextTask> task, const String& mode)
-        : m_task(task)
-        , m_mode(mode.isolatedCopy())
+    WorkerRunLoopTask(const WorkerRunLoop& runLoop, PassOwnPtr<ExecutionContextTask> task)
+        : m_runLoop(runLoop)
+        , m_task(task)
     {
     }
 
+    const WorkerRunLoop& m_runLoop;
     OwnPtr<ExecutionContextTask> m_task;
-    String m_mode;
+};
+
+class TickleDebuggerQueueTask FINAL : public ExecutionContextTask {
+public:
+    static PassOwnPtr<TickleDebuggerQueueTask> create(WorkerRunLoop* loop)
+    {
+        return adoptPtr(new TickleDebuggerQueueTask(loop));
+    }
+    virtual void performTask(ExecutionContext* context) OVERRIDE
+    {
+        ASSERT(context->isWorkerGlobalScope());
+        m_loop->runDebuggerTask(WorkerRunLoop::DontWaitForMessage);
+    }
+
+private:
+    explicit TickleDebuggerQueueTask(WorkerRunLoop* loop) : m_loop(loop) { }
+
+    WorkerRunLoop* m_loop;
 };
 
 class WorkerSharedTimer : public SharedTimer {
@@ -95,33 +110,10 @@
     double m_nextFireTime;
 };
 
-class ModePredicate {
-public:
-    ModePredicate(const String& mode)
-        : m_mode(mode)
-        , m_defaultMode(mode == defaultMode())
-    {
-    }
-
-    bool isDefaultMode() const
-    {
-        return m_defaultMode;
-    }
-
-    bool operator()(WorkerRunLoop::Task* task) const
-    {
-        return m_defaultMode || m_mode == task->mode();
-    }
-
-private:
-    String m_mode;
-    bool m_defaultMode;
-};
-
 WorkerRunLoop::WorkerRunLoop()
     : m_sharedTimer(adoptPtr(new WorkerSharedTimer))
+    , m_context(0)
     , m_nestedCount(0)
-    , m_uniqueId(0)
 {
 }
 
@@ -155,45 +147,51 @@
     WorkerGlobalScope* m_context;
 };
 
-void WorkerRunLoop::run(WorkerGlobalScope* context)
+void WorkerRunLoop::setWorkerGlobalScope(WorkerGlobalScope* context)
 {
-    RunLoopSetup setup(*this, context);
-    ModePredicate modePredicate(defaultMode());
+    ASSERT(!m_context);
+    ASSERT(context);
+    m_context = context;
+}
+
+void WorkerRunLoop::run()
+{
+    ASSERT(m_context);
+    RunLoopSetup setup(*this, m_context);
     MessageQueueWaitResult result;
     do {
         ThreadState::current()->safePoint(ThreadState::NoHeapPointersOnStack);
-        result = runInMode(context, modePredicate, WaitForMessage);
+        result = run(m_messageQueue, WaitForMessage);
     } while (result != MessageQueueTerminated);
-    runCleanupTasks(context);
+    runCleanupTasks();
 }
 
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, const String& mode, WaitMode waitMode)
+MessageQueueWaitResult WorkerRunLoop::runDebuggerTask(WaitMode waitMode)
 {
-    RunLoopSetup setup(*this, context);
-    ModePredicate modePredicate(mode);
-    MessageQueueWaitResult result = runInMode(context, modePredicate, waitMode);
-    return result;
+    ASSERT(m_context);
+    RunLoopSetup setup(*this, m_context);
+    return run(m_debuggerMessageQueue, waitMode);
 }
 
-MessageQueueWaitResult WorkerRunLoop::runInMode(WorkerGlobalScope* context, const ModePredicate& predicate, WaitMode waitMode)
+MessageQueueWaitResult WorkerRunLoop::run(MessageQueue<blink::WebThread::Task>& queue, WaitMode waitMode)
 {
-    ASSERT(context);
-    ASSERT(context->thread());
-    ASSERT(context->thread()->isCurrentThread());
+    ASSERT(m_context);
+    ASSERT(m_context->thread());
+    ASSERT(m_context->thread()->isCurrentThread());
 
     bool nextTimeoutEventIsIdleWatchdog;
     MessageQueueWaitResult result;
-    OwnPtr<WorkerRunLoop::Task> task;
+    OwnPtr<blink::WebThread::Task> task;
     do {
         double absoluteTime = 0.0;
         nextTimeoutEventIsIdleWatchdog = false;
         if (waitMode == WaitForMessage) {
-            absoluteTime = (predicate.isDefaultMode() && m_sharedTimer->isActive()) ? m_sharedTimer->fireTime() : MessageQueue<Task>::infiniteTime();
+            absoluteTime = m_sharedTimer->isActive() ? m_sharedTimer->fireTime() : MessageQueue<blink::WebThread::Task>::infiniteTime();
 
             // Do a script engine idle notification if the next event is distant enough.
             const double kMinIdleTimespan = 0.3; // seconds
-            if (m_messageQueue.isEmpty() && absoluteTime > currentTime() + kMinIdleTimespan) {
-                bool hasMoreWork = !context->idleNotification();
+            if (queue.isEmpty() && absoluteTime > currentTime() + kMinIdleTimespan) {
+                bool hasMoreWork = !m_context->idleNotification();
                 if (hasMoreWork) {
                     // Schedule a watchdog, so if there are no events within a particular time interval
                     // idle notifications won't stop firing.
@@ -209,7 +207,7 @@
 
         {
             ThreadState::SafePointScope safePointScope(ThreadState::NoHeapPointersOnStack);
-            task = m_messageQueue.waitForMessageFilteredWithTimeout(result, predicate, absoluteTime);
+            task = queue.waitForMessageWithTimeout(result, absoluteTime);
         }
     } while (result == MessageQueueTimeout && nextTimeoutEventIsIdleWatchdog);
 
@@ -221,13 +219,13 @@
         break;
 
     case MessageQueueMessageReceived:
-        InspectorInstrumentation::willProcessTask(context);
-        task->performTask(*this, context);
-        InspectorInstrumentation::didProcessTask(context);
+        InspectorInstrumentation::willProcessTask(m_context);
+        task->run();
+        InspectorInstrumentation::didProcessTask(m_context);
         break;
 
     case MessageQueueTimeout:
-        if (!context->isClosing())
+        if (!m_context->isClosing())
             m_sharedTimer->fire();
         break;
     }
@@ -235,44 +233,47 @@
     return result;
 }
 
-void WorkerRunLoop::runCleanupTasks(WorkerGlobalScope* context)
+void WorkerRunLoop::runCleanupTasks()
 {
-    ASSERT(context);
-    ASSERT(context->thread());
-    ASSERT(context->thread()->isCurrentThread());
+    ASSERT(m_context);
+    ASSERT(m_context->thread());
+    ASSERT(m_context->thread()->isCurrentThread());
     ASSERT(m_messageQueue.killed());
+    ASSERT(m_debuggerMessageQueue.killed());
 
     while (true) {
-        OwnPtr<WorkerRunLoop::Task> task = m_messageQueue.tryGetMessageIgnoringKilled();
+        OwnPtr<blink::WebThread::Task> task = m_debuggerMessageQueue.tryGetMessageIgnoringKilled();
+        if (!task)
+            task = m_messageQueue.tryGetMessageIgnoringKilled();
         if (!task)
             return;
-        task->performTask(*this, context);
+        task->run();
     }
 }
 
 void WorkerRunLoop::terminate()
 {
     m_messageQueue.kill();
+    m_debuggerMessageQueue.kill();
 }
 
 bool WorkerRunLoop::postTask(PassOwnPtr<ExecutionContextTask> task)
 {
-    return postTaskForMode(task, defaultMode());
-}
-
-bool WorkerRunLoop::postTask(const Closure& closure)
-{
-    return postTask(CallClosureTask::create(closure));
+    return m_messageQueue.append(WorkerRunLoopTask::create(*this, task));
 }
 
 void WorkerRunLoop::postTaskAndTerminate(PassOwnPtr<ExecutionContextTask> task)
 {
-    m_messageQueue.appendAndKill(Task::create(task, defaultMode().isolatedCopy()));
+    m_debuggerMessageQueue.kill();
+    m_messageQueue.appendAndKill(WorkerRunLoopTask::create(*this, task));
 }
 
-bool WorkerRunLoop::postTaskForMode(PassOwnPtr<ExecutionContextTask> task, const String& mode)
+bool WorkerRunLoop::postDebuggerTask(PassOwnPtr<ExecutionContextTask> task)
 {
-    return m_messageQueue.append(Task::create(task, mode.isolatedCopy()));
+    bool posted = m_debuggerMessageQueue.append(WorkerRunLoopTask::create(*this, task));
+    if (posted)
+        postTask(TickleDebuggerQueueTask::create(this));
+    return posted;
 }
 
 } // namespace WebCore
diff --git a/Source/core/workers/WorkerRunLoop.h b/Source/core/workers/WorkerRunLoop.h
index 3f3f59f..4ec47eb 100644
--- a/Source/core/workers/WorkerRunLoop.h
+++ b/Source/core/workers/WorkerRunLoop.h
@@ -33,6 +33,7 @@
 
 #include "core/dom/ExecutionContext.h"
 #include "core/dom/ExecutionContextTask.h"
+#include "public/platform/WebThread.h"
 #include "wtf/Functional.h"
 #include "wtf/MessageQueue.h"
 #include "wtf/OwnPtr.h"
@@ -40,7 +41,6 @@
 
 namespace WebCore {
 
-    class ModePredicate;
     class WorkerGlobalScope;
     class WorkerSharedTimer;
 
@@ -49,42 +49,42 @@
         WorkerRunLoop();
         ~WorkerRunLoop();
 
+        void setWorkerGlobalScope(WorkerGlobalScope*);
+
         // Blocking call. Waits for tasks and timers, invokes the callbacks.
-        void run(WorkerGlobalScope*);
+        void run();
 
         enum WaitMode { WaitForMessage, DontWaitForMessage };
 
-        // Waits for a single task and returns.
-        MessageQueueWaitResult runInMode(WorkerGlobalScope*, const String& mode, WaitMode = WaitForMessage);
+        // Waits for a single debugger task and returns.
+        MessageQueueWaitResult runDebuggerTask(WaitMode = WaitForMessage);
 
         void terminate();
         bool terminated() const { return m_messageQueue.killed(); }
 
+        WorkerGlobalScope* context() const { return m_context; }
+
         // Returns true if the loop is still alive, false if it has been terminated.
         bool postTask(PassOwnPtr<ExecutionContextTask>);
-        bool postTask(const Closure&);
 
         void postTaskAndTerminate(PassOwnPtr<ExecutionContextTask>);
 
         // Returns true if the loop is still alive, false if it has been terminated.
-        bool postTaskForMode(PassOwnPtr<ExecutionContextTask>, const String& mode);
-
-        unsigned long createUniqueId() { return ++m_uniqueId; }
-
-        class Task;
+        bool postDebuggerTask(PassOwnPtr<ExecutionContextTask>);
 
     private:
         friend class RunLoopSetup;
-        MessageQueueWaitResult runInMode(WorkerGlobalScope*, const ModePredicate&, WaitMode);
+        MessageQueueWaitResult run(MessageQueue<blink::WebThread::Task>&, WaitMode);
 
         // Runs any clean up tasks that are currently in the queue and returns.
         // This should only be called when the context is closed or loop has been terminated.
-        void runCleanupTasks(WorkerGlobalScope*);
+        void runCleanupTasks();
 
-        MessageQueue<Task> m_messageQueue;
+        MessageQueue<blink::WebThread::Task> m_messageQueue;
+        MessageQueue<blink::WebThread::Task> m_debuggerMessageQueue;
         OwnPtr<WorkerSharedTimer> m_sharedTimer;
+        WorkerGlobalScope* m_context;
         int m_nestedCount;
-        unsigned long m_uniqueId;
     };
 
 } // namespace WebCore
diff --git a/Source/core/workers/WorkerSupplementable.h b/Source/core/workers/WorkerSupplementable.h
deleted file mode 100644
index f091474..0000000
--- a/Source/core/workers/WorkerSupplementable.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- *           (C) 2001 Dirk Mueller (mueller@kde.org)
- *           (C) 2006 Alexey Proskuryakov (ap@webkit.org)
- * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012 Apple Inc. All rights reserved.
- * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
- * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies)
- * Copyright (C) 2013 Google Inc. All rights reserved.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WorkerSupplementable_h
-#define WorkerSupplementable_h
-
-#include "platform/Supplementable.h"
-
-namespace WebCore {
-
-class WorkerGlobalScope;
-
-typedef Supplementable<WorkerGlobalScope> WorkerSupplementable;
-typedef Supplement<WorkerGlobalScope> WorkerSupplement;
-
-} // namespace WebCore
-
-#endif // WorkerSupplementable_h
diff --git a/Source/core/workers/WorkerThread.cpp b/Source/core/workers/WorkerThread.cpp
index 1776622..c605115 100644
--- a/Source/core/workers/WorkerThread.cpp
+++ b/Source/core/workers/WorkerThread.cpp
@@ -35,8 +35,6 @@
 #include "core/workers/WorkerReportingProxy.h"
 #include "core/workers/WorkerThreadStartupData.h"
 #include "heap/ThreadState.h"
-#include "modules/webdatabase/DatabaseManager.h"
-#include "modules/webdatabase/DatabaseTask.h"
 #include "platform/PlatformThreadData.h"
 #include "platform/weborigin/KURL.h"
 #include "public/platform/Platform.h"
@@ -67,7 +65,7 @@
     return workerThreads().size();
 }
 
-WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtr<WorkerThreadStartupData> startupData)
+WorkerThread::WorkerThread(WorkerLoaderProxy& workerLoaderProxy, WorkerReportingProxy& workerReportingProxy, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData)
     : m_threadID(0)
     , m_workerLoaderProxy(workerLoaderProxy)
     , m_workerReportingProxy(workerReportingProxy)
@@ -114,6 +112,7 @@
         MutexLocker lock(m_threadCreationMutex);
         ThreadState::attach();
         m_workerGlobalScope = createWorkerGlobalScope(m_startupData.release());
+        m_runLoop.setWorkerGlobalScope(workerGlobalScope());
 
         if (m_runLoop.terminated()) {
             // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet,
@@ -136,29 +135,29 @@
 
     ThreadIdentifier threadID = m_threadID;
 
-    ASSERT(m_workerGlobalScope->hasOneRef());
-
     // The below assignment will destroy the context, which will in turn notify messaging proxy.
     // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them.
-    m_workerGlobalScope = 0;
+    // If Oilpan is enabled, we detach of the context/global scope, with the final heap cleanup below sweeping it out.
+#if ENABLE(OILPAN)
+    m_workerGlobalScope->dispose();
+#else
+    ASSERT(m_workerGlobalScope->hasOneRef());
+#endif
+    m_workerGlobalScope = nullptr;
 
-    // Cleanup thread heap which causes all objects to be finalized.
-    // After this call thread heap must be empty.
-    ThreadState::current()->cleanup();
+    ThreadState::detach();
 
     // Clean up PlatformThreadData before WTF::WTFThreadData goes away!
     PlatformThreadData::current().destroy();
 
     // The thread object may be already destroyed from notification now, don't try to access "this".
     detachThread(threadID);
-
-    ThreadState::detach();
 }
 
 void WorkerThread::runEventLoop()
 {
     // Does not return until terminated.
-    m_runLoop.run(m_workerGlobalScope.get());
+    m_runLoop.run();
 }
 
 class WorkerThreadShutdownFinishTask : public ExecutionContextTask {
@@ -190,22 +189,12 @@
     {
         WorkerGlobalScope* workerGlobalScope = toWorkerGlobalScope(context);
 
-        // FIXME: Should we stop the databases as part of stopActiveDOMObjects() below?
-        DatabaseTaskSynchronizer cleanupSync;
-        DatabaseManager::manager().stopDatabases(workerGlobalScope, &cleanupSync);
-
         workerGlobalScope->stopActiveDOMObjects();
 
-        workerGlobalScope->notifyObserversOfStop();
-
         // Event listeners would keep DOMWrapperWorld objects alive for too long. Also, they have references to JS objects,
         // which become dangling once Heap is destroyed.
         workerGlobalScope->removeAllEventListeners();
 
-        // We wait for the database thread to clean up all its stuff so that we
-        // can do more stringent leak checks as we exit.
-        cleanupSync.waitForTaskCompletion();
-
         // Stick a shutdown command at the end of the queue, so that we deal
         // with all the cleanup tasks the databases post first.
         workerGlobalScope->postTask(WorkerThreadShutdownFinishTask::create());
@@ -229,8 +218,7 @@
     // Ensure that tasks are being handled by thread event loop. If script execution weren't forbidden, a while(1) loop in JS could keep the thread alive forever.
     if (m_workerGlobalScope) {
         m_workerGlobalScope->script()->scheduleExecutionTermination();
-
-        DatabaseManager::manager().interruptAllDatabasesForContext(m_workerGlobalScope.get());
+        m_workerGlobalScope->willStopActiveDOMObjects();
         m_runLoop.postTaskAndTerminate(WorkerThreadShutdownStartTask::create());
         return;
     }
diff --git a/Source/core/workers/WorkerThread.h b/Source/core/workers/WorkerThread.h
index a58d1e7..ccc8b50 100644
--- a/Source/core/workers/WorkerThread.h
+++ b/Source/core/workers/WorkerThread.h
@@ -27,7 +27,7 @@
 #ifndef WorkerThread_h
 #define WorkerThread_h
 
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerRunLoop.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "wtf/Forward.h"
@@ -46,7 +46,7 @@
     class WorkerGlobalScope;
     class WorkerLoaderProxy;
     class WorkerReportingProxy;
-    struct WorkerThreadStartupData;
+    class WorkerThreadStartupData;
 
     enum WorkerThreadStartMode { DontPauseWorkerGlobalScopeOnStart, PauseWorkerGlobalScopeOnStart };
 
@@ -74,10 +74,10 @@
         void setNotificationClient(NotificationClient* client) { m_notificationClient = client; }
 
     protected:
-        WorkerThread(WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtr<WorkerThreadStartupData>);
+        WorkerThread(WorkerLoaderProxy&, WorkerReportingProxy&, PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>);
 
         // Factory method for creating a new worker context for the thread.
-        virtual PassRefPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtr<WorkerThreadStartupData>) = 0;
+        virtual PassRefPtrWillBeRawPtr<WorkerGlobalScope> createWorkerGlobalScope(PassOwnPtrWillBeRawPtr<WorkerThreadStartupData>) = 0;
 
         // Executes the event loop for the worker thread. Derived classes can override to perform actions before/after entering the event loop.
         virtual void runEventLoop();
@@ -95,10 +95,10 @@
         WorkerLoaderProxy& m_workerLoaderProxy;
         WorkerReportingProxy& m_workerReportingProxy;
 
-        RefPtr<WorkerGlobalScope> m_workerGlobalScope;
+        RefPtrWillBePersistent<WorkerGlobalScope> m_workerGlobalScope;
         Mutex m_threadCreationMutex;
 
-        OwnPtr<WorkerThreadStartupData> m_startupData;
+        OwnPtrWillBePersistent<WorkerThreadStartupData> m_startupData;
 
         NotificationClient* m_notificationClient;
 
diff --git a/Source/core/workers/WorkerThreadStartupData.cpp b/Source/core/workers/WorkerThreadStartupData.cpp
index 2e99b06..3d8dc03 100644
--- a/Source/core/workers/WorkerThreadStartupData.cpp
+++ b/Source/core/workers/WorkerThreadStartupData.cpp
@@ -31,10 +31,11 @@
 #include "config.h"
 #include "WorkerThreadStartupData.h"
 
+#include "platform/network/ContentSecurityPolicyParsers.h"
 
 namespace WebCore {
 
-WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients> workerClients)
+WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients> workerClients)
     : m_scriptURL(scriptURL.copy())
     , m_userAgent(userAgent.isolatedCopy())
     , m_sourceCode(sourceCode.isolatedCopy())
diff --git a/Source/core/workers/WorkerThreadStartupData.h b/Source/core/workers/WorkerThreadStartupData.h
index c1b13d7..87befaf 100644
--- a/Source/core/workers/WorkerThreadStartupData.h
+++ b/Source/core/workers/WorkerThreadStartupData.h
@@ -31,9 +31,10 @@
 #ifndef WorkerThreadStartupData_h
 #define WorkerThreadStartupData_h
 
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/workers/WorkerClients.h"
 #include "core/workers/WorkerThread.h"
+#include "platform/network/ContentSecurityPolicyParsers.h"
 #include "platform/weborigin/KURL.h"
 #include "wtf/Forward.h"
 #include "wtf/Noncopyable.h"
@@ -42,12 +43,13 @@
 
 class WorkerClients;
 
-struct WorkerThreadStartupData {
-    WTF_MAKE_NONCOPYABLE(WorkerThreadStartupData); WTF_MAKE_FAST_ALLOCATED;
+class WorkerThreadStartupData : public NoBaseWillBeGarbageCollectedFinalized<WorkerThreadStartupData> {
+    WTF_MAKE_NONCOPYABLE(WorkerThreadStartupData);
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
 public:
-    static PassOwnPtr<WorkerThreadStartupData> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients> workerClients)
+    static PassOwnPtrWillBeRawPtr<WorkerThreadStartupData> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode, const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients> workerClients)
     {
-        return adoptPtr(new WorkerThreadStartupData(scriptURL, userAgent, sourceCode, startMode, contentSecurityPolicy, contentSecurityPolicyType, workerClients));
+        return adoptPtrWillBeNoop(new WorkerThreadStartupData(scriptURL, userAgent, sourceCode, startMode, contentSecurityPolicy, contentSecurityPolicyType, workerClients));
     }
 
     ~WorkerThreadStartupData();
@@ -57,11 +59,13 @@
     String m_sourceCode;
     WorkerThreadStartMode m_startMode;
     String m_contentSecurityPolicy;
-    ContentSecurityPolicy::HeaderType m_contentSecurityPolicyType;
+    ContentSecurityPolicyHeaderType m_contentSecurityPolicyType;
     OwnPtr<WorkerClients> m_workerClients;
 
+    void trace(Visitor*) { }
+
 private:
-    WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const String& contentSecurityPolicy, ContentSecurityPolicy::HeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients>);
+    WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode, const String& contentSecurityPolicy, ContentSecurityPolicyHeaderType contentSecurityPolicyType, PassOwnPtr<WorkerClients>);
 };
 
 } // namespace WebCore
diff --git a/Source/core/xml/DOMParser.cpp b/Source/core/xml/DOMParser.cpp
index bc509de..ecc0443 100644
--- a/Source/core/xml/DOMParser.cpp
+++ b/Source/core/xml/DOMParser.cpp
@@ -34,8 +34,8 @@
         && contentType != "application/xml"
         && contentType != "application/xhtml+xml"
         && contentType != "image/svg+xml") {
-        exceptionState.throwDOMException(TypeError, "Unsupported mime-type specified.");
-        return 0;
+        exceptionState.throwTypeError("Unsupported mime-type specified.");
+        return nullptr;
     }
 
     RefPtr<Document> doc = DOMImplementation::createDocument(contentType, 0, KURL(), false);
diff --git a/Source/core/xml/DOMParser.h b/Source/core/xml/DOMParser.h
index afe0d16..8a5c667 100644
--- a/Source/core/xml/DOMParser.h
+++ b/Source/core/xml/DOMParser.h
@@ -20,6 +20,7 @@
 #define DOMParser_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 #include "wtf/RefPtr.h"
@@ -29,12 +30,17 @@
 class Document;
 class ExceptionState;
 
-class DOMParser : public RefCounted<DOMParser>, public ScriptWrappable {
+class DOMParser : public RefCountedWillBeGarbageCollectedFinalized<DOMParser>, public ScriptWrappable {
 public:
-    static PassRefPtr<DOMParser> create() { return adoptRef(new DOMParser); }
+    static PassRefPtrWillBeRawPtr<DOMParser> create()
+    {
+        return adoptRefWillBeNoop(new DOMParser);
+    }
 
     PassRefPtr<Document> parseFromString(const String&, const String& contentType, ExceptionState&);
 
+    void trace(Visitor*) { }
+
 private:
     DOMParser()
     {
diff --git a/Source/core/xml/DOMParser.idl b/Source/core/xml/DOMParser.idl
index ff6af34..aa390c5 100644
--- a/Source/core/xml/DOMParser.idl
+++ b/Source/core/xml/DOMParser.idl
@@ -18,6 +18,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     Constructor
 ] interface DOMParser {
     [RaisesException] Document parseFromString([Default=Undefined] optional DOMString str,
diff --git a/Source/core/xml/DocumentXPathEvaluator.cpp b/Source/core/xml/DocumentXPathEvaluator.cpp
index d14ca54..10dff25 100644
--- a/Source/core/xml/DocumentXPathEvaluator.cpp
+++ b/Source/core/xml/DocumentXPathEvaluator.cpp
@@ -41,41 +41,41 @@
 {
 }
 
-DocumentXPathEvaluator* DocumentXPathEvaluator::from(DocumentSupplementable* document)
+DocumentXPathEvaluator& DocumentXPathEvaluator::from(DocumentSupplementable& document)
 {
     DocumentXPathEvaluator* cache = static_cast<DocumentXPathEvaluator*>(DocumentSupplement::from(document, supplementName()));
     if (!cache) {
         cache = new DocumentXPathEvaluator();
         DocumentSupplement::provideTo(document, supplementName(), adoptPtr(cache));
     }
-    return cache;
+    return *cache;
 }
 
-PassRefPtr<XPathExpression> DocumentXPathEvaluator::createExpression(DocumentSupplementable* document,
-    const String& expression, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathExpression> DocumentXPathEvaluator::createExpression(DocumentSupplementable& document,
+    const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
 {
-    DocumentXPathEvaluator* suplement = from(document);
-    if (!suplement->m_xpathEvaluator)
-        suplement->m_xpathEvaluator = XPathEvaluator::create();
-    return suplement->m_xpathEvaluator->createExpression(expression, resolver, exceptionState);
+    DocumentXPathEvaluator& suplement = from(document);
+    if (!suplement.m_xpathEvaluator)
+        suplement.m_xpathEvaluator = XPathEvaluator::create();
+    return suplement.m_xpathEvaluator->createExpression(expression, resolver, exceptionState);
 }
 
-PassRefPtr<XPathNSResolver> DocumentXPathEvaluator::createNSResolver(DocumentSupplementable* document, Node* nodeResolver)
+PassRefPtrWillBeRawPtr<XPathNSResolver> DocumentXPathEvaluator::createNSResolver(DocumentSupplementable& document, Node* nodeResolver)
 {
-    DocumentXPathEvaluator* suplement = from(document);
-    if (!suplement->m_xpathEvaluator)
-        suplement->m_xpathEvaluator = XPathEvaluator::create();
-    return suplement->m_xpathEvaluator->createNSResolver(nodeResolver);
+    DocumentXPathEvaluator& suplement = from(document);
+    if (!suplement.m_xpathEvaluator)
+        suplement.m_xpathEvaluator = XPathEvaluator::create();
+    return suplement.m_xpathEvaluator->createNSResolver(nodeResolver);
 }
 
-PassRefPtr<XPathResult> DocumentXPathEvaluator::evaluate(DocumentSupplementable* document, const String& expression,
-    Node* contextNode, PassRefPtr<XPathNSResolver> resolver, unsigned short type,
+PassRefPtrWillBeRawPtr<XPathResult> DocumentXPathEvaluator::evaluate(DocumentSupplementable& document, const String& expression,
+    Node* contextNode, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, unsigned short type,
     XPathResult* result, ExceptionState& exceptionState)
 {
-    DocumentXPathEvaluator* suplement = from(document);
-    if (!suplement->m_xpathEvaluator)
-        suplement->m_xpathEvaluator = XPathEvaluator::create();
-    return suplement->m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, exceptionState);
+    DocumentXPathEvaluator& suplement = from(document);
+    if (!suplement.m_xpathEvaluator)
+        suplement.m_xpathEvaluator = XPathEvaluator::create();
+    return suplement.m_xpathEvaluator->evaluate(expression, contextNode, resolver, type, result, exceptionState);
 }
 
 } // namespace WebCore
diff --git a/Source/core/xml/DocumentXPathEvaluator.h b/Source/core/xml/DocumentXPathEvaluator.h
index 04a39f9..d08c58a 100644
--- a/Source/core/xml/DocumentXPathEvaluator.h
+++ b/Source/core/xml/DocumentXPathEvaluator.h
@@ -40,13 +40,13 @@
 public:
     virtual ~DocumentXPathEvaluator();
 
-    static DocumentXPathEvaluator* from(DocumentSupplementable*);
+    static DocumentXPathEvaluator& from(DocumentSupplementable&);
 
-    static PassRefPtr<XPathExpression> createExpression(DocumentSupplementable*,
-        const String& expression, PassRefPtr<XPathNSResolver>, ExceptionState&);
-    static PassRefPtr<XPathNSResolver> createNSResolver(DocumentSupplementable*, Node* nodeResolver);
-    static PassRefPtr<XPathResult> evaluate(DocumentSupplementable*,
-        const String& expression, Node* contextNode, PassRefPtr<XPathNSResolver>,
+    static PassRefPtrWillBeRawPtr<XPathExpression> createExpression(DocumentSupplementable&,
+        const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
+    static PassRefPtrWillBeRawPtr<XPathNSResolver> createNSResolver(DocumentSupplementable&, Node* nodeResolver);
+    static PassRefPtrWillBeRawPtr<XPathResult> evaluate(DocumentSupplementable&,
+        const String& expression, Node* contextNode, PassRefPtrWillBeRawPtr<XPathNSResolver>,
         unsigned short type, XPathResult*, ExceptionState&);
 
 private:
@@ -54,7 +54,7 @@
 
     static const char* supplementName() { return "DocumentXPathEvaluator"; }
 
-    RefPtr<XPathEvaluator> m_xpathEvaluator;
+    RefPtrWillBePersistent<XPathEvaluator> m_xpathEvaluator;
 };
 
 } // namespace WebCore
diff --git a/Source/core/xml/NativeXPathNSResolver.cpp b/Source/core/xml/NativeXPathNSResolver.cpp
index cbe118a..cc2387b 100644
--- a/Source/core/xml/NativeXPathNSResolver.cpp
+++ b/Source/core/xml/NativeXPathNSResolver.cpp
@@ -51,4 +51,9 @@
     return m_node ? m_node->lookupNamespaceURI(prefix) : nullAtom;
 }
 
+void NativeXPathNSResolver::trace(Visitor* visitor)
+{
+    XPathNSResolver::trace(visitor);
+}
+
 } // namespace WebCore
diff --git a/Source/core/xml/NativeXPathNSResolver.h b/Source/core/xml/NativeXPathNSResolver.h
index 45d5a66..64fb162 100644
--- a/Source/core/xml/NativeXPathNSResolver.h
+++ b/Source/core/xml/NativeXPathNSResolver.h
@@ -35,11 +35,16 @@
 
 class NativeXPathNSResolver FINAL : public XPathNSResolver {
 public:
-    static PassRefPtr<NativeXPathNSResolver> create(PassRefPtr<Node> node) { return adoptRef(new NativeXPathNSResolver(node)); }
+    static PassRefPtrWillBeRawPtr<NativeXPathNSResolver> create(PassRefPtr<Node> node)
+    {
+        return adoptRefWillBeNoop(new NativeXPathNSResolver(node));
+    }
     virtual ~NativeXPathNSResolver();
 
     virtual AtomicString lookupNamespaceURI(const String& prefix) OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     explicit NativeXPathNSResolver(PassRefPtr<Node>);
     RefPtr<Node> m_node;
diff --git a/Source/core/xml/XMLHttpRequest.cpp b/Source/core/xml/XMLHttpRequest.cpp
index adf3672..b758c51 100644
--- a/Source/core/xml/XMLHttpRequest.cpp
+++ b/Source/core/xml/XMLHttpRequest.cpp
@@ -29,13 +29,14 @@
 #include "core/dom/ContextFeatures.h"
 #include "core/dom/DOMImplementation.h"
 #include "core/dom/ExceptionCode.h"
+#include "core/dom/XMLDocument.h"
 #include "core/editing/markup.h"
 #include "core/events/Event.h"
 #include "core/fetch/CrossOriginAccessControl.h"
 #include "core/fileapi/Blob.h"
 #include "core/fileapi/File.h"
 #include "core/fileapi/Stream.h"
-#include "core/frame/ContentSecurityPolicy.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "core/html/DOMFormData.h"
 #include "core/html/HTMLDocument.h"
 #include "core/html/parser/TextResourceDecoder.h"
@@ -153,9 +154,9 @@
     context->addConsoleMessage(JSMessageSource, ErrorMessageLevel, message);
 }
 
-PassRefPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext* context, PassRefPtr<SecurityOrigin> securityOrigin)
+PassRefPtrWillBeRawPtr<XMLHttpRequest> XMLHttpRequest::create(ExecutionContext* context, PassRefPtr<SecurityOrigin> securityOrigin)
 {
-    RefPtr<XMLHttpRequest> xmlHttpRequest(adoptRef(new XMLHttpRequest(context, securityOrigin)));
+    RefPtrWillBeRawPtr<XMLHttpRequest> xmlHttpRequest = adoptRefWillBeRefCountedGarbageCollected(new XMLHttpRequest(context, securityOrigin));
     xmlHttpRequest->suspendIfNeeded();
 
     return xmlHttpRequest.release();
@@ -168,7 +169,6 @@
     , m_timeoutMilliseconds(0)
     , m_state(UNSENT)
     , m_createdDocument(false)
-    , m_downloadedBlobLength(0)
     , m_error(false)
     , m_uploadEventsAllowed(true)
     , m_uploadComplete(false)
@@ -249,19 +249,19 @@
         if ((m_response.isHTTP() && !responseIsXML() && !isHTML)
             || (isHTML && m_responseTypeCode == ResponseTypeDefault)
             || executionContext()->isWorkerGlobalScope()) {
-            m_responseDocument = 0;
+            m_responseDocument = nullptr;
         } else {
             DocumentInit init = DocumentInit::fromContext(document()->contextDocument(), m_url);
             if (isHTML)
                 m_responseDocument = HTMLDocument::create(init);
             else
-                m_responseDocument = Document::create(init);
+                m_responseDocument = XMLDocument::create(init);
             // FIXME: Set Last-Modified.
             m_responseDocument->setContent(m_responseText.flattenToString());
             m_responseDocument->setSecurityOrigin(securityOrigin());
             m_responseDocument->setContextFeatures(document()->contextFeatures());
             if (!m_responseDocument->wellFormed())
-                m_responseDocument = 0;
+                m_responseDocument = nullptr;
         }
         m_createdDocument = true;
     }
@@ -272,26 +272,26 @@
 Blob* XMLHttpRequest::responseBlob()
 {
     ASSERT(m_responseTypeCode == ResponseTypeBlob);
-    ASSERT(!m_binaryResponseBuilder.get());
 
     // We always return null before DONE.
     if (m_error || m_state != DONE)
         return 0;
 
     if (!m_responseBlob) {
-        // When "blob" is specified for the responseType attribute,
-        // we redirect the downloaded data to a file-handle directly
-        // in the browser process.
-        // We get the file-path from the ResourceResponse directly
-        // instead of copying the bytes between the browser and the renderer.
+        // FIXME: Once RedirectToFileResourceHandler is fixed in Chromium,
+        // re-enable download-to-file optimization introduced by Blink revision
+        // 163141.
         OwnPtr<BlobData> blobData = BlobData::create();
-        String filePath = m_response.downloadedFilePath();
-        // If we errored out or got no data, we still return a blob, just an empty one.
-        if (!filePath.isEmpty() && m_downloadedBlobLength) {
-            blobData->appendFile(filePath);
+        size_t size = 0;
+        if (m_binaryResponseBuilder.get() && m_binaryResponseBuilder->size() > 0) {
+            RefPtr<RawData> rawData = RawData::create();
+            size = m_binaryResponseBuilder->size();
+            rawData->mutableData()->append(m_binaryResponseBuilder->data(), size);
+            blobData->appendData(rawData, 0, BlobDataItem::toEndOfFile);
             blobData->setContentType(responseMIMEType()); // responseMIMEType defaults to text/xml which may be incorrect.
+            m_binaryResponseBuilder.clear();
         }
-        m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), m_downloadedBlobLength));
+        m_responseBlob = Blob::create(BlobDataHandle::create(blobData.release(), size));
     }
 
     return m_responseBlob.get();
@@ -765,7 +765,7 @@
 
 void XMLHttpRequest::sendForInspectorXHRReplay(PassRefPtr<FormData> formData, ExceptionState& exceptionState)
 {
-    m_requestEntityBody = formData ? formData->deepCopy() : 0;
+    m_requestEntityBody = formData ? formData->deepCopy() : nullptr;
     createRequest(exceptionState);
     m_exceptionCode = exceptionState.code();
 }
@@ -800,13 +800,7 @@
     request.setHTTPMethod(m_method);
     request.setTargetType(ResourceRequest::TargetIsXHR);
 
-    // When "blob" is specified for the responseType attribute,
-    // we redirect the downloaded data to a file-handle directly
-    // and get the file-path as the result.
-    if (responseTypeCode() == ResponseTypeBlob)
-        request.setDownloadToFile(true);
-
-    InspectorInstrumentation::willLoadXHR(executionContext(), this, this, m_method, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : 0, m_requestHeaders, m_includeCredentials);
+    InspectorInstrumentation::willLoadXHR(executionContext(), this, this, m_method, m_url, m_async, m_requestEntityBody ? m_requestEntityBody->deepCopy() : nullptr, m_requestHeaders, m_includeCredentials);
 
     if (m_requestEntityBody) {
         ASSERT(m_method != "GET");
@@ -830,12 +824,6 @@
     options.mixedContentBlockingTreatment = TreatAsPassiveContent;
     options.timeoutMilliseconds = m_timeoutMilliseconds;
 
-    // Since we redirect the downloaded data to a file-handle directly
-    // when "blob" is specified for the responseType attribute,
-    // buffering is not needed.
-    if (responseTypeCode() == ResponseTypeBlob)
-        options.dataBufferingPolicy = DoNotBufferData;
-
     m_exceptionCode = 0;
     m_error = false;
 
@@ -862,7 +850,7 @@
     if (!m_exceptionCode && m_error)
         m_exceptionCode = NetworkError;
     if (m_exceptionCode)
-        exceptionState.throwUninformativeAndGenericDOMException(m_exceptionCode);
+        exceptionState.throwDOMException(m_exceptionCode, "Failed to load '" + m_url.elidedString() + "'.");
 }
 
 void XMLHttpRequest::abort()
@@ -870,7 +858,7 @@
     WTF_LOG(Network, "XMLHttpRequest %p abort()", this);
 
     // internalAbort() calls dropProtection(), which may release the last reference.
-    RefPtr<XMLHttpRequest> protect(this);
+    RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
 
     bool sendFlag = m_loader;
 
@@ -956,11 +944,11 @@
     m_responseText.clear();
 
     m_createdDocument = false;
-    m_responseDocument = 0;
+    m_responseDocument = nullptr;
 
-    m_responseBlob = 0;
+    m_responseBlob = nullptr;
 
-    m_responseStream = 0;
+    m_responseStream = nullptr;
 
     // These variables may referred by the response accessors. So, we can clear
     // this only when we clear the response holder variables above.
@@ -971,7 +959,7 @@
 void XMLHttpRequest::clearRequest()
 {
     m_requestHeaders.clear();
-    m_requestEntityBody = 0;
+    m_requestEntityBody = nullptr;
 }
 
 void XMLHttpRequest::handleDidFailGeneric()
@@ -1264,10 +1252,10 @@
     InspectorInstrumentation::didFinishXHRLoading(executionContext(), this, this, identifier, m_responseText, m_method, m_url, m_lastSendURL, m_lastSendLineNumber);
 
     // Prevent dropProtection releasing the last reference, and retain |this| until the end of this method.
-    RefPtr<XMLHttpRequest> protect(this);
+    RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
 
     if (m_loader) {
-        m_loader = 0;
+        m_loader = nullptr;
         dropProtection();
     }
 
@@ -1307,8 +1295,6 @@
 
 void XMLHttpRequest::didReceiveData(const char* data, int len)
 {
-    ASSERT(m_responseTypeCode != ResponseTypeBlob);
-
     if (m_error)
         return;
 
@@ -1341,7 +1327,7 @@
 
     if (useDecoder) {
         m_responseText = m_responseText.concatenateWith(m_decoder->decode(data, len));
-    } else if (m_responseTypeCode == ResponseTypeArrayBuffer) {
+    } else if (m_responseTypeCode == ResponseTypeArrayBuffer || m_responseTypeCode == ResponseTypeBlob) {
         // Buffer binary data.
         if (!m_binaryResponseBuilder)
             m_binaryResponseBuilder = SharedBuffer::create();
@@ -1358,32 +1344,12 @@
     trackProgress(len);
 }
 
-void XMLHttpRequest::didDownloadData(int dataLength)
-{
-    ASSERT(m_responseTypeCode == ResponseTypeBlob);
-
-    if (m_error)
-        return;
-
-    if (m_state < HEADERS_RECEIVED)
-        changeState(HEADERS_RECEIVED);
-
-    if (!dataLength)
-        return;
-
-    if (m_error)
-        return;
-
-    m_downloadedBlobLength += dataLength;
-    trackProgress(dataLength);
-}
-
 void XMLHttpRequest::handleDidTimeout()
 {
     WTF_LOG(Network, "XMLHttpRequest %p handleDidTimeout()", this);
 
     // internalAbort() calls dropProtection(), which may release the last reference.
-    RefPtr<XMLHttpRequest> protect(this);
+    RefPtrWillBeRawPtr<XMLHttpRequest> protect(this);
 
     // Response is cleared next, save needed progress event data.
     long long expectedLength = m_response.expectedContentLength();
@@ -1427,4 +1393,10 @@
     return ActiveDOMObject::executionContext();
 }
 
+void XMLHttpRequest::trace(Visitor* visitor)
+{
+    visitor->trace(m_responseBlob);
+    visitor->trace(m_responseStream);
+}
+
 } // namespace WebCore
diff --git a/Source/core/xml/XMLHttpRequest.h b/Source/core/xml/XMLHttpRequest.h
index 6cd13dc..ddb6c66 100644
--- a/Source/core/xml/XMLHttpRequest.h
+++ b/Source/core/xml/XMLHttpRequest.h
@@ -30,6 +30,7 @@
 #include "core/loader/ThreadableLoaderClient.h"
 #include "core/xml/XMLHttpRequestEventTarget.h"
 #include "core/xml/XMLHttpRequestProgressEventThrottle.h"
+#include "heap/Handle.h"
 #include "platform/AsyncMethodRunner.h"
 #include "platform/network/FormData.h"
 #include "platform/network/ResourceResponse.h"
@@ -53,11 +54,11 @@
 
 typedef int ExceptionCode;
 
-class XMLHttpRequest FINAL : public ScriptWrappable, public RefCounted<XMLHttpRequest>, public XMLHttpRequestEventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
-    WTF_MAKE_FAST_ALLOCATED;
-    REFCOUNTED_EVENT_TARGET(XMLHttpRequest);
+class XMLHttpRequest FINAL : public RefCountedWillBeRefCountedGarbageCollected<XMLHttpRequest>, public ScriptWrappable, public XMLHttpRequestEventTarget, private ThreadableLoaderClient, public ActiveDOMObject {
+    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
+    DEFINE_EVENT_TARGET_REFCOUNTING(RefCountedWillBeRefCountedGarbageCollected<XMLHttpRequest>);
 public:
-    static PassRefPtr<XMLHttpRequest> create(ExecutionContext*, PassRefPtr<SecurityOrigin> = 0);
+    static PassRefPtrWillBeRawPtr<XMLHttpRequest> create(ExecutionContext*, PassRefPtr<SecurityOrigin> = nullptr);
     virtual ~XMLHttpRequest();
 
     // These exact numeric values are important because JS expects them.
@@ -143,6 +144,8 @@
 
     DEFINE_ATTRIBUTE_EVENT_LISTENER(readystatechange);
 
+    void trace(Visitor*);
+
 private:
     XMLHttpRequest(ExecutionContext*, PassRefPtr<SecurityOrigin>);
 
@@ -152,9 +155,6 @@
     virtual void didSendData(unsigned long long bytesSent, unsigned long long totalBytesToBeSent) OVERRIDE;
     virtual void didReceiveResponse(unsigned long identifier, const ResourceResponse&) OVERRIDE;
     virtual void didReceiveData(const char* data, int dataLength) OVERRIDE;
-    // When "blob" is specified as the responseType attribute, didDownloadData
-    // is called instead of didReceiveData.
-    virtual void didDownloadData(int dataLength) OVERRIDE;
     virtual void didFinishLoading(unsigned long identifier, double finishTime) OVERRIDE;
     virtual void didFail(const ResourceError&) OVERRIDE;
     virtual void didFailRedirectCheck() OVERRIDE;
@@ -219,8 +219,8 @@
     bool m_async;
     bool m_includeCredentials;
     unsigned long m_timeoutMilliseconds;
-    RefPtr<Blob> m_responseBlob;
-    RefPtr<Stream> m_responseStream;
+    RefPtrWillBeMember<Blob> m_responseBlob;
+    RefPtrWillBeMember<Stream> m_responseStream;
 
     RefPtr<ThreadableLoader> m_loader;
     State m_state;
@@ -237,7 +237,6 @@
     RefPtr<Document> m_responseDocument;
 
     RefPtr<SharedBuffer> m_binaryResponseBuilder;
-    long long m_downloadedBlobLength;
     RefPtr<ArrayBuffer> m_responseArrayBuffer;
 
     bool m_error;
diff --git a/Source/core/xml/XMLHttpRequest.idl b/Source/core/xml/XMLHttpRequest.idl
index 2fba4d6..9cfedb4 100644
--- a/Source/core/xml/XMLHttpRequest.idl
+++ b/Source/core/xml/XMLHttpRequest.idl
@@ -37,6 +37,7 @@
 };
 
 [
+    WillBeGarbageCollected,
     ActiveDOMObject,
     CustomConstructor(optional XMLHttpRequestOptions options),
     GlobalContext=Window&WorkerGlobalScope,
diff --git a/Source/core/xml/XMLHttpRequestProgressEvent.h b/Source/core/xml/XMLHttpRequestProgressEvent.h
index f636515..5e7aa46 100644
--- a/Source/core/xml/XMLHttpRequestProgressEvent.h
+++ b/Source/core/xml/XMLHttpRequestProgressEvent.h
@@ -49,6 +49,8 @@
 
     virtual const AtomicString& interfaceName() const OVERRIDE { return EventNames::XMLHttpRequestProgressEvent; }
 
+    virtual void trace(Visitor* visitor) OVERRIDE { ProgressEvent::trace(visitor); }
+
 private:
     XMLHttpRequestProgressEvent()
     {
diff --git a/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp b/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp
index 9a3c16c..d651dc5 100644
--- a/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp
+++ b/Source/core/xml/XMLHttpRequestProgressEventThrottle.cpp
@@ -65,7 +65,7 @@
         ASSERT(!m_total);
 
         dispatchEvent(XMLHttpRequestProgressEvent::create(EventTypeNames::progress, lengthComputable, loaded, total));
-        startRepeating(minimumProgressEventDispatchingIntervalInSeconds);
+        startRepeating(minimumProgressEventDispatchingIntervalInSeconds, FROM_HERE);
         return;
     }
 
@@ -111,7 +111,7 @@
     if (m_deferEvents && m_deferredProgressEvent) {
         // Move the progress event to the queue, to get it in the right order on resume.
         m_deferredEvents.append(m_deferredProgressEvent);
-        m_deferredProgressEvent = 0;
+        m_deferredProgressEvent = nullptr;
         return true;
     }
     return false;
@@ -143,7 +143,7 @@
     m_deferredEvents.swap(deferredEvents);
 
     RefPtr<Event> deferredProgressEvent = m_deferredProgressEvent;
-    m_deferredProgressEvent = 0;
+    m_deferredProgressEvent = nullptr;
 
     Vector<RefPtr<Event> >::const_iterator it = deferredEvents.begin();
     const Vector<RefPtr<Event> >::const_iterator end = deferredEvents.end();
@@ -213,7 +213,7 @@
     // the list of active DOM objects to resume them, and any activated JS event-handler
     // could insert new active DOM objects to the list.
     // m_deferEvents is kept true until all deferred events have been dispatched.
-    m_dispatchDeferredEventsTimer.startOneShot(0);
+    m_dispatchDeferredEventsTimer.startOneShot(0, FROM_HERE);
 }
 
 } // namespace WebCore
diff --git a/Source/core/xml/XMLSerializer.cpp b/Source/core/xml/XMLSerializer.cpp
index 7c42e56..11e9cd6 100644
--- a/Source/core/xml/XMLSerializer.cpp
+++ b/Source/core/xml/XMLSerializer.cpp
@@ -24,7 +24,7 @@
 #include "bindings/v8/ExceptionState.h"
 #include "core/dom/Document.h"
 #include "core/dom/ExceptionCode.h"
-#include "core/editing/markup.h"
+#include "core/editing/MarkupAccumulator.h"
 #include "wtf/text/WTFString.h"
 
 namespace WebCore {
@@ -32,11 +32,12 @@
 String XMLSerializer::serializeToString(Node* node, ExceptionState& exceptionState)
 {
     if (!node) {
-        exceptionState.throwDOMException(TypeError, "Invalid node value.");
+        exceptionState.throwTypeError("Invalid node value.");
         return String();
     }
 
-    return createMarkup(node);
+    MarkupAccumulator accumulator(0, DoNotResolveURLs, 0, ForcedXML);
+    return accumulator.serializeNodes(*node, IncludeNode);
 }
 
 } // namespace WebCore
diff --git a/Source/core/xml/XMLSerializer.h b/Source/core/xml/XMLSerializer.h
index 53d8c73..b8e720c 100644
--- a/Source/core/xml/XMLSerializer.h
+++ b/Source/core/xml/XMLSerializer.h
@@ -21,6 +21,7 @@
 #define XMLSerializer_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -30,12 +31,17 @@
 class ExceptionState;
 class Node;
 
-class XMLSerializer : public RefCounted<XMLSerializer>, public ScriptWrappable {
+class XMLSerializer : public RefCountedWillBeGarbageCollectedFinalized<XMLSerializer>, public ScriptWrappable {
 public:
-    static PassRefPtr<XMLSerializer> create() { return adoptRef(new XMLSerializer); }
+    static PassRefPtrWillBeRawPtr<XMLSerializer> create()
+    {
+        return adoptRefWillBeNoop(new XMLSerializer);
+    }
 
     String serializeToString(Node*, ExceptionState&);
 
+    void trace(Visitor*) { }
+
 private:
     XMLSerializer()
     {
diff --git a/Source/core/xml/XMLSerializer.idl b/Source/core/xml/XMLSerializer.idl
index 88a9171..1a7b627 100644
--- a/Source/core/xml/XMLSerializer.idl
+++ b/Source/core/xml/XMLSerializer.idl
@@ -19,6 +19,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     Constructor
 ] interface XMLSerializer {
     [RaisesException] DOMString serializeToString([Default=Undefined] optional Node node);
diff --git a/Source/core/xml/XMLTreeViewer.cpp b/Source/core/xml/XMLTreeViewer.cpp
index 287f32d..870a484 100644
--- a/Source/core/xml/XMLTreeViewer.cpp
+++ b/Source/core/xml/XMLTreeViewer.cpp
@@ -37,7 +37,7 @@
 #include "core/dom/Document.h"
 #include "core/dom/Element.h"
 #include "core/dom/Text.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
 
 using namespace std;
 
diff --git a/Source/core/xml/XPathEvaluator.cpp b/Source/core/xml/XPathEvaluator.cpp
index f87cc76..8c2d6f5 100644
--- a/Source/core/xml/XPathEvaluator.cpp
+++ b/Source/core/xml/XPathEvaluator.cpp
@@ -39,32 +39,32 @@
 
 using namespace XPath;
 
-PassRefPtr<XPathExpression> XPathEvaluator::createExpression(const String& expression, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathExpression> XPathEvaluator::createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
 {
     return XPathExpression::createExpression(expression, resolver, exceptionState);
 }
 
-PassRefPtr<XPathNSResolver> XPathEvaluator::createNSResolver(Node* nodeResolver)
+PassRefPtrWillBeRawPtr<XPathNSResolver> XPathEvaluator::createNSResolver(Node* nodeResolver)
 {
     return NativeXPathNSResolver::create(nodeResolver);
 }
 
-PassRefPtr<XPathResult> XPathEvaluator::evaluate(const String& expression, Node* contextNode,
-    PassRefPtr<XPathNSResolver> resolver, unsigned short type, XPathResult* result, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathResult> XPathEvaluator::evaluate(const String& expression, Node* contextNode,
+    PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, unsigned short type, XPathResult* result, ExceptionState& exceptionState)
 {
     if (!contextNode) {
         exceptionState.throwDOMException(NotSupportedError, "The context node provided is null.");
-        return 0;
+        return nullptr;
     }
 
     if (!isValidContextNode(contextNode)) {
         exceptionState.throwDOMException(NotSupportedError, "The node provided is '" + contextNode->nodeName() + "', which is not a valid context node type.");
-        return 0;
+        return nullptr;
     }
 
-    RefPtr<XPathExpression> expr = createExpression(expression, resolver, exceptionState);
+    RefPtrWillBeRawPtr<XPathExpression> expr = createExpression(expression, resolver, exceptionState);
     if (exceptionState.hadException())
-        return 0;
+        return nullptr;
 
     return expr->evaluate(contextNode, type, result, exceptionState);
 }
diff --git a/Source/core/xml/XPathEvaluator.h b/Source/core/xml/XPathEvaluator.h
index 0c556e7..9150a2f 100644
--- a/Source/core/xml/XPathEvaluator.h
+++ b/Source/core/xml/XPathEvaluator.h
@@ -28,6 +28,7 @@
 #define XPathEvaluator_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -40,14 +41,19 @@
 class XPathNSResolver;
 class XPathResult;
 
-class XPathEvaluator : public RefCounted<XPathEvaluator>, public ScriptWrappable {
+class XPathEvaluator : public RefCountedWillBeGarbageCollectedFinalized<XPathEvaluator>, public ScriptWrappable {
 public:
-    static PassRefPtr<XPathEvaluator> create() { return adoptRef(new XPathEvaluator); }
+    static PassRefPtrWillBeRawPtr<XPathEvaluator> create()
+    {
+        return adoptRefWillBeNoop(new XPathEvaluator);
+    }
 
-    PassRefPtr<XPathExpression> createExpression(const String& expression, PassRefPtr<XPathNSResolver>, ExceptionState&);
-    PassRefPtr<XPathNSResolver> createNSResolver(Node* nodeResolver);
-    PassRefPtr<XPathResult> evaluate(const String& expression, Node* contextNode,
-        PassRefPtr<XPathNSResolver>, unsigned short type, XPathResult*, ExceptionState&);
+    PassRefPtrWillBeRawPtr<XPathExpression> createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
+    PassRefPtrWillBeRawPtr<XPathNSResolver> createNSResolver(Node* nodeResolver);
+    PassRefPtrWillBeRawPtr<XPathResult> evaluate(const String& expression, Node* contextNode,
+        PassRefPtrWillBeRawPtr<XPathNSResolver>, unsigned short type, XPathResult*, ExceptionState&);
+
+    void trace(Visitor*) { }
 
 private:
     XPathEvaluator()
diff --git a/Source/core/xml/XPathEvaluator.idl b/Source/core/xml/XPathEvaluator.idl
index 30e899b..d11018a 100644
--- a/Source/core/xml/XPathEvaluator.idl
+++ b/Source/core/xml/XPathEvaluator.idl
@@ -18,6 +18,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     Constructor
 ] interface XPathEvaluator {
     [RaisesException] XPathExpression createExpression([Default=Undefined] optional DOMString expression,
diff --git a/Source/core/xml/XPathExpression.cpp b/Source/core/xml/XPathExpression.cpp
index ae2d7e1..d1b91de 100644
--- a/Source/core/xml/XPathExpression.cpp
+++ b/Source/core/xml/XPathExpression.cpp
@@ -40,14 +40,14 @@
 
 using namespace XPath;
 
-PassRefPtr<XPathExpression> XPathExpression::createExpression(const String& expression, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathExpression> XPathExpression::createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
 {
-    RefPtr<XPathExpression> expr = XPathExpression::create();
+    RefPtrWillBeRawPtr<XPathExpression> expr = XPathExpression::create();
     Parser parser;
 
     expr->m_topExpression = parser.parseStatement(expression, resolver, exceptionState);
     if (!expr->m_topExpression)
-        return 0;
+        return nullptr;
 
     return expr.release();
 }
@@ -57,16 +57,16 @@
     delete m_topExpression;
 }
 
-PassRefPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState& exceptionState)
+PassRefPtrWillBeRawPtr<XPathResult> XPathExpression::evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState& exceptionState)
 {
     if (!contextNode) {
         exceptionState.throwDOMException(NotSupportedError, "The context node provided is null.");
-        return 0;
+        return nullptr;
     }
 
     if (!isValidContextNode(contextNode)) {
         exceptionState.throwDOMException(NotSupportedError, "The node provided is '" + contextNode->nodeName() + "', which is not a valid context node type.");
-        return 0;
+        return nullptr;
     }
 
     EvaluationContext& evaluationContext = Expression::evaluationContext();
@@ -74,19 +74,19 @@
     evaluationContext.size = 1;
     evaluationContext.position = 1;
     evaluationContext.hadTypeConversionError = false;
-    RefPtr<XPathResult> result = XPathResult::create(&contextNode->document(), m_topExpression->evaluate());
-    evaluationContext.node = 0; // Do not hold a reference to the context node, as this may prevent the whole document from being destroyed in time.
+    RefPtrWillBeRawPtr<XPathResult> result = XPathResult::create(&contextNode->document(), m_topExpression->evaluate());
+    evaluationContext.node = nullptr; // Do not hold a reference to the context node, as this may prevent the whole document from being destroyed in time.
 
     if (evaluationContext.hadTypeConversionError) {
         // It is not specified what to do if type conversion fails while evaluating an expression.
         exceptionState.throwDOMException(SyntaxError, "Type conversion failed while evaluating the expression.");
-        return 0;
+        return nullptr;
     }
 
     if (type != XPathResult::ANY_TYPE) {
         result->convertTo(type, exceptionState);
         if (exceptionState.hadException())
-            return 0;
+            return nullptr;
     }
 
     return result;
diff --git a/Source/core/xml/XPathExpression.h b/Source/core/xml/XPathExpression.h
index 64a3cd3..52209da 100644
--- a/Source/core/xml/XPathExpression.h
+++ b/Source/core/xml/XPathExpression.h
@@ -28,6 +28,7 @@
 #define XPathExpression_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/PassRefPtr.h"
 #include "wtf/RefCounted.h"
@@ -43,13 +44,18 @@
 class Expression;
 }
 
-class XPathExpression : public RefCounted<XPathExpression>, public ScriptWrappable {
+class XPathExpression : public RefCountedWillBeGarbageCollectedFinalized<XPathExpression>, public ScriptWrappable {
 public:
-    static PassRefPtr<XPathExpression> create() { return adoptRef(new XPathExpression); }
+    static PassRefPtrWillBeRawPtr<XPathExpression> create()
+    {
+        return adoptRefWillBeNoop(new XPathExpression);
+    }
     ~XPathExpression();
 
-    static PassRefPtr<XPathExpression> createExpression(const String& expression, PassRefPtr<XPathNSResolver>, ExceptionState&);
-    PassRefPtr<XPathResult> evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState&);
+    static PassRefPtrWillBeRawPtr<XPathExpression> createExpression(const String& expression, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
+    PassRefPtrWillBeRawPtr<XPathResult> evaluate(Node* contextNode, unsigned short type, XPathResult*, ExceptionState&);
+
+    void trace(Visitor*) { }
 
 private:
     XPathExpression()
diff --git a/Source/core/xml/XPathExpression.idl b/Source/core/xml/XPathExpression.idl
index 7b881ea..35ab908 100644
--- a/Source/core/xml/XPathExpression.idl
+++ b/Source/core/xml/XPathExpression.idl
@@ -17,7 +17,10 @@
  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  * Boston, MA 02110-1301, USA.
  */
-interface XPathExpression {
+
+[
+    WillBeGarbageCollected
+] interface XPathExpression {
      [RaisesException] XPathResult evaluate([Default=Undefined] optional Node contextNode,
                                         [Default=Undefined] optional unsigned short type,
                                         [Default=Undefined] optional XPathResult inResult);
diff --git a/Source/core/xml/XPathNSResolver.h b/Source/core/xml/XPathNSResolver.h
index fc761f6..9758dc4 100644
--- a/Source/core/xml/XPathNSResolver.h
+++ b/Source/core/xml/XPathNSResolver.h
@@ -28,16 +28,19 @@
 #define XPathNSResolver_h
 
 #include "bindings/v8/ScriptWrappable.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 
 namespace WebCore {
 
-class XPathNSResolver : public RefCounted<XPathNSResolver>, public ScriptWrappable {
+class XPathNSResolver : public RefCountedWillBeGarbageCollectedFinalized<XPathNSResolver>, public ScriptWrappable {
 public:
     virtual ~XPathNSResolver();
     virtual AtomicString lookupNamespaceURI(const String& prefix) = 0;
 
+    virtual void trace(Visitor*) { }
+
 protected:
     XPathNSResolver()
     {
diff --git a/Source/core/xml/XPathNSResolver.idl b/Source/core/xml/XPathNSResolver.idl
index 3210792..fd16fcc 100644
--- a/Source/core/xml/XPathNSResolver.idl
+++ b/Source/core/xml/XPathNSResolver.idl
@@ -19,6 +19,7 @@
  */
 
 [
+    WillBeGarbageCollected,
     NoInterfaceObject
 ] interface XPathNSResolver {
     [TreatReturnedNullStringAs=Null] DOMString lookupNamespaceURI([Default=Undefined] optional DOMString prefix);
diff --git a/Source/core/xml/XPathNodeSet.cpp b/Source/core/xml/XPathNodeSet.cpp
index b0966c6..f4cb8a4 100644
--- a/Source/core/xml/XPathNodeSet.cpp
+++ b/Source/core/xml/XPathNodeSet.cpp
@@ -219,7 +219,7 @@
 
         unsigned attributeCount = element->attributeCount();
         for (unsigned i = 0; i < attributeCount; ++i) {
-            RefPtr<Attr> attr = element->attrIfExists(element->attributeItem(i)->name());
+            RefPtr<Attr> attr = element->attrIfExists(element->attributeItem(i).name());
             if (attr && nodes.contains(attr.get()))
                 sortedNodes.append(attr);
         }
diff --git a/Source/core/xml/XPathNodeSet.h b/Source/core/xml/XPathNodeSet.h
index c90e395..ab9d763 100644
--- a/Source/core/xml/XPathNodeSet.h
+++ b/Source/core/xml/XPathNodeSet.h
@@ -50,7 +50,7 @@
             // NodeSet itself does not verify that nodes in it are unique.
             void append(Node* node) { m_nodes.append(node); }
             void append(PassRefPtr<Node> node) { m_nodes.append(node); }
-            void append(const NodeSet& nodeSet) { m_nodes.append(nodeSet.m_nodes); }
+            void append(const NodeSet& nodeSet) { m_nodes.appendVector(nodeSet.m_nodes); }
 
             // Returns the set's first node in document order, or 0 if the set is empty.
             Node* firstNode() const;
diff --git a/Source/core/xml/XPathParser.cpp b/Source/core/xml/XPathParser.cpp
index 04f1ebf..ed50edb 100644
--- a/Source/core/xml/XPathParser.cpp
+++ b/Source/core/xml/XPathParser.cpp
@@ -463,7 +463,7 @@
     return true;
 }
 
-Expression* Parser::parseStatement(const String& statement, PassRefPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
+Expression* Parser::parseStatement(const String& statement, PassRefPtrWillBeRawPtr<XPathNSResolver> resolver, ExceptionState& exceptionState)
 {
     reset(statement);
 
diff --git a/Source/core/xml/XPathParser.h b/Source/core/xml/XPathParser.h
index e3f4cf0..16d0fac 100644
--- a/Source/core/xml/XPathParser.h
+++ b/Source/core/xml/XPathParser.h
@@ -64,6 +64,8 @@
 
 class Parser {
     WTF_MAKE_NONCOPYABLE(Parser);
+    // FIXME: oilpan: This should be STACK_ALLOCATED.
+    DISALLOW_ALLOCATION();
 public:
     Parser();
     ~Parser();
@@ -71,7 +73,7 @@
     XPathNSResolver* resolver() const { return m_resolver.get(); }
     bool expandQName(const String& qName, AtomicString& localName, AtomicString& namespaceURI);
 
-    Expression* parseStatement(const String& statement, PassRefPtr<XPathNSResolver>, ExceptionState&);
+    Expression* parseStatement(const String& statement, PassRefPtrWillBeRawPtr<XPathNSResolver>, ExceptionState&);
 
     static Parser* current() { return currentParser; }
 
@@ -120,7 +122,7 @@
     unsigned m_nextPos;
     String m_data;
     int m_lastTokenType;
-    RefPtr<XPathNSResolver> m_resolver;
+    RefPtrWillBeRawPtr<XPathNSResolver> m_resolver;
 
     HashSet<ParseNode*> m_parseNodes;
     HashSet<Vector<OwnPtr<Predicate> >*> m_predicateVectors;
diff --git a/Source/core/xml/XPathPath.cpp b/Source/core/xml/XPathPath.cpp
index 80e57b3..df5a185 100644
--- a/Source/core/xml/XPathPath.cpp
+++ b/Source/core/xml/XPathPath.cpp
@@ -105,7 +105,7 @@
         if (context->inDocument())
             context = context->ownerDocument();
         else
-            context = context->highestAncestor();
+            context = &context->highestAncestor();
     }
 
     NodeSet nodes;
diff --git a/Source/core/xml/XPathResult.h b/Source/core/xml/XPathResult.h
index 319ef6c..8ace2fd 100644
--- a/Source/core/xml/XPathResult.h
+++ b/Source/core/xml/XPathResult.h
@@ -29,6 +29,7 @@
 
 #include "bindings/v8/ScriptWrappable.h"
 #include "core/xml/XPathValue.h"
+#include "heap/Handle.h"
 #include "wtf/Forward.h"
 #include "wtf/RefCounted.h"
 
@@ -38,7 +39,7 @@
 class ExceptionState;
 class Node;
 
-class XPathResult : public RefCounted<XPathResult>, public ScriptWrappable {
+class XPathResult : public RefCountedWillBeGarbageCollectedFinalized<XPathResult>, public ScriptWrappable {
 public:
     enum XPathResultType {
         ANY_TYPE = 0,
@@ -53,7 +54,10 @@
         FIRST_ORDERED_NODE_TYPE = 9
     };
 
-    static PassRefPtr<XPathResult> create(Document* document, const XPath::Value& value) { return adoptRef(new XPathResult(document, value)); }
+    static PassRefPtrWillBeRawPtr<XPathResult> create(Document* document, const XPath::Value& value)
+    {
+        return adoptRefWillBeNoop(new XPathResult(document, value));
+    }
     ~XPathResult();
 
     void convertTo(unsigned short type, ExceptionState&);
@@ -72,6 +76,8 @@
 
     const XPath::Value& value() const { return m_value; }
 
+    void trace(Visitor*) { }
+
 private:
     XPathResult(Document*, const XPath::Value&);
 
diff --git a/Source/core/xml/XPathResult.idl b/Source/core/xml/XPathResult.idl
index dd5f9cf..f60a5ea 100644
--- a/Source/core/xml/XPathResult.idl
+++ b/Source/core/xml/XPathResult.idl
@@ -18,6 +18,7 @@
  */
 
 [
+    WillBeGarbageCollected
 ] interface XPathResult {
     const unsigned short ANY_TYPE                       = 0;
     const unsigned short NUMBER_TYPE                    = 1;
diff --git a/Source/core/xml/XPathStep.cpp b/Source/core/xml/XPathStep.cpp
index 56d7d69..4f9d144 100644
--- a/Source/core/xml/XPathStep.cpp
+++ b/Source/core/xml/XPathStep.cpp
@@ -350,8 +350,9 @@
             if (!contextElement->hasAttributes())
                 return;
 
-            for (unsigned i = 0; i < contextElement->attributeCount(); ++i) {
-                RefPtr<Attr> attr = contextElement->ensureAttr(contextElement->attributeItem(i)->name());
+            unsigned attributeCount = contextElement->attributeCount();
+            for (unsigned i = 0; i < attributeCount; ++i) {
+                RefPtr<Attr> attr = contextElement->ensureAttr(contextElement->attributeItem(i).name());
                 if (nodeMatches(attr.get(), AttributeAxis, m_nodeTest))
                     nodes.append(attr.release());
             }
diff --git a/Source/core/xml/XSLStyleSheet.h b/Source/core/xml/XSLStyleSheet.h
index 2a3c9bc..a2064f3 100644
--- a/Source/core/xml/XSLStyleSheet.h
+++ b/Source/core/xml/XSLStyleSheet.h
@@ -38,28 +38,28 @@
 
 class XSLStyleSheet FINAL : public StyleSheet {
 public:
-    static PassRefPtr<XSLStyleSheet> create(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL)
+    static PassRefPtrWillBeRawPtr<XSLStyleSheet> create(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL)
     {
         ASSERT(RuntimeEnabledFeatures::xsltEnabled());
-        return adoptRef(new XSLStyleSheet(parentImport, originalURL, finalURL));
+        return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentImport, originalURL, finalURL));
     }
-    static PassRefPtr<XSLStyleSheet> create(ProcessingInstruction* parentNode, const String& originalURL, const KURL& finalURL)
+    static PassRefPtrWillBeRawPtr<XSLStyleSheet> create(ProcessingInstruction* parentNode, const String& originalURL, const KURL& finalURL)
     {
         ASSERT(RuntimeEnabledFeatures::xsltEnabled());
-        return adoptRef(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
+        return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
     }
-    static PassRefPtr<XSLStyleSheet> createEmbedded(ProcessingInstruction* parentNode, const KURL& finalURL)
+    static PassRefPtrWillBeRawPtr<XSLStyleSheet> createEmbedded(ProcessingInstruction* parentNode, const KURL& finalURL)
     {
         ASSERT(RuntimeEnabledFeatures::xsltEnabled());
-        return adoptRef(new XSLStyleSheet(parentNode, finalURL.string(), finalURL, true));
+        return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentNode, finalURL.string(), finalURL, true));
     }
 
     // Taking an arbitrary node is unsafe, because owner node pointer can become stale.
     // XSLTProcessor ensures that the stylesheet doesn't outlive its parent, in part by not exposing it to JavaScript.
-    static PassRefPtr<XSLStyleSheet> createForXSLTProcessor(Node* parentNode, const String& originalURL, const KURL& finalURL)
+    static PassRefPtrWillBeRawPtr<XSLStyleSheet> createForXSLTProcessor(Node* parentNode, const String& originalURL, const KURL& finalURL)
     {
         ASSERT(RuntimeEnabledFeatures::xsltEnabled());
-        return adoptRef(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
+        return adoptRefWillBeRefCountedGarbageCollected(new XSLStyleSheet(parentNode, originalURL, finalURL, false));
     }
 
     virtual ~XSLStyleSheet();
@@ -99,6 +99,8 @@
     virtual KURL baseURL() const OVERRIDE { return m_finalURL; }
     virtual bool isLoading() const OVERRIDE;
 
+    virtual void trace(Visitor*) OVERRIDE;
+
 private:
     XSLStyleSheet(Node* parentNode, const String& originalURL, const KURL& finalURL, bool embedded);
     XSLStyleSheet(XSLImportRule* parentImport, const String& originalURL, const KURL& finalURL);
diff --git a/Source/core/xml/XSLStyleSheetLibxslt.cpp b/Source/core/xml/XSLStyleSheetLibxslt.cpp
index 38cd4ba..215d922 100644
--- a/Source/core/xml/XSLStyleSheetLibxslt.cpp
+++ b/Source/core/xml/XSLStyleSheetLibxslt.cpp
@@ -25,8 +25,8 @@
 #include "core/dom/Document.h"
 #include "core/dom/Node.h"
 #include "core/dom/TransformSource.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/xml/XSLImportRule.h"
 #include "core/xml/XSLTProcessor.h"
 #include "core/xml/parser/XMLDocumentParserScope.h"
@@ -129,7 +129,7 @@
     m_stylesheetDocTaken = false;
 
     PageConsole* console = 0;
-    Frame* frame = ownerDocument()->frame();
+    LocalFrame* frame = ownerDocument()->frame();
     if (frame && frame->host())
         console = &frame->host()->console();
 
@@ -303,4 +303,8 @@
     m_stylesheetDocTaken = true;
 }
 
+void XSLStyleSheet::trace(Visitor*)
+{
+}
+
 } // namespace WebCore
diff --git a/Source/core/xml/XSLTProcessor.cpp b/Source/core/xml/XSLTProcessor.cpp
index 48fd5cf..a2061fa 100644
--- a/Source/core/xml/XSLTProcessor.cpp
+++ b/Source/core/xml/XSLTProcessor.cpp
@@ -27,10 +27,10 @@
 #include "core/dom/DocumentEncodingData.h"
 #include "core/dom/DocumentFragment.h"
 #include "core/editing/markup.h"
-#include "core/frame/ContentSecurityPolicy.h"
 #include "core/frame/DOMWindow.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameView.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/csp/ContentSecurityPolicy.h"
 #include "platform/weborigin/SecurityOrigin.h"
 #include "wtf/Assertions.h"
 #include "wtf/Vector.h"
@@ -59,7 +59,7 @@
 }
 
 PassRefPtr<Document> XSLTProcessor::createDocumentFromSource(const String& sourceString,
-    const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame)
+    const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, LocalFrame* frame)
 {
     RefPtr<Document> ownerDocument(sourceNode->document());
     bool sourceIsDocument = (sourceNode == ownerDocument.get());
@@ -102,20 +102,20 @@
 PassRefPtr<Document> XSLTProcessor::transformToDocument(Node* sourceNode)
 {
     if (!sourceNode)
-        return 0;
+        return nullptr;
 
     String resultMIMEType;
     String resultString;
     String resultEncoding;
     if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
-        return 0;
+        return nullptr;
     return createDocumentFromSource(resultString, resultEncoding, resultMIMEType, sourceNode, 0);
 }
 
 PassRefPtr<DocumentFragment> XSLTProcessor::transformToFragment(Node* sourceNode, Document* outputDoc)
 {
     if (!sourceNode || !outputDoc)
-        return 0;
+        return nullptr;
 
     String resultMIMEType;
     String resultString;
@@ -126,7 +126,7 @@
         resultMIMEType = "text/html";
 
     if (!transformToString(sourceNode, resultMIMEType, resultString, resultEncoding))
-        return 0;
+        return nullptr;
     return createFragmentForTransformToFragment(resultString, resultMIMEType, *outputDoc);
 }
 
diff --git a/Source/core/xml/XSLTProcessor.h b/Source/core/xml/XSLTProcessor.h
index 23272c2..22fb56b 100644
--- a/Source/core/xml/XSLTProcessor.h
+++ b/Source/core/xml/XSLTProcessor.h
@@ -35,22 +35,22 @@
 
 namespace WebCore {
 
-class Frame;
+class LocalFrame;
 class Document;
 class DocumentFragment;
 
-class XSLTProcessor : public RefCounted<XSLTProcessor>, public ScriptWrappable {
+class XSLTProcessor : public RefCountedWillBeGarbageCollectedFinalized<XSLTProcessor>, public ScriptWrappable {
 public:
-    static PassRefPtr<XSLTProcessor> create()
+    static PassRefPtrWillBeRawPtr<XSLTProcessor> create()
     {
         ASSERT(RuntimeEnabledFeatures::xsltEnabled());
-        return adoptRef(new XSLTProcessor);
+        return adoptRefWillBeNoop(new XSLTProcessor);
     }
     ~XSLTProcessor();
 
     void setXSLStyleSheet(PassRefPtr<XSLStyleSheet> styleSheet) { m_stylesheet = styleSheet; }
     bool transformToString(Node* source, String& resultMIMEType, String& resultString, String& resultEncoding);
-    PassRefPtr<Document> createDocumentFromSource(const String& source, const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, Frame* frame);
+    PassRefPtr<Document> createDocumentFromSource(const String& source, const String& sourceEncoding, const String& sourceMIMEType, Node* sourceNode, LocalFrame* frame);
 
     // DOM methods
     void importStylesheet(PassRefPtr<Node> style)
@@ -76,6 +76,8 @@
 
     typedef HashMap<String, String> ParameterMap;
 
+    void trace(Visitor*) { }
+
 private:
     XSLTProcessor()
     {
diff --git a/Source/core/xml/XSLTProcessor.idl b/Source/core/xml/XSLTProcessor.idl
index 7c99868..dc51a60 100644
--- a/Source/core/xml/XSLTProcessor.idl
+++ b/Source/core/xml/XSLTProcessor.idl
@@ -31,6 +31,7 @@
 // http://bugs.webkit.org/show_bug.cgi?id=5446
 
 [
+    WillBeGarbageCollected,
     Constructor,
     RuntimeEnabled=XSLT,
     MeasureAs=XSLTProcessor
diff --git a/Source/core/xml/XSLTProcessorLibxslt.cpp b/Source/core/xml/XSLTProcessorLibxslt.cpp
index d1a6b12..278fe21 100644
--- a/Source/core/xml/XSLTProcessorLibxslt.cpp
+++ b/Source/core/xml/XSLTProcessorLibxslt.cpp
@@ -33,8 +33,8 @@
 #include "core/editing/markup.h"
 #include "core/fetch/Resource.h"
 #include "core/fetch/ResourceFetcher.h"
-#include "core/frame/Frame.h"
 #include "core/frame/FrameHost.h"
+#include "core/frame/LocalFrame.h"
 #include "core/frame/PageConsole.h"
 #include "core/xml/XSLStyleSheet.h"
 #include "core/xml/XSLTExtensions.h"
@@ -109,7 +109,7 @@
             return 0;
 
         PageConsole* console = 0;
-        Frame* frame = globalProcessor->xslStylesheet()->ownerDocument()->frame();
+        LocalFrame* frame = globalProcessor->xslStylesheet()->ownerDocument()->frame();
         if (frame && frame->host())
             console = &frame->host()->console();
         xmlSetStructuredErrorFunc(console, XSLTProcessor::parseErrorFunc);
@@ -280,7 +280,7 @@
     xsltStylesheetPtr sheet = xsltStylesheetPointer(m_stylesheet, m_stylesheetRootNode.get());
     if (!sheet) {
         setXSLTLoadCallBack(0, 0, 0);
-        m_stylesheet = 0;
+        m_stylesheet = nullptr;
         return false;
     }
     m_stylesheet->clearDocuments();
@@ -339,7 +339,7 @@
     sheet->method = origMethod;
     setXSLTLoadCallBack(0, 0, 0);
     xsltFreeStylesheet(sheet);
-    m_stylesheet = 0;
+    m_stylesheet = nullptr;
 
     return success;
 }
diff --git a/Source/core/xml/parser/SharedBufferReader.cpp b/Source/core/xml/parser/SharedBufferReader.cpp
new file mode 100644
index 0000000..c42c33f
--- /dev/null
+++ b/Source/core/xml/parser/SharedBufferReader.cpp
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/xml/parser/SharedBufferReader.h"
+
+#include "platform/SharedBuffer.h"
+#include "wtf/PassRefPtr.h"
+#include "wtf/RefPtr.h"
+
+#include <algorithm>
+#include <cstring>
+
+namespace WebCore {
+
+SharedBufferReader::SharedBufferReader(PassRefPtr<SharedBuffer> buffer)
+    : m_buffer(buffer)
+    , m_currentOffset(0)
+{
+}
+
+SharedBufferReader::~SharedBufferReader()
+{
+}
+
+int SharedBufferReader::readData(char* outputBuffer, unsigned askedToRead)
+{
+    if (!m_buffer || m_currentOffset > m_buffer->size())
+        return 0;
+
+    unsigned bytesCopied = 0;
+    unsigned bytesLeft = m_buffer->size() - m_currentOffset;
+    unsigned lenToCopy = std::min(askedToRead, bytesLeft);
+
+    while (bytesCopied < lenToCopy) {
+        const char* data;
+        unsigned segmentSize = m_buffer->getSomeData(data, m_currentOffset);
+        if (!segmentSize)
+            break;
+
+        segmentSize = std::min(segmentSize, lenToCopy - bytesCopied);
+        memcpy(outputBuffer + bytesCopied, data, segmentSize);
+        bytesCopied += segmentSize;
+        m_currentOffset += segmentSize;
+    }
+
+    return bytesCopied;
+}
+
+} // namespace WebCore
diff --git a/Source/core/html/HTMLImportStateResolver.h b/Source/core/xml/parser/SharedBufferReader.h
similarity index 71%
copy from Source/core/html/HTMLImportStateResolver.h
copy to Source/core/xml/parser/SharedBufferReader.h
index 417680c..7217de9 100644
--- a/Source/core/html/HTMLImportStateResolver.h
+++ b/Source/core/xml/parser/SharedBufferReader.h
@@ -28,34 +28,33 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef HTMLImportStateResolver_h
-#define HTMLImportStateResolver_h
+#ifndef SharedBufferReader_h
+#define SharedBufferReader_h
 
-#include "core/html/HTMLImportState.h"
+#include "wtf/FastAllocBase.h"
+#include "wtf/Forward.h"
+#include "wtf/RefPtr.h"
 
 namespace WebCore {
 
-class HTMLImport;
+class SharedBuffer;
 
-class HTMLImportStateResolver {
+// Allows transfer of data in multiple chunks from a SharedBuffer to a provided buffer.
+class SharedBufferReader {
+    WTF_MAKE_FAST_ALLOCATED;
 public:
-    explicit HTMLImportStateResolver(HTMLImport* import)
-        : m_import(import)
-    { }
+    SharedBufferReader(PassRefPtr<SharedBuffer>);
 
-    HTMLImportState resolve() const;
+    ~SharedBufferReader();
+
+    // Returns the number of bytes that were read (i.e. written to |outputBuffer|).
+    int readData(char* outputBuffer, unsigned askedToRead);
 
 private:
-    static bool isBlockingFollowers(HTMLImport*);
-
-    bool shouldBlockDocumentCreation() const;
-    bool shouldBlockScriptExecution() const;
-    bool isActive() const;
-
-    HTMLImport* m_import;
+    RefPtr<SharedBuffer> m_buffer;
+    unsigned m_currentOffset;
 };
 
-}
+} // namespace WebCore
 
-#endif // HTMLImportStateResolver_h
-
+#endif // SharedBufferReader_h
diff --git a/Source/core/xml/parser/SharedBufferReaderTest.cpp b/Source/core/xml/parser/SharedBufferReaderTest.cpp
new file mode 100644
index 0000000..a908c94
--- /dev/null
+++ b/Source/core/xml/parser/SharedBufferReaderTest.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright (C) 2014 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "core/xml/parser/SharedBufferReader.h"
+
+#include "platform/SharedBuffer.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <gtest/gtest.h>
+#include <vector>
+
+namespace WebCore {
+
+TEST(SharedBufferReaderTest, readDataWithNullSharedBuffer)
+{
+    SharedBufferReader reader(nullptr);
+    char buffer[32];
+
+    EXPECT_EQ(0, reader.readData(buffer, sizeof(buffer)));
+}
+
+TEST(SharedBufferReaderTest, readDataWith0BytesRequest)
+{
+    RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create();
+    SharedBufferReader reader(sharedBuffer);
+
+    EXPECT_EQ(0, reader.readData(0, 0));
+}
+
+TEST(SharedBufferReaderTest, readDataWithSizeBiggerThanSharedBufferSize)
+{
+    static const char testData[] = "hello";
+    RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(testData, sizeof(testData));
+
+    SharedBufferReader reader(sharedBuffer);
+
+    const int extraBytes = 3;
+    char outputBuffer[sizeof(testData) + extraBytes];
+
+    const char initializationByte = 'a';
+    memset(outputBuffer, initializationByte, sizeof(outputBuffer));
+    EXPECT_EQ(sizeof(testData),
+        static_cast<size_t>(reader.readData(outputBuffer, sizeof(outputBuffer))));
+
+    EXPECT_TRUE(std::equal(testData, testData + sizeof(testData), outputBuffer));
+    // Check that the bytes past index sizeof(testData) were not touched.
+    EXPECT_EQ(extraBytes,
+        std::count(outputBuffer, outputBuffer + sizeof(outputBuffer), initializationByte));
+}
+
+TEST(SharedBufferReaderTest, readDataInMultiples)
+{
+    const int iterationsCount = 8;
+    const int bytesPerIteration = 64;
+
+    std::vector<char> testData(iterationsCount * bytesPerIteration);
+    std::generate(testData.begin(), testData.end(), &std::rand);
+
+    RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(&testData[0], testData.size());
+    SharedBufferReader reader(sharedBuffer);
+
+    std::vector<char> destinationVector(testData.size());
+
+    for (int i = 0; i < iterationsCount; ++i) {
+        const int offset = i * bytesPerIteration;
+        const int bytesRead = reader.readData(&destinationVector[0] + offset, bytesPerIteration);
+        EXPECT_EQ(bytesPerIteration, bytesRead);
+    }
+
+    EXPECT_TRUE(std::equal(testData.begin(), testData.end(), destinationVector.begin()));
+}
+
+TEST(SharedBufferReaderTest, clearSharedBufferBetweenCallsToReadData)
+{
+    std::vector<char> testData(128);
+    std::generate(testData.begin(), testData.end(), &std::rand);
+
+    RefPtr<SharedBuffer> sharedBuffer = SharedBuffer::create(&testData[0], testData.size());
+    SharedBufferReader reader(sharedBuffer);
+
+    std::vector<char> destinationVector(testData.size());
+    const int bytesToRead = testData.size() / 2;
+    EXPECT_EQ(bytesToRead, reader.readData(&destinationVector[0], bytesToRead));
+
+    sharedBuffer->clear();
+
+    EXPECT_EQ(0, reader.readData(&destinationVector[0], bytesToRead));
+}
+
+} // namespace WebCore
diff --git a/Source/core/xml/parser/XMLDocumentParser.cpp b/Source/core/xml/parser/XMLDocumentParser.cpp
index 10106ae..56c0f3d 100644
--- a/Source/core/xml/parser/XMLDocumentParser.cpp
+++ b/Source/core/xml/parser/XMLDocumentParser.cpp
@@ -48,15 +48,16 @@
 #include "core/dom/TransformSource.h"
 #include "core/fetch/ResourceFetcher.h"
 #include "core/fetch/ScriptResource.h"
-#include "core/frame/Frame.h"
+#include "core/frame/LocalFrame.h"
+#include "core/frame/UseCounter.h"
 #include "core/html/HTMLHtmlElement.h"
 #include "core/html/HTMLTemplateElement.h"
 #include "core/html/parser/HTMLEntityParser.h"
 #include "core/html/parser/TextResourceDecoder.h"
 #include "core/loader/FrameLoader.h"
 #include "core/loader/ImageLoader.h"
-#include "core/frame/UseCounter.h"
 #include "core/xml/XMLTreeViewer.h"
+#include "core/xml/parser/SharedBufferReader.h"
 #include "core/xml/parser/XMLDocumentParserScope.h"
 #include "core/xml/parser/XMLParserInput.h"
 #include "platform/SharedBuffer.h"
@@ -320,7 +321,7 @@
     if (m_currentNode && m_currentNode != document())
         m_currentNode->deref();
     m_currentNode = 0;
-    m_leafTextNode = 0;
+    m_leafTextNode = nullptr;
 
     if (m_currentNodeStack.size()) { // Aborted parsing.
         for (size_t i = m_currentNodeStack.size() - 1; i != 0; --i)
@@ -390,7 +391,7 @@
 
     m_leafTextNode->appendData(toString(m_bufferedText.data(), m_bufferedText.size()));
     m_bufferedText.clear();
-    m_leafTextNode = 0;
+    m_leafTextNode = nullptr;
 }
 
 void XMLDocumentParser::detach()
@@ -460,7 +461,7 @@
     m_pendingScript = 0;
 
     RefPtr<Element> e = m_scriptElement;
-    m_scriptElement = 0;
+    m_scriptElement = nullptr;
 
     ScriptLoader* scriptLoader = toScriptLoaderIfPossible(e.get());
     ASSERT(scriptLoader);
@@ -475,7 +476,7 @@
         scriptLoader->dispatchLoadEvent();
     }
 
-    m_scriptElement = 0;
+    m_scriptElement = nullptr;
 
     if (!isDetached() && !m_requestingScript)
         resumeParsing();
@@ -525,27 +526,6 @@
     return XMLDocumentParserScope::currentFetcher && currentThread() == libxmlLoaderThread;
 }
 
-class OffsetBuffer {
-    WTF_MAKE_FAST_ALLOCATED;
-public:
-    OffsetBuffer(const Vector<char>& b) : m_buffer(b), m_currentOffset(0) { }
-
-    int readOutBytes(char* outputBuffer, unsigned askedToRead)
-    {
-        unsigned bytesLeft = m_buffer.size() - m_currentOffset;
-        unsigned lenToCopy = min(askedToRead, bytesLeft);
-        if (lenToCopy) {
-            memcpy(outputBuffer, m_buffer.data() + m_currentOffset, lenToCopy);
-            m_currentOffset += lenToCopy;
-        }
-        return lenToCopy;
-    }
-
-private:
-    Vector<char> m_buffer;
-    unsigned m_currentOffset;
-};
-
 static inline void setAttributes(Element* element, Vector<Attribute>& attributeVector, ParserContentPolicy parserContentPolicy)
 {
     if (!scriptingContentIsAllowed(parserContentPolicy))
@@ -642,7 +622,7 @@
         return &globalDescriptor;
 
     KURL finalURL;
-    Vector<char> data;
+    RefPtr<SharedBuffer> data;
 
     {
         ResourceFetcher* fetcher = XMLDocumentParserScope::currentFetcher;
@@ -653,7 +633,7 @@
             FetchRequest request(ResourceRequest(url), FetchInitiatorTypeNames::xml, ResourceFetcher::defaultResourceOptions());
             ResourcePtr<Resource> resource = fetcher->fetchSynchronously(request);
             if (resource && !resource->errorOccurred()) {
-                resource->resourceBuffer()->moveTo(data);
+                data = resource->resourceBuffer();
                 finalURL = resource->response().url();
             }
         }
@@ -664,7 +644,7 @@
     if (!shouldAllowExternalLoad(finalURL))
         return &globalDescriptor;
 
-    return new OffsetBuffer(data);
+    return new SharedBufferReader(data);
 }
 
 static int readFunc(void* context, char* buffer, int len)
@@ -673,8 +653,8 @@
     if (context == &globalDescriptor)
         return 0;
 
-    OffsetBuffer* data = static_cast<OffsetBuffer*>(context);
-    return data->readOutBytes(buffer, len);
+    SharedBufferReader* data = static_cast<SharedBufferReader*>(context);
+    return data->readData(buffer, len);
 }
 
 static int writeFunc(void*, const char*, int)
@@ -686,7 +666,7 @@
 static int closeFunc(void* context)
 {
     if (context != &globalDescriptor) {
-        OffsetBuffer* data = static_cast<OffsetBuffer*>(context);
+        SharedBufferReader* data = static_cast<SharedBufferReader*>(context);
         delete data;
     }
     return 0;
@@ -733,7 +713,7 @@
     xmlParserCtxtPtr parser = xmlCreateMemoryParserCtxt(chunk.data(), chunk.length());
 
     if (!parser)
-        return 0;
+        return nullptr;
 
     // Copy the sax handler
     memcpy(parser->sax, handlers, sizeof(xmlSAXHandler));
@@ -765,7 +745,7 @@
 XMLDocumentParser::XMLDocumentParser(Document* document, FrameView* frameView)
     : ScriptableDocumentParser(document)
     , m_view(frameView)
-    , m_context(0)
+    , m_context(nullptr)
     , m_currentNode(document)
     , m_isCurrentlyParsing8BitChunk(false)
     , m_sawError(false)
@@ -788,7 +768,7 @@
 XMLDocumentParser::XMLDocumentParser(DocumentFragment* fragment, Element* parentElement, ParserContentPolicy parserContentPolicy)
     : ScriptableDocumentParser(&fragment->document(), parserContentPolicy)
     , m_view(0)
-    , m_context(0)
+    , m_context(nullptr)
     , m_currentNode(fragment)
     , m_isCurrentlyParsing8BitChunk(false)
     , m_sawError(false)
@@ -823,12 +803,13 @@
     for (; !elemStack.isEmpty(); elemStack.removeLast()) {
         Element* element = elemStack.last();
         if (element->hasAttributes()) {
-            for (unsigned i = 0; i < element->attributeCount(); i++) {
-                const Attribute* attribute = element->attributeItem(i);
-                if (attribute->localName() == xmlnsAtom)
-                    m_defaultNamespaceURI = attribute->value();
-                else if (attribute->prefix() == xmlnsAtom)
-                    m_prefixToNamespaceMap.set(attribute->localName(), attribute->value());
+            unsigned attributeCount = element->attributeCount();
+            for (unsigned i = 0; i < attributeCount; ++i) {
+                const Attribute& attribute = element->attributeItem(i);
+                if (attribute.localName() == xmlnsAtom)
+                    m_defaultNamespaceURI = attribute.value();
+                else if (attribute.prefix() == xmlnsAtom)
+                    m_prefixToNamespaceMap.set(attribute.localName(), attribute.value());
             }
         }
     }
@@ -995,13 +976,13 @@
 
     m_currentNode->parserAppendChild(newElement.get());
 
-    if (newElement->hasTagName(HTMLNames::templateTag))
-        pushCurrentNode(toHTMLTemplateElement(newElement.get())->content());
+    if (isHTMLTemplateElement(*newElement))
+        pushCurrentNode(toHTMLTemplateElement(*newElement).content());
     else
         pushCurrentNode(newElement.get());
 
-    if (newElement->hasTagName(HTMLNames::htmlTag))
-        toHTMLHtmlElement(newElement)->insertedByParser();
+    if (isHTMLHtmlElement(*newElement))
+        toHTMLHtmlElement(*newElement).insertedByParser();
 
     if (!m_parsingFragment && isFirstElement && document()->frame())
         document()->frame()->loader().dispatchDocumentElementAvailable();
@@ -1072,7 +1053,7 @@
             if (m_pendingScript)
                 pauseParsing();
         } else {
-            m_scriptElement = 0;
+            m_scriptElement = nullptr;
         }
 
         // JavaScript may have detached the parser
@@ -1453,7 +1434,7 @@
                 finishParsing(context());
             }
 
-            m_context = 0;
+            m_context = nullptr;
         }
     }